no more useful fields in CallInfo

This commit is contained in:
Roberto Ierusalimschy 2017-11-03 15:22:54 -02:00
parent 54eb35a8aa
commit 472c560705
7 changed files with 100 additions and 91 deletions

18
lapi.c
View File

@ -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
** 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);
func = L->top - (nargs+1);
if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
L->ci->u.c.k = k; /* save continuation */
L->ci->u.c.ctx = ctx; /* save context */
L->func->stkci.u.c.k = k; /* save continuation */
L->func->stkci.u.c.ctx = ctx; /* save context */
luaD_call(L, func, nresults); /* do the call */
}
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);
}
else { /* prepare continuation (call is already protected by 'resume') */
CallInfo *ci = L->ci;
StkId func = L->func;
ci->u.c.k = k; /* save continuation */
ci->u.c.ctx = ctx; /* save context */
func->stkci.u.c.k = k; /* save continuation */
func->stkci.u.c.ctx = ctx; /* save context */
/* save information for error recovery */
ci->u2.funcidx = savestack(L, c.func);
ci->u.c.old_errfunc = L->errfunc;
func->stkci.u2.funcidx = c.func - func;
func->stkci.u.c.old_errfunc = L->errfunc;
L->errfunc = efunc;
setoah(callstatus(func), L->allowhook); /* save value of 'allowhook' */
callstatus(func) |= CIST_YPCALL; /* function can do error recovery */
luaD_call(L, c.func, nresults); /* do the call */
func = L->func; /* previous call can reallocate stack */
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 */
}
adjustresults(L, nresults);

View File

@ -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
** See Copyright Notice in lua.h
*/
@ -44,7 +44,7 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
static int currentpc (CallInfo *ci) {
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;
}
if (isLua(L->func))
L->oldpc = L->ci->u.l.savedpc;
L->oldpc = L->func->stkci.u.l.savedpc;
L->hook = func;
L->basehookcount = count;
resethookcount(L);
@ -755,19 +755,21 @@ void luaG_traceexec (lua_State *L) {
luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
if (mask & LUA_MASKLINE) {
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, */
ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */
changedline(p, pcRel(L->oldpc, p), npc)) { /* enter new line */
func->stkci.u.l.savedpc <= L->oldpc || /* when jump back (loop), */
changedline(p, pcRel(L->oldpc, p), npc)) { /* when enter new line */
int newline = luaG_getfuncline(p, npc); /* new line */
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 (counthook)
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 */
luaD_throw(L, LUA_YIELD);
}

54
ldo.c
View File

@ -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
** 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;
StkId previous = L->func - L->func->stkci.previous;
ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
StkId func = L->func;
StkId previous = func - L->func->stkci.previous;
func->stkci.u.l.savedpc++; /* hooks assume 'pc' is already incremented */
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;
hook = LUA_HOOKTAILCALL;
}
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 */
luaD_hook(L, LUA_HOOKRET, -1);
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->func -= L->func->stkci.previous;
L->func = res - res->stkci.previous;
lua_assert(L->func == L->ci->func);
/* move results to proper place */
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->top = func + 1 + fsize;
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;
if (L->hookmask & LUA_MASKCALL)
callhook(L, ci);
callhook(L);
return 0;
}
default: { /* not a function */
@ -500,18 +504,19 @@ static void finishCcall (lua_State *L, int status) {
StkId func = L->func;
int n;
/* 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 */
lua_assert((callstatus(func) & CIST_YPCALL) || status == LUA_YIELD);
if (callstatus(func) & CIST_YPCALL) { /* was inside a pcall? */
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
handled */
adjustresults(L, func->stkci.nresults);
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);
api_checknelems(L, n);
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);
if (ci == NULL) return 0; /* no recovery point */
/* "finish" luaD_pcall */
oldtop = restorestack(L, ci->u2.funcidx);
oldtop = ci->func + ci->func->stkci.u2.funcidx;
luaF_close(L, oldtop);
seterrorobj(L, status, oldtop);
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->nny = 0; /* should be zero to be yieldable */
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 */
}
@ -602,6 +607,7 @@ static void resume (lua_State *L, void *ud) {
int n = *(cast(int*, ud)); /* number of arguments */
StkId firstArg = L->top - n; /* first argument */
CallInfo *ci = L->ci;
StkId func = L->func;
if (L->status == LUA_OK) { /* starting a coroutine? */
if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
luaV_execute(L); /* call it */
@ -609,12 +615,13 @@ static void resume (lua_State *L, void *ud) {
else { /* resuming from previous yield */
lua_assert(L->status == LUA_YIELD);
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 */
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);
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);
api_checknelems(L, n);
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 */
}
*nresults = (status == LUA_YIELD) ? L->ci->u2.nyield
*nresults = (status == LUA_YIELD) ? L->func->stkci.u2.nyield
: L->top - (L->func + 1);
L->nny = oldnny; /* restore 'nny' */
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_KFunction k) {
CallInfo *ci = L->ci;
StkId func = L->func;
luai_userstateyield(L, nresults);
lua_lock(L);
@ -689,12 +695,12 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
L->status = LUA_YIELD;
if (isLua(func)) { /* inside a hook? */
api_check(L, k == NULL, "hooks cannot continue after yielding");
ci->u2.nyield = 0; /* no results */
func->stkci.u2.nyield = 0; /* no results */
}
else {
if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
ci->u.c.ctx = ctx; /* save context */
ci->u2.nyield = nresults; /* save number of results */
if ((func->stkci.u.c.k = k) != NULL) /* is there a continuation? */
func->stkci.u.c.ctx = ctx; /* save context */
func->stkci.u2.nyield = nresults; /* save number of results */
luaD_throw(L, LUA_YIELD);
}
lua_assert(callstatus(func) & CIST_HOOKED); /* must be inside a hook */

View File

@ -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
** See Copyright Notice in lua.h
*/
@ -314,9 +314,23 @@ typedef union StackValue {
struct {
TValuefields;
lu_byte callstatus_;
unsigned short previous; /* difference to previous 'func' */
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 */
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;
} StackValue;

View File

@ -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
** See Copyright Notice in lua.h
*/
@ -87,20 +87,6 @@ typedef struct stringtable {
typedef struct CallInfo {
StkId func; /* function index in the stack */
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;

View File

@ -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
** See Copyright Notice in lua.h
*/
@ -309,28 +309,26 @@ static void checkLclosure (global_State *g, LClosure *cl) {
}
static int lua_checkpc (CallInfo *ci) {
if (!isLua(ci->func)) return 1;
static int lua_checkpc (StkId func) {
if (!isLua(func)) return 1;
else {
StkId f = ci->func;
Proto *p = clLvalue(s2v(f))->p;
return p->code <= ci->u.l.savedpc &&
ci->u.l.savedpc <= p->code + p->sizecode;
Proto *p = clLvalue(s2v(func))->p;
return p->code <= func->stkci.u.l.savedpc &&
func->stkci.u.l.savedpc <= p->code + p->sizecode;
}
}
static void checkstack (global_State *g, lua_State *L1) {
StkId o;
CallInfo *ci;
UpVal *uv;
lua_assert(!isdead(g, L1));
for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next)
lua_assert(upisopen(uv)); /* must be open */
for (ci = L1->ci; ci != NULL; ci = ci->previous)
lua_assert(lua_checkpc(ci));
for (o = L1->func; o->stkci.previous != 0; o -= o->stkci.previous)
for (o = L1->func; o->stkci.previous != 0; o -= o->stkci.previous) {
lua_assert(functop(o) <= L1->stack_last);
lua_assert(lua_checkpc(o));
}
lua_assert(o == L1->stack);
if (L1->stack) { /* complete thread? */
for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++)

47
lvm.c
View File

@ -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
** 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
*/
void luaV_finishOp (lua_State *L) {
CallInfo *ci = L->ci;
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);
switch (op) { /* finish its execution */
case OP_ADDI: case OP_SUBI:
@ -684,9 +685,9 @@ void luaV_finishOp (lua_State *L) {
callstatus(base - 1) ^= CIST_LEQ; /* clear mark */
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? */
ci->u.l.savedpc++; /* skip jump instruction */
basepc(base)++; /* skip jump instruction */
break;
}
case OP_CONCAT: {
@ -704,7 +705,7 @@ void luaV_finishOp (lua_State *L) {
break;
}
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 */
break;
}
@ -763,20 +764,22 @@ void luaV_finishOp (lua_State *L) {
** Whenever code can raise errors (including memory errors), the global
** '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
** stack, and change the hooks.
*/
#define Protect(code) \
{ savepc(L); {code;}; base = L->func + 1; updatemask(L); }
#define Protect(code) { savepc(base); {code;}; updatestate(); }
#define checkGC(L,c) \
{ 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); }
@ -798,14 +801,14 @@ void luaV_execute (lua_State *L) {
TValue *k;
StkId base = L->func + 1; /* local copy of 'L->func + 1' */
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" */
newframe: /* reentry point when frame changes (call/return) */
lua_assert(ci == L->ci);
cl = clLvalue(s2v(L->func)); /* local reference to function's closure */
k = cl->p->k; /* local reference to function's constant table */
updatemask(L);
pc = ci->u.l.savedpc;
pc = basepc(base);
/* main loop of interpreter */
for (;;) {
Instruction i;
@ -969,7 +972,7 @@ void luaV_execute (lua_State *L) {
int b = GETARG_B(i);
int c = GETARG_C(i);
Table *t;
savepc(L); /* in case of allocation errors */
savepc(base); /* in case of allocation errors */
t = luaH_new(L);
sethvalue2s(L, ra, t);
if (b != 0 || c != 0)
@ -1368,9 +1371,9 @@ void luaV_execute (lua_State *L) {
int b = GETARG_B(i);
if (b != 0) L->top = ra+b; /* else previous instruction set top */
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
savepc(L);
savepc(base);
if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */
Protect((void)0); /* update 'base' */
updatestate(); /* update 'base' */
}
else {
/* 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);
ofunc->stkci.framesize = L->top - nfunc;
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 */
ci = L->ci = oci; /* remove new frame */
base = ofunc + 1;
@ -1401,7 +1404,7 @@ void luaV_execute (lua_State *L) {
vmcase(OP_RETURN) {
int b = GETARG_B(i);
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)));
if (callstatus(base - 1) & CIST_FRESH) /* local 'base' still from callee */
return; /* external invocation: return */
@ -1409,8 +1412,8 @@ void luaV_execute (lua_State *L) {
ci = L->ci;
base = L->func + 1;
if (b) L->top = functop(base - 1);
lua_assert(isLua(L->func));
lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
lua_assert(isLua(base - 1));
lua_assert(GET_OPCODE(*(basepc(base) - 1)) == OP_CALL);
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 */
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))
luaG_runerror(L, "'for' limit must be a number");
setfltvalue(plimit, nlimit);
@ -1501,7 +1504,7 @@ void luaV_execute (lua_State *L) {
}
h = hvalue(s2v(ra));
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? */
luaH_resizearray(L, h, last); /* preallocate it at once */
for (; n > 0; n--) {
@ -1518,7 +1521,7 @@ void luaV_execute (lua_State *L) {
Proto *p = cl->p->p[GETARG_Bx(i)];
LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */
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 */
}
else