浏览代码

no more useful fields in CallInfo

Roberto Ierusalimschy 7 年之前
父节点
当前提交
472c560705
共有 7 个文件被更改,包括 100 次插入91 次删除
  1. 9 9
      lapi.c
  2. 10 8
      ldebug.c
  3. 30 24
      ldo.c
  4. 16 2
      lobject.h
  5. 1 15
      lstate.h
  6. 9 11
      ltests.c
  7. 25 22
      lvm.c

+ 9 - 9
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.273 2017/11/02 11:28:56 roberto Exp roberto $
+** $Id: lapi.c,v 2.274 2017/11/03 12:12:30 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -948,8 +948,8 @@ LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
   checkresults(L, nargs, nresults);
   func = L->top - (nargs+1);
   if (k != NULL && L->nny == 0) {  /* need to prepare continuation? */
-    L->ci->u.c.k = k;  /* save continuation */
-    L->ci->u.c.ctx = ctx;  /* save context */
+    L->func->stkci.u.c.k = k;  /* save continuation */
+    L->func->stkci.u.c.ctx = ctx;  /* save context */
     luaD_call(L, func, nresults);  /* do the call */
   }
   else  /* no continuation or no yieldable */
@@ -999,19 +999,19 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
     status = luaD_pcall(L, f_call, &c, savestack(L, c.func), efunc);
   }
   else {  /* prepare continuation (call is already protected by 'resume') */
-    CallInfo *ci = L->ci;
     StkId func = L->func;
-    ci->u.c.k = k;  /* save continuation */
-    ci->u.c.ctx = ctx;  /* save context */
+    func->stkci.u.c.k = k;  /* save continuation */
+    func->stkci.u.c.ctx = ctx;  /* save context */
     /* save information for error recovery */
-    ci->u2.funcidx = savestack(L, c.func);
-    ci->u.c.old_errfunc = L->errfunc;
+    func->stkci.u2.funcidx = c.func - func;
+    func->stkci.u.c.old_errfunc = L->errfunc;
     L->errfunc = efunc;
     setoah(callstatus(func), L->allowhook);  /* save value of 'allowhook' */
     callstatus(func) |= CIST_YPCALL;  /* function can do error recovery */
     luaD_call(L, c.func, nresults);  /* do the call */
+    func = L->func;  /* previous call can reallocate stack */
     callstatus(func) &= ~CIST_YPCALL;
-    L->errfunc = ci->u.c.old_errfunc;
+    L->errfunc = func->stkci.u.c.old_errfunc;
     status = LUA_OK;  /* if it is here, there were no errors */
   }
   adjustresults(L, nresults);

+ 10 - 8
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 2.135 2017/11/02 11:28:56 roberto Exp roberto $
+** $Id: ldebug.c,v 2.136 2017/11/03 12:12:30 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -44,7 +44,7 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
 
 static int currentpc (CallInfo *ci) {
   lua_assert(isLua(ci->func));
-  return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
+  return pcRel(ci->func->stkci.u.l.savedpc, ci_func(ci)->p);
 }
 
 
@@ -121,7 +121,7 @@ LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
     func = NULL;
   }
   if (isLua(L->func))
-    L->oldpc = L->ci->u.l.savedpc;
+    L->oldpc = L->func->stkci.u.l.savedpc;
   L->hook = func;
   L->basehookcount = count;
   resethookcount(L);
@@ -755,19 +755,21 @@ void luaG_traceexec (lua_State *L) {
     luaD_hook(L, LUA_HOOKCOUNT, -1);  /* call count hook */
   if (mask & LUA_MASKLINE) {
     Proto *p = ci_func(ci)->p;
-    int npc = pcRel(ci->u.l.savedpc, p);
+    int npc = pcRel(func->stkci.u.l.savedpc, p);
     if (npc == 0 ||  /* call linehook when enter a new function, */
-        ci->u.l.savedpc <= L->oldpc ||  /* when jump back (loop), or when */
-        changedline(p, pcRel(L->oldpc, p), npc)) {  /* enter new line */
+        func->stkci.u.l.savedpc <= L->oldpc ||  /* when jump back (loop), */
+        changedline(p, pcRel(L->oldpc, p), npc)) {  /* when enter new line */
       int newline = luaG_getfuncline(p, npc);  /* new line */
       luaD_hook(L, LUA_HOOKLINE, newline);  /* call line hook */
     }
   }
-  L->oldpc = ci->u.l.savedpc;
+  func = L->func;  /* previous calls can reallocate stack */
+  L->oldpc = func->stkci.u.l.savedpc;
   if (L->status == LUA_YIELD) {  /* did hook yield? */
     if (counthook)
       L->hookcount = 1;  /* undo decrement to zero */
-    ci->u.l.savedpc--;  /* undo increment (resume will increment it again) */
+    /* undo increment (resume will increment it again) */
+    func->stkci.u.l.savedpc--;
     callstatus(func) |= CIST_HOOKYIELD;  /* mark that it yielded */
     luaD_throw(L, LUA_YIELD);
   }

+ 30 - 24
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 2.165 2017/11/02 11:28:56 roberto Exp roberto $
+** $Id: ldo.c,v 2.166 2017/11/03 12:12:30 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -280,17 +280,19 @@ void luaD_hook (lua_State *L, int event, int line) {
 }
 
 
-static void callhook (lua_State *L, CallInfo *ci) {
+static void callhook (lua_State *L) {
   int hook = LUA_HOOKCALL;
-  StkId previous = L->func - L->func->stkci.previous;
-  ci->u.l.savedpc++;  /* hooks assume 'pc' is already incremented */
+  StkId func = L->func;
+  StkId previous = func - L->func->stkci.previous;
+  func->stkci.u.l.savedpc++;  /* hooks assume 'pc' is already incremented */
   if (isLua(previous) &&
-      GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
+      GET_OPCODE(*(previous->stkci.u.l.savedpc - 1)) == OP_TAILCALL) {
     callstatus(L->func) |= CIST_TAIL;
     hook = LUA_HOOKTAILCALL;
   }
   luaD_hook(L, hook, -1);
-  ci->u.l.savedpc--;  /* correct 'pc' */
+  func = L->func;  /* previous call can change stack */
+  func->stkci.u.l.savedpc--;  /* correct 'pc' */
 }
 
 
@@ -369,11 +371,13 @@ int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
       ptrdiff_t fr = savestack(L, firstResult);  /* hook may change stack */
       luaD_hook(L, LUA_HOOKRET, -1);
       firstResult = restorestack(L, fr);
+      res = L->func;
     }
-    L->oldpc = ci->previous->u.l.savedpc;  /* 'oldpc' for caller function */
+    /* 'oldpc' for caller function */
+    L->oldpc = (res - res->stkci.previous)->stkci.u.l.savedpc;
   }
   L->ci = ci->previous;  /* back to caller */
-  L->func -= L->func->stkci.previous;
+  L->func = res - res->stkci.previous;
   lua_assert(L->func == L->ci->func);
   /* move results to proper place */
   return moveresults(L, firstResult, res, nres, wanted);
@@ -436,10 +440,10 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
       L->func = ci->func = func;
       L->top = func + 1 + fsize;
       lua_assert(functop(func) <= L->stack_last);
-      ci->u.l.savedpc = p->code;  /* starting point */
+      func->stkci.u.l.savedpc = p->code;  /* starting point */
       callstatus(func) = 0;
       if (L->hookmask & LUA_MASKCALL)
-        callhook(L, ci);
+        callhook(L);
       return 0;
     }
     default: {  /* not a function */
@@ -500,18 +504,19 @@ static void finishCcall (lua_State *L, int status) {
   StkId func = L->func;
   int n;
   /* must have a continuation and must be able to call it */
-  lua_assert(ci->u.c.k != NULL && L->nny == 0);
+  lua_assert(func->stkci.u.c.k != NULL && L->nny == 0);
   /* error status can only happen in a protected call */
   lua_assert((callstatus(func) & CIST_YPCALL) || status == LUA_YIELD);
   if (callstatus(func) & CIST_YPCALL) {  /* was inside a pcall? */
     callstatus(func) &= ~CIST_YPCALL;  /* continuation is also inside it */
-    L->errfunc = ci->u.c.old_errfunc;  /* with the same error function */
+    L->errfunc = func->stkci.u.c.old_errfunc;  /* with same error function */
   }
   /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
      handled */
   adjustresults(L, func->stkci.nresults);
   lua_unlock(L);
-  n = (*ci->u.c.k)(L, status, ci->u.c.ctx);  /* call continuation function */
+  /* call continuation function */
+  n = (*func->stkci.u.c.k)(L, status, func->stkci.u.c.ctx);
   lua_lock(L);
   api_checknelems(L, n);
   luaD_poscall(L, ci, L->top - n, n);  /* finish 'luaD_precall' */
@@ -564,7 +569,7 @@ static int recover (lua_State *L, int status) {
   CallInfo *ci = findpcall(L);
   if (ci == NULL) return 0;  /* no recovery point */
   /* "finish" luaD_pcall */
-  oldtop = restorestack(L, ci->u2.funcidx);
+  oldtop = ci->func + ci->func->stkci.u2.funcidx;
   luaF_close(L, oldtop);
   seterrorobj(L, status, oldtop);
   L->ci = ci;
@@ -572,7 +577,7 @@ static int recover (lua_State *L, int status) {
   L->allowhook = getoah(callstatus(L->func));  /* restore original 'allowhook' */
   L->nny = 0;  /* should be zero to be yieldable */
   luaD_shrinkstack(L);
-  L->errfunc = ci->u.c.old_errfunc;
+  L->errfunc = ci->func->stkci.u.c.old_errfunc;
   return 1;  /* continue running the coroutine */
 }
 
@@ -602,6 +607,7 @@ static void resume (lua_State *L, void *ud) {
   int n = *(cast(int*, ud));  /* number of arguments */
   StkId firstArg = L->top - n;  /* first argument */
   CallInfo *ci = L->ci;
+  StkId func = L->func;
   if (L->status == LUA_OK) {  /* starting a coroutine? */
     if (!luaD_precall(L, firstArg - 1, LUA_MULTRET))  /* Lua function? */
       luaV_execute(L);  /* call it */
@@ -609,12 +615,13 @@ static void resume (lua_State *L, void *ud) {
   else {  /* resuming from previous yield */
     lua_assert(L->status == LUA_YIELD);
     L->status = LUA_OK;  /* mark that it is running (again) */
-    if (isLua(L->func))  /* yielded inside a hook? */
+    if (isLua(func))  /* yielded inside a hook? */
       luaV_execute(L);  /* just continue running Lua code */
     else {  /* 'common' yield */
-      if (ci->u.c.k != NULL) {  /* does it have a continuation function? */
+      if (func->stkci.u.c.k != NULL) {  /* does it have a continuation? */
         lua_unlock(L);
-        n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
+        /* call continuation */
+        n = (*func->stkci.u.c.k)(L, LUA_YIELD, func->stkci.u.c.ctx);
         lua_lock(L);
         api_checknelems(L, n);
         firstArg = L->top - n;  /* yield results come from continuation */
@@ -658,7 +665,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
     }
     else lua_assert(status == L->status);  /* normal end or yield */
   }
-  *nresults = (status == LUA_YIELD) ? L->ci->u2.nyield
+  *nresults = (status == LUA_YIELD) ? L->func->stkci.u2.nyield
                                     : L->top - (L->func + 1);
   L->nny = oldnny;  /* restore 'nny' */
   L->nCcalls--;
@@ -675,7 +682,6 @@ LUA_API int lua_isyieldable (lua_State *L) {
 
 LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
                         lua_KFunction k) {
-  CallInfo *ci = L->ci;
   StkId func = L->func;
   luai_userstateyield(L, nresults);
   lua_lock(L);
@@ -689,12 +695,12 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
   L->status = LUA_YIELD;
   if (isLua(func)) {  /* inside a hook? */
     api_check(L, k == NULL, "hooks cannot continue after yielding");
-    ci->u2.nyield = 0;  /* no results */
+    func->stkci.u2.nyield = 0;  /* no results */
   }
   else {
-    if ((ci->u.c.k = k) != NULL)  /* is there a continuation? */
-      ci->u.c.ctx = ctx;  /* save context */
-    ci->u2.nyield = nresults;  /* save number of results */
+    if ((func->stkci.u.c.k = k) != NULL)  /* is there a continuation? */
+      func->stkci.u.c.ctx = ctx;  /* save context */
+    func->stkci.u2.nyield = nresults;  /* save number of results */
     luaD_throw(L, LUA_YIELD);
   }
   lua_assert(callstatus(func) & CIST_HOOKED);  /* must be inside a hook */

+ 16 - 2
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 2.126 2017/10/31 17:54:35 roberto Exp roberto $
+** $Id: lobject.h,v 2.127 2017/11/03 12:12:30 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -314,9 +314,23 @@ typedef union StackValue {
   struct {
     TValuefields;
     lu_byte callstatus_;
-    unsigned short previous;  /* difference to previous 'func' */
     short nresults;  /* expected number of results from this function */
+    unsigned short previous;  /* difference to previous 'func' */
     unsigned short framesize;  /* stack space available for this function */
+    union {
+      unsigned short funcidx;  /* called-function index */
+      unsigned short nyield;  /* number of values yielded */
+    } u2;
+    union {
+      struct {  /* only for Lua functions */
+        const Instruction *savedpc;
+      } l;
+      struct {  /* only for C functions */
+        lua_KFunction k;  /* continuation in case of yields */
+        ptrdiff_t old_errfunc;
+        lua_KContext ctx;  /* context info. in case of yields */
+      } c;
+    } u;
   } stkci;
 } StackValue;
 

+ 1 - 15
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 2.146 2017/11/02 11:28:56 roberto Exp roberto $
+** $Id: lstate.h,v 2.147 2017/11/03 12:12:30 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -87,20 +87,6 @@ typedef struct stringtable {
 typedef struct CallInfo {
   StkId func;  /* function index in the stack */
   struct CallInfo *previous, *next;  /* dynamic call link */
-  union {
-    struct {  /* only for Lua functions */
-      const Instruction *savedpc;
-    } l;
-    struct {  /* only for C functions */
-      lua_KFunction k;  /* continuation in case of yields */
-      ptrdiff_t old_errfunc;
-      lua_KContext ctx;  /* context info. in case of yields */
-    } c;
-  } u;
-  union {
-    ptrdiff_t funcidx;  /* called-function index */
-    int nyield;  /* number of values yielded */
-  } u2;
 } CallInfo;
 
 

+ 9 - 11
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.227 2017/11/02 11:28:56 roberto Exp roberto $
+** $Id: ltests.c,v 2.228 2017/11/03 12:12:30 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -309,28 +309,26 @@ static void checkLclosure (global_State *g, LClosure *cl) {
 }
 
 
-static int lua_checkpc (CallInfo *ci) {
-  if (!isLua(ci->func)) return 1;
+static int lua_checkpc (StkId func) {
+  if (!isLua(func)) return 1;
   else {
-    StkId f = ci->func;
-    Proto *p = clLvalue(s2v(f))->p;
-    return p->code <= ci->u.l.savedpc &&
-           ci->u.l.savedpc <= p->code + p->sizecode;
+    Proto *p = clLvalue(s2v(func))->p;
+    return p->code <= func->stkci.u.l.savedpc &&
+           func->stkci.u.l.savedpc <= p->code + p->sizecode;
   }
 }
 
 
 static void checkstack (global_State *g, lua_State *L1) {
   StkId o;
-  CallInfo *ci;
   UpVal *uv;
   lua_assert(!isdead(g, L1));
   for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next)
     lua_assert(upisopen(uv));  /* must be open */
-  for (ci = L1->ci; ci != NULL; ci = ci->previous)
-    lua_assert(lua_checkpc(ci));
-  for (o = L1->func; o->stkci.previous != 0; o -= o->stkci.previous)
+  for (o = L1->func; o->stkci.previous != 0; o -= o->stkci.previous) {
     lua_assert(functop(o) <= L1->stack_last);
+    lua_assert(lua_checkpc(o));
+  }
   lua_assert(o == L1->stack);
   if (L1->stack) {  /* complete thread? */
     for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++)

+ 25 - 22
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.301 2017/11/01 18:20:48 roberto Exp roberto $
+** $Id: lvm.c,v 2.302 2017/11/03 12:12:30 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -654,13 +654,14 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
 }
 
 
+#define basepc(base)	((base - 1)->stkci.u.l.savedpc)
+
 /*
 ** finish execution of an opcode interrupted by an yield
 */
 void luaV_finishOp (lua_State *L) {
-  CallInfo *ci = L->ci;
   StkId base = L->func + 1;
-  Instruction inst = *(ci->u.l.savedpc - 1);  /* interrupted instruction */
+  Instruction inst = *(basepc(base) - 1);  /* interrupted instruction */
   OpCode op = GET_OPCODE(inst);
   switch (op) {  /* finish its execution */
     case OP_ADDI: case OP_SUBI:
@@ -684,9 +685,9 @@ void luaV_finishOp (lua_State *L) {
         callstatus(base - 1) ^= CIST_LEQ;  /* clear mark */
         res = !res;  /* negate result */
       }
-      lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
+      lua_assert(GET_OPCODE(*basepc(base)) == OP_JMP);
       if (res != GETARG_A(inst))  /* condition failed? */
-        ci->u.l.savedpc++;  /* skip jump instruction */
+        basepc(base)++;  /* skip jump instruction */
       break;
     }
     case OP_CONCAT: {
@@ -704,7 +705,7 @@ void luaV_finishOp (lua_State *L) {
       break;
     }
     case OP_TFORCALL: {
-      lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
+      lua_assert(GET_OPCODE(*basepc(base)) == OP_TFORLOOP);
       L->top = functop(base - 1);  /* correct top */
       break;
     }
@@ -763,20 +764,22 @@ void luaV_finishOp (lua_State *L) {
 ** Whenever code can raise errors (including memory errors), the global
 ** 'pc' must be correct to report occasional errors.
 */
-#define savepc(L)	(ci->u.l.savedpc = pc)
+#define savepc(base)	(basepc(base) = pc)
+
 
+/* update internal copies to its correct values */
+#define updatestate()	(base = L->func + 1, updatemask(L))
 
 /*
 ** Protect code that, in general, can raise errors, reallocate the
 ** stack, and change the hooks.
 */
-#define Protect(code)  \
-  { savepc(L); {code;}; base = L->func + 1; updatemask(L); }
+#define Protect(code)	{ savepc(base); {code;}; updatestate(); }
 
 
 #define checkGC(L,c)  \
   { luaC_condGC(L, L->top = (c),  /* limit of live values */ \
-    {Protect((void)0); L->top = functop(base - 1);});  /* restore top */ \
+    {updatestate(); L->top = functop(base - 1);});  /* restore top */ \
     luai_threadyield(L); }
 
 
@@ -798,14 +801,14 @@ void luaV_execute (lua_State *L) {
   TValue *k;
   StkId base = L->func + 1;  /* local copy of 'L->func + 1' */
   int mask;  /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */
-  const Instruction *pc;  /* local copy of 'ci->u.l.savedpc' */
+  const Instruction *pc;  /* local copy of 'basepc(base)' */
   callstatus(base - 1) |= CIST_FRESH;  /* fresh invocation of 'luaV_execute" */
  newframe:  /* reentry point when frame changes (call/return) */
   lua_assert(ci == L->ci);
   cl = clLvalue(s2v(L->func));  /* local reference to function's closure */
   k = cl->p->k;  /* local reference to function's constant table */
   updatemask(L);
-  pc = ci->u.l.savedpc;
+  pc = basepc(base);
   /* main loop of interpreter */
   for (;;) {
     Instruction i;
@@ -969,7 +972,7 @@ void luaV_execute (lua_State *L) {
         int b = GETARG_B(i);
         int c = GETARG_C(i);
         Table *t;
-        savepc(L);  /* in case of allocation errors */
+        savepc(base);  /* in case of allocation errors */
         t = luaH_new(L);
         sethvalue2s(L, ra, t);
         if (b != 0 || c != 0)
@@ -1368,9 +1371,9 @@ void luaV_execute (lua_State *L) {
         int b = GETARG_B(i);
         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
         lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
-        savepc(L);
+        savepc(base);
         if (luaD_precall(L, ra, LUA_MULTRET)) {  /* C function? */
-          Protect((void)0);  /* update 'base' */
+          updatestate();  /* update 'base' */
         }
         else {
           /* tail call: put called frame (n) in place of caller one (o) */
@@ -1388,7 +1391,7 @@ void luaV_execute (lua_State *L) {
             setobjs2s(L, ofunc + aux, nfunc + aux);
           ofunc->stkci.framesize = L->top - nfunc;
           L->top = functop(ofunc);  /* correct top */
-          oci->u.l.savedpc = nci->u.l.savedpc;
+          ofunc->stkci.u.l.savedpc = nfunc->stkci.u.l.savedpc;
           callstatus(ofunc) |= CIST_TAIL;  /* function was tail called */
           ci = L->ci = oci;  /* remove new frame */
           base = ofunc + 1;
@@ -1401,7 +1404,7 @@ void luaV_execute (lua_State *L) {
       vmcase(OP_RETURN) {
         int b = GETARG_B(i);
         if (cl->p->sizep > 0) luaF_close(L, base);
-        savepc(L);
+        savepc(base);
         b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
         if (callstatus(base - 1) & CIST_FRESH)  /* local 'base' still from callee */
           return;  /* external invocation: return */
@@ -1409,8 +1412,8 @@ void luaV_execute (lua_State *L) {
           ci = L->ci;
           base = L->func + 1;
           if (b) L->top = functop(base - 1);
-          lua_assert(isLua(L->func));
-          lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
+          lua_assert(isLua(base - 1));
+          lua_assert(GET_OPCODE(*(basepc(base) - 1)) == OP_CALL);
           goto newframe;  /* restart luaV_execute over previous Lua function */
         }
       }
@@ -1455,7 +1458,7 @@ void luaV_execute (lua_State *L) {
         }
         else {  /* try making all values floats */
           lua_Number ninit; lua_Number nlimit; lua_Number nstep;
-          savepc(L);  /* in case of errors */
+          savepc(base);  /* in case of errors */
           if (!tonumber(plimit, &nlimit))
             luaG_runerror(L, "'for' limit must be a number");
           setfltvalue(plimit, nlimit);
@@ -1501,7 +1504,7 @@ void luaV_execute (lua_State *L) {
         }
         h = hvalue(s2v(ra));
         last = ((c-1)*LFIELDS_PER_FLUSH) + n;
-        savepc(L);  /* in case of allocation errors */
+        savepc(base);  /* in case of allocation errors */
         if (last > h->sizearray)  /* needs more space? */
           luaH_resizearray(L, h, last);  /* preallocate it at once */
         for (; n > 0; n--) {
@@ -1518,7 +1521,7 @@ void luaV_execute (lua_State *L) {
         Proto *p = cl->p->p[GETARG_Bx(i)];
         LClosure *ncl = getcached(p, cl->upvals, base);  /* cached closure */
         if (ncl == NULL) {  /* no match? */
-          savepc(L);  /* in case of allocation errors */
+          savepc(base);  /* in case of allocation errors */
           pushclosure(L, p, cl->upvals, base, ra);  /* create a new one */
         }
         else