lua

A copy of the Lua development repository
Log | Files | Refs | README

commit 6063c5c61f55d15ea4abb1eed05f597deaf4a9c3
parent 2a70107581378fd43a6d4382963d5f7c4d5a3c53
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Fri,  5 Sep 2003 11:30:37 -0300

bug: cannot invalidate a running coroutine

Diffstat:
Mldo.c | 30+++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/ldo.c b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.223 2003/08/26 12:04:13 roberto Exp roberto $ +** $Id: ldo.c,v 1.224 2003/08/27 21:01:44 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -331,13 +331,8 @@ static void resume (lua_State *L, void *ud) { int nargs = *cast(int *, ud); CallInfo *ci = L->ci; if (!L->isSuspended) { - if (ci == L->base_ci) { /* no activation record? */ - if (nargs >= L->top - L->base) - luaG_runerror(L, "cannot resume dead coroutine"); - luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */ - } - else - luaG_runerror(L, "cannot resume non-suspended coroutine"); + lua_assert(ci == L->base_ci && nargs < L->top - L->base); + luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */ } else { /* resumming from previous yield */ if (!f_isLua(ci)) { /* `common' yield? */ @@ -357,12 +352,29 @@ static void resume (lua_State *L, void *ud) { } +static int resume_error (lua_State *L, const char *msg) { + L->top = L->ci->base; + setsvalue2s(L->top, luaS_new(L, msg)); + incr_top(L); + lua_unlock(L); + return LUA_ERRRUN; +} + + LUA_API int lua_resume (lua_State *L, int nargs) { int status; lu_byte old_allowhooks; lua_lock(L); - old_allowhooks = L->allowhook; lua_assert(L->errfunc == 0 && L->nCcalls == 0); + if (!L->isSuspended) { + if (L->ci == L->base_ci) { /* no activation record? */ + if (nargs >= L->top - L->base) + return resume_error(L, "cannot resume dead coroutine"); + } + else + return resume_error(L, "cannot resume non-suspended coroutine"); + } + old_allowhooks = L->allowhook; status = luaD_rawrunprotected(L, resume, &nargs); if (status != 0) { /* error? */ L->ci = L->base_ci; /* go back to initial level */