From 0bda88e6cd960d3b1ad1d46826bfdef179098d2a Mon Sep 17 00:00:00 2001
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Fri, 14 May 2004 16:25:09 -0300
Subject: small steps towards yields in iterators and tag methods

---
 ldo.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

(limited to 'ldo.c')

diff --git a/ldo.c b/ldo.c
index f2682670..fc1caa7f 100644
--- a/ldo.c
+++ b/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
 ** 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;
   ptrdiff_t funcr = savestack(L, func);
   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->u.l.savedpc = p->code;  /* starting point */
     ci->u.l.tailcalls = 0;
+    ci->nresults = nresults;
     for (st = L->top; st < ci->top; st++)
       setnilvalue(st);
     L->top = ci->top;
-    return NULL;
+    return PCRLUA;
   }
   else {  /* if is a C function, call it */
     CallInfo *ci;
@@ -256,7 +257,14 @@ StkId luaD_precall (lua_State *L, StkId func) {
     lua_unlock(L);
     n = (*curr_func(L)->c.f)(L);  /* do the actual call */
     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.
 */ 
 void luaD_call (lua_State *L, StkId func, int nResults) {
-  StkId firstResult;
   if (++L->nCcalls >= LUA_MAXCCALLS) {
     if (L->nCcalls == LUA_MAXCCALLS)
       luaG_runerror(L, "C stack overflow");
     else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3)))
       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--;
   luaC_checkGC(L);
 }
@@ -319,15 +326,14 @@ static void resume (lua_State *L, void *ud) {
   CallInfo *ci = L->ci;
   if (!L->isSuspended) {
     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 */
     if (!f_isLua(ci)) {  /* `common' yield? */
       /* finish interrupted execution of `OP_CALL' */
-      int nresults;
+      int nresults = ci->nresults;
       lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL ||
                  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 */
       if (nresults >= 0) L->top = L->ci->top;
     }  /* else yielded inside a hook: just continue its execution */
-- 
cgit v1.2.3-55-g6feb