From 5016f43aa439662ca35a5d78e820c617c517f60a Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 7 Aug 2002 16:22:39 -0300 Subject: (much) cleaner way to control function states --- ldebug.c | 14 ++++++++------ ldo.c | 16 ++++++++-------- lstate.c | 4 ++-- lstate.h | 16 ++++++++++++++-- lvm.c | 37 +++++++++++++++++++++---------------- lvm.h | 9 +-------- 6 files changed, 54 insertions(+), 42 deletions(-) diff --git a/ldebug.c b/ldebug.c index 82f82612..bd123234 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 1.128 2002/08/06 18:01:50 roberto Exp roberto $ +** $Id: ldebug.c,v 1.129 2002/08/07 14:35:55 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -28,14 +28,16 @@ static const char *getfuncname (CallInfo *ci, const char **name); -static int isLua (CallInfo *ci) { - return isLfunction (ci->base - 1); -} +#define isLua(ci) (!((ci)->state & CI_C)) + static int currentpc (CallInfo *ci) { if (!isLua(ci)) return -1; /* function is not a Lua function? */ - if (ci->pc != &luaV_callingmark) /* is not calling another Lua function? */ - ci->u.l.savedpc = *ci->pc; /* `pc' may not be saved; save it */ + if (!(ci->state & CI_SAVEDPC)) { /* savedpc outdated? */ + lua_assert(ci->state & CI_HASFRAME); + ci->u.l.savedpc = *ci->u.l.pc; + ci->state |= CI_SAVEDPC; + } /* function's pc is saved */ return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p); } diff --git a/ldo.c b/ldo.c index 85561e06..8f125372 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.189 2002/08/05 17:36:24 roberto Exp roberto $ +** $Id: ldo.c,v 1.190 2002/08/06 15:32:22 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -108,7 +108,7 @@ static void correctstack (lua_State *L, TObject *oldstack) { for (ci = L->base_ci; ci <= L->ci; ci++) { ci->base = (ci->base - oldstack) + L->stack; ci->top = (ci->top - oldstack) + L->stack; - if (ci->pc && ci->pc != &luaV_callingmark) /* function has a frame? */ + if (ci->state & CI_HASFRAME) /* Lua function with active frame? */ *ci->u.l.pb = (*ci->u.l.pb - oldstack) + L->stack; /* correct frame */ } } @@ -229,6 +229,7 @@ StkId luaD_precall (lua_State *L, StkId func) { ci->base = restorestack(L, funcr) + 1; ci->top = ci->base + p->maxstacksize; ci->u.l.savedpc = p->code; /* starting point */ + ci->state = CI_SAVEDPC; while (L->top < ci->top) setnilvalue(L->top++); L->top = ci->top; @@ -241,7 +242,7 @@ StkId luaD_precall (lua_State *L, StkId func) { ci = ++L->ci; /* now `enter' new function */ ci->base = restorestack(L, funcr) + 1; ci->top = L->top + LUA_MINSTACK; - ci->pc = NULL; /* not a Lua function */ + ci->state = CI_C; /* a C function */ if (L->hookmask & LUA_MASKCALL) { luaD_callhook(L, LUA_HOOKCALL, -1); ci = L->ci; /* previous call may realocate `ci' */ @@ -300,7 +301,6 @@ void luaD_call (lua_State *L, StkId func, int nResults) { LUA_API void lua_cobegin (lua_State *L, int nargs) { lua_lock(L); luaD_precall(L, L->top - (nargs+1)); - L->ci->pc = &luaV_callingmark; /* function is not active (yet) */ lua_unlock(L); } @@ -317,10 +317,10 @@ static void move_results (lua_State *L, TObject *from, TObject *to) { static void resume (lua_State *L, void *ud) { StkId firstResult; CallInfo *ci = L->ci; - if (ci->pc == NULL) { /* not first time? */ + if (ci->state & CI_C) { /* not first time (i.e. inside a yield)? */ /* finish interrupted execution of `OP_CALL' */ int nresults; - lua_assert((ci - 1)->pc == &luaV_callingmark); + lua_assert((ci-1)->state & CI_SAVEDPC); lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL || GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL); nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1; @@ -363,9 +363,9 @@ LUA_API int lua_yield (lua_State *L, int nresults) { CallInfo *ci; lua_lock(L); ci = L->ci; - if ((ci-1)->pc == NULL) + if ((ci-1)->state & CI_C) luaG_runerror(L, "cannot yield a C function"); - lua_assert(ci->pc == NULL); /* current function is not Lua */ + lua_assert(ci->state & CI_C); /* current function is not Lua */ ci->u.c.yield_results = nresults; lua_unlock(L); return -1; diff --git a/lstate.c b/lstate.c index 4e281977..ab2b7bb5 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 1.101 2002/08/05 18:45:45 roberto Exp roberto $ +** $Id: lstate.c,v 1.102 2002/08/06 15:32:22 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -41,7 +41,7 @@ static void stack_init (lua_State *L, lua_State *OL) { L->stack_last = L->stack+(L->stacksize - EXTRA_STACK)-1; L->base_ci = luaM_newvector(OL, BASIC_CI_SIZE, CallInfo); L->ci = L->base_ci; - L->ci->pc = NULL; /* not a Lua function */ + L->ci->state = CI_C; /* not a Lua function */ setnilvalue(L->top++); /* `function' entry for this `ci' */ L->ci->base = L->top; L->ci->top = L->top + LUA_MINSTACK; diff --git a/lstate.h b/lstate.h index bcd411a6..c5001f7b 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 1.91 2002/08/06 15:32:22 roberto Exp roberto $ +** $Id: lstate.h,v 1.92 2002/08/06 18:01:50 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -87,10 +87,11 @@ typedef struct stringtable { typedef struct CallInfo { StkId base; /* base for called function */ StkId top; /* top for this function */ - const Instruction **pc; /* points to `pc' variable in `luaV_execute' */ + int state; /* bit fields; see below */ union { struct { /* for Lua functions */ const Instruction *savedpc; + const Instruction **pc; /* points to `pc' variable in `luaV_execute' */ StkId *pb; /* points to `base' variable in `luaV_execute' */ } l; struct { /* for C functions */ @@ -100,6 +101,17 @@ typedef struct CallInfo { } CallInfo; +/* +** bit fields for `CallInfo.state' +*/ +#define CI_C 1 /* 1 if function is a C function */ +/* 1 if (Lua) function has an active `luaV_execute' running it */ +#define CI_HASFRAME 2 +/* 1 if Lua function is calling another Lua function (and therefore its + `pc' is being used by the other, and therefore CI_SAVEDPC is 1 too) */ +#define CI_CALLING 4 +#define CI_SAVEDPC 8 /* 1 if `savedpc' is updated */ + #define ci_func(ci) (clvalue((ci)->base - 1)) diff --git a/lvm.c b/lvm.c index 3eeb2ff8..c61d4a3c 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.249 2002/08/05 17:36:24 roberto Exp roberto $ +** $Id: lvm.c,v 1.250 2002/08/07 14:24:24 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -24,8 +24,6 @@ #include "lvm.h" -Instruction const *luaV_callingmark = NULL; - /* function to convert a lua_Number to a string */ #ifndef lua_number2str @@ -83,16 +81,18 @@ static void traceexec (lua_State *L) { if (mask & LUA_MASKLINE) { CallInfo *ci = L->ci; Proto *p = ci_func(ci)->l.p; - int newline = getline(p, pcRel(*ci->pc, p)); - if (pcRel(*ci->pc, p) == 0) /* tracing may be starting now? */ - ci->u.l.savedpc = *ci->pc; /* initialize `savedpc' */ + int newline = getline(p, pcRel(*ci->u.l.pc, p)); + lua_assert(ci->state & CI_HASFRAME); + if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */ + ci->u.l.savedpc = *ci->u.l.pc; /* initialize `savedpc' */ /* calls linehook when enters a new line or jumps back (loop) */ - if (*ci->pc <= ci->u.l.savedpc || + if (*ci->u.l.pc <= ci->u.l.savedpc || newline != getline(p, pcRel(ci->u.l.savedpc, p))) { luaD_callhook(L, LUA_HOOKLINE, newline); ci = L->ci; /* previous call may reallocate `ci' */ } - ci->u.l.savedpc = *ci->pc; + ci->u.l.savedpc = *ci->u.l.pc; + ci->state |= CI_SAVEDPC; /* `savedpc' is updated */ } } @@ -374,11 +374,13 @@ StkId luaV_execute (lua_State *L) { const Instruction *pc; callentry: /* entry point when calling new functions */ L->ci->u.l.pb = &base; - L->ci->pc = &pc; - pc = L->ci->u.l.savedpc; + L->ci->u.l.pc = &pc; if (L->hookmask & LUA_MASKCALL) luaD_callhook(L, LUA_HOOKCALL, -1); retentry: /* entry point when returning to old functions */ + lua_assert(L->ci->state & CI_SAVEDPC); + L->ci->state = CI_HASFRAME; /* activate frame */ + pc = L->ci->u.l.savedpc; base = L->ci->base; cl = &clvalue(base - 1)->l; k = cl->p->k; @@ -599,7 +601,7 @@ StkId luaV_execute (lua_State *L) { if (firstResult) { if (firstResult > L->top) { /* yield? */ (L->ci - 1)->u.l.savedpc = pc; - (L->ci - 1)->pc = &luaV_callingmark; + (L->ci - 1)->state = CI_SAVEDPC; return NULL; } /* it was a C function (`precall' called it); adjust results */ @@ -609,7 +611,7 @@ StkId luaV_execute (lua_State *L) { else { /* it is a Lua function */ if (GET_OPCODE(i) == OP_CALL) { /* regular call? */ (L->ci-1)->u.l.savedpc = pc; /* save `pc' to return later */ - (L->ci-1)->pc = &luaV_callingmark; /* function is calling */ + (L->ci-1)->state = (CI_SAVEDPC | CI_CALLING); } else { /* tail call: put new frame in place of previous one */ int aux; @@ -618,7 +620,9 @@ StkId luaV_execute (lua_State *L) { for (aux = 0; ra1+aux < L->top; aux++) /* move frame down */ setobj(base+aux-1, ra1+aux); (L->ci - 1)->top = L->top = base+aux; /* correct top */ + lua_assert(L->ci->state & CI_SAVEDPC); (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc; + (L->ci - 1)->state = CI_SAVEDPC; L->ci--; /* remove previous frame */ } goto callentry; @@ -629,20 +633,21 @@ StkId luaV_execute (lua_State *L) { CallInfo *ci = L->ci - 1; int b = GETARG_B(i); if (b != 0) L->top = ra+b-1; - lua_assert(L->ci->pc == &pc); + lua_assert(L->ci->state & CI_HASFRAME); if (L->openupval) luaF_close(L, base); + L->ci->state = CI_SAVEDPC; /* deactivate current function */ + L->ci->u.l.savedpc = pc; /* previous function was running `here'? */ - if (ci->pc != &luaV_callingmark) + if (!(ci->state & CI_CALLING)) return ra; /* no: return */ else { /* yes: continue its execution (go through) */ int nresults; lua_assert(ttisfunction(ci->base - 1)); + lua_assert(ci->state & CI_SAVEDPC); lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL); nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1; luaD_poscall(L, nresults, ra); if (nresults >= 0) L->top = L->ci->top; - L->ci->pc = &pc; /* function is active again */ - pc = L->ci->u.l.savedpc; goto retentry; } } diff --git a/lvm.h b/lvm.h index c1b2c312..17cbfb8c 100644 --- a/lvm.h +++ b/lvm.h @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 1.44 2002/07/05 18:27:39 roberto Exp $ +** $Id: lvm.h,v 1.45 2002/08/05 17:36:24 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -22,13 +22,6 @@ (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) -/* -** dummy addrees, to mark Lua functions calling other Lua functions (and -** therefore without a valid `pc' -*/ -extern Instruction const *luaV_callingmark; - - int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2); const TObject *luaV_tonumber (const TObject *obj, TObject *n); -- cgit v1.2.3-55-g6feb