diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-05-14 16:25:09 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-05-14 16:25:09 -0300 |
| commit | 0bda88e6cd960d3b1ad1d46826bfdef179098d2a (patch) | |
| tree | d3b237faef502dba76747a5563be9ccc4c404754 /ldo.c | |
| parent | 7966a4acaea50230e30acc8fd6997bce22307f24 (diff) | |
| download | lua-0bda88e6cd960d3b1ad1d46826bfdef179098d2a.tar.gz lua-0bda88e6cd960d3b1ad1d46826bfdef179098d2a.tar.bz2 lua-0bda88e6cd960d3b1ad1d46826bfdef179098d2a.zip | |
small steps towards yields in iterators and tag methods
Diffstat (limited to 'ldo.c')
| -rw-r--r-- | ldo.c | 30 |
1 files changed, 18 insertions, 12 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 2.3 2004/04/30 20:13:38 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.4 2004/05/10 17:50:51 roberto Exp roberto $ |
| 3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -219,7 +219,7 @@ static StkId tryfuncTM (lua_State *L, StkId func) { | |||
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | 221 | ||
| 222 | StkId luaD_precall (lua_State *L, StkId func) { | 222 | int luaD_precall (lua_State *L, StkId func, int nresults) { |
| 223 | LClosure *cl; | 223 | LClosure *cl; |
| 224 | ptrdiff_t funcr = savestack(L, func); | 224 | ptrdiff_t funcr = savestack(L, func); |
| 225 | if (!ttisfunction(func)) /* `func' is not a function? */ | 225 | if (!ttisfunction(func)) /* `func' is not a function? */ |
| @@ -239,10 +239,11 @@ StkId luaD_precall (lua_State *L, StkId func) { | |||
| 239 | ci->top = L->base + p->maxstacksize; | 239 | ci->top = L->base + p->maxstacksize; |
| 240 | ci->u.l.savedpc = p->code; /* starting point */ | 240 | ci->u.l.savedpc = p->code; /* starting point */ |
| 241 | ci->u.l.tailcalls = 0; | 241 | ci->u.l.tailcalls = 0; |
| 242 | ci->nresults = nresults; | ||
| 242 | for (st = L->top; st < ci->top; st++) | 243 | for (st = L->top; st < ci->top; st++) |
| 243 | setnilvalue(st); | 244 | setnilvalue(st); |
| 244 | L->top = ci->top; | 245 | L->top = ci->top; |
| 245 | return NULL; | 246 | return PCRLUA; |
| 246 | } | 247 | } |
| 247 | else { /* if is a C function, call it */ | 248 | else { /* if is a C function, call it */ |
| 248 | CallInfo *ci; | 249 | CallInfo *ci; |
| @@ -256,7 +257,14 @@ StkId luaD_precall (lua_State *L, StkId func) { | |||
| 256 | lua_unlock(L); | 257 | lua_unlock(L); |
| 257 | n = (*curr_func(L)->c.f)(L); /* do the actual call */ | 258 | n = (*curr_func(L)->c.f)(L); /* do the actual call */ |
| 258 | lua_lock(L); | 259 | lua_lock(L); |
| 259 | return L->top - n; | 260 | if (n >= 0) { /* no yielding? */ |
| 261 | luaD_poscall(L, nresults, L->top - n); | ||
| 262 | return PCRC; | ||
| 263 | } | ||
| 264 | else { | ||
| 265 | ci->nresults = nresults; | ||
| 266 | return PCRYIELD; | ||
| 267 | } | ||
| 260 | } | 268 | } |
| 261 | } | 269 | } |
| 262 | 270 | ||
| @@ -297,17 +305,16 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { | |||
| 297 | ** function position. | 305 | ** function position. |
| 298 | */ | 306 | */ |
| 299 | void luaD_call (lua_State *L, StkId func, int nResults) { | 307 | void luaD_call (lua_State *L, StkId func, int nResults) { |
| 300 | StkId firstResult; | ||
| 301 | if (++L->nCcalls >= LUA_MAXCCALLS) { | 308 | if (++L->nCcalls >= LUA_MAXCCALLS) { |
| 302 | if (L->nCcalls == LUA_MAXCCALLS) | 309 | if (L->nCcalls == LUA_MAXCCALLS) |
| 303 | luaG_runerror(L, "C stack overflow"); | 310 | luaG_runerror(L, "C stack overflow"); |
| 304 | else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3))) | 311 | else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3))) |
| 305 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ | 312 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ |
| 306 | } | 313 | } |
| 307 | firstResult = luaD_precall(L, func); | 314 | if (luaD_precall(L, func, nResults) == PCRLUA) { /* is a Lua function? */ |
| 308 | if (firstResult == NULL) /* is a Lua function? */ | 315 | StkId firstResult = luaV_execute(L, 1); /* call it */ |
| 309 | firstResult = luaV_execute(L, 1); /* call it */ | 316 | luaD_poscall(L, nResults, firstResult); |
| 310 | luaD_poscall(L, nResults, firstResult); | 317 | } |
| 311 | L->nCcalls--; | 318 | L->nCcalls--; |
| 312 | luaC_checkGC(L); | 319 | luaC_checkGC(L); |
| 313 | } | 320 | } |
| @@ -319,15 +326,14 @@ static void resume (lua_State *L, void *ud) { | |||
| 319 | CallInfo *ci = L->ci; | 326 | CallInfo *ci = L->ci; |
| 320 | if (!L->isSuspended) { | 327 | if (!L->isSuspended) { |
| 321 | lua_assert(ci == L->base_ci && nargs < L->top - L->base); | 328 | lua_assert(ci == L->base_ci && nargs < L->top - L->base); |
| 322 | luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */ | 329 | luaD_precall(L, L->top - (nargs + 1), LUA_MULTRET); /* start coroutine */ |
| 323 | } | 330 | } |
| 324 | else { /* resuming from previous yield */ | 331 | else { /* resuming from previous yield */ |
| 325 | if (!f_isLua(ci)) { /* `common' yield? */ | 332 | if (!f_isLua(ci)) { /* `common' yield? */ |
| 326 | /* finish interrupted execution of `OP_CALL' */ | 333 | /* finish interrupted execution of `OP_CALL' */ |
| 327 | int nresults; | 334 | int nresults = ci->nresults; |
| 328 | lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL || | 335 | lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL || |
| 329 | GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL); | 336 | GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL); |
| 330 | nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1; | ||
| 331 | luaD_poscall(L, nresults, L->top - nargs); /* complete it */ | 337 | luaD_poscall(L, nresults, L->top - nargs); /* complete it */ |
| 332 | if (nresults >= 0) L->top = L->ci->top; | 338 | if (nresults >= 0) L->top = L->ci->top; |
| 333 | } /* else yielded inside a hook: just continue its execution */ | 339 | } /* else yielded inside a hook: just continue its execution */ |
