瀏覽代碼

call hooks can only be called when `pc' is active (that is, inside
`execute'...)

Roberto Ierusalimschy 25 年之前
父節點
當前提交
cd2ddaded9
共有 3 個文件被更改,包括 30 次插入19 次删除
  1. 10 11
      ldo.c
  2. 3 1
      ldo.h
  3. 17 7
      lvm.c

+ 10 - 11
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.99 2000/10/02 14:47:43 roberto Exp roberto $
+** $Id: ldo.c,v 1.100 2000/10/02 20:10:55 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -112,7 +112,7 @@ void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
 }
 
 
-static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
+void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
                     const char *event) {
   if (L->allowhooks) {
     lua_Debug ar;
@@ -124,6 +124,7 @@ static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
 
 
 static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
+  lua_Hook callhook = L->callhook;
   int nup = cl->nupvalues;  /* number of upvalues */
   StkId old_Cbase = L->Cbase;
   int n;
@@ -131,7 +132,11 @@ static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
   luaD_checkstack(L, nup+LUA_MINSTACK);  /* assures minimum stack size */
   for (n=0; n<nup; n++)  /* copy upvalues as extra arguments */
     *(L->top++) = cl->upvalue[n];
+  if (callhook)
+    luaD_callHook(L, base-1, callhook, "call");
   n = (*cl->f.c)(L);  /* do the actual call */
+  if (callhook)  /* same hook that was active at entry */
+    luaD_callHook(L, base-1, callhook, "return");
   L->Cbase = old_Cbase;  /* restore old C base */
   return L->top - n;  /* return index of first result */
 }
@@ -154,25 +159,21 @@ void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) {
 */ 
 void luaD_call (lua_State *L, StkId func, int nResults) {
   StkId firstResult;
-  lua_Hook callhook = L->callhook;
   retry:  /* for `function' tag method */
   switch (ttype(func)) {
     case TAG_LCLOSURE: {
       CallInfo ci;
       ci.func = clvalue(func);
-      ci.line = 0;
-      ttype(func) = TAG_LMARK;
       infovalue(func) = &ci;
-      if (callhook)
-        luaD_callHook(L, func, callhook, "call");
+      ttype(func) = TAG_LMARK;
       firstResult = luaV_execute(L, ci.func, func+1);
+      LUA_ASSERT(ttype(func) == TAG_LMARK, "invalid tag");
       break;
     }
     case TAG_CCLOSURE: {
       ttype(func) = TAG_CMARK;
-      if (callhook)
-        luaD_callHook(L, func, callhook, "call");
       firstResult = callCclosure(L, clvalue(func), func+1);
+      LUA_ASSERT(ttype(func) == TAG_CMARK, "invalid tag");
       break;
     }
     default: { /* `func' is not a function; check the `function' tag method */
@@ -184,8 +185,6 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
       goto retry;   /* retry the call */
     }
   }
-  if (callhook)  /* same hook that was active at entry */
-    luaD_callHook(L, func, callhook, "return");
   /* adjust the number of results */
   if (nResults == LUA_MULTRET)
     nResults = L->top - firstResult;

+ 3 - 1
ldo.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.h,v 1.24 2000/08/29 14:48:16 roberto Exp roberto $
+** $Id: ldo.h,v 1.25 2000/09/25 16:22:42 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -22,6 +22,8 @@
 void luaD_init (lua_State *L, int stacksize);
 void luaD_adjusttop (lua_State *L, StkId base, int extra);
 void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook);
+void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
+                    const char *event);
 void luaD_call (lua_State *L, StkId func, int nResults);
 void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults);
 void luaD_checkstack (lua_State *L, int n);

+ 17 - 7
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.140 2000/10/03 14:03:21 roberto Exp roberto $
+** $Id: lvm.c,v 1.141 2000/10/03 14:27:44 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -69,7 +69,7 @@ static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) {
   int *lineinfo = ci->func->f.l->lineinfo;
   int pc = (*ci->pc - 1) - ci->func->f.l->code;
   int newline;
-  if (ci->line == 0) {  /* first time? */
+  if (pc == 0) {  /* may be first time? */
     ci->line = 1;
     ci->refi = 0;
     ci->lastpc = pc+1;  /* make sure it will call linehook */
@@ -348,14 +348,18 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
   StkId top;  /* keep top local, for performance */
   const Instruction *pc = tf->code;
   TString **kstr = tf->kstr;
-  lua_Hook linehook = L->linehook;
+  lua_Hook callhook = L->callhook;
+  lua_Hook linehook;  /* set it only after calling eventual call hook */
   infovalue(base-1)->pc = &pc;
   luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
   if (tf->is_vararg)  /* varargs? */
     adjust_varargs(L, base, tf->numparams);
   else
     luaD_adjusttop(L, base, tf->numparams);
+  if (callhook)
+    luaD_callHook(L, base-1, callhook, "call");
   top = L->top;
+  linehook = L->linehook;
   /* main loop of interpreter */
   for (;;) {
     const Instruction i = *pc++;
@@ -363,11 +367,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       traceexec(L, base, top, linehook);
     switch (GET_OPCODE(i)) {
       case OP_END: {
-        return L->top;  /* no results */
+        L->top = top;
+        goto endloop;
       }
       case OP_RETURN: {
         L->top = top;
-        return base+GETARG_U(i);
+        top = base+GETARG_U(i);
+        goto endloop;
       }
       case OP_CALL: {
         int nres = GETARG_B(i);
@@ -380,7 +386,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       case OP_TAILCALL: {
         L->top = top;
         luaD_call(L, base+GETARG_A(i), LUA_MULTRET);
-        return base+GETARG_B(i);
+        top = base+GETARG_B(i);
+        goto endloop;
       }
       case OP_PUSHNIL: {
         int n = GETARG_U(i);
@@ -700,5 +707,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
         break;
       }
     }
-  }
+  } endloop:
+  if (callhook)  /* same hook that was active at entry */
+    luaD_callHook(L, base-1, callhook, "return");
+  return top;
 }