Browse Source

small steps towards yields in iterators and tag methods

Roberto Ierusalimschy 21 years ago
parent
commit
0bda88e6cd
6 changed files with 111 additions and 79 deletions
  1. 5 5
      lapi.c
  2. 18 12
      ldo.c
  3. 8 2
      ldo.h
  4. 3 2
      lstate.h
  5. 72 55
      lvm.c
  6. 5 3
      lvm.h

+ 5 - 5
lapi.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lapi.c,v 2.7 2004/04/30 20:13:38 roberto Exp roberto $
+** $Id: lapi.c,v 2.8 2004/05/11 16:52:08 roberto Exp roberto $
 ** Lua API
 ** Lua API
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -488,7 +488,7 @@ LUA_API void lua_gettable (lua_State *L, int idx) {
   lua_lock(L);
   lua_lock(L);
   t = luaA_index(L, idx);
   t = luaA_index(L, idx);
   api_checkvalidindex(L, t);
   api_checkvalidindex(L, t);
-  luaV_gettable(L, t, L->top - 1, L->top - 1);
+  luaV_gettable(L, t, L->top - 1, L->top - 1, NULL);
   lua_unlock(L);
   lua_unlock(L);
 }
 }
 
 
@@ -500,7 +500,7 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
   t = luaA_index(L, idx);
   t = luaA_index(L, idx);
   api_checkvalidindex(L, t);
   api_checkvalidindex(L, t);
   setsvalue(L, &key, luaS_new(L, k));
   setsvalue(L, &key, luaS_new(L, k));
-  luaV_gettable(L, t, &key, L->top);
+  luaV_gettable(L, t, &key, L->top, NULL);
   api_incr_top(L);
   api_incr_top(L);
   lua_unlock(L);
   lua_unlock(L);
 }
 }
@@ -584,7 +584,7 @@ LUA_API void lua_settable (lua_State *L, int idx) {
   api_checknelems(L, 2);
   api_checknelems(L, 2);
   t = luaA_index(L, idx);
   t = luaA_index(L, idx);
   api_checkvalidindex(L, t);
   api_checkvalidindex(L, t);
-  luaV_settable(L, t, L->top - 2, L->top - 1);
+  luaV_settable(L, t, L->top - 2, L->top - 1, NULL);
   L->top -= 2;  /* pop index and value */
   L->top -= 2;  /* pop index and value */
   lua_unlock(L);
   lua_unlock(L);
 }
 }
@@ -598,7 +598,7 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
   t = luaA_index(L, idx);
   t = luaA_index(L, idx);
   api_checkvalidindex(L, t);
   api_checkvalidindex(L, t);
   setsvalue(L, &key, luaS_new(L, k));
   setsvalue(L, &key, luaS_new(L, k));
-  luaV_settable(L, t, &key, L->top - 1);
+  luaV_settable(L, t, &key, L->top - 1, NULL);
   L->top--;  /* pop value */
   L->top--;  /* pop value */
   lua_unlock(L);
   lua_unlock(L);
 }
 }

+ 18 - 12
ldo.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ldo.c,v 2.3 2004/04/30 20:13:38 roberto Exp roberto $
+** $Id: ldo.c,v 2.4 2004/05/10 17:50:51 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -219,7 +219,7 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
 }
 }
 
 
 
 
-StkId luaD_precall (lua_State *L, StkId func) {
+int luaD_precall (lua_State *L, StkId func, int nresults) {
   LClosure *cl;
   LClosure *cl;
   ptrdiff_t funcr = savestack(L, func);
   ptrdiff_t funcr = savestack(L, func);
   if (!ttisfunction(func)) /* `func' is not a function? */
   if (!ttisfunction(func)) /* `func' is not a function? */
@@ -239,10 +239,11 @@ StkId luaD_precall (lua_State *L, StkId func) {
     ci->top = L->base + p->maxstacksize;
     ci->top = L->base + p->maxstacksize;
     ci->u.l.savedpc = p->code;  /* starting point */
     ci->u.l.savedpc = p->code;  /* starting point */
     ci->u.l.tailcalls = 0;
     ci->u.l.tailcalls = 0;
+    ci->nresults = nresults;
     for (st = L->top; st < ci->top; st++)
     for (st = L->top; st < ci->top; st++)
       setnilvalue(st);
       setnilvalue(st);
     L->top = ci->top;
     L->top = ci->top;
-    return NULL;
+    return PCRLUA;
   }
   }
   else {  /* if is a C function, call it */
   else {  /* if is a C function, call it */
     CallInfo *ci;
     CallInfo *ci;
@@ -256,7 +257,14 @@ StkId luaD_precall (lua_State *L, StkId func) {
     lua_unlock(L);
     lua_unlock(L);
     n = (*curr_func(L)->c.f)(L);  /* do the actual call */
     n = (*curr_func(L)->c.f)(L);  /* do the actual call */
     lua_lock(L);
     lua_lock(L);
-    return L->top - n;
+    if (n >= 0) {  /* no yielding? */
+      luaD_poscall(L, nresults, L->top - n);
+      return PCRC;
+    }
+    else {
+      ci->nresults = nresults;
+      return PCRYIELD;
+    }
   }
   }
 }
 }
 
 
@@ -297,17 +305,16 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
 ** function position.
 ** function position.
 */ 
 */ 
 void luaD_call (lua_State *L, StkId func, int nResults) {
 void luaD_call (lua_State *L, StkId func, int nResults) {
-  StkId firstResult;
   if (++L->nCcalls >= LUA_MAXCCALLS) {
   if (++L->nCcalls >= LUA_MAXCCALLS) {
     if (L->nCcalls == LUA_MAXCCALLS)
     if (L->nCcalls == LUA_MAXCCALLS)
       luaG_runerror(L, "C stack overflow");
       luaG_runerror(L, "C stack overflow");
     else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3)))
     else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3)))
       luaD_throw(L, LUA_ERRERR);  /* error while handing stack error */
       luaD_throw(L, LUA_ERRERR);  /* error while handing stack error */
   }
   }
-  firstResult = luaD_precall(L, func);
-  if (firstResult == NULL)  /* is a Lua function? */
-    firstResult = luaV_execute(L, 1);  /* call it */
-  luaD_poscall(L, nResults, firstResult);
+  if (luaD_precall(L, func, nResults) == PCRLUA) {  /* is a Lua function? */
+    StkId firstResult = luaV_execute(L, 1);  /* call it */
+    luaD_poscall(L, nResults, firstResult);
+  }
   L->nCcalls--;
   L->nCcalls--;
   luaC_checkGC(L);
   luaC_checkGC(L);
 }
 }
@@ -319,15 +326,14 @@ static void resume (lua_State *L, void *ud) {
   CallInfo *ci = L->ci;
   CallInfo *ci = L->ci;
   if (!L->isSuspended) {
   if (!L->isSuspended) {
     lua_assert(ci == L->base_ci && nargs < L->top - L->base);
     lua_assert(ci == L->base_ci && nargs < L->top - L->base);
-    luaD_precall(L, L->top - (nargs + 1));  /* start coroutine */
+    luaD_precall(L, L->top - (nargs + 1), LUA_MULTRET);  /* start coroutine */
   }
   }
   else {  /* resuming from previous yield */
   else {  /* resuming from previous yield */
     if (!f_isLua(ci)) {  /* `common' yield? */
     if (!f_isLua(ci)) {  /* `common' yield? */
       /* finish interrupted execution of `OP_CALL' */
       /* finish interrupted execution of `OP_CALL' */
-      int nresults;
+      int nresults = ci->nresults;
       lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL ||
       lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL ||
                  GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL);
                  GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL);
-      nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1;
       luaD_poscall(L, nresults, L->top - nargs);  /* complete it */
       luaD_poscall(L, nresults, L->top - nargs);  /* complete it */
       if (nresults >= 0) L->top = L->ci->top;
       if (nresults >= 0) L->top = L->ci->top;
     }  /* else yielded inside a hook: just continue its execution */
     }  /* else yielded inside a hook: just continue its execution */

+ 8 - 2
ldo.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ldo.h,v 1.58 2003/08/27 21:01:44 roberto Exp roberto $
+** $Id: ldo.h,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -38,13 +38,19 @@
 #define restoreci(L,n)		((CallInfo *)((char *)L->base_ci + (n)))
 #define restoreci(L,n)		((CallInfo *)((char *)L->base_ci + (n)))
 
 
 
 
+/* results from luaD_precall */
+#define PCRLUA		0	/* initiated a call to a Lua function */
+#define PCRC		1	/* did a call to a C function */
+#define PCRYIELD	2	/* C funtion yielded */
+
+
 /* type of protected functions, to be ran by `runprotected' */
 /* type of protected functions, to be ran by `runprotected' */
 typedef void (*Pfunc) (lua_State *L, void *ud);
 typedef void (*Pfunc) (lua_State *L, void *ud);
 
 
 void luaD_resetprotection (lua_State *L);
 void luaD_resetprotection (lua_State *L);
 int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
 int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
 void luaD_callhook (lua_State *L, int event, int line);
 void luaD_callhook (lua_State *L, int event, int line);
-StkId luaD_precall (lua_State *L, StkId func);
+int luaD_precall (lua_State *L, StkId func, int nresults);
 void luaD_call (lua_State *L, StkId func, int nResults);
 void luaD_call (lua_State *L, StkId func, int nResults);
 int luaD_pcall (lua_State *L, Pfunc func, void *u,
 int luaD_pcall (lua_State *L, Pfunc func, void *u,
                 ptrdiff_t oldtop, ptrdiff_t ef);
                 ptrdiff_t oldtop, ptrdiff_t ef);

+ 3 - 2
lstate.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.h,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $
+** $Id: lstate.h,v 2.2 2004/03/23 17:02:58 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -70,8 +70,9 @@ typedef struct stringtable {
 ** informations about a call
 ** informations about a call
 */
 */
 typedef struct CallInfo {
 typedef struct CallInfo {
-  StkId base;  /* base for called function */
+  StkId base;  /* base for this function */
   StkId	top;  /* top for this function */
   StkId	top;  /* top for this function */
+  int nresults;  /* expected number of results from this function */
   union {
   union {
     struct {  /* for Lua functions */
     struct {  /* for Lua functions */
       const Instruction *savedpc;
       const Instruction *savedpc;

+ 72 - 55
lvm.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lvm.c,v 2.4 2004/04/30 20:13:38 roberto Exp roberto $
+** $Id: lvm.c,v 2.5 2004/05/10 17:50:51 roberto Exp roberto $
 ** Lua virtual machine
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -106,7 +106,8 @@ static void callTM (lua_State *L) {
 }
 }
 
 
 
 
-void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
+StkId luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val,
+                     const Instruction *pc) {
   int loop;
   int loop;
   for (loop = 0; loop < MAXTAGLOOP; loop++) {
   for (loop = 0; loop < MAXTAGLOOP; loop++) {
     const TValue *tm;
     const TValue *tm;
@@ -116,24 +117,30 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
       if (!ttisnil(res) ||  /* result is no nil? */
       if (!ttisnil(res) ||  /* result is no nil? */
           (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
           (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
         setobj2s(L, val, res);
         setobj2s(L, val, res);
-        return;
+        return L->base;
       }
       }
       /* else will try the tag method */
       /* else will try the tag method */
     }
     }
-    else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
+    else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) {
+      if (pc) L->ci->u.l.savedpc = pc;
       luaG_typeerror(L, t, "index");
       luaG_typeerror(L, t, "index");
+    }
     if (ttisfunction(tm)) {
     if (ttisfunction(tm)) {
+      if (pc) L->ci->u.l.savedpc = pc;
       prepTMcall(L, tm, t, key);
       prepTMcall(L, tm, t, key);
       callTMres(L, val);
       callTMres(L, val);
-      return;
+      return L->base;
     }
     }
     t = tm;  /* else repeat with `tm' */ 
     t = tm;  /* else repeat with `tm' */ 
   }
   }
+  if (pc) L->ci->u.l.savedpc = pc;
   luaG_runerror(L, "loop in gettable");
   luaG_runerror(L, "loop in gettable");
+  return NULL;  /* to avoid warnings */
 }
 }
 
 
 
 
-void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
+StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val,
+                     const Instruction *pc) {
   int loop;
   int loop;
   for (loop = 0; loop < MAXTAGLOOP; loop++) {
   for (loop = 0; loop < MAXTAGLOOP; loop++) {
     const TValue *tm;
     const TValue *tm;
@@ -144,21 +151,26 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
           (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
           (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
         setobj2t(L, oldval, val);
         setobj2t(L, oldval, val);
         luaC_barrier(L, h, val);
         luaC_barrier(L, h, val);
-        return;
+        return L->base;
       }
       }
       /* else will try the tag method */
       /* else will try the tag method */
     }
     }
-    else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
+    else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) {
+      if (pc) L->ci->u.l.savedpc = pc;
       luaG_typeerror(L, t, "index");
       luaG_typeerror(L, t, "index");
+    }
     if (ttisfunction(tm)) {
     if (ttisfunction(tm)) {
+      if (pc) L->ci->u.l.savedpc = pc;
       prepTMcall(L, tm, t, key);
       prepTMcall(L, tm, t, key);
       setobj2s(L, L->top+3, val);  /* 3th argument */
       setobj2s(L, L->top+3, val);  /* 3th argument */
       callTM(L);
       callTM(L);
-      return;
+      return L->base;
     }
     }
     t = tm;  /* else repeat with `tm' */ 
     t = tm;  /* else repeat with `tm' */ 
   }
   }
+  if (pc) L->ci->u.l.savedpc = pc;
   luaG_runerror(L, "loop in settable");
   luaG_runerror(L, "loop in settable");
+  return NULL;  /* to avoid warnings */
 }
 }
 
 
 
 
@@ -427,22 +439,16 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
       case OP_GETGLOBAL: {
       case OP_GETGLOBAL: {
         TValue *rb = KBx(i);
         TValue *rb = KBx(i);
         lua_assert(ttisstring(rb) && ttistable(&cl->g));
         lua_assert(ttisstring(rb) && ttistable(&cl->g));
-        L->ci->u.l.savedpc = pc;
-        luaV_gettable(L, &cl->g, rb, ra);  /***/
-        base = L->base;
+        base = luaV_gettable(L, &cl->g, rb, ra, pc);  /***/
         break;
         break;
       }
       }
       case OP_GETTABLE: {
       case OP_GETTABLE: {
-        L->ci->u.l.savedpc = pc;
-        luaV_gettable(L, RB(i), RKC(i), ra);  /***/
-        base = L->base;
+        base = luaV_gettable(L, RB(i), RKC(i), ra, pc);  /***/
         break;
         break;
       }
       }
       case OP_SETGLOBAL: {
       case OP_SETGLOBAL: {
         lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g));
         lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g));
-        L->ci->u.l.savedpc = pc;
-        luaV_settable(L, &cl->g, KBx(i), ra);  /***/
-        base = L->base;
+        base = luaV_settable(L, &cl->g, KBx(i), ra, pc);  /***/
         break;
         break;
       }
       }
       case OP_SETUPVAL: {
       case OP_SETUPVAL: {
@@ -452,9 +458,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         break;
         break;
       }
       }
       case OP_SETTABLE: {
       case OP_SETTABLE: {
-        L->ci->u.l.savedpc = pc;
-        luaV_settable(L, ra, RKB(i), RKC(i));  /***/
-        base = L->base;
+        base = luaV_settable(L, ra, RKB(i), RKC(i), pc);  /***/
         break;
         break;
       }
       }
       case OP_NEWTABLE: {
       case OP_NEWTABLE: {
@@ -469,9 +473,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
       case OP_SELF: {
       case OP_SELF: {
         StkId rb = RB(i);
         StkId rb = RB(i);
         setobjs2s(L, ra+1, rb);
         setobjs2s(L, ra+1, rb);
-        L->ci->u.l.savedpc = pc;
-        luaV_gettable(L, rb, RKC(i), ra);  /***/
-        base = L->base;
+        base = luaV_gettable(L, rb, RKC(i), ra, pc);  /***/
         break;
         break;
       }
       }
       case OP_ADD: {
       case OP_ADD: {
@@ -582,43 +584,59 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         }
         }
         break;
         break;
       }
       }
-      case OP_CALL:
-      case OP_TAILCALL: {  /***/
-        StkId firstResult;
+      case OP_CALL: {  /***/
+        int pcr;
         int b = GETARG_B(i);
         int b = GETARG_B(i);
+        int nresults = GETARG_C(i) - 1;
         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
         L->ci->u.l.savedpc = pc;
         L->ci->u.l.savedpc = pc;
-        firstResult = luaD_precall(L, ra);
-        if (firstResult) {
-          int nresults = GETARG_C(i) - 1;
-          if (firstResult > L->top) {  /* yield? */
-            (L->ci - 1)->u.l.savedpc = pc;
-            return NULL;
-          }
+        pcr = luaD_precall(L, ra, nresults);
+        if (pcr == PCRLUA) {
+          nexeccalls++;
+          goto callentry;  /* restart luaV_execute over new Lua function */
+        }
+        else if (pcr == PCRC) {
           /* it was a C function (`precall' called it); adjust results */
           /* it was a C function (`precall' called it); adjust results */
-          luaD_poscall(L, nresults, firstResult);
           if (nresults >= 0) L->top = L->ci->top;
           if (nresults >= 0) L->top = L->ci->top;
+          base = L->base;
+          break;
         }
         }
-        else {  /* it is a Lua function */
-          if (GET_OPCODE(i) == OP_CALL)  /* regular call? */
-            nexeccalls++;
-          else {  /* tail call: put new frame in place of previous one */
-            int aux;
-            base = (L->ci - 1)->base;  /* `luaD_precall' may change the stack */
-            ra = RA(i);
-            if (L->openupval) luaF_close(L, base);
-            for (aux = 0; ra+aux < L->top; aux++)  /* move frame down */
-              setobjs2s(L, base+aux-1, ra+aux);
-            (L->ci - 1)->top = L->top = base+aux;  /* correct top */
-            (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;
-            (L->ci - 1)->u.l.tailcalls++;  /* one more call lost */
-            L->ci--;  /* remove new frame */
-            L->base = L->ci->base;
-          }
+        else {
+          lua_assert(pcr == PCRYIELD);
+          return NULL;
+        }
+      }
+      case OP_TAILCALL: {  /***/
+        int pcr;
+        int b = GETARG_B(i);
+        if (b != 0) L->top = ra+b;  /* else previous instruction set top */
+        L->ci->u.l.savedpc = pc;
+        lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
+        pcr = luaD_precall(L, ra, LUA_MULTRET);
+        if (pcr == PCRLUA) {
+          /* tail call: put new frame in place of previous one */
+          int aux;
+          base = (L->ci - 1)->base;  /* `luaD_precall' may change the stack */
+          ra = RA(i);
+          if (L->openupval) luaF_close(L, base);
+          for (aux = 0; ra+aux < L->top; aux++)  /* move frame down */
+            setobjs2s(L, base+aux-1, ra+aux);
+          (L->ci - 1)->top = L->top = base+aux;  /* correct top */
+          (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;
+          (L->ci - 1)->u.l.tailcalls++;  /* one more call lost */
+          L->ci--;  /* remove new frame */
+          L->base = L->ci->base;
           goto callentry;
           goto callentry;
         }
         }
-        base = L->base;
-        break;
+        else if (pcr == PCRC) {
+          /* it was a C function (`precall' called it) */
+          base = L->base;
+          break;
+        }
+        else {
+          lua_assert(pcr == PCRYIELD);
+          return NULL;
+        }
       }
       }
       case OP_RETURN: {
       case OP_RETURN: {
         CallInfo *ci = L->ci - 1;  /* previous function frame */
         CallInfo *ci = L->ci - 1;  /* previous function frame */
@@ -629,10 +647,9 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         if (--nexeccalls == 0)  /* was previous function running `here'? */
         if (--nexeccalls == 0)  /* was previous function running `here'? */
           return ra;  /* no: return */
           return ra;  /* no: return */
         else {  /* yes: continue its execution */
         else {  /* yes: continue its execution */
-          int nresults;
+          int nresults = (ci+1)->nresults;
           lua_assert(isLua(ci));
           lua_assert(isLua(ci));
           lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);
           lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);
-          nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1;
           luaD_poscall(L, nresults, ra);
           luaD_poscall(L, nresults, ra);
           if (nresults >= 0) L->top = L->ci->top;
           if (nresults >= 0) L->top = L->ci->top;
           goto retentry;
           goto retentry;

+ 5 - 3
lvm.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lvm.h,v 1.49 2003/07/16 20:49:02 roberto Exp roberto $
+** $Id: lvm.h,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $
 ** Lua virtual machine
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -26,8 +26,10 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
 int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
 int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
 const TValue *luaV_tonumber (const TValue *obj, TValue *n);
 const TValue *luaV_tonumber (const TValue *obj, TValue *n);
 int luaV_tostring (lua_State *L, StkId obj);
 int luaV_tostring (lua_State *L, StkId obj);
-void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val);
-void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val);
+StkId luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val,
+                     const Instruction *pc);
+StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val,
+                     const Instruction *pc);
 StkId luaV_execute (lua_State *L, int nexeccalls);
 StkId luaV_execute (lua_State *L, int nexeccalls);
 void luaV_concat (lua_State *L, int total, int last);
 void luaV_concat (lua_State *L, int total, int last);