diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-18 13:24:11 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-18 13:24:11 -0200 |
| commit | 9bab2cf55d9b151d730c1461e3882a5fbc7d790d (patch) | |
| tree | c264480215e163b96fe1d44d874648ee39cc3cfa /ldo.c | |
| parent | c4ae00a3d107a27d80bd157a135ef115104f98f0 (diff) | |
| download | lua-9bab2cf55d9b151d730c1461e3882a5fbc7d790d.tar.gz lua-9bab2cf55d9b151d730c1461e3882a5fbc7d790d.tar.bz2 lua-9bab2cf55d9b151d730c1461e3882a5fbc7d790d.zip | |
support for yield inside hooks
Diffstat (limited to 'ldo.c')
| -rw-r--r-- | ldo.c | 44 |
1 files changed, 26 insertions, 18 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 1.201 2002/11/14 16:15:53 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.202 2002/11/18 11:01:55 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 | */ |
| @@ -308,15 +308,20 @@ static void resume (lua_State *L, void *ud) { | |||
| 308 | luaG_runerror(L, "cannot resume dead coroutine"); | 308 | luaG_runerror(L, "cannot resume dead coroutine"); |
| 309 | luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */ | 309 | luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */ |
| 310 | } | 310 | } |
| 311 | else if (ci->state && CI_YIELD) { /* inside a yield? */ | 311 | else if (ci->state & CI_YIELD) { /* inside a yield? */ |
| 312 | /* finish interrupted execution of `OP_CALL' */ | 312 | if (ci->state & CI_C) { /* `common' yield? */ |
| 313 | int nresults; | 313 | /* finish interrupted execution of `OP_CALL' */ |
| 314 | lua_assert((ci-1)->state & CI_SAVEDPC); | 314 | int nresults; |
| 315 | lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL || | 315 | lua_assert((ci-1)->state & CI_SAVEDPC); |
| 316 | GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL); | 316 | lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL || |
| 317 | nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1; | 317 | GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL); |
| 318 | luaD_poscall(L, nresults, L->top - nargs); /* complete it */ | 318 | nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1; |
| 319 | if (nresults >= 0) L->top = L->ci->top; | 319 | luaD_poscall(L, nresults, L->top - nargs); /* complete it */ |
| 320 | if (nresults >= 0) L->top = L->ci->top; | ||
| 321 | } | ||
| 322 | else { /* yielded inside a hook: just continue its execution */ | ||
| 323 | ci->state &= ~CI_YIELD; | ||
| 324 | } | ||
| 320 | } | 325 | } |
| 321 | else | 326 | else |
| 322 | luaG_runerror(L, "cannot resume non-suspended coroutine"); | 327 | luaG_runerror(L, "cannot resume non-suspended coroutine"); |
| @@ -349,15 +354,18 @@ LUA_API int lua_yield (lua_State *L, int nresults) { | |||
| 349 | CallInfo *ci; | 354 | CallInfo *ci; |
| 350 | lua_lock(L); | 355 | lua_lock(L); |
| 351 | ci = L->ci; | 356 | ci = L->ci; |
| 352 | if ((ci-1)->state & CI_C) | 357 | if (ci->state & CI_C) { /* usual yield */ |
| 353 | luaG_runerror(L, "cannot yield a C function"); | 358 | if ((ci-1)->state & CI_C) |
| 354 | lua_assert(ci->state & CI_C); /* current function is not Lua */ | 359 | luaG_runerror(L, "cannot yield a C function"); |
| 355 | if (L->top - nresults > ci->base) { /* is there garbage in the stack? */ | 360 | if (L->top - nresults > ci->base) { /* is there garbage in the stack? */ |
| 356 | int i; | 361 | int i; |
| 357 | for (i=0; i<nresults; i++) /* move down results */ | 362 | for (i=0; i<nresults; i++) /* move down results */ |
| 358 | setobjs2s(ci->base + i, L->top - nresults + i); | 363 | setobjs2s(ci->base + i, L->top - nresults + i); |
| 359 | L->top = ci->base + nresults; | 364 | L->top = ci->base + nresults; |
| 365 | } | ||
| 360 | } | 366 | } |
| 367 | /* else it's an yield inside a hook: nothing to do */ | ||
| 368 | ci->state |= CI_YIELD; | ||
| 361 | lua_unlock(L); | 369 | lua_unlock(L); |
| 362 | return -1; | 370 | return -1; |
| 363 | } | 371 | } |
