mirror of https://github.com/rusefi/lua.git
no more useful fields in CallInfo
This commit is contained in:
parent
54eb35a8aa
commit
472c560705
18
lapi.c
18
lapi.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lapi.c,v 2.273 2017/11/02 11:28:56 roberto Exp roberto $
|
** $Id: lapi.c,v 2.274 2017/11/03 12:12:30 roberto Exp roberto $
|
||||||
** Lua API
|
** Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -948,8 +948,8 @@ LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
|
||||||
checkresults(L, nargs, nresults);
|
checkresults(L, nargs, nresults);
|
||||||
func = L->top - (nargs+1);
|
func = L->top - (nargs+1);
|
||||||
if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
|
if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
|
||||||
L->ci->u.c.k = k; /* save continuation */
|
L->func->stkci.u.c.k = k; /* save continuation */
|
||||||
L->ci->u.c.ctx = ctx; /* save context */
|
L->func->stkci.u.c.ctx = ctx; /* save context */
|
||||||
luaD_call(L, func, nresults); /* do the call */
|
luaD_call(L, func, nresults); /* do the call */
|
||||||
}
|
}
|
||||||
else /* no continuation or no yieldable */
|
else /* no continuation or no yieldable */
|
||||||
|
@ -999,19 +999,19 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
|
||||||
status = luaD_pcall(L, f_call, &c, savestack(L, c.func), efunc);
|
status = luaD_pcall(L, f_call, &c, savestack(L, c.func), efunc);
|
||||||
}
|
}
|
||||||
else { /* prepare continuation (call is already protected by 'resume') */
|
else { /* prepare continuation (call is already protected by 'resume') */
|
||||||
CallInfo *ci = L->ci;
|
|
||||||
StkId func = L->func;
|
StkId func = L->func;
|
||||||
ci->u.c.k = k; /* save continuation */
|
func->stkci.u.c.k = k; /* save continuation */
|
||||||
ci->u.c.ctx = ctx; /* save context */
|
func->stkci.u.c.ctx = ctx; /* save context */
|
||||||
/* save information for error recovery */
|
/* save information for error recovery */
|
||||||
ci->u2.funcidx = savestack(L, c.func);
|
func->stkci.u2.funcidx = c.func - func;
|
||||||
ci->u.c.old_errfunc = L->errfunc;
|
func->stkci.u.c.old_errfunc = L->errfunc;
|
||||||
L->errfunc = efunc;
|
L->errfunc = efunc;
|
||||||
setoah(callstatus(func), L->allowhook); /* save value of 'allowhook' */
|
setoah(callstatus(func), L->allowhook); /* save value of 'allowhook' */
|
||||||
callstatus(func) |= CIST_YPCALL; /* function can do error recovery */
|
callstatus(func) |= CIST_YPCALL; /* function can do error recovery */
|
||||||
luaD_call(L, c.func, nresults); /* do the call */
|
luaD_call(L, c.func, nresults); /* do the call */
|
||||||
|
func = L->func; /* previous call can reallocate stack */
|
||||||
callstatus(func) &= ~CIST_YPCALL;
|
callstatus(func) &= ~CIST_YPCALL;
|
||||||
L->errfunc = ci->u.c.old_errfunc;
|
L->errfunc = func->stkci.u.c.old_errfunc;
|
||||||
status = LUA_OK; /* if it is here, there were no errors */
|
status = LUA_OK; /* if it is here, there were no errors */
|
||||||
}
|
}
|
||||||
adjustresults(L, nresults);
|
adjustresults(L, nresults);
|
||||||
|
|
18
ldebug.c
18
ldebug.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: ldebug.c,v 2.135 2017/11/02 11:28:56 roberto Exp roberto $
|
** $Id: ldebug.c,v 2.136 2017/11/03 12:12:30 roberto Exp roberto $
|
||||||
** Debug Interface
|
** Debug Interface
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -44,7 +44,7 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
|
||||||
|
|
||||||
static int currentpc (CallInfo *ci) {
|
static int currentpc (CallInfo *ci) {
|
||||||
lua_assert(isLua(ci->func));
|
lua_assert(isLua(ci->func));
|
||||||
return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
|
return pcRel(ci->func->stkci.u.l.savedpc, ci_func(ci)->p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
|
||||||
func = NULL;
|
func = NULL;
|
||||||
}
|
}
|
||||||
if (isLua(L->func))
|
if (isLua(L->func))
|
||||||
L->oldpc = L->ci->u.l.savedpc;
|
L->oldpc = L->func->stkci.u.l.savedpc;
|
||||||
L->hook = func;
|
L->hook = func;
|
||||||
L->basehookcount = count;
|
L->basehookcount = count;
|
||||||
resethookcount(L);
|
resethookcount(L);
|
||||||
|
@ -755,19 +755,21 @@ void luaG_traceexec (lua_State *L) {
|
||||||
luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
|
luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
|
||||||
if (mask & LUA_MASKLINE) {
|
if (mask & LUA_MASKLINE) {
|
||||||
Proto *p = ci_func(ci)->p;
|
Proto *p = ci_func(ci)->p;
|
||||||
int npc = pcRel(ci->u.l.savedpc, p);
|
int npc = pcRel(func->stkci.u.l.savedpc, p);
|
||||||
if (npc == 0 || /* call linehook when enter a new function, */
|
if (npc == 0 || /* call linehook when enter a new function, */
|
||||||
ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */
|
func->stkci.u.l.savedpc <= L->oldpc || /* when jump back (loop), */
|
||||||
changedline(p, pcRel(L->oldpc, p), npc)) { /* enter new line */
|
changedline(p, pcRel(L->oldpc, p), npc)) { /* when enter new line */
|
||||||
int newline = luaG_getfuncline(p, npc); /* new line */
|
int newline = luaG_getfuncline(p, npc); /* new line */
|
||||||
luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */
|
luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
L->oldpc = ci->u.l.savedpc;
|
func = L->func; /* previous calls can reallocate stack */
|
||||||
|
L->oldpc = func->stkci.u.l.savedpc;
|
||||||
if (L->status == LUA_YIELD) { /* did hook yield? */
|
if (L->status == LUA_YIELD) { /* did hook yield? */
|
||||||
if (counthook)
|
if (counthook)
|
||||||
L->hookcount = 1; /* undo decrement to zero */
|
L->hookcount = 1; /* undo decrement to zero */
|
||||||
ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
|
/* undo increment (resume will increment it again) */
|
||||||
|
func->stkci.u.l.savedpc--;
|
||||||
callstatus(func) |= CIST_HOOKYIELD; /* mark that it yielded */
|
callstatus(func) |= CIST_HOOKYIELD; /* mark that it yielded */
|
||||||
luaD_throw(L, LUA_YIELD);
|
luaD_throw(L, LUA_YIELD);
|
||||||
}
|
}
|
||||||
|
|
54
ldo.c
54
ldo.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: ldo.c,v 2.165 2017/11/02 11:28:56 roberto Exp roberto $
|
** $Id: ldo.c,v 2.166 2017/11/03 12:12:30 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
|
||||||
*/
|
*/
|
||||||
|
@ -280,17 +280,19 @@ void luaD_hook (lua_State *L, int event, int line) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void callhook (lua_State *L, CallInfo *ci) {
|
static void callhook (lua_State *L) {
|
||||||
int hook = LUA_HOOKCALL;
|
int hook = LUA_HOOKCALL;
|
||||||
StkId previous = L->func - L->func->stkci.previous;
|
StkId func = L->func;
|
||||||
ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
|
StkId previous = func - L->func->stkci.previous;
|
||||||
|
func->stkci.u.l.savedpc++; /* hooks assume 'pc' is already incremented */
|
||||||
if (isLua(previous) &&
|
if (isLua(previous) &&
|
||||||
GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
|
GET_OPCODE(*(previous->stkci.u.l.savedpc - 1)) == OP_TAILCALL) {
|
||||||
callstatus(L->func) |= CIST_TAIL;
|
callstatus(L->func) |= CIST_TAIL;
|
||||||
hook = LUA_HOOKTAILCALL;
|
hook = LUA_HOOKTAILCALL;
|
||||||
}
|
}
|
||||||
luaD_hook(L, hook, -1);
|
luaD_hook(L, hook, -1);
|
||||||
ci->u.l.savedpc--; /* correct 'pc' */
|
func = L->func; /* previous call can change stack */
|
||||||
|
func->stkci.u.l.savedpc--; /* correct 'pc' */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -369,11 +371,13 @@ int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
|
||||||
ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
|
ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
|
||||||
luaD_hook(L, LUA_HOOKRET, -1);
|
luaD_hook(L, LUA_HOOKRET, -1);
|
||||||
firstResult = restorestack(L, fr);
|
firstResult = restorestack(L, fr);
|
||||||
|
res = L->func;
|
||||||
}
|
}
|
||||||
L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
|
/* 'oldpc' for caller function */
|
||||||
|
L->oldpc = (res - res->stkci.previous)->stkci.u.l.savedpc;
|
||||||
}
|
}
|
||||||
L->ci = ci->previous; /* back to caller */
|
L->ci = ci->previous; /* back to caller */
|
||||||
L->func -= L->func->stkci.previous;
|
L->func = res - res->stkci.previous;
|
||||||
lua_assert(L->func == L->ci->func);
|
lua_assert(L->func == L->ci->func);
|
||||||
/* move results to proper place */
|
/* move results to proper place */
|
||||||
return moveresults(L, firstResult, res, nres, wanted);
|
return moveresults(L, firstResult, res, nres, wanted);
|
||||||
|
@ -436,10 +440,10 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||||
L->func = ci->func = func;
|
L->func = ci->func = func;
|
||||||
L->top = func + 1 + fsize;
|
L->top = func + 1 + fsize;
|
||||||
lua_assert(functop(func) <= L->stack_last);
|
lua_assert(functop(func) <= L->stack_last);
|
||||||
ci->u.l.savedpc = p->code; /* starting point */
|
func->stkci.u.l.savedpc = p->code; /* starting point */
|
||||||
callstatus(func) = 0;
|
callstatus(func) = 0;
|
||||||
if (L->hookmask & LUA_MASKCALL)
|
if (L->hookmask & LUA_MASKCALL)
|
||||||
callhook(L, ci);
|
callhook(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
default: { /* not a function */
|
default: { /* not a function */
|
||||||
|
@ -500,18 +504,19 @@ static void finishCcall (lua_State *L, int status) {
|
||||||
StkId func = L->func;
|
StkId func = L->func;
|
||||||
int n;
|
int n;
|
||||||
/* must have a continuation and must be able to call it */
|
/* must have a continuation and must be able to call it */
|
||||||
lua_assert(ci->u.c.k != NULL && L->nny == 0);
|
lua_assert(func->stkci.u.c.k != NULL && L->nny == 0);
|
||||||
/* error status can only happen in a protected call */
|
/* error status can only happen in a protected call */
|
||||||
lua_assert((callstatus(func) & CIST_YPCALL) || status == LUA_YIELD);
|
lua_assert((callstatus(func) & CIST_YPCALL) || status == LUA_YIELD);
|
||||||
if (callstatus(func) & CIST_YPCALL) { /* was inside a pcall? */
|
if (callstatus(func) & CIST_YPCALL) { /* was inside a pcall? */
|
||||||
callstatus(func) &= ~CIST_YPCALL; /* continuation is also inside it */
|
callstatus(func) &= ~CIST_YPCALL; /* continuation is also inside it */
|
||||||
L->errfunc = ci->u.c.old_errfunc; /* with the same error function */
|
L->errfunc = func->stkci.u.c.old_errfunc; /* with same error function */
|
||||||
}
|
}
|
||||||
/* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
|
/* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
|
||||||
handled */
|
handled */
|
||||||
adjustresults(L, func->stkci.nresults);
|
adjustresults(L, func->stkci.nresults);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */
|
/* call continuation function */
|
||||||
|
n = (*func->stkci.u.c.k)(L, status, func->stkci.u.c.ctx);
|
||||||
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_precall' */
|
||||||
|
@ -564,7 +569,7 @@ static int recover (lua_State *L, int status) {
|
||||||
CallInfo *ci = findpcall(L);
|
CallInfo *ci = findpcall(L);
|
||||||
if (ci == NULL) return 0; /* no recovery point */
|
if (ci == NULL) return 0; /* no recovery point */
|
||||||
/* "finish" luaD_pcall */
|
/* "finish" luaD_pcall */
|
||||||
oldtop = restorestack(L, ci->u2.funcidx);
|
oldtop = ci->func + ci->func->stkci.u2.funcidx;
|
||||||
luaF_close(L, oldtop);
|
luaF_close(L, oldtop);
|
||||||
seterrorobj(L, status, oldtop);
|
seterrorobj(L, status, oldtop);
|
||||||
L->ci = ci;
|
L->ci = ci;
|
||||||
|
@ -572,7 +577,7 @@ static int recover (lua_State *L, int status) {
|
||||||
L->allowhook = getoah(callstatus(L->func)); /* restore original 'allowhook' */
|
L->allowhook = getoah(callstatus(L->func)); /* restore original 'allowhook' */
|
||||||
L->nny = 0; /* should be zero to be yieldable */
|
L->nny = 0; /* should be zero to be yieldable */
|
||||||
luaD_shrinkstack(L);
|
luaD_shrinkstack(L);
|
||||||
L->errfunc = ci->u.c.old_errfunc;
|
L->errfunc = ci->func->stkci.u.c.old_errfunc;
|
||||||
return 1; /* continue running the coroutine */
|
return 1; /* continue running the coroutine */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,6 +607,7 @@ static void resume (lua_State *L, void *ud) {
|
||||||
int n = *(cast(int*, ud)); /* number of arguments */
|
int n = *(cast(int*, ud)); /* number of arguments */
|
||||||
StkId firstArg = L->top - n; /* first argument */
|
StkId firstArg = L->top - n; /* first argument */
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
|
StkId func = L->func;
|
||||||
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? */
|
if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
|
||||||
luaV_execute(L); /* call it */
|
luaV_execute(L); /* call it */
|
||||||
|
@ -609,12 +615,13 @@ static void resume (lua_State *L, void *ud) {
|
||||||
else { /* resuming from previous yield */
|
else { /* resuming from previous yield */
|
||||||
lua_assert(L->status == LUA_YIELD);
|
lua_assert(L->status == LUA_YIELD);
|
||||||
L->status = LUA_OK; /* mark that it is running (again) */
|
L->status = LUA_OK; /* mark that it is running (again) */
|
||||||
if (isLua(L->func)) /* yielded inside a hook? */
|
if (isLua(func)) /* yielded inside a hook? */
|
||||||
luaV_execute(L); /* just continue running Lua code */
|
luaV_execute(L); /* just continue running Lua code */
|
||||||
else { /* 'common' yield */
|
else { /* 'common' yield */
|
||||||
if (ci->u.c.k != NULL) { /* does it have a continuation function? */
|
if (func->stkci.u.c.k != NULL) { /* does it have a continuation? */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
|
/* call continuation */
|
||||||
|
n = (*func->stkci.u.c.k)(L, LUA_YIELD, func->stkci.u.c.ctx);
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
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 */
|
||||||
|
@ -658,7 +665,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
|
||||||
}
|
}
|
||||||
else lua_assert(status == L->status); /* normal end or yield */
|
else lua_assert(status == L->status); /* normal end or yield */
|
||||||
}
|
}
|
||||||
*nresults = (status == LUA_YIELD) ? L->ci->u2.nyield
|
*nresults = (status == LUA_YIELD) ? L->func->stkci.u2.nyield
|
||||||
: L->top - (L->func + 1);
|
: L->top - (L->func + 1);
|
||||||
L->nny = oldnny; /* restore 'nny' */
|
L->nny = oldnny; /* restore 'nny' */
|
||||||
L->nCcalls--;
|
L->nCcalls--;
|
||||||
|
@ -675,7 +682,6 @@ LUA_API int lua_isyieldable (lua_State *L) {
|
||||||
|
|
||||||
LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
|
LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
|
||||||
lua_KFunction k) {
|
lua_KFunction k) {
|
||||||
CallInfo *ci = L->ci;
|
|
||||||
StkId func = L->func;
|
StkId func = L->func;
|
||||||
luai_userstateyield(L, nresults);
|
luai_userstateyield(L, nresults);
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
|
@ -689,12 +695,12 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
|
||||||
L->status = LUA_YIELD;
|
L->status = LUA_YIELD;
|
||||||
if (isLua(func)) { /* inside a hook? */
|
if (isLua(func)) { /* inside a hook? */
|
||||||
api_check(L, k == NULL, "hooks cannot continue after yielding");
|
api_check(L, k == NULL, "hooks cannot continue after yielding");
|
||||||
ci->u2.nyield = 0; /* no results */
|
func->stkci.u2.nyield = 0; /* no results */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
|
if ((func->stkci.u.c.k = k) != NULL) /* is there a continuation? */
|
||||||
ci->u.c.ctx = ctx; /* save context */
|
func->stkci.u.c.ctx = ctx; /* save context */
|
||||||
ci->u2.nyield = nresults; /* save number of results */
|
func->stkci.u2.nyield = nresults; /* save number of results */
|
||||||
luaD_throw(L, LUA_YIELD);
|
luaD_throw(L, LUA_YIELD);
|
||||||
}
|
}
|
||||||
lua_assert(callstatus(func) & CIST_HOOKED); /* must be inside a hook */
|
lua_assert(callstatus(func) & CIST_HOOKED); /* must be inside a hook */
|
||||||
|
|
18
lobject.h
18
lobject.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lobject.h,v 2.126 2017/10/31 17:54:35 roberto Exp roberto $
|
** $Id: lobject.h,v 2.127 2017/11/03 12:12:30 roberto Exp roberto $
|
||||||
** Type definitions for Lua objects
|
** Type definitions for Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -314,9 +314,23 @@ typedef union StackValue {
|
||||||
struct {
|
struct {
|
||||||
TValuefields;
|
TValuefields;
|
||||||
lu_byte callstatus_;
|
lu_byte callstatus_;
|
||||||
unsigned short previous; /* difference to previous 'func' */
|
|
||||||
short nresults; /* expected number of results from this function */
|
short nresults; /* expected number of results from this function */
|
||||||
|
unsigned short previous; /* difference to previous 'func' */
|
||||||
unsigned short framesize; /* stack space available for this function */
|
unsigned short framesize; /* stack space available for this function */
|
||||||
|
union {
|
||||||
|
unsigned short funcidx; /* called-function index */
|
||||||
|
unsigned short nyield; /* number of values yielded */
|
||||||
|
} u2;
|
||||||
|
union {
|
||||||
|
struct { /* only for Lua functions */
|
||||||
|
const Instruction *savedpc;
|
||||||
|
} l;
|
||||||
|
struct { /* only for C functions */
|
||||||
|
lua_KFunction k; /* continuation in case of yields */
|
||||||
|
ptrdiff_t old_errfunc;
|
||||||
|
lua_KContext ctx; /* context info. in case of yields */
|
||||||
|
} c;
|
||||||
|
} u;
|
||||||
} stkci;
|
} stkci;
|
||||||
} StackValue;
|
} StackValue;
|
||||||
|
|
||||||
|
|
16
lstate.h
16
lstate.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lstate.h,v 2.146 2017/11/02 11:28:56 roberto Exp roberto $
|
** $Id: lstate.h,v 2.147 2017/11/03 12:12:30 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -87,20 +87,6 @@ typedef struct stringtable {
|
||||||
typedef struct CallInfo {
|
typedef struct CallInfo {
|
||||||
StkId func; /* function index in the stack */
|
StkId func; /* function index in the stack */
|
||||||
struct CallInfo *previous, *next; /* dynamic call link */
|
struct CallInfo *previous, *next; /* dynamic call link */
|
||||||
union {
|
|
||||||
struct { /* only for Lua functions */
|
|
||||||
const Instruction *savedpc;
|
|
||||||
} l;
|
|
||||||
struct { /* only for C functions */
|
|
||||||
lua_KFunction k; /* continuation in case of yields */
|
|
||||||
ptrdiff_t old_errfunc;
|
|
||||||
lua_KContext ctx; /* context info. in case of yields */
|
|
||||||
} c;
|
|
||||||
} u;
|
|
||||||
union {
|
|
||||||
ptrdiff_t funcidx; /* called-function index */
|
|
||||||
int nyield; /* number of values yielded */
|
|
||||||
} u2;
|
|
||||||
} CallInfo;
|
} CallInfo;
|
||||||
|
|
||||||
|
|
||||||
|
|
20
ltests.c
20
ltests.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: ltests.c,v 2.227 2017/11/02 11:28:56 roberto Exp roberto $
|
** $Id: ltests.c,v 2.228 2017/11/03 12:12:30 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
|
||||||
*/
|
*/
|
||||||
|
@ -309,28 +309,26 @@ static void checkLclosure (global_State *g, LClosure *cl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int lua_checkpc (CallInfo *ci) {
|
static int lua_checkpc (StkId func) {
|
||||||
if (!isLua(ci->func)) return 1;
|
if (!isLua(func)) return 1;
|
||||||
else {
|
else {
|
||||||
StkId f = ci->func;
|
Proto *p = clLvalue(s2v(func))->p;
|
||||||
Proto *p = clLvalue(s2v(f))->p;
|
return p->code <= func->stkci.u.l.savedpc &&
|
||||||
return p->code <= ci->u.l.savedpc &&
|
func->stkci.u.l.savedpc <= p->code + p->sizecode;
|
||||||
ci->u.l.savedpc <= p->code + p->sizecode;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void checkstack (global_State *g, lua_State *L1) {
|
static void checkstack (global_State *g, lua_State *L1) {
|
||||||
StkId o;
|
StkId o;
|
||||||
CallInfo *ci;
|
|
||||||
UpVal *uv;
|
UpVal *uv;
|
||||||
lua_assert(!isdead(g, L1));
|
lua_assert(!isdead(g, L1));
|
||||||
for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next)
|
for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next)
|
||||||
lua_assert(upisopen(uv)); /* must be open */
|
lua_assert(upisopen(uv)); /* must be open */
|
||||||
for (ci = L1->ci; ci != NULL; ci = ci->previous)
|
for (o = L1->func; o->stkci.previous != 0; o -= o->stkci.previous) {
|
||||||
lua_assert(lua_checkpc(ci));
|
|
||||||
for (o = L1->func; o->stkci.previous != 0; o -= o->stkci.previous)
|
|
||||||
lua_assert(functop(o) <= L1->stack_last);
|
lua_assert(functop(o) <= L1->stack_last);
|
||||||
|
lua_assert(lua_checkpc(o));
|
||||||
|
}
|
||||||
lua_assert(o == L1->stack);
|
lua_assert(o == L1->stack);
|
||||||
if (L1->stack) { /* complete thread? */
|
if (L1->stack) { /* complete thread? */
|
||||||
for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++)
|
for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++)
|
||||||
|
|
47
lvm.c
47
lvm.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 2.301 2017/11/01 18:20:48 roberto Exp roberto $
|
** $Id: lvm.c,v 2.302 2017/11/03 12:12:30 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -654,13 +654,14 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define basepc(base) ((base - 1)->stkci.u.l.savedpc)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** finish execution of an opcode interrupted by an yield
|
** finish execution of an opcode interrupted by an yield
|
||||||
*/
|
*/
|
||||||
void luaV_finishOp (lua_State *L) {
|
void luaV_finishOp (lua_State *L) {
|
||||||
CallInfo *ci = L->ci;
|
|
||||||
StkId base = L->func + 1;
|
StkId base = L->func + 1;
|
||||||
Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */
|
Instruction inst = *(basepc(base) - 1); /* interrupted instruction */
|
||||||
OpCode op = GET_OPCODE(inst);
|
OpCode op = GET_OPCODE(inst);
|
||||||
switch (op) { /* finish its execution */
|
switch (op) { /* finish its execution */
|
||||||
case OP_ADDI: case OP_SUBI:
|
case OP_ADDI: case OP_SUBI:
|
||||||
|
@ -684,9 +685,9 @@ void luaV_finishOp (lua_State *L) {
|
||||||
callstatus(base - 1) ^= CIST_LEQ; /* clear mark */
|
callstatus(base - 1) ^= CIST_LEQ; /* clear mark */
|
||||||
res = !res; /* negate result */
|
res = !res; /* negate result */
|
||||||
}
|
}
|
||||||
lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
|
lua_assert(GET_OPCODE(*basepc(base)) == OP_JMP);
|
||||||
if (res != GETARG_A(inst)) /* condition failed? */
|
if (res != GETARG_A(inst)) /* condition failed? */
|
||||||
ci->u.l.savedpc++; /* skip jump instruction */
|
basepc(base)++; /* skip jump instruction */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_CONCAT: {
|
case OP_CONCAT: {
|
||||||
|
@ -704,7 +705,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_TFORCALL: {
|
case OP_TFORCALL: {
|
||||||
lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
|
lua_assert(GET_OPCODE(*basepc(base)) == OP_TFORLOOP);
|
||||||
L->top = functop(base - 1); /* correct top */
|
L->top = functop(base - 1); /* correct top */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -763,20 +764,22 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** Whenever code can raise errors (including memory errors), the global
|
** Whenever code can raise errors (including memory errors), the global
|
||||||
** 'pc' must be correct to report occasional errors.
|
** 'pc' must be correct to report occasional errors.
|
||||||
*/
|
*/
|
||||||
#define savepc(L) (ci->u.l.savedpc = pc)
|
#define savepc(base) (basepc(base) = pc)
|
||||||
|
|
||||||
|
|
||||||
|
/* update internal copies to its correct values */
|
||||||
|
#define updatestate() (base = L->func + 1, updatemask(L))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Protect code that, in general, can raise errors, reallocate the
|
** Protect code that, in general, can raise errors, reallocate the
|
||||||
** stack, and change the hooks.
|
** stack, and change the hooks.
|
||||||
*/
|
*/
|
||||||
#define Protect(code) \
|
#define Protect(code) { savepc(base); {code;}; updatestate(); }
|
||||||
{ savepc(L); {code;}; base = L->func + 1; updatemask(L); }
|
|
||||||
|
|
||||||
|
|
||||||
#define checkGC(L,c) \
|
#define checkGC(L,c) \
|
||||||
{ luaC_condGC(L, L->top = (c), /* limit of live values */ \
|
{ luaC_condGC(L, L->top = (c), /* limit of live values */ \
|
||||||
{Protect((void)0); L->top = functop(base - 1);}); /* restore top */ \
|
{updatestate(); L->top = functop(base - 1);}); /* restore top */ \
|
||||||
luai_threadyield(L); }
|
luai_threadyield(L); }
|
||||||
|
|
||||||
|
|
||||||
|
@ -798,14 +801,14 @@ void luaV_execute (lua_State *L) {
|
||||||
TValue *k;
|
TValue *k;
|
||||||
StkId base = L->func + 1; /* local copy of 'L->func + 1' */
|
StkId base = L->func + 1; /* local copy of 'L->func + 1' */
|
||||||
int mask; /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */
|
int mask; /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */
|
||||||
const Instruction *pc; /* local copy of 'ci->u.l.savedpc' */
|
const Instruction *pc; /* local copy of 'basepc(base)' */
|
||||||
callstatus(base - 1) |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */
|
callstatus(base - 1) |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */
|
||||||
newframe: /* reentry point when frame changes (call/return) */
|
newframe: /* reentry point when frame changes (call/return) */
|
||||||
lua_assert(ci == L->ci);
|
lua_assert(ci == L->ci);
|
||||||
cl = clLvalue(s2v(L->func)); /* local reference to function's closure */
|
cl = clLvalue(s2v(L->func)); /* local reference to function's closure */
|
||||||
k = cl->p->k; /* local reference to function's constant table */
|
k = cl->p->k; /* local reference to function's constant table */
|
||||||
updatemask(L);
|
updatemask(L);
|
||||||
pc = ci->u.l.savedpc;
|
pc = basepc(base);
|
||||||
/* main loop of interpreter */
|
/* main loop of interpreter */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Instruction i;
|
Instruction i;
|
||||||
|
@ -969,7 +972,7 @@ void luaV_execute (lua_State *L) {
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
int c = GETARG_C(i);
|
int c = GETARG_C(i);
|
||||||
Table *t;
|
Table *t;
|
||||||
savepc(L); /* in case of allocation errors */
|
savepc(base); /* in case of allocation errors */
|
||||||
t = luaH_new(L);
|
t = luaH_new(L);
|
||||||
sethvalue2s(L, ra, t);
|
sethvalue2s(L, ra, t);
|
||||||
if (b != 0 || c != 0)
|
if (b != 0 || c != 0)
|
||||||
|
@ -1368,9 +1371,9 @@ void luaV_execute (lua_State *L) {
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
||||||
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
|
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
|
||||||
savepc(L);
|
savepc(base);
|
||||||
if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */
|
if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */
|
||||||
Protect((void)0); /* update 'base' */
|
updatestate(); /* update 'base' */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* tail call: put called frame (n) in place of caller one (o) */
|
/* tail call: put called frame (n) in place of caller one (o) */
|
||||||
|
@ -1388,7 +1391,7 @@ void luaV_execute (lua_State *L) {
|
||||||
setobjs2s(L, ofunc + aux, nfunc + aux);
|
setobjs2s(L, ofunc + aux, nfunc + aux);
|
||||||
ofunc->stkci.framesize = L->top - nfunc;
|
ofunc->stkci.framesize = L->top - nfunc;
|
||||||
L->top = functop(ofunc); /* correct top */
|
L->top = functop(ofunc); /* correct top */
|
||||||
oci->u.l.savedpc = nci->u.l.savedpc;
|
ofunc->stkci.u.l.savedpc = nfunc->stkci.u.l.savedpc;
|
||||||
callstatus(ofunc) |= CIST_TAIL; /* function was tail called */
|
callstatus(ofunc) |= CIST_TAIL; /* function was tail called */
|
||||||
ci = L->ci = oci; /* remove new frame */
|
ci = L->ci = oci; /* remove new frame */
|
||||||
base = ofunc + 1;
|
base = ofunc + 1;
|
||||||
|
@ -1401,7 +1404,7 @@ void luaV_execute (lua_State *L) {
|
||||||
vmcase(OP_RETURN) {
|
vmcase(OP_RETURN) {
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
if (cl->p->sizep > 0) luaF_close(L, base);
|
if (cl->p->sizep > 0) luaF_close(L, base);
|
||||||
savepc(L);
|
savepc(base);
|
||||||
b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
|
b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
|
||||||
if (callstatus(base - 1) & CIST_FRESH) /* local 'base' still from callee */
|
if (callstatus(base - 1) & CIST_FRESH) /* local 'base' still from callee */
|
||||||
return; /* external invocation: return */
|
return; /* external invocation: return */
|
||||||
|
@ -1409,8 +1412,8 @@ void luaV_execute (lua_State *L) {
|
||||||
ci = L->ci;
|
ci = L->ci;
|
||||||
base = L->func + 1;
|
base = L->func + 1;
|
||||||
if (b) L->top = functop(base - 1);
|
if (b) L->top = functop(base - 1);
|
||||||
lua_assert(isLua(L->func));
|
lua_assert(isLua(base - 1));
|
||||||
lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
|
lua_assert(GET_OPCODE(*(basepc(base) - 1)) == OP_CALL);
|
||||||
goto newframe; /* restart luaV_execute over previous Lua function */
|
goto newframe; /* restart luaV_execute over previous Lua function */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1455,7 +1458,7 @@ void luaV_execute (lua_State *L) {
|
||||||
}
|
}
|
||||||
else { /* try making all values floats */
|
else { /* try making all values floats */
|
||||||
lua_Number ninit; lua_Number nlimit; lua_Number nstep;
|
lua_Number ninit; lua_Number nlimit; lua_Number nstep;
|
||||||
savepc(L); /* in case of errors */
|
savepc(base); /* in case of errors */
|
||||||
if (!tonumber(plimit, &nlimit))
|
if (!tonumber(plimit, &nlimit))
|
||||||
luaG_runerror(L, "'for' limit must be a number");
|
luaG_runerror(L, "'for' limit must be a number");
|
||||||
setfltvalue(plimit, nlimit);
|
setfltvalue(plimit, nlimit);
|
||||||
|
@ -1501,7 +1504,7 @@ void luaV_execute (lua_State *L) {
|
||||||
}
|
}
|
||||||
h = hvalue(s2v(ra));
|
h = hvalue(s2v(ra));
|
||||||
last = ((c-1)*LFIELDS_PER_FLUSH) + n;
|
last = ((c-1)*LFIELDS_PER_FLUSH) + n;
|
||||||
savepc(L); /* in case of allocation errors */
|
savepc(base); /* in case of allocation errors */
|
||||||
if (last > h->sizearray) /* needs more space? */
|
if (last > h->sizearray) /* needs more space? */
|
||||||
luaH_resizearray(L, h, last); /* preallocate it at once */
|
luaH_resizearray(L, h, last); /* preallocate it at once */
|
||||||
for (; n > 0; n--) {
|
for (; n > 0; n--) {
|
||||||
|
@ -1518,7 +1521,7 @@ void luaV_execute (lua_State *L) {
|
||||||
Proto *p = cl->p->p[GETARG_Bx(i)];
|
Proto *p = cl->p->p[GETARG_Bx(i)];
|
||||||
LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */
|
LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */
|
||||||
if (ncl == NULL) { /* no match? */
|
if (ncl == NULL) { /* no match? */
|
||||||
savepc(L); /* in case of allocation errors */
|
savepc(base); /* in case of allocation errors */
|
||||||
pushclosure(L, p, cl->upvals, base, ra); /* create a new one */
|
pushclosure(L, p, cl->upvals, base, ra); /* create a new one */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue