commit d3037d97ec192e7719de485f15dacb473bf96528
parent c6b442bd369ce05b3d4bfb95ba64451521aa1b31
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Fri, 17 Apr 2009 18:59:37 -0300
several small improvements based on 'ci' being fixed now (including
erasing savedpc from lua_State)
Diffstat:
M | lapi.c | | | 19 | ++++++++++--------- |
M | ldebug.c | | | 8 | +++----- |
M | ldo.c | | | 52 | +++++++++++++++++++++++++--------------------------- |
M | lstate.c | | | 3 | +-- |
M | lstate.h | | | 5 | ++--- |
M | ltests.c | | | 26 | ++++++++++++-------------- |
M | ltests.h | | | 3 | +-- |
M | lvm.c | | | 155 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
8 files changed, 133 insertions(+), 138 deletions(-)
diff --git a/lapi.c b/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 2.74 2009/04/08 18:04:33 roberto Exp roberto $
+** $Id: lapi.c,v 2.75 2009/04/17 14:28:06 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -829,18 +829,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), func);
}
else { /* prepare continuation (call is already protected by 'resume') */
- L->ci->u.c.k = k; /* save continuation */
- L->ci->u.c.ctx = ctx; /* save context */
+ CallInfo *ci = L->ci;
+ ci->u.c.k = k; /* save continuation */
+ ci->u.c.ctx = ctx; /* save context */
/* save information for error recovery */
- L->ci->u.c.oldtop = savestack(L, c.func);
- L->ci->u.c.old_allowhook = L->allowhook;
- L->ci->u.c.old_errfunc = L->errfunc;
+ ci->u.c.oldtop = savestack(L, c.func);
+ ci->u.c.old_allowhook = L->allowhook;
+ ci->u.c.old_errfunc = L->errfunc;
L->errfunc = func;
/* mark that function may do error recovery */
- L->ci->callstatus |= CIST_YPCALL;
+ ci->callstatus |= CIST_YPCALL;
luaD_call(L, c.func, nresults, 1); /* do the call */
- L->ci->callstatus &= ~CIST_YPCALL;
- L->errfunc = L->ci->u.c.old_errfunc;
+ ci->callstatus &= ~CIST_YPCALL;
+ L->errfunc = ci->u.c.old_errfunc;
status = LUA_OK; /* if it is here, there were no errors */
}
adjustresults(L, nresults);
diff --git a/ldebug.c b/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 2.45 2009/03/26 12:56:38 roberto Exp roberto $
+** $Id: ldebug.c,v 2.46 2009/04/17 14:28:06 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -35,9 +35,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
static int currentpc (lua_State *L, CallInfo *ci) {
if (!isLua(ci)) return -1; /* function is not a Lua function? */
- if (ci == L->ci)
- ci->savedpc = L->savedpc;
- return pcRel(ci->savedpc, ci_func(ci)->l.p);
+ return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);
}
@@ -58,7 +56,7 @@ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
mask = 0;
func = NULL;
}
- L->oldpc = L->savedpc;
+ L->oldpc = NULL;
L->hook = func;
L->basehookcount = count;
resethookcount(L);
diff --git a/ldo.c b/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 2.59 2009/04/15 16:53:39 roberto Exp roberto $
+** $Id: ldo.c,v 2.60 2009/04/17 14:28:06 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -151,28 +151,29 @@ void luaD_growstack (lua_State *L, int n) {
void luaD_callhook (lua_State *L, int event, int line) {
lua_Hook hook = L->hook;
if (hook && L->allowhook) {
+ CallInfo *ci = L->ci;
ptrdiff_t top = savestack(L, L->top);
- ptrdiff_t ci_top = savestack(L, L->ci->top);
+ ptrdiff_t ci_top = savestack(L, ci->top);
lua_Debug ar;
ar.event = event;
ar.currentline = line;
if (event == LUA_HOOKTAILRET)
ar.i_ci = NULL; /* tail call; no debug information about it */
else
- ar.i_ci = L->ci;
+ ar.i_ci = ci;
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
- L->ci->top = L->top + LUA_MINSTACK;
- lua_assert(L->ci->top <= L->stack_last);
+ ci->top = L->top + LUA_MINSTACK;
+ lua_assert(ci->top <= L->stack_last);
L->allowhook = 0; /* cannot call hooks inside a hook */
- L->ci->callstatus |= CIST_HOOKED;
+ ci->callstatus |= CIST_HOOKED;
lua_unlock(L);
(*hook)(L, &ar);
lua_lock(L);
lua_assert(!L->allowhook);
L->allowhook = 1;
- L->ci->top = restorestack(L, ci_top);
+ ci->top = restorestack(L, ci_top);
L->top = restorestack(L, top);
- L->ci->callstatus &= ~CIST_HOOKED;
+ ci->callstatus &= ~CIST_HOOKED;
}
}
@@ -223,7 +224,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
func = tryfuncTM(L, func); /* check the `function' tag method */
funcr = savestack(L, func);
cl = &clvalue(func)->l;
- L->ci->savedpc = L->savedpc;
L->ci->nresults = nresults;
if (!cl->isC) { /* Lua function? prepare its call */
CallInfo *ci;
@@ -243,16 +243,16 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
L->base = ci->base = base;
ci->top = L->base + p->maxstacksize;
lua_assert(ci->top <= L->stack_last);
- L->savedpc = p->code; /* starting point */
+ ci->u.l.savedpc = p->code; /* starting point */
ci->u.l.tailcalls = 0;
ci->callstatus = CIST_LUA;
for (st = L->top; st < ci->top; st++)
setnilvalue(st);
L->top = ci->top;
if (L->hookmask & LUA_MASKCALL) {
- L->savedpc++; /* hooks assume 'pc' is already incremented */
+ ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
luaD_callhook(L, LUA_HOOKCALL, -1);
- L->savedpc--; /* correct 'pc' */
+ ci->u.l.savedpc--; /* correct 'pc' */
}
return 0;
}
@@ -295,13 +295,12 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
if (L->hookmask & LUA_MASKRET)
firstResult = callrethooks(L, firstResult);
- L->oldpc = L->ci->previous->savedpc; /* 'oldpc' for returning function */
+ L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for returning function */
}
res = ci->func; /* res == final position of 1st result */
- L->ci = ci = L->ci->previous; /* back to caller */
+ L->ci = ci = ci->previous; /* back to caller */
wanted = ci->nresults;
L->base = ci->base; /* restore base */
- L->savedpc = ci->savedpc; /* restore savedpc */
/* move results to correct place */
for (i = wanted; i != 0 && firstResult < L->top; i--)
setobjs2s(L, res++, firstResult++);
@@ -336,21 +335,21 @@ void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
static void finishCcall (lua_State *L) {
+ CallInfo *ci = L->ci;
int n;
- lua_assert(L->ci->u.c.k != NULL); /* must have a continuation */
+ lua_assert(ci->u.c.k != NULL); /* must have a continuation */
lua_assert(L->nny == 0);
/* finish 'luaD_call' */
G(L)->nCcalls--;
/* finish 'lua_callk' */
- adjustresults(L, L->ci->nresults);
+ adjustresults(L, ci->nresults);
/* call continuation function */
- if (!(L->ci->callstatus & CIST_STAT)) /* no call status? */
- L->ci->u.c.status = LUA_YIELD; /* 'default' status */
- lua_assert(L->ci->u.c.status != LUA_OK);
- L->ci->callstatus = (L->ci->callstatus & ~(CIST_YPCALL | CIST_STAT))
- | CIST_YIELDED;
+ if (!(ci->callstatus & CIST_STAT)) /* no call status? */
+ ci->u.c.status = LUA_YIELD; /* 'default' status */
+ lua_assert(ci->u.c.status != LUA_OK);
+ ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED;
lua_unlock(L);
- n = (*L->ci->u.c.k)(L);
+ n = (*ci->u.c.k)(L);
lua_lock(L);
/* finish 'luaD_precall' */
luaD_poscall(L, L->top - n);
@@ -384,7 +383,7 @@ static void resume (lua_State *L, void *ud) {
lua_assert(L->status == LUA_YIELD);
L->status = LUA_OK;
if (isLua(ci)) { /* yielded inside a hook? */
- L->base = L->ci->base; /* just continue its execution */
+ L->base = ci->base; /* just continue its execution */
luaV_execute(L);
}
else { /* 'common' yield */
@@ -427,7 +426,7 @@ static int recover (lua_State *L, int status) {
luaF_close(L, oldtop);
luaD_seterrorobj(L, status, oldtop);
L->ci = ci;
- L->base = L->ci->base;
+ L->base = ci->base;
L->allowhook = ci->u.c.old_allowhook;
L->nny = 0; /* should be zero to be yieldable */
restore_stack_limit(L);
@@ -499,8 +498,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
luaF_close(L, oldtop); /* close possible pending closures */
luaD_seterrorobj(L, status, oldtop);
L->ci = old_ci;
- L->base = L->ci->base;
- L->savedpc = L->ci->savedpc;
+ L->base = old_ci->base;
L->allowhook = old_allowhooks;
L->nny = old_nny;
restore_stack_limit(L);
diff --git a/lstate.c b/lstate.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.c,v 2.51 2009/04/17 14:28:06 roberto Exp roberto $
+** $Id: lstate.c,v 2.52 2009/04/17 14:40:13 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -130,7 +130,6 @@ static void preinit_state (lua_State *L, global_State *g) {
L->base_ci.next = L->base_ci.previous = NULL;
L->ci = &L->base_ci;
L->nci = 0;
- L->savedpc = NULL;
L->errfunc = 0;
setnilvalue(gt(L));
}
diff --git a/lstate.h b/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 2.41 2009/04/08 18:04:33 roberto Exp roberto $
+** $Id: lstate.h,v 2.42 2009/04/17 14:28:06 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -81,11 +81,11 @@ typedef struct CallInfo {
StkId func; /* function index in the stack */
StkId top; /* top for this function */
struct CallInfo *previous, *next; /* dynamic call link */
- const Instruction *savedpc;
short nresults; /* expected number of results from a call */
lu_byte callstatus;
union {
struct { /* only for Lua functions */
+ const Instruction *savedpc;
int tailcalls; /* number of tail calls lost under this entry */
} l;
struct { /* only for C functions */
@@ -165,7 +165,6 @@ struct lua_State {
global_State *l_G;
CallInfo *ci; /* call info for current function */
int nci; /* number of total CallInfo structures linked */
- const Instruction *savedpc; /* `savedpc' of current function */
const Instruction *oldpc; /* last pc traced */
StkId stack_last; /* last free slot in the stack */
StkId stack; /* stack base */
diff --git a/ltests.c b/ltests.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltests.c,v 2.60 2009/04/14 19:10:17 roberto Exp roberto $
+** $Id: ltests.c,v 2.61 2009/04/17 14:28:06 roberto Exp roberto $
** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
@@ -285,6 +285,16 @@ static void checkclosure (global_State *g, Closure *cl) {
}
+static int lua_checkpc (pCallInfo ci) {
+ if (!isLua(ci)) return 1;
+ else {
+ Proto *p = ci_func(ci)->l.p;
+ return p->code <= ci->u.l.savedpc &&
+ ci->u.l.savedpc <= p->code + p->sizecode;
+ }
+}
+
+
static void checkstack (global_State *g, lua_State *L1) {
StkId o;
CallInfo *ci;
@@ -298,7 +308,7 @@ static void checkstack (global_State *g, lua_State *L1) {
checkliveness(g, gt(L1));
for (ci = L1->ci; ci != NULL; ci = ci->previous) {
lua_assert(ci->top <= L1->stack_last);
- lua_assert(lua_checkpc(L1, ci));
+ lua_assert(lua_checkpc(ci));
}
if (L1->stack) {
for (o = L1->stack; o < L1->top; o++)
@@ -352,18 +362,6 @@ printf(">>> %d %s %02x\n", g->gcstate, luaT_typenames[gch(o)->tt], gch(o)->mar
}
-int lua_checkpc (lua_State *L, pCallInfo ci) {
- if (!isLua(ci)) return 1;
- else {
- Proto *p = ci_func(ci)->l.p;
- if (ci != L->ci)
- return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode;
- else
- return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode;
- }
-}
-
-
int lua_checkmemory (lua_State *L) {
global_State *g = G(L);
GCObject *o;
diff --git a/ltests.h b/ltests.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltests.h,v 2.23 2008/07/18 19:58:10 roberto Exp roberto $
+** $Id: ltests.h,v 2.24 2008/08/05 19:24:46 roberto Exp roberto $
** Internal Header for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
@@ -51,7 +51,6 @@ void *debug_realloc (void *ud, void *block, size_t osize, size_t nsize);
typedef struct CallInfo *pCallInfo;
int lua_checkmemory (lua_State *L);
-int lua_checkpc (lua_State *L, pCallInfo ci);
/* test for lock/unlock */
diff --git a/lvm.c b/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 2.84 2009/03/10 17:14:37 roberto Exp roberto $
+** $Id: lvm.c,v 2.85 2009/04/17 14:28:06 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -58,21 +58,22 @@ int luaV_tostring (lua_State *L, StkId obj) {
static void traceexec (lua_State *L) {
+ CallInfo *ci = L->ci;
lu_byte mask = L->hookmask;
if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
resethookcount(L);
luaD_callhook(L, LUA_HOOKCOUNT, -1);
}
if (mask & LUA_MASKLINE) {
- Proto *p = ci_func(L->ci)->l.p;
- int npc = pcRel(L->savedpc, p);
+ Proto *p = ci_func(ci)->l.p;
+ int npc = pcRel(ci->u.l.savedpc, p);
int newline = getline(p, npc);
if (npc == 0 || /* call linehook when enter a new function, */
- L->savedpc <= L->oldpc || /* when jump back (loop), or when */
+ ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */
newline != getline(p, pcRel(L->oldpc, p))) /* enter a new line */
luaD_callhook(L, LUA_HOOKLINE, newline);
}
- L->oldpc = L->savedpc;
+ L->oldpc = ci->u.l.savedpc;
}
@@ -357,7 +358,8 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb,
** finish execution of an opcode interrupted by an yield
*/
void luaV_finishOp (lua_State *L) {
- Instruction inst = *(L->savedpc - 1); /* interrupted instruction */
+ CallInfo *ci = L->ci;
+ Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */
switch (GET_OPCODE(inst)) { /* finish its execution */
case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN:
@@ -373,9 +375,9 @@ void luaV_finishOp (lua_State *L) {
if (GET_OPCODE(inst) == OP_LE && /* "<=" using "<" instead? */
ttisnil(luaT_gettmbyobj(L, L->base + GETARG_B(inst), TM_LE)))
res = !res; /* invert result */
- lua_assert(GET_OPCODE(*L->savedpc) == OP_JMP);
+ lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
if (res != GETARG_A(inst)) /* condition failed? */
- L->savedpc++; /* skip jump instruction */
+ ci->u.l.savedpc++; /* skip jump instruction */
break;
}
case OP_CONCAT: {
@@ -384,7 +386,7 @@ void luaV_finishOp (lua_State *L) {
int b = GETARG_B(inst); /* ... first element to concatenate */
int total = last - b + 1; /* number of elements to concatenate */
setobj2s(L, top - 2, top); /* put TM result in proper position */
- L->top = L->ci->top; /* correct top */
+ L->top = ci->top; /* correct top */
if (total > 1) /* are there elements to concat? */
luaV_concat(L, total, last); /* concat them (may yield again) */
/* move final result to final position */
@@ -392,13 +394,13 @@ void luaV_finishOp (lua_State *L) {
break;
}
case OP_TFORCALL: {
- lua_assert(GET_OPCODE(*L->savedpc) == OP_TFORLOOP);
- L->top = L->ci->top; /* correct top */
+ lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
+ L->top = ci->top; /* correct top */
break;
}
case OP_CALL: {
if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */
- L->top = L->ci->top; /* adjust results */
+ L->top = ci->top; /* adjust results */
break;
}
case OP_TAILCALL: case OP_SETGLOBAL: case OP_SETTABLE:
@@ -413,8 +415,6 @@ void luaV_finishOp (lua_State *L) {
** some macros for common tasks in `luaV_execute'
*/
-#define runtime_check(L, c) { if (!(c)) break; }
-
#define RA(i) (base+GETARG_A(i))
/* to be used after possible stack reallocation */
#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
@@ -426,10 +426,10 @@ void luaV_finishOp (lua_State *L) {
#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
-#define dojump(L,i) { L->savedpc += (i); luai_threadyield(L);}
+#define dojump(i) { ci->u.l.savedpc += (i); luai_threadyield(L);}
-#define Protect(x) { {x;}; base = L->base; }
+#define Protect(x) { {x;}; base = ci->base; }
#define arith_op(op,tm) { \
@@ -446,32 +446,29 @@ void luaV_finishOp (lua_State *L) {
void luaV_execute (lua_State *L) {
- LClosure *cl;
- StkId base;
- TValue *k;
- reentry: /* entry point */
- lua_assert(isLua(L->ci));
- cl = &curr_func(L)->l;
- base = L->base;
- k = cl->p->k;
+ CallInfo *ci = L->ci;
+ LClosure *cl = &clvalue(ci->func)->l;
+ TValue *k = cl->p->k;
+ StkId base = ci->base;
+ lua_assert(isLua(ci));
/* main loop of interpreter */
for (;;) {
- Instruction i = *(L->savedpc++);
+ Instruction i = *(ci->u.l.savedpc++);
StkId ra;
if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
(--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
traceexec(L);
if (L->status == LUA_YIELD) { /* did hook yield? */
- L->savedpc--; /* undo increment */
+ ci->u.l.savedpc--; /* undo increment */
luaD_throw(L, LUA_YIELD);
}
- base = L->base;
+ base = ci->base;
}
/* warning!! several calls may realloc the stack and invalidate `ra' */
ra = RA(i);
- lua_assert(base == L->base && L->base == L->ci->base);
+ lua_assert(base == ci->base && base == L->base);
lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
- lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
+ lua_assert(L->top == ci->top || luaG_checkopenop(i));
switch (GET_OPCODE(i)) {
case OP_MOVE: {
setobjs2s(L, ra, RB(i));
@@ -483,7 +480,7 @@ void luaV_execute (lua_State *L) {
}
case OP_LOADBOOL: {
setbvalue(ra, GETARG_B(i));
- if (GETARG_C(i)) L->savedpc++; /* skip next instruction (if C) */
+ if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */
continue;
}
case OP_LOADNIL: {
@@ -595,7 +592,7 @@ void luaV_execute (lua_State *L) {
continue;
}
case OP_JMP: {
- dojump(L, GETARG_sBx(i));
+ dojump(GETARG_sBx(i));
continue;
}
case OP_EQ: {
@@ -603,40 +600,40 @@ void luaV_execute (lua_State *L) {
TValue *rc = RKC(i);
Protect(
if (equalobj(L, rb, rc) == GETARG_A(i))
- dojump(L, GETARG_sBx(*L->savedpc));
+ dojump(GETARG_sBx(*ci->u.l.savedpc));
)
- L->savedpc++;
+ ci->u.l.savedpc++;
continue;
}
case OP_LT: {
Protect(
if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
- dojump(L, GETARG_sBx(*L->savedpc));
+ dojump(GETARG_sBx(*ci->u.l.savedpc));
)
- L->savedpc++;
+ ci->u.l.savedpc++;
continue;
}
case OP_LE: {
Protect(
if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
- dojump(L, GETARG_sBx(*L->savedpc));
+ dojump(GETARG_sBx(*ci->u.l.savedpc));
)
- L->savedpc++;
+ ci->u.l.savedpc++;
continue;
}
case OP_TEST: {
if (GETARG_C(i) ? !l_isfalse(ra) : l_isfalse(ra))
- dojump(L, GETARG_sBx(*L->savedpc));
- L->savedpc++;
+ dojump(GETARG_sBx(*ci->u.l.savedpc));
+ ci->u.l.savedpc++;
continue;
}
case OP_TESTSET: {
TValue *rb = RB(i);
if (GETARG_C(i) ? !l_isfalse(rb) : l_isfalse(rb)) {
setobjs2s(L, ra, rb);
- dojump(L, GETARG_sBx(*L->savedpc));
+ dojump(GETARG_sBx(*ci->u.l.savedpc));
}
- L->savedpc++;
+ ci->u.l.savedpc++;
continue;
}
case OP_CALL: {
@@ -644,13 +641,14 @@ void luaV_execute (lua_State *L) {
int nresults = GETARG_C(i) - 1;
if (b != 0) L->top = ra+b; /* else previous instruction set top */
if (luaD_precall(L, ra, nresults)) { /* C function? */
- if (nresults >= 0) L->top = L->ci->top; /* adjust results */
- base = L->base;
+ if (nresults >= 0) L->top = ci->top; /* adjust results */
+ base = ci->base;
continue;
}
else { /* Lua function */
- L->ci->callstatus |= CIST_REENTRY;
- goto reentry; /* restart luaV_execute over new Lua function */
+ ci = L->ci;
+ ci->callstatus |= CIST_REENTRY;
+ break; /* restart luaV_execute over new Lua function */
}
}
case OP_TAILCALL: {
@@ -658,25 +656,26 @@ void luaV_execute (lua_State *L) {
if (b != 0) L->top = ra+b; /* else previous instruction set top */
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */
- base = L->base;
+ base = ci->base;
continue;
}
else {
- /* tail call: put new frame in place of previous one */
- StkId pfunc = L->ci->func; /* called function index */
- CallInfo *ci = L->ci->previous; /* caller frame */
- StkId func = ci->func;
+ /* tail call: put called frame (n) in place of caller one (o) */
+ CallInfo *nci = L->ci; /* called frame */
+ CallInfo *oci = nci->previous; /* caller frame */
+ StkId nfunc = nci->func; /* called function index */
+ StkId ofunc = oci->func;
int aux;
- if (cl->p->sizep > 0) luaF_close(L, ci->base);
- L->base = ci->base = ci->func + (L->ci->base - pfunc);
- for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
- setobjs2s(L, func+aux, pfunc+aux);
- ci->top = L->top = func+aux; /* correct top */
- lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
- ci->savedpc = L->savedpc;
- ci->u.l.tailcalls++; /* one more call lost */
- L->ci = ci; /* remove new frame */
- goto reentry;
+ if (cl->p->sizep > 0) luaF_close(L, oci->base);
+ L->base = oci->base = ofunc + (nci->base - nfunc);
+ for (aux = 0; nfunc+aux < L->top; aux++) /* move frame down */
+ setobjs2s(L, ofunc + aux, nfunc + aux);
+ oci->top = L->top = ofunc + aux; /* correct top */
+ lua_assert(L->top == L->base + clvalue(ofunc)->l.p->maxstacksize);
+ oci->u.l.savedpc = nci->u.l.savedpc;
+ oci->u.l.tailcalls++; /* one more call lost */
+ ci = L->ci = oci; /* remove new frame */
+ break; /* restart luaV_execute over new Lua function */
}
}
case OP_RETURN: {
@@ -684,13 +683,14 @@ void luaV_execute (lua_State *L) {
if (b != 0) L->top = ra+b-1;
if (cl->p->sizep > 0) luaF_close(L, base);
b = luaD_poscall(L, ra);
- if (!(L->ci->next->callstatus & CIST_REENTRY))
+ if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */
return; /* external invocation: return */
else { /* invocation via reentry: continue execution */
- if (b) L->top = L->ci->top;
- lua_assert(isLua(L->ci));
- lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
- goto reentry;
+ ci = L->ci;
+ if (b) L->top = ci->top;
+ lua_assert(isLua(ci));
+ lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
+ break; /* restart luaV_execute over new Lua function */
}
}
case OP_FORLOOP: {
@@ -699,7 +699,7 @@ void luaV_execute (lua_State *L) {
lua_Number limit = nvalue(ra+1);
if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit)
: luai_numle(L, limit, idx)) {
- dojump(L, GETARG_sBx(i)); /* jump back */
+ dojump(GETARG_sBx(i)); /* jump back */
setnvalue(ra, idx); /* update internal index... */
setnvalue(ra+3, idx); /* ...and external index */
}
@@ -716,7 +716,7 @@ void luaV_execute (lua_State *L) {
else if (!tonumber(pstep, ra+2))
luaG_runerror(L, LUA_QL("for") " step must be a number");
setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep)));
- dojump(L, GETARG_sBx(i));
+ dojump(GETARG_sBx(i));
continue;
}
case OP_TFORCALL: {
@@ -726,8 +726,8 @@ void luaV_execute (lua_State *L) {
setobjs2s(L, cb, ra);
L->top = cb + 3; /* func. + 2 args (state and index) */
Protect(luaD_call(L, cb, GETARG_C(i), 1));
- L->top = L->ci->top;
- i = *(L->savedpc++); /* go to next instruction */
+ L->top = ci->top;
+ i = *(ci->u.l.savedpc++); /* go to next instruction */
ra = RA(i);
lua_assert(GET_OPCODE(i) == OP_TFORLOOP);
/* go through */
@@ -735,7 +735,7 @@ void luaV_execute (lua_State *L) {
case OP_TFORLOOP: {
if (!ttisnil(ra + 1)) { /* continue loop? */
setobjs2s(L, ra, ra + 1); /* save control variable */
- dojump(L, GETARG_sBx(i)); /* jump back */
+ dojump(GETARG_sBx(i)); /* jump back */
}
continue;
}
@@ -746,10 +746,9 @@ void luaV_execute (lua_State *L) {
Table *h;
if (n == 0) n = cast_int(L->top - ra) - 1;
if (c == 0) {
- lua_assert(GET_OPCODE(*L->savedpc) == OP_EXTRAARG);
- c = GETARG_Ax(*L->savedpc++);
+ lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
+ c = GETARG_Ax(*ci->u.l.savedpc++);
}
- runtime_check(L, ttistable(ra));
h = hvalue(ra);
last = ((c-1)*LFIELDS_PER_FLUSH) + n;
if (last > h->sizearray) /* needs more space? */
@@ -759,7 +758,7 @@ void luaV_execute (lua_State *L) {
setobj2t(L, luaH_setnum(L, h, last--), val);
luaC_barriert(L, h, val);
}
- L->top = L->ci->top; /* correct top (in case of previous open call) */
+ L->top = ci->top; /* correct top (in case of previous open call) */
continue;
}
case OP_CLOSE: {
@@ -776,7 +775,7 @@ void luaV_execute (lua_State *L) {
ncl->l.p = p;
setclvalue(L, ra, ncl);
for (j=0; j<nup; j++) {
- Instruction u = *L->savedpc++;
+ Instruction u = *ci->u.l.savedpc++;
if (GET_OPCODE(u) == OP_GETUPVAL)
ncl->l.upvals[j] = cl->upvals[GETARG_B(u)];
else {
@@ -790,7 +789,6 @@ void luaV_execute (lua_State *L) {
case OP_VARARG: {
int b = GETARG_B(i) - 1;
int j;
- CallInfo *ci = L->ci;
int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
if (b == LUA_MULTRET) {
Protect(luaD_checkstack(L, n));
@@ -813,6 +811,11 @@ void luaV_execute (lua_State *L) {
return;
}
}
+ /* function changed (call/return): update pointers */
+ lua_assert(ci == L->ci);
+ cl = &clvalue(ci->func)->l;
+ k = cl->p->k;
+ base = ci->base;
}
}