diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-09-05 11:30:59 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-09-05 11:30:59 -0300 |
| commit | 6063c5c61f55d15ea4abb1eed05f597deaf4a9c3 (patch) | |
| tree | c5e3ef72d57573098f3f83d153d4e45f79ff6d25 | |
| parent | 2a70107581378fd43a6d4382963d5f7c4d5a3c53 (diff) | |
| download | lua-6063c5c61f55d15ea4abb1eed05f597deaf4a9c3.tar.gz lua-6063c5c61f55d15ea4abb1eed05f597deaf4a9c3.tar.bz2 lua-6063c5c61f55d15ea4abb1eed05f597deaf4a9c3.zip | |
bug: cannot invalidate a running coroutine
| -rw-r--r-- | ldo.c | 30 |
1 files changed, 21 insertions, 9 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 1.223 2003/08/26 12:04:13 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.224 2003/08/27 21:01:44 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 | */ |
| @@ -331,13 +331,8 @@ static void resume (lua_State *L, void *ud) { | |||
| 331 | int nargs = *cast(int *, ud); | 331 | int nargs = *cast(int *, ud); |
| 332 | CallInfo *ci = L->ci; | 332 | CallInfo *ci = L->ci; |
| 333 | if (!L->isSuspended) { | 333 | if (!L->isSuspended) { |
| 334 | if (ci == L->base_ci) { /* no activation record? */ | 334 | lua_assert(ci == L->base_ci && nargs < L->top - L->base); |
| 335 | if (nargs >= L->top - L->base) | 335 | luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */ |
| 336 | luaG_runerror(L, "cannot resume dead coroutine"); | ||
| 337 | luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */ | ||
| 338 | } | ||
| 339 | else | ||
| 340 | luaG_runerror(L, "cannot resume non-suspended coroutine"); | ||
| 341 | } | 336 | } |
| 342 | else { /* resumming from previous yield */ | 337 | else { /* resumming from previous yield */ |
| 343 | if (!f_isLua(ci)) { /* `common' yield? */ | 338 | if (!f_isLua(ci)) { /* `common' yield? */ |
| @@ -357,12 +352,29 @@ static void resume (lua_State *L, void *ud) { | |||
| 357 | } | 352 | } |
| 358 | 353 | ||
| 359 | 354 | ||
| 355 | static int resume_error (lua_State *L, const char *msg) { | ||
| 356 | L->top = L->ci->base; | ||
| 357 | setsvalue2s(L->top, luaS_new(L, msg)); | ||
| 358 | incr_top(L); | ||
| 359 | lua_unlock(L); | ||
| 360 | return LUA_ERRRUN; | ||
| 361 | } | ||
| 362 | |||
| 363 | |||
| 360 | LUA_API int lua_resume (lua_State *L, int nargs) { | 364 | LUA_API int lua_resume (lua_State *L, int nargs) { |
| 361 | int status; | 365 | int status; |
| 362 | lu_byte old_allowhooks; | 366 | lu_byte old_allowhooks; |
| 363 | lua_lock(L); | 367 | lua_lock(L); |
| 364 | old_allowhooks = L->allowhook; | ||
| 365 | lua_assert(L->errfunc == 0 && L->nCcalls == 0); | 368 | lua_assert(L->errfunc == 0 && L->nCcalls == 0); |
| 369 | if (!L->isSuspended) { | ||
| 370 | if (L->ci == L->base_ci) { /* no activation record? */ | ||
| 371 | if (nargs >= L->top - L->base) | ||
| 372 | return resume_error(L, "cannot resume dead coroutine"); | ||
| 373 | } | ||
| 374 | else | ||
| 375 | return resume_error(L, "cannot resume non-suspended coroutine"); | ||
| 376 | } | ||
| 377 | old_allowhooks = L->allowhook; | ||
| 366 | status = luaD_rawrunprotected(L, resume, &nargs); | 378 | status = luaD_rawrunprotected(L, resume, &nargs); |
| 367 | if (status != 0) { /* error? */ | 379 | if (status != 0) { /* error? */ |
| 368 | L->ci = L->base_ci; /* go back to initial level */ | 380 | L->ci = L->base_ci; /* go back to initial level */ |
