diff --git a/ldebug.c b/ldebug.c index 73029a5d..413bab69 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 1.123 2002/06/24 15:07:21 roberto Exp roberto $ +** $Id: ldebug.c,v 1.124 2002/07/08 18:21:33 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -30,15 +30,11 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); -static int isLmark (CallInfo *ci) { - return (ttype(ci->base - 1) == LUA_TFUNCTION && !ci_func(ci)->c.isC); -} - - static int currentpc (lua_State *L, CallInfo *ci) { - if (ci->pc == NULL) return -1; /* function is not an active Lua function */ - if (ci == L->ci || ci->pc != (ci+1)->pc) /* no other function using `pc'? */ - ci->savedpc = *ci->pc; /* may not be saved; save it */ + if (!isLua(ci)) return -1; /* function is not a Lua function? */ + /* next function is not using the same `pc'? (not a Lua->Lua call?) */ + if (ci == L->ci || !isLua(ci+1) || ci->u.l.pc != (ci+1)->u.l.pc) + ci->savedpc = *ci->u.l.pc; /* may not be saved; save it */ /* function's pc is saved */ return pcRel(ci->savedpc, ci_func(ci)->l.p); } @@ -95,7 +91,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { static Proto *getluaproto (CallInfo *ci) { - return (isLmark(ci) ? ci_func(ci)->l.p : NULL); + return (isLua(ci) ? ci_func(ci)->l.p : NULL); } @@ -424,7 +420,7 @@ static const char *kname (Proto *p, int c) { static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, const char **name) { - if (isLmark(ci)) { /* an active Lua function? */ + if (isLua(ci)) { /* an active Lua function? */ Proto *p = ci_func(ci)->l.p; int pc = currentpc(L, ci); Instruction i; @@ -462,7 +458,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, static Instruction getcurrentinstr (lua_State *L, CallInfo *ci) { - if (ci == L->base_ci || !isLmark(ci)) + if (ci == L->base_ci || !isLua(ci)) return (Instruction)(-1); /* not an active Lua function */ else return ci_func(ci)->l.p->code[currentpc(L, ci)]; @@ -531,7 +527,7 @@ static void addinfo (lua_State *L, int internal) { CallInfo *ci = L->ci; if (!internal && ci > L->base_ci) ci--; if (strchr(msg, '\n')) return; /* message already `formatted' */ - if (!isLmark(ci)) { /* no Lua code? */ + if (!isLua(ci)) { /* no Lua code? */ luaO_pushfstring(L, "%s\n", msg); /* no extra info */ } else { /* add file:line information */ diff --git a/ldo.c b/ldo.c index e2511bde..55f7958f 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.186 2002/07/08 18:21:33 roberto Exp roberto $ +** $Id: ldo.c,v 1.187 2002/07/09 18:19:19 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -60,10 +60,10 @@ 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) { /* entry is of an active Lua function? */ - if (ci->pc != (ci-1)->pc) - *ci->pb = (*ci->pb - oldstack) + L->stack; - } + if (isLua(ci) && /* is a Lua function... */ + !(isLua(ci-1) && /* and next is not a Lua function... */ + ci->u.l.pc == (ci-1)->u.l.pc)) /* sharing the same C frame? */ + *ci->u.l.pb = (*ci->u.l.pb - oldstack) + L->stack; /* correct frame */ } } @@ -134,10 +134,6 @@ void luaD_callhook (lua_State *L, lua_Hookevent event, int line) { ar.event = event; ar.currentline = line; ar.i_ci = L->ci - L->base_ci; - if (event <= LUA_HOOKRET) { /* `call' or `return' event? */ - L->ci->pc = NULL; /* function is not active */ - L->ci->top = L->ci->base; /* `top' may not have a valid value yet */ - } luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ L->ci->top = L->top + LUA_MINSTACK; setallowhook(L, 0); /* cannot call hooks inside a hook */ @@ -152,11 +148,11 @@ void luaD_callhook (lua_State *L, lua_Hookevent event, int line) { } -static void adjust_varargs (lua_State *L, int nfixargs) { +static void adjust_varargs (lua_State *L, int nfixargs, StkId base) { int i; Table *htab; TObject nname; - int actual = L->top - L->ci->base; /* actual number of arguments */ + int actual = L->top - base; /* actual number of arguments */ if (actual < nfixargs) { luaD_checkstack(L, nfixargs - actual); for (; actual < nfixargs; ++actual) @@ -178,49 +174,52 @@ static void adjust_varargs (lua_State *L, int nfixargs) { static StkId tryfuncTM (lua_State *L, StkId func) { const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); StkId p; - if (ttype(tm) != LUA_TFUNCTION) { - L->ci--; /* undo increment (no function here) */ + ptrdiff_t funcr = savestack(L, func); + if (ttype(tm) != LUA_TFUNCTION) luaG_typeerror(L, func, "call"); - } /* Open a hole inside the stack at `func' */ for (p = L->top; p > func; p--) setobj(p, p-1); incr_top(L); - func = L->ci->base - 1; /* previous call may change stack */ + func = restorestack(L, funcr); /* previous call may change stack */ setobj(func, tm); /* tag method is the new function to be called */ return func; } StkId luaD_precall (lua_State *L, StkId func) { - CallInfo *ci; LClosure *cl; - if (++L->ci == L->end_ci) luaD_growCI(L); - ci = L->ci; - ci->base = func+1; - ci->pc = NULL; + ptrdiff_t funcr = savestack(L, func); if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */ func = tryfuncTM(L, func); /* check the `function' tag method */ + if (L->ci + 1 == L->end_ci) luaD_growCI(L); cl = &clvalue(func)->l; - if (L->hookmask & LUA_MASKCALL) { - luaD_callhook(L, LUA_HOOKCALL, -1); - ci = L->ci; /* previous call may realocate `ci' */ - } if (!cl->isC) { /* Lua function? prepare its call */ + CallInfo *ci; Proto *p = cl->p; - ci->savedpc = p->code; /* starting point */ if (p->is_vararg) /* varargs? */ - adjust_varargs(L, p->numparams); + adjust_varargs(L, p->numparams, func+1); luaD_checkstack(L, p->maxstacksize); + ci = ++L->ci; /* now `enter' new function */ + ci->base = restorestack(L, funcr) + 1; ci->top = ci->base + p->maxstacksize; + ci->savedpc = p->code; /* starting point */ while (L->top < ci->top) setnilvalue(L->top++); L->top = ci->top; return NULL; } else { /* if is a C function, call it */ + CallInfo *ci; int n; luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci = ++L->ci; /* now `enter' new function */ + ci->base = restorestack(L, funcr) + 1; ci->top = L->top + LUA_MINSTACK; + ci->savedpc = NULL; /* not a Lua function */ + if (L->hookmask & LUA_MASKCALL) { + luaD_callhook(L, LUA_HOOKCALL, -1); + ci = L->ci; /* previous call may realocate `ci' */ + } lua_unlock(L); #if LUA_COMPATUPVALUES lua_pushupvalues(L); @@ -296,9 +295,10 @@ struct ResS { static void resume (lua_State *L, void *ud) { StkId firstResult; CallInfo *ci = L->ci; - if (ci->savedpc != ci_func(ci)->l.p->code) { /* not first time? */ - /* finish interupted execution of `OP_CALL' */ + if (!isLua(ci)) { /* not first time? */ + /* finish interrupted execution of `OP_CALL' */ int nresults; + lua_assert(isLua(ci - 1)); lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL); nresults = GETARG_C(*((ci-1)->savedpc - 1)) - 1; luaD_poscall(L, nresults, L->top); /* complete it */ @@ -306,7 +306,7 @@ static void resume (lua_State *L, void *ud) { } firstResult = luaV_execute(L); if (firstResult == NULL) /* yield? */ - cast(struct ResS *, ud)->numres = L->ci->yield_results; + cast(struct ResS *, ud)->numres = L->ci->u.c.yield_results; else { /* return */ cast(struct ResS *, ud)->numres = L->top - firstResult; luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ @@ -338,9 +338,10 @@ LUA_API int lua_yield (lua_State *L, int nresults) { CallInfo *ci; lua_lock(L); ci = L->ci; - if (ci_func(ci-1)->c.isC) + if (!isLua(ci-1)) luaG_runerror(L, "cannot yield a C function"); - ci->yield_results = nresults; + lua_assert(!isLua(ci)); + ci->u.c.yield_results = nresults; lua_unlock(L); return -1; } diff --git a/lstate.c b/lstate.c index 241c177b..1edb93f4 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 1.97 2002/06/18 15:19:27 roberto Exp roberto $ +** $Id: lstate.c,v 1.98 2002/07/08 18:21:33 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -41,9 +41,9 @@ static void stack_init (lua_State *L, lua_State *OL) { L->stack_last = L->stack+(BASIC_STACK_SIZE-EXTRA_STACK)-1; L->base_ci = luaM_newvector(OL, BASIC_CI_SIZE, CallInfo); L->ci = L->base_ci; + L->ci->savedpc = NULL; L->ci->base = L->top; L->ci->top = L->top + LUA_MINSTACK; - L->ci->pc = NULL; L->size_ci = BASIC_CI_SIZE; L->end_ci = L->base_ci + L->size_ci; } diff --git a/lstate.h b/lstate.h index ef47de36..5db528ff 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 1.87 2002/07/08 18:21:33 roberto Exp roberto $ +** $Id: lstate.h,v 1.88 2002/07/08 20:22:08 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -87,13 +87,22 @@ typedef struct stringtable { */ typedef struct CallInfo { StkId base; /* base for called function */ - const Instruction *savedpc; - StkId top; /* top for this function (when it's a Lua function) */ - const Instruction **pc; /* points to `pc' variable in `luaV_execute' */ - StkId *pb; /* points to `base' variable in `luaV_execute' */ - int yield_results; + StkId top; /* top for this function */ + const Instruction *savedpc; /* NULL means not a Lua function */ + union { + struct { /* for Lua functions */ + const Instruction **pc; /* points to `pc' variable in `luaV_execute' */ + StkId *pb; /* points to `base' variable in `luaV_execute' */ + } l; + struct { /* for C functions */ + int yield_results; + } c; + } u; } CallInfo; + +#define isLua(ci) ((ci)->savedpc != NULL) + #define ci_func(ci) (clvalue((ci)->base - 1)) diff --git a/lvm.c b/lvm.c index ced4d7f1..8dcd83eb 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.245 2002/07/08 18:21:33 roberto Exp roberto $ +** $Id: lvm.c,v 1.246 2002/07/08 20:22:08 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -80,16 +80,16 @@ 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->savedpc = *ci->pc; /* initialize `savedpc' */ + int newline = getline(p, pcRel(*ci->u.l.pc, p)); + if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */ + ci->savedpc = *ci->u.l.pc; /* initialize `savedpc' */ /* calls linehook when enters a new line or jumps back (loop) */ - if (*ci->pc <= ci->savedpc || + if (*ci->u.l.pc <= ci->savedpc || newline != getline(p, pcRel(ci->savedpc, p))) { luaD_callhook(L, LUA_HOOKLINE, newline); ci = L->ci; /* previous call may reallocate `ci' */ } - ci->savedpc = *ci->pc; + ci->savedpc = *ci->u.l.pc; } } @@ -370,9 +370,11 @@ StkId luaV_execute (lua_State *L) { TObject *k; const Instruction *pc; callentry: /* entry point when calling new functions */ - L->ci->pc = &pc; - L->ci->pb = &base; + L->ci->u.l.pc = &pc; + L->ci->u.l.pb = &base; pc = L->ci->savedpc; + if (L->hookmask & LUA_MASKCALL) + luaD_callhook(L, LUA_HOOKCALL, -1); retentry: /* entry point when returning to old functions */ base = L->ci->base; cl = &clvalue(base - 1)->l; @@ -619,12 +621,13 @@ StkId luaV_execute (lua_State *L) { if (L->openupval) luaF_close(L, base); b = GETARG_B(i); if (b != 0) L->top = ra+b-1; - lua_assert(L->ci->pc == &pc); + lua_assert(L->ci->u.l.pc == &pc); } ret: { CallInfo *ci; ci = L->ci - 1; - if (ci->pc != &pc) /* previous function was running `here'? */ + /* previous function was running `here'? */ + if (!isLua(ci) || ci->u.l.pc != &pc) return ra; /* no: return */ else { /* yes: continue its execution */ int nresults;