From f94cd2201c3a8d341db448f2719dfb0ae4338adf Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 26 Aug 2008 10:27:42 -0300 Subject: [PATCH] better control of call status through CallInfo --- ldebug.c | 4 ++-- ldo.c | 19 ++++++++++--------- lstate.c | 4 ++-- lstate.h | 15 +++++++++++---- ltests.c | 4 ++-- lvm.c | 21 ++++++++++++--------- lvm.h | 4 ++-- 7 files changed, 41 insertions(+), 30 deletions(-) diff --git a/ldebug.c b/ldebug.c index 9455a937..a74c4c3e 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.39 2008/04/02 19:14:16 roberto Exp roberto $ +** $Id: ldebug.c,v 2.40 2008/07/03 14:24:11 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -88,7 +88,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { lua_lock(L); for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { level--; - if (f_isLua(ci)) /* Lua function? */ + if (isLua(ci)) /* Lua function? */ level -= ci->tailcalls; /* skip lost tail calls */ } if (level == 0 && ci > L->base_ci) { /* level found? */ diff --git a/ldo.c b/ldo.c index c984dd09..6df778bc 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.46 2008/01/18 22:36:50 roberto Exp roberto $ +** $Id: ldo.c,v 2.47 2008/08/13 17:02:42 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -193,9 +193,9 @@ void luaD_callhook (lua_State *L, int event, int line) { ar.i_ci = cast_int(L->ci - L->base_ci); luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ L->ci->top = L->top + LUA_MINSTACK; - L->ci->status |= 1; /* this level is running a hook */ lua_assert(L->ci->top <= L->stack_last); L->allowhook = 0; /* cannot call hooks inside a hook */ + L->ci->callstatus |= CIST_HOOKED; lua_unlock(L); (*hook)(L, &ar); lua_lock(L); @@ -203,7 +203,7 @@ void luaD_callhook (lua_State *L, int event, int line) { L->allowhook = 1; L->ci->top = restorestack(L, ci_top); L->top = restorestack(L, top); - L->ci->status &= ~1; /* this level is not running a hook anymore */ + L->ci->callstatus &= ~CIST_HOOKED; } } @@ -297,7 +297,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { lua_assert(ci->top <= L->stack_last); L->savedpc = p->code; /* starting point */ ci->tailcalls = 0; - ci->status = 0; + ci->callstatus = CIST_LUA; ci->nresults = nresults; for (st = L->top; st < ci->top; st++) setnilvalue(st); @@ -319,6 +319,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { ci->top = L->top + LUA_MINSTACK; lua_assert(ci->top <= L->stack_last); ci->nresults = nresults; + ci->callstatus = 0; if (L->hookmask & LUA_MASKCALL) luaD_callhook(L, LUA_HOOKCALL, -1); lua_unlock(L); @@ -333,7 +334,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { static StkId callrethooks (lua_State *L, StkId firstResult) { ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ luaD_callhook(L, LUA_HOOKRET, -1); - if (f_isLua(L->ci)) { /* Lua function? */ + if (isLua(L->ci)) { /* Lua function? */ while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ luaD_callhook(L, LUA_HOOKTAILRET, -1); } @@ -381,7 +382,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) { luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ } if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ - luaV_execute(L, 1); /* call it */ + luaV_execute(L); /* call it */ g->nCcalls--; luaC_checkGC(L); } @@ -398,7 +399,7 @@ static void resume (lua_State *L, void *ud) { else { /* resuming from previous yield */ lua_assert(L->status == LUA_YIELD); L->status = LUA_OK; - if (!f_isLua(ci)) { /* `common' yield? */ + if (!isLua(ci)) { /* `common' yield? */ /* finish interrupted execution of `OP_CALL' */ lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); @@ -408,7 +409,7 @@ static void resume (lua_State *L, void *ud) { else /* yielded inside a hook: just continue its execution */ L->base = L->ci->base; } - luaV_execute(L, cast_int(L->ci - L->base_ci)); + luaV_execute(L); } @@ -461,7 +462,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) { L->status = LUA_YIELD; if (!isLua(L->ci)) /* not inside a hook? */ luaD_throw(L, LUA_YIELD); - lua_assert(L->ci->status & 1); /* must be inside a hook */ + lua_assert(L->ci->callstatus & CIST_HOOKED); /* must be inside a hook */ lua_unlock(L); return 0; /* otherwise, return to 'luaD_callhook' */ } diff --git a/lstate.c b/lstate.c index b88f49a4..c57b11d6 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.45 2008/06/26 19:42:45 roberto Exp roberto $ +** $Id: lstate.c,v 2.46 2008/08/13 17:01:33 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -56,7 +56,7 @@ static void stack_init (lua_State *L1, lua_State *L) { setnilvalue(L1->top++); /* `function' entry for this `ci' */ L1->base = L1->ci->base = L1->top; L1->ci->top = L1->top + LUA_MINSTACK; - L1->ci->status = 0; + L1->ci->callstatus = 0; } diff --git a/lstate.h b/lstate.h index b34bb163..c4106562 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.34 2008/06/26 19:42:45 roberto Exp roberto $ +** $Id: lstate.h,v 2.35 2008/08/13 17:01:33 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -82,16 +82,23 @@ typedef struct CallInfo { StkId top; /* top for this function */ const Instruction *savedpc; short nresults; /* expected number of results from this function */ - lu_byte status; + lu_byte callstatus; int tailcalls; /* number of tail calls lost under this entry */ } CallInfo; +/* +** Bits in CallInfo status +*/ +#define CIST_LUA 1 /* call is running a Lua function */ +#define CIST_HOOKED 2 /* call is running a debug hook */ +#define CIST_REENTRY 4 /* call is running on same invocation of + luaV_execute of previous call */ + #define curr_func(L) (clvalue(L->ci->func)) #define ci_func(ci) (clvalue((ci)->func)) -#define f_isLua(ci) (!ci_func(ci)->c.isC) -#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) +#define isLua(ci) ((ci)->callstatus & CIST_LUA) /* diff --git a/ltests.c b/ltests.c index 9d58ed2d..0b361c7f 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.53 2008/06/26 19:42:45 roberto Exp roberto $ +** $Id: ltests.c,v 2.54 2008/08/13 17:02:12 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -349,7 +349,7 @@ printf(">>> %d %s %02x\n", g->gcstate, luaT_typenames[gch(o)->tt], gch(o)->mar int lua_checkpc (lua_State *L, pCallInfo ci) { - if (ci == L->base_ci || !f_isLua(ci)) return 1; + if (ci == L->base_ci || !isLua(ci)) return 1; else { Proto *p = ci_func(ci)->l.p; if (ci < L->ci) diff --git a/lvm.c b/lvm.c index c499913a..e18afe52 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.74 2008/04/02 16:16:06 roberto Exp roberto $ +** $Id: lvm.c,v 2.75 2008/08/13 17:02:42 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -280,11 +280,14 @@ void luaV_concat (lua_State *L, int total, int last) { if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) luaG_concaterror(L, top-2, top-1); - } else if (tsvalue(top-1)->len == 0) { /* second operand is empty? */ + } + else if (tsvalue(top-1)->len == 0) { /* second operand is empty? */ (void)tostring(L, top - 2); /* result is first operand */ ; - } else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { + } + else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { setsvalue2s(L, top-2, rawtsvalue(top-1)); /* result is second op. */ - } else { + } + else { /* at least two (non-empty) string values; get as many as possible */ size_t tl = tsvalue(top-1)->len; char *buffer; @@ -397,7 +400,7 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb, -void luaV_execute (lua_State *L, int nexeccalls) { +void luaV_execute (lua_State *L) { LClosure *cl; StkId base; TValue *k; @@ -601,7 +604,7 @@ void luaV_execute (lua_State *L, int nexeccalls) { continue; } else { /* Lua function */ - nexeccalls++; + L->ci->callstatus |= CIST_REENTRY; goto reentry; /* restart luaV_execute over new Lua function */ } } @@ -636,9 +639,9 @@ void luaV_execute (lua_State *L, int nexeccalls) { if (b != 0) L->top = ra+b-1; if (L->openupval) luaF_close(L, base); b = luaD_poscall(L, ra); - if (--nexeccalls == 0) /* was previous function running `here'? */ - return; /* no: return */ - else { /* yes: continue its execution */ + if (!((L->ci + 1)->callstatus & CIST_REENTRY)) + 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); diff --git a/lvm.h b/lvm.h index 7fd88c71..8a3ae994 100644 --- a/lvm.h +++ b/lvm.h @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 2.5 2005/08/22 18:54:49 roberto Exp roberto $ +** $Id: lvm.h,v 2.6 2007/02/09 13:04:52 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -32,7 +32,7 @@ LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val); LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val); -LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); +LUAI_FUNC void luaV_execute (lua_State *L); LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); #endif