mirror of https://github.com/rusefi/lua.git
no more 'stackless' implementation; 'luaV_execute' calls itself
recursively to execute function calls. 'unroll' continues all executions suspended by an yield (through a long jump)
This commit is contained in:
parent
39f26b1480
commit
196c87c9ce
3
ldebug.c
3
ldebug.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: ldebug.c,v 2.143 2017/11/13 12:20:51 roberto Exp roberto $
|
** $Id: ldebug.c,v 2.144 2017/11/13 15:36:52 roberto Exp roberto $
|
||||||
** Debug Interface
|
** Debug Interface
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -724,6 +724,7 @@ l_noret luaG_errormsg (lua_State *L) {
|
||||||
setobjs2s(L, L->top, L->top - 1); /* move argument */
|
setobjs2s(L, L->top, L->top - 1); /* move argument */
|
||||||
setobjs2s(L, L->top - 1, errfunc); /* push function */
|
setobjs2s(L, L->top - 1, errfunc); /* push function */
|
||||||
L->top++; /* assume EXTRA_STACK */
|
L->top++; /* assume EXTRA_STACK */
|
||||||
|
luaE_incCcalls(L);
|
||||||
luaD_callnoyield(L, L->top - 2, 1); /* call it */
|
luaD_callnoyield(L, L->top - 2, 1); /* call it */
|
||||||
}
|
}
|
||||||
luaD_throw(L, LUA_ERRRUN);
|
luaD_throw(L, LUA_ERRRUN);
|
||||||
|
|
66
ldo.c
66
ldo.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: ldo.c,v 2.172 2017/11/13 15:36:52 roberto Exp roberto $
|
** $Id: ldo.c,v 2.173 2017/11/21 14:17:35 roberto Exp roberto $
|
||||||
** Stack and Call structure of Lua
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -135,7 +135,7 @@ l_noret luaD_throw (lua_State *L, int errcode) {
|
||||||
|
|
||||||
|
|
||||||
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
|
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
|
||||||
unsigned short oldnCcalls = L->nCcalls;
|
unsigned short oldnCcalls = L->nCcalls - L->nci;
|
||||||
struct lua_longjmp lj;
|
struct lua_longjmp lj;
|
||||||
lj.status = LUA_OK;
|
lj.status = LUA_OK;
|
||||||
lj.previous = L->errorJmp; /* chain new error handler */
|
lj.previous = L->errorJmp; /* chain new error handler */
|
||||||
|
@ -144,7 +144,7 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
|
||||||
(*f)(L, ud);
|
(*f)(L, ud);
|
||||||
);
|
);
|
||||||
L->errorJmp = lj.previous; /* restore old error handler */
|
L->errorJmp = lj.previous; /* restore old error handler */
|
||||||
L->nCcalls = oldnCcalls;
|
L->nCcalls = oldnCcalls + L->nci;
|
||||||
return lj.status;
|
return lj.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ static void callhook (lua_State *L, CallInfo *ci, int istail) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Check whether __call metafield of 'func' is a function. If so, put
|
** 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 in stack below original 'func' so that 'luaD_call' can call
|
||||||
** it. Raise an error if __call metafield is not a function.
|
** it. Raise an error if __call metafield is not a function.
|
||||||
*/
|
*/
|
||||||
StkId luaD_tryfuncTM (lua_State *L, StkId func) {
|
StkId luaD_tryfuncTM (lua_State *L, StkId func) {
|
||||||
|
@ -417,13 +417,12 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n) {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Prepares a function call: checks the stack, creates a new CallInfo
|
** Call a function (C or Lua). The function to be called is at *func.
|
||||||
** entry, fills in the relevant information, calls hook if needed.
|
** The arguments are on the stack, right after the function.
|
||||||
** If function is a C function, does the call, too. (Otherwise, leave
|
** When returns, all the results are on the stack, starting at the original
|
||||||
** the execution ('luaV_execute') to the caller, to allow stackless
|
** function position.
|
||||||
** calls.) Returns true iff function has been executed (C function).
|
|
||||||
*/
|
*/
|
||||||
int luaD_precall (lua_State *L, StkId func, int nresults) {
|
void luaD_call (lua_State *L, StkId func, int nresults) {
|
||||||
lua_CFunction f;
|
lua_CFunction f;
|
||||||
TValue *funcv = s2v(func);
|
TValue *funcv = s2v(func);
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
|
@ -449,7 +448,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, n);
|
api_checknelems(L, n);
|
||||||
luaD_poscall(L, ci, L->top - n, n);
|
luaD_poscall(L, ci, L->top - n, n);
|
||||||
return 1;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_TLCL: { /* Lua function: prepare its call */
|
case LUA_TLCL: { /* Lua function: prepare its call */
|
||||||
Proto *p = clLvalue(funcv)->p;
|
Proto *p = clLvalue(funcv)->p;
|
||||||
|
@ -469,46 +468,18 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||||
ci->callstatus = CIST_LUA;
|
ci->callstatus = CIST_LUA;
|
||||||
if (L->hookmask)
|
if (L->hookmask)
|
||||||
callhook(L, ci, 0);
|
callhook(L, ci, 0);
|
||||||
return 0;
|
luaV_execute(L); /* run the function */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default: { /* not a function */
|
default: { /* not a function */
|
||||||
func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
|
func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
|
||||||
return luaD_precall(L, func, nresults); /* now it must be a function */
|
luaD_call(L, func, nresults); /* now it must be a function */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Check appropriate error for stack overflow ("regular" overflow or
|
|
||||||
** overflow while handling stack overflow). If 'nCalls' is larger than
|
|
||||||
** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but
|
|
||||||
** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to
|
|
||||||
** allow overflow handling to work)
|
|
||||||
*/
|
|
||||||
static void stackerror (lua_State *L) {
|
|
||||||
if (L->nCcalls == LUAI_MAXCCALLS)
|
|
||||||
luaG_runerror(L, "C stack overflow");
|
|
||||||
else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
|
|
||||||
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Call a function (C or Lua). The function to be called is at *func.
|
|
||||||
** The arguments are on the stack, right after the function.
|
|
||||||
** When returns, all the results are on the stack, starting at the original
|
|
||||||
** function position.
|
|
||||||
*/
|
|
||||||
void luaD_call (lua_State *L, StkId func, int nResults) {
|
|
||||||
if (++L->nCcalls >= LUAI_MAXCCALLS)
|
|
||||||
stackerror(L);
|
|
||||||
if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
|
|
||||||
luaV_execute(L); /* call it */
|
|
||||||
L->nCcalls--;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Similar to 'luaD_call', but does not allow yields during the call
|
** Similar to 'luaD_call', but does not allow yields during the call
|
||||||
*/
|
*/
|
||||||
|
@ -541,7 +512,7 @@ static void finishCcall (lua_State *L, int status) {
|
||||||
n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */
|
n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, n);
|
api_checknelems(L, n);
|
||||||
luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */
|
luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_call' */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -629,8 +600,7 @@ static void resume (lua_State *L, void *ud) {
|
||||||
StkId firstArg = L->top - n; /* first argument */
|
StkId firstArg = L->top - n; /* first argument */
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
if (L->status == LUA_OK) { /* starting a coroutine? */
|
if (L->status == LUA_OK) { /* starting a coroutine? */
|
||||||
if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
|
luaD_call(L, firstArg - 1, LUA_MULTRET);
|
||||||
luaV_execute(L); /* call it */
|
|
||||||
}
|
}
|
||||||
else { /* resuming from previous yield */
|
else { /* resuming from previous yield */
|
||||||
lua_assert(L->status == LUA_YIELD);
|
lua_assert(L->status == LUA_YIELD);
|
||||||
|
@ -645,7 +615,7 @@ static void resume (lua_State *L, void *ud) {
|
||||||
api_checknelems(L, n);
|
api_checknelems(L, n);
|
||||||
firstArg = L->top - n; /* yield results come from continuation */
|
firstArg = L->top - n; /* yield results come from continuation */
|
||||||
}
|
}
|
||||||
luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */
|
luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_call' */
|
||||||
}
|
}
|
||||||
unroll(L, NULL); /* run continuation */
|
unroll(L, NULL); /* run continuation */
|
||||||
}
|
}
|
||||||
|
@ -688,7 +658,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
|
||||||
: L->top - (L->ci->func + 1);
|
: L->top - (L->ci->func + 1);
|
||||||
L->nny = oldnny; /* restore 'nny' */
|
L->nny = oldnny; /* restore 'nny' */
|
||||||
L->nCcalls--;
|
L->nCcalls--;
|
||||||
lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
|
// lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
3
ldo.h
3
ldo.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: ldo.h,v 2.33 2017/11/07 13:25:26 roberto Exp roberto $
|
** $Id: ldo.h,v 2.34 2017/11/21 14:18:03 roberto Exp roberto $
|
||||||
** Stack and Call structure of Lua
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -47,7 +47,6 @@ typedef void (*Pfunc) (lua_State *L, void *ud);
|
||||||
LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
||||||
const char *mode);
|
const char *mode);
|
||||||
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
|
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
|
||||||
LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
|
|
||||||
LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n);
|
LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n);
|
||||||
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
|
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
|
||||||
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
|
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: llimits.h,v 1.143 2017/06/01 19:16:34 roberto Exp roberto $
|
** $Id: llimits.h,v 1.144 2017/06/27 11:35:01 roberto Exp roberto $
|
||||||
** Limits, basic types, and some other 'installation-dependent' definitions
|
** Limits, basic types, and some other 'installation-dependent' definitions
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -140,10 +140,11 @@ typedef LUAI_UACINT l_uacInt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** maximum depth for nested C calls and syntactical nested non-terminals
|
** maximum depth for nested C calls and syntactical nested non-terminals
|
||||||
** in a program. (Value must fit in an unsigned short int.)
|
** in a program. (Value must fit in an unsigned short int. It must also
|
||||||
|
** be compatible with the size of the C stack.)
|
||||||
*/
|
*/
|
||||||
#if !defined(LUAI_MAXCCALLS)
|
#if !defined(LUAI_MAXCCALLS)
|
||||||
#define LUAI_MAXCCALLS 200
|
#define LUAI_MAXCCALLS 1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
12
lparser.c
12
lparser.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lparser.c,v 2.166 2017/09/28 16:53:29 roberto Exp roberto $
|
** $Id: lparser.c,v 2.167 2017/10/04 21:53:03 roberto Exp roberto $
|
||||||
** Lua Parser
|
** Lua Parser
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -330,11 +330,7 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void enterlevel (LexState *ls) {
|
#define enterlevel(ls) luaE_incCcalls((ls)->L)
|
||||||
lua_State *L = ls->L;
|
|
||||||
++L->nCcalls;
|
|
||||||
checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define leavelevel(ls) ((ls)->L->nCcalls--)
|
#define leavelevel(ls) ((ls)->L->nCcalls--)
|
||||||
|
@ -1188,9 +1184,9 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
|
||||||
suffixedexp(ls, &nv.v);
|
suffixedexp(ls, &nv.v);
|
||||||
if (!vkisindexed(nv.v.k))
|
if (!vkisindexed(nv.v.k))
|
||||||
check_conflict(ls, lh, &nv.v);
|
check_conflict(ls, lh, &nv.v);
|
||||||
checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS,
|
luaE_incCcalls(ls->L); /* control recursion depth */
|
||||||
"C levels");
|
|
||||||
assignment(ls, &nv, nvars+1);
|
assignment(ls, &nv, nvars+1);
|
||||||
|
ls->L->nCcalls--;
|
||||||
}
|
}
|
||||||
else { /* assignment -> '=' explist */
|
else { /* assignment -> '=' explist */
|
||||||
int nexps;
|
int nexps;
|
||||||
|
|
28
lstate.c
28
lstate.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lstate.c,v 2.146 2017/11/07 13:25:26 roberto Exp roberto $
|
** $Id: lstate.c,v 2.147 2017/11/13 15:36:52 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -97,8 +97,28 @@ void luaE_setdebt (global_State *g, l_mem debt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Increment count of "C calls" and check for overflows. In case of
|
||||||
|
** a stack overflow, check appropriate error ("regular" overflow or
|
||||||
|
** overflow while handling stack overflow). If 'nCalls' is larger than
|
||||||
|
** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but
|
||||||
|
** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to
|
||||||
|
** allow overflow handling to work)
|
||||||
|
*/
|
||||||
|
void luaE_incCcalls (lua_State *L) {
|
||||||
|
if (++L->nCcalls >= LUAI_MAXCCALLS) {
|
||||||
|
if (L->nCcalls == LUAI_MAXCCALLS)
|
||||||
|
luaG_runerror(L, "C stack overflow");
|
||||||
|
else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
|
||||||
|
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CallInfo *luaE_extendCI (lua_State *L) {
|
CallInfo *luaE_extendCI (lua_State *L) {
|
||||||
CallInfo *ci = luaM_new(L, CallInfo);
|
CallInfo *ci;
|
||||||
|
luaE_incCcalls(L);
|
||||||
|
ci = luaM_new(L, CallInfo);
|
||||||
lua_assert(L->ci->next == NULL);
|
lua_assert(L->ci->next == NULL);
|
||||||
L->ci->next = ci;
|
L->ci->next = ci;
|
||||||
ci->previous = L->ci;
|
ci->previous = L->ci;
|
||||||
|
@ -116,11 +136,13 @@ void luaE_freeCI (lua_State *L) {
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
CallInfo *next = ci->next;
|
CallInfo *next = ci->next;
|
||||||
ci->next = NULL;
|
ci->next = NULL;
|
||||||
|
L->nCcalls -= L->nci; /* to subtract removed elements from 'nCcalls' */
|
||||||
while ((ci = next) != NULL) {
|
while ((ci = next) != NULL) {
|
||||||
next = ci->next;
|
next = ci->next;
|
||||||
luaM_free(L, ci);
|
luaM_free(L, ci);
|
||||||
L->nci--;
|
L->nci--;
|
||||||
}
|
}
|
||||||
|
L->nCcalls += L->nci; /* to subtract removed elements from 'nCcalls' */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,6 +152,7 @@ void luaE_freeCI (lua_State *L) {
|
||||||
void luaE_shrinkCI (lua_State *L) {
|
void luaE_shrinkCI (lua_State *L) {
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
CallInfo *next2; /* next's next */
|
CallInfo *next2; /* next's next */
|
||||||
|
L->nCcalls -= L->nci; /* to subtract removed elements from 'nCcalls' */
|
||||||
/* while there are two nexts */
|
/* while there are two nexts */
|
||||||
while (ci->next != NULL && (next2 = ci->next->next) != NULL) {
|
while (ci->next != NULL && (next2 = ci->next->next) != NULL) {
|
||||||
luaM_free(L, ci->next); /* free next */
|
luaM_free(L, ci->next); /* free next */
|
||||||
|
@ -138,6 +161,7 @@ void luaE_shrinkCI (lua_State *L) {
|
||||||
next2->previous = ci;
|
next2->previous = ci;
|
||||||
ci = next2; /* keep next's next */
|
ci = next2; /* keep next's next */
|
||||||
}
|
}
|
||||||
|
L->nCcalls += L->nci; /* to subtract removed elements from 'nCcalls' */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
17
lstate.h
17
lstate.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lstate.h,v 2.150 2017/11/07 13:25:26 roberto Exp roberto $
|
** $Id: lstate.h,v 2.151 2017/11/13 15:36:52 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -104,7 +104,7 @@ typedef struct CallInfo {
|
||||||
int nyield; /* number of values yielded */
|
int nyield; /* number of values yielded */
|
||||||
} u2;
|
} u2;
|
||||||
short nresults; /* expected number of results from this function */
|
short nresults; /* expected number of results from this function */
|
||||||
unsigned short callstatus;
|
lu_byte callstatus;
|
||||||
} CallInfo;
|
} CallInfo;
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,13 +114,11 @@ typedef struct CallInfo {
|
||||||
#define CIST_OAH (1<<0) /* original value of 'allowhook' */
|
#define CIST_OAH (1<<0) /* original value of 'allowhook' */
|
||||||
#define CIST_LUA (1<<1) /* call is running a Lua function */
|
#define CIST_LUA (1<<1) /* call is running a Lua function */
|
||||||
#define CIST_HOOKED (1<<2) /* call is running a debug hook */
|
#define CIST_HOOKED (1<<2) /* call is running a debug hook */
|
||||||
#define CIST_FRESH (1<<3) /* call is running on a fresh invocation
|
#define CIST_YPCALL (1<<3) /* call is a yieldable protected call */
|
||||||
of luaV_execute */
|
#define CIST_TAIL (1<<4) /* call was tail called */
|
||||||
#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */
|
#define CIST_HOOKYIELD (1<<5) /* last hook called yielded */
|
||||||
#define CIST_TAIL (1<<5) /* call was tail called */
|
#define CIST_LEQ (1<<6) /* using __lt for __le */
|
||||||
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
|
#define CIST_FIN (1<<7) /* call is running a finalizer */
|
||||||
#define CIST_LEQ (1<<7) /* using __lt for __le */
|
|
||||||
#define CIST_FIN (1<<8) /* call is running a finalizer */
|
|
||||||
|
|
||||||
#define isLua(ci) ((ci)->callstatus & CIST_LUA)
|
#define isLua(ci) ((ci)->callstatus & CIST_LUA)
|
||||||
|
|
||||||
|
@ -256,6 +254,7 @@ LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
|
||||||
LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
|
LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
|
||||||
LUAI_FUNC void luaE_freeCI (lua_State *L);
|
LUAI_FUNC void luaE_freeCI (lua_State *L);
|
||||||
LUAI_FUNC void luaE_shrinkCI (lua_State *L);
|
LUAI_FUNC void luaE_shrinkCI (lua_State *L);
|
||||||
|
LUAI_FUNC void luaE_incCcalls (lua_State *L);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
6
ltests.h
6
ltests.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: ltests.h,v 2.51 2017/06/27 11:35:31 roberto Exp roberto $
|
** $Id: ltests.h,v 2.52 2017/11/13 12:19:35 roberto Exp roberto $
|
||||||
** Internal Header for Debugging of the Lua Implementation
|
** Internal Header for Debugging of the Lua Implementation
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -34,6 +34,10 @@
|
||||||
#define lua_assert(c) assert(c)
|
#define lua_assert(c) assert(c)
|
||||||
|
|
||||||
|
|
||||||
|
/* compiled with -O0, Lua uses a lot of C stack space... */
|
||||||
|
#undef LUAI_MAXCCALLS
|
||||||
|
#define LUAI_MAXCCALLS 300
|
||||||
|
|
||||||
/* to avoid warnings, and to make sure value is really unused */
|
/* to avoid warnings, and to make sure value is really unused */
|
||||||
#define UNUSED(x) (x=0, (void)(x))
|
#define UNUSED(x) (x=0, (void)(x))
|
||||||
|
|
||||||
|
|
52
lvm.c
52
lvm.c
|
@ -1,5 +1,9 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 2.314 2017/11/22 18:41:20 roberto Exp roberto $
|
<<<<<<< lvm.c
|
||||||
|
** $Id: lvm.c,v 2.313 2017/11/21 14:17:35 roberto Exp roberto $
|
||||||
|
=======
|
||||||
|
** $Id: lvm.c,v 2.315 2017/11/22 19:15:44 roberto Exp $
|
||||||
|
>>>>>>> 2.315
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -829,20 +833,12 @@ void luaV_finishOp (lua_State *L) {
|
||||||
|
|
||||||
|
|
||||||
void luaV_execute (lua_State *L) {
|
void luaV_execute (lua_State *L) {
|
||||||
CallInfo *ci = L->ci; /* local copy of 'L->ci' */
|
CallInfo *ci = L->ci;
|
||||||
LClosure *cl;
|
LClosure *cl = clLvalue(s2v(ci->func));
|
||||||
TValue *k;
|
TValue *k = cl->p->k;
|
||||||
StkId base; /* local copy of 'ci->func + 1' */
|
StkId base = ci->func + 1;
|
||||||
int trap;
|
int trap = ci->u.l.trap;
|
||||||
const Instruction *pc; /* local copy of 'ci->u.l.savedpc' */
|
const Instruction *pc = ci->u.l.savedpc;
|
||||||
ci->callstatus |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */
|
|
||||||
newframe: /* reentry point when frame changes (call/return) */
|
|
||||||
lua_assert(ci == L->ci);
|
|
||||||
cl = clLvalue(s2v(ci->func)); /* local reference to function's closure */
|
|
||||||
k = cl->p->k; /* local reference to function's constant table */
|
|
||||||
updatetrap(ci);
|
|
||||||
updatebase(ci);
|
|
||||||
pc = ci->u.l.savedpc;
|
|
||||||
/* main loop of interpreter */
|
/* main loop of interpreter */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Instruction i;
|
Instruction i;
|
||||||
|
@ -1418,20 +1414,13 @@ void luaV_execute (lua_State *L) {
|
||||||
vmcase(OP_CALL) {
|
vmcase(OP_CALL) {
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
int nresults = GETARG_C(i) - 1;
|
int nresults = GETARG_C(i) - 1;
|
||||||
int isC;
|
|
||||||
if (b != 0) /* fixed number of arguments? */
|
if (b != 0) /* fixed number of arguments? */
|
||||||
L->top = ra + b; /* top signals number of arguments */
|
L->top = ra + b; /* top signals number of arguments */
|
||||||
/* else previous instruction set top */
|
/* else previous instruction set top */
|
||||||
Protect(isC = luaD_precall(L, ra, nresults));
|
Protect(luaD_call(L, ra, nresults));
|
||||||
if (isC) { /* C function? */
|
|
||||||
if (nresults >= 0) /* fixed number of results? */
|
if (nresults >= 0) /* fixed number of results? */
|
||||||
L->top = ci->top; /* correct top */
|
L->top = ci->top; /* correct top */
|
||||||
/* else leave top for next instruction */
|
/* else leave top for next instruction */
|
||||||
}
|
|
||||||
else { /* Lua function */
|
|
||||||
ci = L->ci;
|
|
||||||
goto newframe; /* restart luaV_execute over new Lua function */
|
|
||||||
}
|
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_TAILCALL) {
|
vmcase(OP_TAILCALL) {
|
||||||
|
@ -1447,12 +1436,15 @@ void luaV_execute (lua_State *L) {
|
||||||
b++; /* there is now one extra argument */
|
b++; /* there is now one extra argument */
|
||||||
}
|
}
|
||||||
if (!ttisLclosure(s2v(ra))) /* C function? */
|
if (!ttisLclosure(s2v(ra))) /* C function? */
|
||||||
Protect(luaD_precall(L, ra, LUA_MULTRET)); /* call it */
|
Protect(luaD_call(L, ra, LUA_MULTRET)); /* call it */
|
||||||
else { /* tail call */
|
else { /* tail call */
|
||||||
if (cl->p->sizep > 0) /* close upvalues from previous call */
|
if (cl->p->sizep > 0) /* close upvalues from previous call */
|
||||||
luaF_close(L, ci->func + 1);
|
luaF_close(L, ci->func + 1);
|
||||||
luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
|
luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
|
||||||
goto newframe; /* restart luaV_execute over new Lua function */
|
cl = clLvalue(s2v(ci->func));
|
||||||
|
k = cl->p->k;
|
||||||
|
updatebase(ci);
|
||||||
|
pc = ci->u.l.savedpc;
|
||||||
}
|
}
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
|
@ -1461,16 +1453,8 @@ void luaV_execute (lua_State *L) {
|
||||||
if (cl->p->sizep > 0)
|
if (cl->p->sizep > 0)
|
||||||
luaF_close(L, base);
|
luaF_close(L, base);
|
||||||
savepc(L);
|
savepc(L);
|
||||||
b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
|
luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
|
||||||
if (ci->callstatus & CIST_FRESH) /* local 'ci' still from callee */
|
|
||||||
return; /* external invocation: return */
|
return; /* external invocation: return */
|
||||||
else { /* invocation via reentry: continue execution */
|
|
||||||
ci = L->ci;
|
|
||||||
if (b) L->top = ci->top;
|
|
||||||
lua_assert(isLua(ci));
|
|
||||||
lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
|
|
||||||
goto newframe; /* restart luaV_execute over new Lua function */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
vmcase(OP_FORLOOP) {
|
vmcase(OP_FORLOOP) {
|
||||||
if (ttisinteger(s2v(ra))) { /* integer loop? */
|
if (ttisinteger(s2v(ra))) { /* integer loop? */
|
||||||
|
|
Loading…
Reference in New Issue