Просмотр исходного кода

CallInfo has different fields for C functions and Lua functions

Roberto Ierusalimschy 23 лет назад
Родитель
Сommit
e5146fb01f
5 измененных файлов с 71 добавлено и 62 удалено
  1. 9 13
      ldebug.c
  2. 32 31
      ldo.c
  3. 2 2
      lstate.c
  4. 15 6
      lstate.h
  5. 13 10
      lvm.c

+ 9 - 13
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 */

+ 32 - 31
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;
 }

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

+ 15 - 6
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))
 
 

+ 13 - 10
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;