diff --git a/lapi.c b/lapi.c
index 0e3ef071..69307a3c 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.74 2009/04/08 18:04:33 roberto Exp roberto $
+** $Id: lapi.c,v 2.75 2009/04/17 14:28:06 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -829,18 +829,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), func);
   }
   else {  /* prepare continuation (call is already protected by 'resume') */
-    L->ci->u.c.k = k;  /* save continuation */
-    L->ci->u.c.ctx = ctx;  /* save context */
+    CallInfo *ci = L->ci;
+    ci->u.c.k = k;  /* save continuation */
+    ci->u.c.ctx = ctx;  /* save context */
     /* save information for error recovery */
-    L->ci->u.c.oldtop = savestack(L, c.func);
-    L->ci->u.c.old_allowhook = L->allowhook;
-    L->ci->u.c.old_errfunc = L->errfunc;
+    ci->u.c.oldtop = savestack(L, c.func);
+    ci->u.c.old_allowhook = L->allowhook;
+    ci->u.c.old_errfunc = L->errfunc;
     L->errfunc = func;
     /* mark that function may do error recovery */
-    L->ci->callstatus |= CIST_YPCALL;
+    ci->callstatus |= CIST_YPCALL;
     luaD_call(L, c.func, nresults, 1);  /* do the call */
-    L->ci->callstatus &= ~CIST_YPCALL;
-    L->errfunc = L->ci->u.c.old_errfunc;
+    ci->callstatus &= ~CIST_YPCALL;
+    L->errfunc = ci->u.c.old_errfunc;
     status = LUA_OK;  /* if it is here, there were no errors */
   }
   adjustresults(L, nresults);
diff --git a/ldebug.c b/ldebug.c
index bcb7eaf3..629d040b 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 2.45 2009/03/26 12:56:38 roberto Exp roberto $
+** $Id: ldebug.c,v 2.46 2009/04/17 14:28:06 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -35,9 +35,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
 
 static int currentpc (lua_State *L, CallInfo *ci) {
   if (!isLua(ci)) return -1;  /* function is not a Lua function? */
-  if (ci == L->ci)
-    ci->savedpc = L->savedpc;
-  return pcRel(ci->savedpc, ci_func(ci)->l.p);
+  return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);
 }
 
 
@@ -58,7 +56,7 @@ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
     mask = 0;
     func = NULL;
   }
-  L->oldpc = L->savedpc;
+  L->oldpc = NULL;
   L->hook = func;
   L->basehookcount = count;
   resethookcount(L);
diff --git a/ldo.c b/ldo.c
index 1a051222..040b8cdb 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 2.59 2009/04/15 16:53:39 roberto Exp roberto $
+** $Id: ldo.c,v 2.60 2009/04/17 14:28:06 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -151,28 +151,29 @@ void luaD_growstack (lua_State *L, int n) {
 void luaD_callhook (lua_State *L, int event, int line) {
   lua_Hook hook = L->hook;
   if (hook && L->allowhook) {
+    CallInfo *ci = L->ci;
     ptrdiff_t top = savestack(L, L->top);
-    ptrdiff_t ci_top = savestack(L, L->ci->top);
+    ptrdiff_t ci_top = savestack(L, ci->top);
     lua_Debug ar;
     ar.event = event;
     ar.currentline = line;
     if (event == LUA_HOOKTAILRET)
       ar.i_ci = NULL;  /* tail call; no debug information about it */
     else
-      ar.i_ci = L->ci;
+      ar.i_ci = ci;
     luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
-    L->ci->top = L->top + LUA_MINSTACK;
-    lua_assert(L->ci->top <= L->stack_last);
+    ci->top = L->top + LUA_MINSTACK;
+    lua_assert(ci->top <= L->stack_last);
     L->allowhook = 0;  /* cannot call hooks inside a hook */
-    L->ci->callstatus |= CIST_HOOKED;
+    ci->callstatus |= CIST_HOOKED;
     lua_unlock(L);
     (*hook)(L, &ar);
     lua_lock(L);
     lua_assert(!L->allowhook);
     L->allowhook = 1;
-    L->ci->top = restorestack(L, ci_top);
+    ci->top = restorestack(L, ci_top);
     L->top = restorestack(L, top);
-    L->ci->callstatus &= ~CIST_HOOKED;
+    ci->callstatus &= ~CIST_HOOKED;
   }
 }
 
@@ -223,7 +224,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
     func = tryfuncTM(L, func);  /* check the `function' tag method */
   funcr = savestack(L, func);
   cl = &clvalue(func)->l;
-  L->ci->savedpc = L->savedpc;
   L->ci->nresults = nresults;
   if (!cl->isC) {  /* Lua function? prepare its call */
     CallInfo *ci;
@@ -243,16 +243,16 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
     L->base = ci->base = base;
     ci->top = L->base + p->maxstacksize;
     lua_assert(ci->top <= L->stack_last);
-    L->savedpc = p->code;  /* starting point */
+    ci->u.l.savedpc = p->code;  /* starting point */
     ci->u.l.tailcalls = 0;
     ci->callstatus = CIST_LUA;
     for (st = L->top; st < ci->top; st++)
       setnilvalue(st);
     L->top = ci->top;
     if (L->hookmask & LUA_MASKCALL) {
-      L->savedpc++;  /* hooks assume 'pc' is already incremented */
+      ci->u.l.savedpc++;  /* hooks assume 'pc' is already incremented */
       luaD_callhook(L, LUA_HOOKCALL, -1);
-      L->savedpc--;  /* correct 'pc' */
+      ci->u.l.savedpc--;  /* correct 'pc' */
     }
     return 0;
   }
@@ -295,13 +295,12 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
   if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
     if (L->hookmask & LUA_MASKRET)
       firstResult = callrethooks(L, firstResult);
-    L->oldpc = L->ci->previous->savedpc;  /* 'oldpc' for returning function */
+    L->oldpc = ci->previous->u.l.savedpc;  /* 'oldpc' for returning function */
   }
   res = ci->func;  /* res == final position of 1st result */
-  L->ci = ci = L->ci->previous;  /* back to caller */
+  L->ci = ci = ci->previous;  /* back to caller */
   wanted = ci->nresults;
   L->base = ci->base;  /* restore base */
-  L->savedpc = ci->savedpc;  /* restore savedpc */
   /* move results to correct place */
   for (i = wanted; i != 0 && firstResult < L->top; i--)
     setobjs2s(L, res++, firstResult++);
@@ -336,21 +335,21 @@ void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
 
 
 static void finishCcall (lua_State *L) {
+  CallInfo *ci = L->ci;
   int n;
-  lua_assert(L->ci->u.c.k != NULL);  /* must have a continuation */
+  lua_assert(ci->u.c.k != NULL);  /* must have a continuation */
   lua_assert(L->nny == 0);
   /* finish 'luaD_call' */
   G(L)->nCcalls--;
   /* finish 'lua_callk' */
-  adjustresults(L, L->ci->nresults);
+  adjustresults(L, ci->nresults);
   /* call continuation function */
-  if (!(L->ci->callstatus & CIST_STAT))  /* no call status? */
-    L->ci->u.c.status = LUA_YIELD;  /* 'default' status */
-  lua_assert(L->ci->u.c.status != LUA_OK);
-  L->ci->callstatus = (L->ci->callstatus & ~(CIST_YPCALL | CIST_STAT))
-                    | CIST_YIELDED;
+  if (!(ci->callstatus & CIST_STAT))  /* no call status? */
+    ci->u.c.status = LUA_YIELD;  /* 'default' status */
+  lua_assert(ci->u.c.status != LUA_OK);
+  ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED;
   lua_unlock(L);
-  n = (*L->ci->u.c.k)(L);
+  n = (*ci->u.c.k)(L);
   lua_lock(L);
   /* finish 'luaD_precall' */
   luaD_poscall(L, L->top - n);
@@ -384,7 +383,7 @@ static void resume (lua_State *L, void *ud) {
     lua_assert(L->status == LUA_YIELD);
     L->status = LUA_OK;
     if (isLua(ci)) {  /* yielded inside a hook? */
-      L->base = L->ci->base;  /* just continue its execution */
+      L->base = ci->base;  /* just continue its execution */
       luaV_execute(L);
     }
     else {  /* 'common' yield */
@@ -427,7 +426,7 @@ static int recover (lua_State *L, int status) {
   luaF_close(L, oldtop);
   luaD_seterrorobj(L, status, oldtop);
   L->ci = ci;
-  L->base = L->ci->base;
+  L->base = ci->base;
   L->allowhook = ci->u.c.old_allowhook;
   L->nny = 0;  /* should be zero to be yieldable */
   restore_stack_limit(L);
@@ -499,8 +498,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
     luaF_close(L, oldtop);  /* close possible pending closures */
     luaD_seterrorobj(L, status, oldtop);
     L->ci = old_ci;
-    L->base = L->ci->base;
-    L->savedpc = L->ci->savedpc;
+    L->base = old_ci->base;
     L->allowhook = old_allowhooks;
     L->nny = old_nny;
     restore_stack_limit(L);
diff --git a/lstate.c b/lstate.c
index e1bbd7bd..7df2ba2b 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 2.51 2009/04/17 14:28:06 roberto Exp roberto $
+** $Id: lstate.c,v 2.52 2009/04/17 14:40:13 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -130,7 +130,6 @@ static void preinit_state (lua_State *L, global_State *g) {
   L->base_ci.next = L->base_ci.previous = NULL;
   L->ci = &L->base_ci;
   L->nci = 0;
-  L->savedpc = NULL;
   L->errfunc = 0;
   setnilvalue(gt(L));
 }
diff --git a/lstate.h b/lstate.h
index 0e34a54c..23d1dfb5 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 2.41 2009/04/08 18:04:33 roberto Exp roberto $
+** $Id: lstate.h,v 2.42 2009/04/17 14:28:06 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -81,11 +81,11 @@ typedef struct CallInfo {
   StkId func;  /* function index in the stack */
   StkId	top;  /* top for this function */
   struct CallInfo *previous, *next;  /* dynamic call link */
-  const Instruction *savedpc;
   short nresults;  /* expected number of results from a call */
   lu_byte callstatus;
   union {
     struct {  /* only for Lua functions */
+      const Instruction *savedpc;
       int tailcalls;  /* number of tail calls lost under this entry */
     } l;
     struct {  /* only for C functions */
@@ -165,7 +165,6 @@ struct lua_State {
   global_State *l_G;
   CallInfo *ci;  /* call info for current function */
   int nci;  /* number of total CallInfo structures linked */
-  const Instruction *savedpc;  /* `savedpc' of current function */
   const Instruction *oldpc;  /* last pc traced */
   StkId stack_last;  /* last free slot in the stack */
   StkId stack;  /* stack base */
diff --git a/ltests.c b/ltests.c
index 9a55f6da..5e2b6d75 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.60 2009/04/14 19:10:17 roberto Exp roberto $
+** $Id: ltests.c,v 2.61 2009/04/17 14:28:06 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -285,6 +285,16 @@ static void checkclosure (global_State *g, Closure *cl) {
 }
 
 
+static int lua_checkpc (pCallInfo ci) {
+  if (!isLua(ci)) return 1;
+  else {
+    Proto *p = ci_func(ci)->l.p;
+    return p->code <= ci->u.l.savedpc &&
+           ci->u.l.savedpc <= p->code + p->sizecode;
+  }
+}
+
+
 static void checkstack (global_State *g, lua_State *L1) {
   StkId o;
   CallInfo *ci;
@@ -298,7 +308,7 @@ static void checkstack (global_State *g, lua_State *L1) {
   checkliveness(g, gt(L1));
   for (ci = L1->ci; ci != NULL; ci = ci->previous) {
     lua_assert(ci->top <= L1->stack_last);
-    lua_assert(lua_checkpc(L1, ci));
+    lua_assert(lua_checkpc(ci));
   }
   if (L1->stack) {
     for (o = L1->stack; o < L1->top; o++)
@@ -352,18 +362,6 @@ printf(">>> %d  %s  %02x\n", g->gcstate, luaT_typenames[gch(o)->tt], gch(o)->mar
 }
 
 
-int lua_checkpc (lua_State *L, pCallInfo ci) {
-  if (!isLua(ci)) return 1;
-  else {
-    Proto *p = ci_func(ci)->l.p;
-    if (ci != L->ci)
-      return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode;
-    else
-      return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode;
-  }
-}
-
-
 int lua_checkmemory (lua_State *L) {
   global_State *g = G(L);
   GCObject *o;
diff --git a/ltests.h b/ltests.h
index 180d067b..4a27d099 100644
--- a/ltests.h
+++ b/ltests.h
@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.h,v 2.23 2008/07/18 19:58:10 roberto Exp roberto $
+** $Id: ltests.h,v 2.24 2008/08/05 19:24:46 roberto Exp roberto $
 ** Internal Header for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -51,7 +51,6 @@ void *debug_realloc (void *ud, void *block, size_t osize, size_t nsize);
 typedef struct CallInfo *pCallInfo;
 
 int lua_checkmemory (lua_State *L);
-int lua_checkpc (lua_State *L, pCallInfo ci);
 
 
 /* test for lock/unlock */
diff --git a/lvm.c b/lvm.c
index 0c70491d..ad3a26cd 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.84 2009/03/10 17:14:37 roberto Exp roberto $
+** $Id: lvm.c,v 2.85 2009/04/17 14:28:06 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -58,21 +58,22 @@ int luaV_tostring (lua_State *L, StkId obj) {
 
 
 static void traceexec (lua_State *L) {
+  CallInfo *ci = L->ci;
   lu_byte mask = L->hookmask;
   if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
     resethookcount(L);
     luaD_callhook(L, LUA_HOOKCOUNT, -1);
   }
   if (mask & LUA_MASKLINE) {
-    Proto *p = ci_func(L->ci)->l.p;
-    int npc = pcRel(L->savedpc, p);
+    Proto *p = ci_func(ci)->l.p;
+    int npc = pcRel(ci->u.l.savedpc, p);
     int newline = getline(p, npc);
     if (npc == 0 ||  /* call linehook when enter a new function, */
-        L->savedpc <= L->oldpc ||  /* when jump back (loop), or when */
+        ci->u.l.savedpc <= L->oldpc ||  /* when jump back (loop), or when */
         newline != getline(p, pcRel(L->oldpc, p)))  /* enter a new line */
       luaD_callhook(L, LUA_HOOKLINE, newline);
   }
-  L->oldpc = L->savedpc;
+  L->oldpc = ci->u.l.savedpc;
 }
 
 
@@ -357,7 +358,8 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb,
 ** finish execution of an opcode interrupted by an yield
 */
 void luaV_finishOp (lua_State *L) {
-  Instruction inst = *(L->savedpc - 1);  /* interrupted instruction */
+  CallInfo *ci = L->ci;
+  Instruction inst = *(ci->u.l.savedpc - 1);  /* interrupted instruction */
   switch (GET_OPCODE(inst)) {  /* finish its execution */
     case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
     case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN:
@@ -373,9 +375,9 @@ void luaV_finishOp (lua_State *L) {
       if (GET_OPCODE(inst) == OP_LE &&  /* "<=" using "<" instead? */
           ttisnil(luaT_gettmbyobj(L, L->base + GETARG_B(inst), TM_LE)))
         res = !res;  /* invert result */
-      lua_assert(GET_OPCODE(*L->savedpc) == OP_JMP);
+      lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
       if (res != GETARG_A(inst))  /* condition failed? */
-        L->savedpc++;  /* skip jump instruction */
+        ci->u.l.savedpc++;  /* skip jump instruction */
       break;
     }
     case OP_CONCAT: {
@@ -384,7 +386,7 @@ void luaV_finishOp (lua_State *L) {
       int b = GETARG_B(inst);      /* ... first element to concatenate */
       int total = last - b + 1;  /* number of elements to concatenate */
       setobj2s(L, top - 2, top);  /* put TM result in proper position */
-      L->top = L->ci->top;  /* correct top */
+      L->top = ci->top;  /* correct top */
       if (total > 1)  /* are there elements to concat? */
         luaV_concat(L, total, last);  /* concat them (may yield again) */
       /* move final result to final position */
@@ -392,13 +394,13 @@ void luaV_finishOp (lua_State *L) {
       break;
     }
     case OP_TFORCALL: {
-      lua_assert(GET_OPCODE(*L->savedpc) == OP_TFORLOOP);
-      L->top = L->ci->top;  /* correct top */
+      lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
+      L->top = ci->top;  /* correct top */
       break;
     }
     case OP_CALL: {
       if (GETARG_C(inst) - 1 >= 0)  /* nresults >= 0? */
-        L->top = L->ci->top;  /* adjust results */
+        L->top = ci->top;  /* adjust results */
       break;
     }
     case OP_TAILCALL: case OP_SETGLOBAL: case OP_SETTABLE:
@@ -413,8 +415,6 @@ void luaV_finishOp (lua_State *L) {
 ** some macros for common tasks in `luaV_execute'
 */
 
-#define runtime_check(L, c)	{ if (!(c)) break; }
-
 #define RA(i)	(base+GETARG_A(i))
 /* to be used after possible stack reallocation */
 #define RB(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
@@ -426,10 +426,10 @@ void luaV_finishOp (lua_State *L) {
 #define KBx(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
 
 
-#define dojump(L,i)	{ L->savedpc += (i); luai_threadyield(L);}
+#define dojump(i)	{ ci->u.l.savedpc += (i); luai_threadyield(L);}
 
 
-#define Protect(x)	{ {x;}; base = L->base; }
+#define Protect(x)	{ {x;}; base = ci->base; }
 
 
 #define arith_op(op,tm) { \
@@ -446,32 +446,29 @@ void luaV_finishOp (lua_State *L) {
 
 
 void luaV_execute (lua_State *L) {
-  LClosure *cl;
-  StkId base;
-  TValue *k;
- reentry:  /* entry point */
-  lua_assert(isLua(L->ci));
-  cl = &curr_func(L)->l;
-  base = L->base;
-  k = cl->p->k;
+  CallInfo *ci = L->ci;
+  LClosure *cl = &clvalue(ci->func)->l;
+  TValue *k = cl->p->k;
+  StkId base = ci->base;
+  lua_assert(isLua(ci));
   /* main loop of interpreter */
   for (;;) {
-    Instruction i = *(L->savedpc++);
+    Instruction i = *(ci->u.l.savedpc++);
     StkId ra;
     if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
         (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
       traceexec(L);
       if (L->status == LUA_YIELD) {  /* did hook yield? */
-        L->savedpc--;  /* undo increment */
+        ci->u.l.savedpc--;  /* undo increment */
         luaD_throw(L, LUA_YIELD);
       }
-      base = L->base;
+      base = ci->base;
     }
     /* warning!! several calls may realloc the stack and invalidate `ra' */
     ra = RA(i);
-    lua_assert(base == L->base && L->base == L->ci->base);
+    lua_assert(base == ci->base && base == L->base);
     lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
-    lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
+    lua_assert(L->top == ci->top || luaG_checkopenop(i));
     switch (GET_OPCODE(i)) {
       case OP_MOVE: {
         setobjs2s(L, ra, RB(i));
@@ -483,7 +480,7 @@ void luaV_execute (lua_State *L) {
       }
       case OP_LOADBOOL: {
         setbvalue(ra, GETARG_B(i));
-        if (GETARG_C(i)) L->savedpc++;  /* skip next instruction (if C) */
+        if (GETARG_C(i)) ci->u.l.savedpc++;  /* skip next instruction (if C) */
         continue;
       }
       case OP_LOADNIL: {
@@ -595,7 +592,7 @@ void luaV_execute (lua_State *L) {
         continue;
       }
       case OP_JMP: {
-        dojump(L, GETARG_sBx(i));
+        dojump(GETARG_sBx(i));
         continue;
       }
       case OP_EQ: {
@@ -603,40 +600,40 @@ void luaV_execute (lua_State *L) {
         TValue *rc = RKC(i);
         Protect(
           if (equalobj(L, rb, rc) == GETARG_A(i))
-            dojump(L, GETARG_sBx(*L->savedpc));
+            dojump(GETARG_sBx(*ci->u.l.savedpc));
         )
-        L->savedpc++;
+        ci->u.l.savedpc++;
         continue;
       }
       case OP_LT: {
         Protect(
           if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
-            dojump(L, GETARG_sBx(*L->savedpc));
+            dojump(GETARG_sBx(*ci->u.l.savedpc));
         )
-        L->savedpc++;
+        ci->u.l.savedpc++;
         continue;
       }
       case OP_LE: {
         Protect(
           if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
-            dojump(L, GETARG_sBx(*L->savedpc));
+            dojump(GETARG_sBx(*ci->u.l.savedpc));
         )
-        L->savedpc++;
+        ci->u.l.savedpc++;
         continue;
       }
       case OP_TEST: {
         if (GETARG_C(i) ? !l_isfalse(ra) : l_isfalse(ra))
-          dojump(L, GETARG_sBx(*L->savedpc));
-        L->savedpc++;
+          dojump(GETARG_sBx(*ci->u.l.savedpc));
+        ci->u.l.savedpc++;
         continue;
       }
       case OP_TESTSET: {
         TValue *rb = RB(i);
         if (GETARG_C(i) ? !l_isfalse(rb) : l_isfalse(rb)) {
           setobjs2s(L, ra, rb);
-          dojump(L, GETARG_sBx(*L->savedpc));
+          dojump(GETARG_sBx(*ci->u.l.savedpc));
         }
-        L->savedpc++;
+        ci->u.l.savedpc++;
         continue;
       }
       case OP_CALL: {
@@ -644,13 +641,14 @@ void luaV_execute (lua_State *L) {
         int nresults = GETARG_C(i) - 1;
         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
         if (luaD_precall(L, ra, nresults)) {  /* C function? */
-          if (nresults >= 0) L->top = L->ci->top;  /* adjust results */
-          base = L->base;
+          if (nresults >= 0) L->top = ci->top;  /* adjust results */
+          base = ci->base;
           continue;
         }
         else {  /* Lua function */
-          L->ci->callstatus |= CIST_REENTRY;
-          goto reentry;  /* restart luaV_execute over new Lua function */
+          ci = L->ci;
+          ci->callstatus |= CIST_REENTRY;
+          break;  /* restart luaV_execute over new Lua function */
         }
       }
       case OP_TAILCALL: {
@@ -658,25 +656,26 @@ void luaV_execute (lua_State *L) {
         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
         lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
         if (luaD_precall(L, ra, LUA_MULTRET)) {  /* C function? */
-          base = L->base;
+          base = ci->base;
           continue;
         }
         else {
-          /* tail call: put new frame in place of previous one */
-          StkId pfunc = L->ci->func;  /* called function index */
-          CallInfo *ci = L->ci->previous;  /* caller frame */
-          StkId func = ci->func;
+          /* tail call: put called frame (n) in place of caller one (o) */
+          CallInfo *nci = L->ci;  /* called frame */
+          CallInfo *oci = nci->previous;  /* caller frame */
+          StkId nfunc = nci->func;  /* called function index */
+          StkId ofunc = oci->func;
           int aux;
-          if (cl->p->sizep > 0) luaF_close(L, ci->base);
-          L->base = ci->base = ci->func + (L->ci->base - pfunc);
-          for (aux = 0; pfunc+aux < L->top; aux++)  /* move frame down */
-            setobjs2s(L, func+aux, pfunc+aux);
-          ci->top = L->top = func+aux;  /* correct top */
-          lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
-          ci->savedpc = L->savedpc;
-          ci->u.l.tailcalls++;  /* one more call lost */
-          L->ci = ci;  /* remove new frame */
-          goto reentry;
+          if (cl->p->sizep > 0) luaF_close(L, oci->base);
+          L->base = oci->base = ofunc + (nci->base - nfunc);
+          for (aux = 0; nfunc+aux < L->top; aux++)  /* move frame down */
+            setobjs2s(L, ofunc + aux, nfunc + aux);
+          oci->top = L->top = ofunc + aux;  /* correct top */
+          lua_assert(L->top == L->base + clvalue(ofunc)->l.p->maxstacksize);
+          oci->u.l.savedpc = nci->u.l.savedpc;
+          oci->u.l.tailcalls++;  /* one more call lost */
+          ci = L->ci = oci;  /* remove new frame */
+          break;  /* restart luaV_execute over new Lua function */
         }
       }
       case OP_RETURN: {
@@ -684,13 +683,14 @@ void luaV_execute (lua_State *L) {
         if (b != 0) L->top = ra+b-1;
         if (cl->p->sizep > 0) luaF_close(L, base);
         b = luaD_poscall(L, ra);
-        if (!(L->ci->next->callstatus & CIST_REENTRY))
+        if (!(ci->callstatus & CIST_REENTRY))  /* 'ci' still the called one */
           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);
-          goto reentry;
+          ci = L->ci;
+          if (b) L->top = ci->top;
+          lua_assert(isLua(ci));
+          lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
+          break;  /* restart luaV_execute over new Lua function */
         }
       }
       case OP_FORLOOP: {
@@ -699,7 +699,7 @@ void luaV_execute (lua_State *L) {
         lua_Number limit = nvalue(ra+1);
         if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit)
                                    : luai_numle(L, limit, idx)) {
-          dojump(L, GETARG_sBx(i));  /* jump back */
+          dojump(GETARG_sBx(i));  /* jump back */
           setnvalue(ra, idx);  /* update internal index... */
           setnvalue(ra+3, idx);  /* ...and external index */
         }
@@ -716,7 +716,7 @@ void luaV_execute (lua_State *L) {
         else if (!tonumber(pstep, ra+2))
           luaG_runerror(L, LUA_QL("for") " step must be a number");
         setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep)));
-        dojump(L, GETARG_sBx(i));
+        dojump(GETARG_sBx(i));
         continue;
       }
       case OP_TFORCALL: {
@@ -726,8 +726,8 @@ void luaV_execute (lua_State *L) {
         setobjs2s(L, cb, ra);
         L->top = cb + 3;  /* func. + 2 args (state and index) */
         Protect(luaD_call(L, cb, GETARG_C(i), 1));
-        L->top = L->ci->top;
-        i = *(L->savedpc++);  /* go to next instruction */
+        L->top = ci->top;
+        i = *(ci->u.l.savedpc++);  /* go to next instruction */
         ra = RA(i);
         lua_assert(GET_OPCODE(i) == OP_TFORLOOP);
         /* go through */
@@ -735,7 +735,7 @@ void luaV_execute (lua_State *L) {
       case OP_TFORLOOP: {
         if (!ttisnil(ra + 1)) {  /* continue loop? */
           setobjs2s(L, ra, ra + 1);  /* save control variable */
-          dojump(L, GETARG_sBx(i));  /* jump back */
+          dojump(GETARG_sBx(i));  /* jump back */
         }
         continue;
       }
@@ -746,10 +746,9 @@ void luaV_execute (lua_State *L) {
         Table *h;
         if (n == 0) n = cast_int(L->top - ra) - 1;
         if (c == 0) {
-          lua_assert(GET_OPCODE(*L->savedpc) == OP_EXTRAARG);
-          c = GETARG_Ax(*L->savedpc++);
+          lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
+          c = GETARG_Ax(*ci->u.l.savedpc++);
         }
-        runtime_check(L, ttistable(ra));
         h = hvalue(ra);
         last = ((c-1)*LFIELDS_PER_FLUSH) + n;
         if (last > h->sizearray)  /* needs more space? */
@@ -759,7 +758,7 @@ void luaV_execute (lua_State *L) {
           setobj2t(L, luaH_setnum(L, h, last--), val);
           luaC_barriert(L, h, val);
         }
-        L->top = L->ci->top;  /* correct top (in case of previous open call) */
+        L->top = ci->top;  /* correct top (in case of previous open call) */
         continue;
       }
       case OP_CLOSE: {
@@ -776,7 +775,7 @@ void luaV_execute (lua_State *L) {
         ncl->l.p = p;
         setclvalue(L, ra, ncl);
         for (j=0; j<nup; j++) {
-          Instruction u = *L->savedpc++;
+          Instruction u = *ci->u.l.savedpc++;
           if (GET_OPCODE(u) == OP_GETUPVAL)
             ncl->l.upvals[j] = cl->upvals[GETARG_B(u)];
           else {
@@ -790,7 +789,6 @@ void luaV_execute (lua_State *L) {
       case OP_VARARG: {
         int b = GETARG_B(i) - 1;
         int j;
-        CallInfo *ci = L->ci;
         int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
         if (b == LUA_MULTRET) {
           Protect(luaD_checkstack(L, n));
@@ -813,6 +811,11 @@ void luaV_execute (lua_State *L) {
         return;
       }
     }
+    /* function changed (call/return): update pointers */
+    lua_assert(ci == L->ci);
+    cl = &clvalue(ci->func)->l;
+    k = cl->p->k;
+    base = ci->base;
   }
 }