Kaynağa Gözat

better control of call status through CallInfo

Roberto Ierusalimschy 17 yıl önce
ebeveyn
işleme
f94cd2201c
7 değiştirilmiş dosya ile 41 ekleme ve 30 silme
  1. 2 2
      ldebug.c
  2. 10 9
      ldo.c
  3. 2 2
      lstate.c
  4. 11 4
      lstate.h
  5. 2 2
      ltests.c
  6. 12 9
      lvm.c
  7. 2 2
      lvm.h

+ 2 - 2
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? */

+ 10 - 9
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' */
 }

+ 2 - 2
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;
 }
 
 

+ 11 - 4
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)
 
 
 /*

+ 2 - 2
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)

+ 12 - 9
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);

+ 2 - 2
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