'CallInfo' stack implemented as double-linked list instead of an array
This commit is contained in:
6
lapi.c
6
lapi.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lapi.c,v 2.73 2009/03/30 18:39:20 roberto Exp roberto $
|
** $Id: lapi.c,v 2.74 2009/04/08 18:04:33 roberto Exp roberto $
|
||||||
** Lua API
|
** Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -72,7 +72,7 @@ static TValue *index2adr (lua_State *L, int idx) {
|
|||||||
|
|
||||||
|
|
||||||
static Table *getcurrenv (lua_State *L) {
|
static Table *getcurrenv (lua_State *L) {
|
||||||
if (L->ci == L->base_ci) /* no enclosing function? */
|
if (L->ci->previous == NULL) /* no enclosing function? */
|
||||||
return hvalue(gt(L)); /* use global table as environment */
|
return hvalue(gt(L)); /* use global table as environment */
|
||||||
else {
|
else {
|
||||||
Closure *func = curr_func(L);
|
Closure *func = curr_func(L);
|
||||||
@@ -185,7 +185,7 @@ LUA_API void lua_replace (lua_State *L, int idx) {
|
|||||||
StkId o;
|
StkId o;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
/* explicit test for incompatible code */
|
/* explicit test for incompatible code */
|
||||||
if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
|
if (idx == LUA_ENVIRONINDEX && L->ci->previous == NULL)
|
||||||
luaG_runerror(L, "no calling environment");
|
luaG_runerror(L, "no calling environment");
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
o = index2adr(L, idx);
|
o = index2adr(L, idx);
|
||||||
|
|||||||
24
ldebug.c
24
ldebug.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldebug.c,v 2.44 2009/03/10 17:14:37 roberto Exp roberto $
|
** $Id: ldebug.c,v 2.45 2009/03/26 12:56:38 roberto Exp roberto $
|
||||||
** Debug Interface
|
** Debug Interface
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -86,18 +86,18 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
|
|||||||
int status;
|
int status;
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
|
for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) {
|
||||||
level--;
|
level--;
|
||||||
if (isLua(ci)) /* Lua function? */
|
if (isLua(ci)) /* Lua function? */
|
||||||
level -= ci->u.l.tailcalls; /* skip lost tail calls */
|
level -= ci->u.l.tailcalls; /* skip lost tail calls */
|
||||||
}
|
}
|
||||||
if (level == 0 && ci > L->base_ci) { /* level found? */
|
if (level == 0 && ci != &L->base_ci) { /* level found? */
|
||||||
status = 1;
|
status = 1;
|
||||||
ar->i_ci = cast_int(ci - L->base_ci);
|
ar->i_ci = ci;
|
||||||
}
|
}
|
||||||
else if (level < 0) { /* level is of a lost tail call? */
|
else if (level < 0) { /* level is of a lost tail call? */
|
||||||
status = 1;
|
status = 1;
|
||||||
ar->i_ci = 0;
|
ar->i_ci = NULL;
|
||||||
}
|
}
|
||||||
else status = 0; /* no such level */
|
else status = 0; /* no such level */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@@ -116,7 +116,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
|
|||||||
if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL)
|
if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL)
|
||||||
return name; /* is a local variable in a Lua function */
|
return name; /* is a local variable in a Lua function */
|
||||||
else {
|
else {
|
||||||
StkId limit = (ci == L->ci) ? L->top : (ci+1)->func;
|
StkId limit = (ci == L->ci) ? L->top : ci->next->func;
|
||||||
if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */
|
if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */
|
||||||
return "(*temporary)";
|
return "(*temporary)";
|
||||||
else
|
else
|
||||||
@@ -126,7 +126,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
|
|||||||
|
|
||||||
|
|
||||||
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
|
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
|
||||||
CallInfo *ci = L->base_ci + ar->i_ci;
|
CallInfo *ci = ar->i_ci;
|
||||||
const char *name = findlocal(L, ci, n);
|
const char *name = findlocal(L, ci, n);
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
if (name) {
|
if (name) {
|
||||||
@@ -139,7 +139,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
|
|||||||
|
|
||||||
|
|
||||||
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
|
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
|
||||||
CallInfo *ci = L->base_ci + ar->i_ci;
|
CallInfo *ci = ar->i_ci;
|
||||||
const char *name = findlocal(L, ci, n);
|
const char *name = findlocal(L, ci, n);
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
if (name)
|
if (name)
|
||||||
@@ -246,8 +246,8 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
|||||||
f = clvalue(func);
|
f = clvalue(func);
|
||||||
L->top--; /* pop function */
|
L->top--; /* pop function */
|
||||||
}
|
}
|
||||||
else if (ar->i_ci != 0) { /* no tail call? */
|
else if (ar->i_ci != NULL) { /* no tail call? */
|
||||||
ci = L->base_ci + ar->i_ci;
|
ci = ar->i_ci;
|
||||||
lua_assert(ttisfunction(ci->func));
|
lua_assert(ttisfunction(ci->func));
|
||||||
f = clvalue(ci->func);
|
f = clvalue(ci->func);
|
||||||
}
|
}
|
||||||
@@ -525,9 +525,9 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
|
|||||||
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
|
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
|
||||||
TMS tm = 0;
|
TMS tm = 0;
|
||||||
Instruction i;
|
Instruction i;
|
||||||
if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1))
|
if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci->previous))
|
||||||
return NULL; /* calling function is not Lua (or is unknown) */
|
return NULL; /* calling function is not Lua (or is unknown) */
|
||||||
ci--; /* calling function */
|
ci = ci->previous; /* calling function */
|
||||||
i = ci_func(ci)->l.p->code[currentpc(L, ci)];
|
i = ci_func(ci)->l.p->code[currentpc(L, ci)];
|
||||||
switch (GET_OPCODE(i)) {
|
switch (GET_OPCODE(i)) {
|
||||||
case OP_CALL:
|
case OP_CALL:
|
||||||
|
|||||||
69
ldo.c
69
ldo.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.c,v 2.58 2009/04/08 18:04:33 roberto Exp roberto $
|
** $Id: ldo.c,v 2.59 2009/04/15 16:53:39 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
|
||||||
*/
|
*/
|
||||||
@@ -70,12 +70,8 @@ void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
|
|||||||
|
|
||||||
|
|
||||||
static void restore_stack_limit (lua_State *L) {
|
static void restore_stack_limit (lua_State *L) {
|
||||||
lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
|
if (L->nci >= LUAI_MAXCALLS) /* stack overflow? */
|
||||||
if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */
|
luaE_freeCI(L); /* erase all extras CIs */
|
||||||
int inuse = cast_int(L->ci - L->base_ci);
|
|
||||||
if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */
|
|
||||||
luaD_reallocCI(L, LUAI_MAXCALLS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -124,7 +120,7 @@ static void correctstack (lua_State *L, TValue *oldstack) {
|
|||||||
L->top = (L->top - oldstack) + L->stack;
|
L->top = (L->top - oldstack) + L->stack;
|
||||||
for (up = L->openupval; up != NULL; up = up->gch.next)
|
for (up = L->openupval; up != NULL; up = up->gch.next)
|
||||||
gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
|
gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
|
||||||
for (ci = L->base_ci; ci <= L->ci; ci++) {
|
for (ci = L->ci; ci != NULL; ci = ci->previous) {
|
||||||
ci->top = (ci->top - oldstack) + L->stack;
|
ci->top = (ci->top - oldstack) + L->stack;
|
||||||
ci->base = (ci->base - oldstack) + L->stack;
|
ci->base = (ci->base - oldstack) + L->stack;
|
||||||
ci->func = (ci->func - oldstack) + L->stack;
|
ci->func = (ci->func - oldstack) + L->stack;
|
||||||
@@ -144,15 +140,6 @@ void luaD_reallocstack (lua_State *L, int newsize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaD_reallocCI (lua_State *L, int newsize) {
|
|
||||||
CallInfo *oldci = L->base_ci;
|
|
||||||
luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
|
|
||||||
L->size_ci = newsize;
|
|
||||||
L->ci = (L->ci - oldci) + L->base_ci;
|
|
||||||
L->end_ci = L->base_ci + L->size_ci - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void luaD_growstack (lua_State *L, int n) {
|
void luaD_growstack (lua_State *L, int n) {
|
||||||
if (n <= L->stacksize) /* double size is enough? */
|
if (n <= L->stacksize) /* double size is enough? */
|
||||||
luaD_reallocstack(L, 2*L->stacksize);
|
luaD_reallocstack(L, 2*L->stacksize);
|
||||||
@@ -161,18 +148,6 @@ void luaD_growstack (lua_State *L, int n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CallInfo *growCI (lua_State *L) {
|
|
||||||
if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */
|
|
||||||
luaD_throw(L, LUA_ERRERR);
|
|
||||||
else {
|
|
||||||
luaD_reallocCI(L, 2*L->size_ci);
|
|
||||||
if (L->size_ci > LUAI_MAXCALLS)
|
|
||||||
luaG_runerror(L, "stack overflow");
|
|
||||||
}
|
|
||||||
return ++L->ci;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void luaD_callhook (lua_State *L, int event, int line) {
|
void luaD_callhook (lua_State *L, int event, int line) {
|
||||||
lua_Hook hook = L->hook;
|
lua_Hook hook = L->hook;
|
||||||
if (hook && L->allowhook) {
|
if (hook && L->allowhook) {
|
||||||
@@ -182,9 +157,9 @@ void luaD_callhook (lua_State *L, int event, int line) {
|
|||||||
ar.event = event;
|
ar.event = event;
|
||||||
ar.currentline = line;
|
ar.currentline = line;
|
||||||
if (event == LUA_HOOKTAILRET)
|
if (event == LUA_HOOKTAILRET)
|
||||||
ar.i_ci = 0; /* tail call; no debug information about it */
|
ar.i_ci = NULL; /* tail call; no debug information about it */
|
||||||
else
|
else
|
||||||
ar.i_ci = cast_int(L->ci - L->base_ci);
|
ar.i_ci = L->ci;
|
||||||
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
||||||
L->ci->top = L->top + LUA_MINSTACK;
|
L->ci->top = L->top + LUA_MINSTACK;
|
||||||
lua_assert(L->ci->top <= L->stack_last);
|
lua_assert(L->ci->top <= L->stack_last);
|
||||||
@@ -235,9 +210,7 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define inc_ci(L) \
|
#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
|
||||||
((L->ci == L->end_ci) ? growCI(L) : \
|
|
||||||
(condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -265,7 +238,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
|||||||
base = adjust_varargs(L, p, nargs);
|
base = adjust_varargs(L, p, nargs);
|
||||||
func = restorestack(L, funcr); /* previous call may change the stack */
|
func = restorestack(L, funcr); /* previous call may change the stack */
|
||||||
}
|
}
|
||||||
ci = inc_ci(L); /* now `enter' new function */
|
ci = next_ci(L); /* now 'enter' new function */
|
||||||
ci->func = func;
|
ci->func = func;
|
||||||
L->base = ci->base = base;
|
L->base = ci->base = base;
|
||||||
ci->top = L->base + p->maxstacksize;
|
ci->top = L->base + p->maxstacksize;
|
||||||
@@ -287,7 +260,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
|||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
int n;
|
int n;
|
||||||
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
||||||
ci = inc_ci(L); /* now `enter' new function */
|
ci = next_ci(L); /* now 'enter' new function */
|
||||||
ci->func = restorestack(L, funcr);
|
ci->func = restorestack(L, funcr);
|
||||||
L->base = ci->base = ci->func + 1;
|
L->base = ci->base = ci->func + 1;
|
||||||
ci->top = L->top + LUA_MINSTACK;
|
ci->top = L->top + LUA_MINSTACK;
|
||||||
@@ -318,17 +291,17 @@ static StkId callrethooks (lua_State *L, StkId firstResult) {
|
|||||||
int luaD_poscall (lua_State *L, StkId firstResult) {
|
int luaD_poscall (lua_State *L, StkId firstResult) {
|
||||||
StkId res;
|
StkId res;
|
||||||
int wanted, i;
|
int wanted, i;
|
||||||
CallInfo *ci;
|
CallInfo *ci = L->ci;
|
||||||
if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
|
if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
|
||||||
if (L->hookmask & LUA_MASKRET)
|
if (L->hookmask & LUA_MASKRET)
|
||||||
firstResult = callrethooks(L, firstResult);
|
firstResult = callrethooks(L, firstResult);
|
||||||
L->oldpc = (L->ci - 1)->savedpc; /* set 'oldpc' for returning function */
|
L->oldpc = L->ci->previous->savedpc; /* 'oldpc' for returning function */
|
||||||
}
|
}
|
||||||
ci = L->ci--;
|
|
||||||
res = ci->func; /* res == final position of 1st result */
|
res = ci->func; /* res == final position of 1st result */
|
||||||
wanted = (ci - 1)->nresults;
|
L->ci = ci = L->ci->previous; /* back to caller */
|
||||||
L->base = (ci - 1)->base; /* restore base */
|
wanted = ci->nresults;
|
||||||
L->savedpc = (ci - 1)->savedpc; /* restore savedpc */
|
L->base = ci->base; /* restore base */
|
||||||
|
L->savedpc = ci->savedpc; /* restore savedpc */
|
||||||
/* move results to correct place */
|
/* move results to correct place */
|
||||||
for (i = wanted; i != 0 && firstResult < L->top; i--)
|
for (i = wanted; i != 0 && firstResult < L->top; i--)
|
||||||
setobjs2s(L, res++, firstResult++);
|
setobjs2s(L, res++, firstResult++);
|
||||||
@@ -387,7 +360,7 @@ static void finishCcall (lua_State *L) {
|
|||||||
static void unroll (lua_State *L, void *ud) {
|
static void unroll (lua_State *L, void *ud) {
|
||||||
UNUSED(ud);
|
UNUSED(ud);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (L->ci == L->base_ci) /* stack is empty? */
|
if (L->ci == &L->base_ci) /* stack is empty? */
|
||||||
return; /* coroutine finished normally */
|
return; /* coroutine finished normally */
|
||||||
if (!isLua(L->ci)) /* C function? */
|
if (!isLua(L->ci)) /* C function? */
|
||||||
finishCcall(L);
|
finishCcall(L);
|
||||||
@@ -403,7 +376,7 @@ static void resume (lua_State *L, void *ud) {
|
|||||||
StkId firstArg = cast(StkId, ud);
|
StkId firstArg = cast(StkId, ud);
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
if (L->status == LUA_OK) { /* start coroutine? */
|
if (L->status == LUA_OK) { /* start coroutine? */
|
||||||
lua_assert(ci == L->base_ci && firstArg > L->base);
|
lua_assert(ci == &L->base_ci && firstArg > L->base);
|
||||||
if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
|
if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
|
||||||
luaV_execute(L); /* call it */
|
luaV_execute(L); /* call it */
|
||||||
}
|
}
|
||||||
@@ -437,7 +410,7 @@ static int resume_error (lua_State *L, const char *msg) {
|
|||||||
*/
|
*/
|
||||||
static CallInfo *findpcall (lua_State *L) {
|
static CallInfo *findpcall (lua_State *L) {
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
for (ci = L->ci; ci > L->base_ci; ci--) { /* search for first pcall */
|
for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */
|
||||||
if (ci->callstatus & CIST_YPCALL)
|
if (ci->callstatus & CIST_YPCALL)
|
||||||
return ci;
|
return ci;
|
||||||
}
|
}
|
||||||
@@ -471,7 +444,7 @@ LUA_API int lua_resume (lua_State *L, int nargs) {
|
|||||||
if (L->status != LUA_YIELD) {
|
if (L->status != LUA_YIELD) {
|
||||||
if (L->status != LUA_OK)
|
if (L->status != LUA_OK)
|
||||||
return resume_error(L, "cannot resume dead coroutine");
|
return resume_error(L, "cannot resume dead coroutine");
|
||||||
else if (L->ci != L->base_ci)
|
else if (L->ci != &L->base_ci)
|
||||||
return resume_error(L, "cannot resume non-suspended coroutine");
|
return resume_error(L, "cannot resume non-suspended coroutine");
|
||||||
}
|
}
|
||||||
luai_userstateresume(L, nargs);
|
luai_userstateresume(L, nargs);
|
||||||
@@ -515,7 +488,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
|
|||||||
int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
||||||
ptrdiff_t old_top, ptrdiff_t ef) {
|
ptrdiff_t old_top, ptrdiff_t ef) {
|
||||||
int status;
|
int status;
|
||||||
ptrdiff_t old_ci = saveci(L, L->ci);
|
CallInfo *old_ci = L->ci;
|
||||||
lu_byte old_allowhooks = L->allowhook;
|
lu_byte old_allowhooks = L->allowhook;
|
||||||
unsigned short old_nny = L->nny;
|
unsigned short old_nny = L->nny;
|
||||||
ptrdiff_t old_errfunc = L->errfunc;
|
ptrdiff_t old_errfunc = L->errfunc;
|
||||||
@@ -525,7 +498,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
|||||||
StkId oldtop = restorestack(L, old_top);
|
StkId oldtop = restorestack(L, old_top);
|
||||||
luaF_close(L, oldtop); /* close possible pending closures */
|
luaF_close(L, oldtop); /* close possible pending closures */
|
||||||
luaD_seterrorobj(L, status, oldtop);
|
luaD_seterrorobj(L, status, oldtop);
|
||||||
L->ci = restoreci(L, old_ci);
|
L->ci = old_ci;
|
||||||
L->base = L->ci->base;
|
L->base = L->ci->base;
|
||||||
L->savedpc = L->ci->savedpc;
|
L->savedpc = L->ci->savedpc;
|
||||||
L->allowhook = old_allowhooks;
|
L->allowhook = old_allowhooks;
|
||||||
|
|||||||
5
ldo.h
5
ldo.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.h,v 2.10 2008/08/13 17:02:42 roberto Exp roberto $
|
** $Id: ldo.h,v 2.11 2009/03/10 17:14:37 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
|
||||||
*/
|
*/
|
||||||
@@ -24,9 +24,6 @@
|
|||||||
#define savestack(L,p) ((char *)(p) - (char *)L->stack)
|
#define savestack(L,p) ((char *)(p) - (char *)L->stack)
|
||||||
#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
|
#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
|
||||||
|
|
||||||
#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
|
|
||||||
#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
|
|
||||||
|
|
||||||
|
|
||||||
/* type of protected functions, to be ran by `runprotected' */
|
/* type of protected functions, to be ran by `runprotected' */
|
||||||
typedef void (*Pfunc) (lua_State *L, void *ud);
|
typedef void (*Pfunc) (lua_State *L, void *ud);
|
||||||
|
|||||||
39
lgc.c
39
lgc.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 2.48 2009/02/17 19:47:58 roberto Exp roberto $
|
** $Id: lgc.c,v 2.49 2009/03/10 17:14:37 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -379,38 +379,34 @@ static void traverseclosure (global_State *g, Closure *cl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void checkstacksizes (lua_State *L, StkId max) {
|
static void checkstacksize (lua_State *L, StkId max) {
|
||||||
/* should not change the stack when handling overflow or
|
/* should not change the stack during an emergency gc cycle */
|
||||||
during an emergency gc cycle */
|
if (G(L)->gckind == KGC_EMERGENCY)
|
||||||
if (L->size_ci > LUAI_MAXCALLS || G(L)->gckind == KGC_EMERGENCY)
|
return; /* do not touch the stack */
|
||||||
return; /* do not touch the stacks */
|
|
||||||
else {
|
else {
|
||||||
int ci_used = cast_int(L->ci - L->base_ci) + 1; /* number of `ci' in use */
|
|
||||||
int s_used = cast_int(max - L->stack) + 1; /* part of stack in use */
|
int s_used = cast_int(max - L->stack) + 1; /* part of stack in use */
|
||||||
if (2*ci_used < L->size_ci)
|
|
||||||
luaD_reallocCI(L, 2*ci_used);
|
|
||||||
if (2*s_used < (L->stacksize - EXTRA_STACK))
|
if (2*s_used < (L->stacksize - EXTRA_STACK))
|
||||||
luaD_reallocstack(L, 2*s_used);
|
luaD_reallocstack(L, 2*s_used);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void traversestack (global_State *g, lua_State *l) {
|
static void traversestack (global_State *g, lua_State *L) {
|
||||||
StkId o, lim;
|
StkId o, lim;
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
if (l->stack == NULL || l->base_ci == NULL)
|
if (L->stack == NULL)
|
||||||
return; /* stack not completely built yet */
|
return; /* stack not completely built yet */
|
||||||
markvalue(g, gt(l));
|
markvalue(g, gt(L));
|
||||||
lim = l->top;
|
lim = L->top;
|
||||||
for (ci = l->base_ci; ci <= l->ci; ci++) {
|
for (ci = L->ci; ci != NULL; ci = ci->previous) {
|
||||||
lua_assert(ci->top <= l->stack_last);
|
lua_assert(ci->top <= L->stack_last);
|
||||||
if (lim < ci->top) lim = ci->top;
|
if (lim < ci->top) lim = ci->top;
|
||||||
}
|
}
|
||||||
for (o = l->stack; o < l->top; o++)
|
for (o = L->stack; o < L->top; o++)
|
||||||
markvalue(g, o);
|
markvalue(g, o);
|
||||||
for (; o <= lim; o++)
|
for (; o <= lim; o++)
|
||||||
setnilvalue(o);
|
setnilvalue(o);
|
||||||
checkstacksizes(l, lim);
|
checkstacksize(L, lim);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -445,7 +441,7 @@ static l_mem propagatemark (global_State *g) {
|
|||||||
black2gray(o);
|
black2gray(o);
|
||||||
traversestack(g, th);
|
traversestack(g, th);
|
||||||
return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
|
return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
|
||||||
sizeof(CallInfo) * th->size_ci;
|
sizeof(CallInfo) * th->nci;
|
||||||
}
|
}
|
||||||
case LUA_TPROTO: {
|
case LUA_TPROTO: {
|
||||||
Proto *p = gco2p(o);
|
Proto *p = gco2p(o);
|
||||||
@@ -554,8 +550,11 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
|
|||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
int deadmask = otherwhite(g);
|
int deadmask = otherwhite(g);
|
||||||
while ((curr = *p) != NULL && count-- > 0) {
|
while ((curr = *p) != NULL && count-- > 0) {
|
||||||
if (ttisthread(gch(curr))) /* sweep open upvalues of each thread */
|
if (ttisthread(gch(curr))) {
|
||||||
sweepwholelist(L, &gco2th(curr)->openupval);
|
lua_State *L1 = gco2th(curr);
|
||||||
|
sweepwholelist(L, &L1->openupval); /* sweep open upvalues */
|
||||||
|
luaE_freeCI(L1); /* free extra CallInfo slots */
|
||||||
|
}
|
||||||
if ((gch(curr)->marked ^ WHITEBITS) & deadmask) { /* not dead? */
|
if ((gch(curr)->marked ^ WHITEBITS) & deadmask) { /* not dead? */
|
||||||
lua_assert(!isdead(g, curr) || testbit(gch(curr)->marked, FIXEDBIT));
|
lua_assert(!isdead(g, curr) || testbit(gch(curr)->marked, FIXEDBIT));
|
||||||
makewhite(g, curr); /* make it white (for next cycle) */
|
makewhite(g, curr); /* make it white (for next cycle) */
|
||||||
|
|||||||
61
lstate.c
61
lstate.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstate.c,v 2.49 2009/02/18 17:20:56 roberto Exp roberto $
|
** $Id: lstate.c,v 2.50 2009/03/10 17:14:37 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -40,12 +40,41 @@ typedef struct LG {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** maximum number of nested calls made by error-handling function
|
||||||
|
*/
|
||||||
|
#define LUAI_EXTRACALLS 10
|
||||||
|
|
||||||
|
|
||||||
|
CallInfo *luaE_extendCI (lua_State *L) {
|
||||||
|
CallInfo *ci = luaM_new(L, CallInfo);
|
||||||
|
lua_assert(L->ci->next == NULL);
|
||||||
|
L->ci->next = ci;
|
||||||
|
ci->previous = L->ci;
|
||||||
|
ci->next = NULL;
|
||||||
|
if (++L->nci >= LUAI_MAXCALLS) {
|
||||||
|
if (L->nci == LUAI_MAXCALLS) /* overflow? */
|
||||||
|
luaG_runerror(L, "stack overflow");
|
||||||
|
if (L->nci >= LUAI_MAXCALLS + LUAI_EXTRACALLS) /* again? */
|
||||||
|
luaD_throw(L, LUA_ERRERR); /* error while handling overflow */
|
||||||
|
}
|
||||||
|
return ci;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void luaE_freeCI (lua_State *L) {
|
||||||
|
CallInfo *ci = L->ci;
|
||||||
|
CallInfo *next = ci->next;
|
||||||
|
ci->next = NULL;
|
||||||
|
while ((ci = next) != NULL) {
|
||||||
|
next = ci->next;
|
||||||
|
luaM_free(L, ci);
|
||||||
|
L->nci--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void stack_init (lua_State *L1, lua_State *L) {
|
static void stack_init (lua_State *L1, lua_State *L) {
|
||||||
/* initialize CallInfo array */
|
|
||||||
L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
|
|
||||||
L1->ci = L1->base_ci;
|
|
||||||
L1->size_ci = BASIC_CI_SIZE;
|
|
||||||
L1->end_ci = L1->base_ci + L1->size_ci - 1;
|
|
||||||
/* initialize stack array */
|
/* initialize stack array */
|
||||||
L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
|
L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
|
||||||
L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
|
L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
|
||||||
@@ -53,16 +82,18 @@ static void stack_init (lua_State *L1, lua_State *L) {
|
|||||||
L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
|
L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
|
||||||
/* initialize first ci */
|
/* initialize first ci */
|
||||||
L1->ci->func = L1->top;
|
L1->ci->func = L1->top;
|
||||||
setnilvalue(L1->top++); /* `function' entry for this `ci' */
|
setnilvalue(L1->top++); /* 'function' entry for this 'ci' */
|
||||||
L1->base = L1->ci->base = L1->top;
|
L1->base = L1->ci->base = L1->top;
|
||||||
L1->ci->top = L1->top + LUA_MINSTACK;
|
L1->ci->top = L1->top + LUA_MINSTACK;
|
||||||
L1->ci->callstatus = 0;
|
L1->ci->callstatus = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void freestack (lua_State *L, lua_State *L1) {
|
static void freestack (lua_State *L) {
|
||||||
luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
|
L->ci = &L->base_ci; /* reset 'ci' list */
|
||||||
luaM_freearray(L, L1->stack, L1->stacksize, TValue);
|
luaE_freeCI(L);
|
||||||
|
lua_assert(L->nci == 0);
|
||||||
|
luaM_freearray(L, L->stack, L->stacksize, TValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -94,10 +125,11 @@ static void preinit_state (lua_State *L, global_State *g) {
|
|||||||
L->allowhook = 1;
|
L->allowhook = 1;
|
||||||
resethookcount(L);
|
resethookcount(L);
|
||||||
L->openupval = NULL;
|
L->openupval = NULL;
|
||||||
L->size_ci = 0;
|
|
||||||
L->nny = 1;
|
L->nny = 1;
|
||||||
L->status = LUA_OK;
|
L->status = LUA_OK;
|
||||||
L->base_ci = L->ci = NULL;
|
L->base_ci.next = L->base_ci.previous = NULL;
|
||||||
|
L->ci = &L->base_ci;
|
||||||
|
L->nci = 0;
|
||||||
L->savedpc = NULL;
|
L->savedpc = NULL;
|
||||||
L->errfunc = 0;
|
L->errfunc = 0;
|
||||||
setnilvalue(gt(L));
|
setnilvalue(gt(L));
|
||||||
@@ -110,7 +142,7 @@ static void close_state (lua_State *L) {
|
|||||||
luaC_freeall(L); /* collect all objects */
|
luaC_freeall(L); /* collect all objects */
|
||||||
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
|
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
|
||||||
luaZ_freebuffer(L, &g->buff);
|
luaZ_freebuffer(L, &g->buff);
|
||||||
freestack(L, L);
|
freestack(L);
|
||||||
lua_assert(g->totalbytes == sizeof(LG));
|
lua_assert(g->totalbytes == sizeof(LG));
|
||||||
(*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
|
(*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
|
||||||
}
|
}
|
||||||
@@ -142,7 +174,7 @@ void luaE_freethread (lua_State *L, lua_State *L1) {
|
|||||||
luaF_close(L1, L1->stack); /* close all upvalues for this thread */
|
luaF_close(L1, L1->stack); /* close all upvalues for this thread */
|
||||||
lua_assert(L1->openupval == NULL);
|
lua_assert(L1->openupval == NULL);
|
||||||
luai_userstatefree(L1);
|
luai_userstatefree(L1);
|
||||||
freestack(L, L1);
|
freestack(L1);
|
||||||
luaM_freemem(L, fromstate(L1), state_size(lua_State));
|
luaM_freemem(L, fromstate(L1), state_size(lua_State));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,3 +243,4 @@ LUA_API void lua_close (lua_State *L) {
|
|||||||
close_state(L);
|
close_state(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
13
lstate.h
13
lstate.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstate.h,v 2.40 2009/03/23 14:26:12 roberto Exp roberto $
|
** $Id: lstate.h,v 2.41 2009/04/08 18:04:33 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -80,8 +80,9 @@ typedef struct CallInfo {
|
|||||||
StkId base; /* base for this function */
|
StkId base; /* base for this function */
|
||||||
StkId func; /* function index in the stack */
|
StkId func; /* function index in the stack */
|
||||||
StkId top; /* top for this function */
|
StkId top; /* top for this function */
|
||||||
|
struct CallInfo *previous, *next; /* dynamic call link */
|
||||||
const Instruction *savedpc;
|
const Instruction *savedpc;
|
||||||
short nresults; /* expected number of results from this function */
|
short nresults; /* expected number of results from a call */
|
||||||
lu_byte callstatus;
|
lu_byte callstatus;
|
||||||
union {
|
union {
|
||||||
struct { /* only for Lua functions */
|
struct { /* only for Lua functions */
|
||||||
@@ -163,14 +164,12 @@ struct lua_State {
|
|||||||
StkId base; /* base of current function */
|
StkId base; /* base of current function */
|
||||||
global_State *l_G;
|
global_State *l_G;
|
||||||
CallInfo *ci; /* call info for current function */
|
CallInfo *ci; /* call info for current function */
|
||||||
|
int nci; /* number of total CallInfo structures linked */
|
||||||
const Instruction *savedpc; /* `savedpc' of current function */
|
const Instruction *savedpc; /* `savedpc' of current function */
|
||||||
const Instruction *oldpc; /* last pc traced */
|
const Instruction *oldpc; /* last pc traced */
|
||||||
StkId stack_last; /* last free slot in the stack */
|
StkId stack_last; /* last free slot in the stack */
|
||||||
StkId stack; /* stack base */
|
StkId stack; /* stack base */
|
||||||
CallInfo *end_ci; /* points after end of ci array*/
|
|
||||||
CallInfo *base_ci; /* array of CallInfo's */
|
|
||||||
int stacksize;
|
int stacksize;
|
||||||
int size_ci; /* size of array `base_ci' */
|
|
||||||
unsigned short nny; /* number of non-yieldable calls in stack */
|
unsigned short nny; /* number of non-yieldable calls in stack */
|
||||||
lu_byte hookmask;
|
lu_byte hookmask;
|
||||||
lu_byte allowhook;
|
lu_byte allowhook;
|
||||||
@@ -183,6 +182,7 @@ struct lua_State {
|
|||||||
GCObject *gclist;
|
GCObject *gclist;
|
||||||
struct lua_longjmp *errorJmp; /* current error recover point */
|
struct lua_longjmp *errorJmp; /* current error recover point */
|
||||||
ptrdiff_t errfunc; /* current error handling function (stack index) */
|
ptrdiff_t errfunc; /* current error handling function (stack index) */
|
||||||
|
CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -223,6 +223,9 @@ union GCObject {
|
|||||||
|
|
||||||
|
|
||||||
LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
|
LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
|
||||||
|
LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
|
||||||
|
LUAI_FUNC void luaE_freeCI (lua_State *L);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
18
ltests.c
18
ltests.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltests.c,v 2.59 2009/03/03 18:52:36 roberto Exp roberto $
|
** $Id: ltests.c,v 2.60 2009/04/14 19:10:17 roberto Exp roberto $
|
||||||
** Internal Module for Debugging of the Lua Implementation
|
** Internal Module for Debugging of the Lua Implementation
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -296,13 +296,10 @@ static void checkstack (global_State *g, lua_State *L1) {
|
|||||||
lua_assert(!isblack(uvo)); /* open upvalues cannot be black */
|
lua_assert(!isblack(uvo)); /* open upvalues cannot be black */
|
||||||
}
|
}
|
||||||
checkliveness(g, gt(L1));
|
checkliveness(g, gt(L1));
|
||||||
if (L1->base_ci) {
|
for (ci = L1->ci; ci != NULL; ci = ci->previous) {
|
||||||
for (ci = L1->base_ci; ci <= L1->ci; ci++) {
|
lua_assert(ci->top <= L1->stack_last);
|
||||||
lua_assert(ci->top <= L1->stack_last);
|
lua_assert(lua_checkpc(L1, ci));
|
||||||
lua_assert(lua_checkpc(L1, ci));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else lua_assert(L1->size_ci == 0);
|
|
||||||
if (L1->stack) {
|
if (L1->stack) {
|
||||||
for (o = L1->stack; o < L1->top; o++)
|
for (o = L1->stack; o < L1->top; o++)
|
||||||
checkliveness(g, o);
|
checkliveness(g, o);
|
||||||
@@ -356,10 +353,10 @@ printf(">>> %d %s %02x\n", g->gcstate, luaT_typenames[gch(o)->tt], gch(o)->mar
|
|||||||
|
|
||||||
|
|
||||||
int lua_checkpc (lua_State *L, pCallInfo ci) {
|
int lua_checkpc (lua_State *L, pCallInfo ci) {
|
||||||
if (ci == L->base_ci || !isLua(ci)) return 1;
|
if (!isLua(ci)) return 1;
|
||||||
else {
|
else {
|
||||||
Proto *p = ci_func(ci)->l.p;
|
Proto *p = ci_func(ci)->l.p;
|
||||||
if (ci < L->ci)
|
if (ci != L->ci)
|
||||||
return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode;
|
return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode;
|
||||||
else
|
else
|
||||||
return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode;
|
return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode;
|
||||||
@@ -575,8 +572,7 @@ static int stacklevel (lua_State *L) {
|
|||||||
unsigned long a = 0;
|
unsigned long a = 0;
|
||||||
lua_pushinteger(L, (L->top - L->stack));
|
lua_pushinteger(L, (L->top - L->stack));
|
||||||
lua_pushinteger(L, (L->stack_last - L->stack));
|
lua_pushinteger(L, (L->stack_last - L->stack));
|
||||||
lua_pushinteger(L, (L->ci - L->base_ci));
|
lua_pushinteger(L, L->nci);
|
||||||
lua_pushinteger(L, (L->end_ci - L->base_ci));
|
|
||||||
lua_pushinteger(L, (unsigned long)&a);
|
lua_pushinteger(L, (unsigned long)&a);
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|||||||
4
lua.h
4
lua.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lua.h,v 1.234 2009/03/23 14:26:12 roberto Exp roberto $
|
** $Id: lua.h,v 1.235 2009/04/08 18:04:33 roberto Exp roberto $
|
||||||
** Lua - An Extensible Extension Language
|
** Lua - An Extensible Extension Language
|
||||||
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
|
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
|
||||||
** See Copyright Notice at the end of this file
|
** See Copyright Notice at the end of this file
|
||||||
@@ -367,7 +367,7 @@ struct lua_Debug {
|
|||||||
int lastlinedefined; /* (S) */
|
int lastlinedefined; /* (S) */
|
||||||
char short_src[LUA_IDSIZE]; /* (S) */
|
char short_src[LUA_IDSIZE]; /* (S) */
|
||||||
/* private part */
|
/* private part */
|
||||||
int i_ci; /* active function */
|
struct CallInfo *i_ci; /* active function */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* }====================================================================== */
|
/* }====================================================================== */
|
||||||
|
|||||||
14
lvm.c
14
lvm.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 2.83 2009/03/04 13:32:29 roberto Exp roberto $
|
** $Id: lvm.c,v 2.84 2009/03/10 17:14:37 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -663,19 +663,19 @@ void luaV_execute (lua_State *L) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* tail call: put new frame in place of previous one */
|
/* tail call: put new frame in place of previous one */
|
||||||
CallInfo *ci = L->ci - 1; /* previous frame */
|
StkId pfunc = L->ci->func; /* called function index */
|
||||||
int aux;
|
CallInfo *ci = L->ci->previous; /* caller frame */
|
||||||
StkId func = ci->func;
|
StkId func = ci->func;
|
||||||
StkId pfunc = (ci+1)->func; /* previous function index */
|
int aux;
|
||||||
if (cl->p->sizep > 0) luaF_close(L, ci->base);
|
if (cl->p->sizep > 0) luaF_close(L, ci->base);
|
||||||
L->base = ci->base = ci->func + ((ci+1)->base - pfunc);
|
L->base = ci->base = ci->func + (L->ci->base - pfunc);
|
||||||
for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
|
for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
|
||||||
setobjs2s(L, func+aux, pfunc+aux);
|
setobjs2s(L, func+aux, pfunc+aux);
|
||||||
ci->top = L->top = func+aux; /* correct top */
|
ci->top = L->top = func+aux; /* correct top */
|
||||||
lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
|
lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
|
||||||
ci->savedpc = L->savedpc;
|
ci->savedpc = L->savedpc;
|
||||||
ci->u.l.tailcalls++; /* one more call lost */
|
ci->u.l.tailcalls++; /* one more call lost */
|
||||||
L->ci--; /* remove new frame */
|
L->ci = ci; /* remove new frame */
|
||||||
goto reentry;
|
goto reentry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -684,7 +684,7 @@ void luaV_execute (lua_State *L) {
|
|||||||
if (b != 0) L->top = ra+b-1;
|
if (b != 0) L->top = ra+b-1;
|
||||||
if (cl->p->sizep > 0) luaF_close(L, base);
|
if (cl->p->sizep > 0) luaF_close(L, base);
|
||||||
b = luaD_poscall(L, ra);
|
b = luaD_poscall(L, ra);
|
||||||
if (!((L->ci + 1)->callstatus & CIST_REENTRY))
|
if (!(L->ci->next->callstatus & CIST_REENTRY))
|
||||||
return; /* external invocation: return */
|
return; /* external invocation: return */
|
||||||
else { /* invocation via reentry: continue execution */
|
else { /* invocation via reentry: continue execution */
|
||||||
if (b) L->top = L->ci->top;
|
if (b) L->top = L->ci->top;
|
||||||
|
|||||||
Reference in New Issue
Block a user