Browse Source

better control of call status through CallInfo

pull/9/head
Roberto Ierusalimschy 16 years ago
parent
commit
f94cd2201c
  1. 4
      ldebug.c
  2. 19
      ldo.c
  3. 4
      lstate.c
  4. 15
      lstate.h
  5. 4
      ltests.c
  6. 21
      lvm.c
  7. 4
      lvm.h

4
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 ** Debug Interface
** See Copyright Notice in lua.h ** 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); lua_lock(L);
for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
level--; level--;
if (f_isLua(ci)) /* Lua function? */ if (isLua(ci)) /* Lua function? */
level -= ci->tailcalls; /* skip lost tail calls */ level -= ci->tailcalls; /* skip lost tail calls */
} }
if (level == 0 && ci > L->base_ci) { /* level found? */ if (level == 0 && ci > L->base_ci) { /* level found? */

19
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 ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** 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); ar.i_ci = cast_int(L->ci - L->base_ci);
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
L->ci->top = L->top + LUA_MINSTACK; 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); lua_assert(L->ci->top <= L->stack_last);
L->allowhook = 0; /* cannot call hooks inside a hook */ L->allowhook = 0; /* cannot call hooks inside a hook */
L->ci->callstatus |= CIST_HOOKED;
lua_unlock(L); lua_unlock(L);
(*hook)(L, &ar); (*hook)(L, &ar);
lua_lock(L); lua_lock(L);
@ -203,7 +203,7 @@ void luaD_callhook (lua_State *L, int event, int line) {
L->allowhook = 1; L->allowhook = 1;
L->ci->top = restorestack(L, ci_top); L->ci->top = restorestack(L, ci_top);
L->top = restorestack(L, 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); lua_assert(ci->top <= L->stack_last);
L->savedpc = p->code; /* starting point */ L->savedpc = p->code; /* starting point */
ci->tailcalls = 0; ci->tailcalls = 0;
ci->status = 0; ci->callstatus = CIST_LUA;
ci->nresults = nresults; ci->nresults = nresults;
for (st = L->top; st < ci->top; st++) for (st = L->top; st < ci->top; st++)
setnilvalue(st); setnilvalue(st);
@ -319,6 +319,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
ci->top = L->top + LUA_MINSTACK; ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last); lua_assert(ci->top <= L->stack_last);
ci->nresults = nresults; ci->nresults = nresults;
ci->callstatus = 0;
if (L->hookmask & LUA_MASKCALL) if (L->hookmask & LUA_MASKCALL)
luaD_callhook(L, LUA_HOOKCALL, -1); luaD_callhook(L, LUA_HOOKCALL, -1);
lua_unlock(L); 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) { static StkId callrethooks (lua_State *L, StkId firstResult) {
ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
luaD_callhook(L, LUA_HOOKRET, -1); 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 */ while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */
luaD_callhook(L, LUA_HOOKTAILRET, -1); 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 */ luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
} }
if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
luaV_execute(L, 1); /* call it */ luaV_execute(L); /* call it */
g->nCcalls--; g->nCcalls--;
luaC_checkGC(L); luaC_checkGC(L);
} }
@ -398,7 +399,7 @@ static void resume (lua_State *L, void *ud) {
else { /* resuming from previous yield */ else { /* resuming from previous yield */
lua_assert(L->status == LUA_YIELD); lua_assert(L->status == LUA_YIELD);
L->status = LUA_OK; L->status = LUA_OK;
if (!f_isLua(ci)) { /* `common' yield? */ if (!isLua(ci)) { /* `common' yield? */
/* finish interrupted execution of `OP_CALL' */ /* finish interrupted execution of `OP_CALL' */
lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); 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 */ else /* yielded inside a hook: just continue its execution */
L->base = L->ci->base; 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; L->status = LUA_YIELD;
if (!isLua(L->ci)) /* not inside a hook? */ if (!isLua(L->ci)) /* not inside a hook? */
luaD_throw(L, LUA_YIELD); 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); lua_unlock(L);
return 0; /* otherwise, return to 'luaD_callhook' */ return 0; /* otherwise, return to 'luaD_callhook' */
} }

4
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 ** Global State
** See Copyright Notice in lua.h ** 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' */ setnilvalue(L1->top++); /* `function' entry for this `ci' */
L1->base = L1->ci->base = L1->top; L1->base = L1->ci->base = L1->top;
L1->ci->top = L1->top + LUA_MINSTACK; L1->ci->top = L1->top + LUA_MINSTACK;
L1->ci->status = 0; L1->ci->callstatus = 0;
} }

15
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 ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -82,16 +82,23 @@ typedef struct CallInfo {
StkId top; /* top for this function */ StkId top; /* top for this function */
const Instruction *savedpc; const Instruction *savedpc;
short nresults; /* expected number of results from this function */ 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 */ int tailcalls; /* number of tail calls lost under this entry */
} CallInfo; } 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 curr_func(L) (clvalue(L->ci->func))
#define ci_func(ci) (clvalue((ci)->func)) #define ci_func(ci) (clvalue((ci)->func))
#define f_isLua(ci) (!ci_func(ci)->c.isC) #define isLua(ci) ((ci)->callstatus & CIST_LUA)
#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
/* /*

4
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 ** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h ** 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) { 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 { else {
Proto *p = ci_func(ci)->l.p; Proto *p = ci_func(ci)->l.p;
if (ci < L->ci) if (ci < L->ci)

21
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 ** Lua virtual machine
** See Copyright Notice in lua.h ** 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 (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
luaG_concaterror(L, top-2, top-1); 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 */ ; (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. */ 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 */ /* at least two (non-empty) string values; get as many as possible */
size_t tl = tsvalue(top-1)->len; size_t tl = tsvalue(top-1)->len;
char *buffer; 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; LClosure *cl;
StkId base; StkId base;
TValue *k; TValue *k;
@ -601,7 +604,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
else { /* Lua function */ else { /* Lua function */
nexeccalls++; L->ci->callstatus |= CIST_REENTRY;
goto reentry; /* restart luaV_execute over new Lua function */ 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 (b != 0) L->top = ra+b-1;
if (L->openupval) luaF_close(L, base); if (L->openupval) luaF_close(L, base);
b = luaD_poscall(L, ra); b = luaD_poscall(L, ra);
if (--nexeccalls == 0) /* was previous function running `here'? */ if (!((L->ci + 1)->callstatus & CIST_REENTRY))
return; /* no: return */ return; /* external invocation: return */
else { /* yes: continue its execution */ else { /* invocation via reentry: continue execution */
if (b) L->top = L->ci->top; if (b) L->top = L->ci->top;
lua_assert(isLua(L->ci)); lua_assert(isLua(L->ci));
lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);

4
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 ** Lua virtual machine
** See Copyright Notice in lua.h ** 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); StkId val);
LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
StkId val); 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); LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
#endif #endif

Loading…
Cancel
Save