diff options
Diffstat (limited to 'src/ldo.c')
-rw-r--r-- | src/ldo.c | 42 |
1 files changed, 26 insertions, 16 deletions
@@ -1,17 +1,19 @@ /* -** $Id: ldo.c,v 2.130 2014/10/17 16:28:21 roberto Exp $ +** $Id: ldo.c,v 2.135 2014/11/11 17:13:39 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ +#define ldo_c +#define LUA_CORE + +#include "lprefix.h" + #include <setjmp.h> #include <stdlib.h> #include <string.h> -#define ldo_c -#define LUA_CORE - #include "lua.h" #include "lapi.h" @@ -67,7 +69,7 @@ #else /* }{ */ -/* ANSI handling with long jumps */ +/* ISO C handling with long jumps */ #define LUAI_THROW(L,c) longjmp((c)->b, 1) #define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } #define luai_jmpbuf jmp_buf @@ -119,8 +121,11 @@ l_noret luaD_throw (lua_State *L, int errcode) { } else { /* no handler at all; abort */ if (g->panic) { /* panic function? */ + seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */ + if (L->ci->top < L->top) + L->ci->top = L->top; /* pushing msg. can break this invariant */ lua_unlock(L); - g->panic(L); /* call it (last chance to jump out) */ + g->panic(L); /* call panic function (last chance to jump out) */ } abort(); } @@ -281,18 +286,21 @@ static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { } -static StkId tryfuncTM (lua_State *L, StkId func) { +/* +** Check whether __call metafield of 'func' is a function. If so, put +** it in stack below original 'func' so that 'luaD_precall' can call +** it. Raise an error if __call metafield is not a function. +*/ +static void tryfuncTM (lua_State *L, StkId func) { const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); StkId p; - ptrdiff_t funcr = savestack(L, func); if (!ttisfunction(tm)) luaG_typeerror(L, func, "call"); - /* Open a hole inside the stack at `func' */ - for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); - incr_top(L); - func = restorestack(L, funcr); /* previous call may change stack */ + /* Open a hole inside the stack at 'func' */ + for (p = L->top; p > func; p--) + setobjs2s(L, p, p-1); + L->top++; /* slot ensured by caller */ setobj2s(L, func, tm); /* tag method is the new function to be called */ - return func; } @@ -362,7 +370,9 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { return 0; } default: { /* not a function */ - func = tryfuncTM(L, func); /* retry with 'function' tag method */ + luaD_checkstack(L, 1); /* ensure space for metamethod */ + func = restorestack(L, funcr); /* previous call may change stack */ + tryfuncTM(L, func); /* try to get '__call' metamethod */ return luaD_precall(L, func, nresults); /* now it must be a function */ } } @@ -575,7 +585,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { status = luaD_rawrunprotected(L, unroll, &status); } if (errorstatus(status)) { /* unrecoverable error? */ - L->status = cast_byte(status); /* mark thread as `dead' */ + L->status = cast_byte(status); /* mark thread as 'dead' */ seterrorobj(L, status, L->top); /* push error message */ L->ci->top = L->top; } @@ -650,7 +660,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, /* ** Execute a protected parser. */ -struct SParser { /* data to `f_parser' */ +struct SParser { /* data to 'f_parser' */ ZIO *z; Mbuffer buff; /* dynamic structure used by the scanner */ Dyndata dyd; /* dynamic structures used by the parser */ |