From 542b6cfc02d57e66db7afc23a1d8350ae189e3c6 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 10 Jun 2014 15:51:21 -0300 Subject: [PATCH] no need for field 'status' in structure 'CallInfo' (after removal of 'lua_getctx') + field 'old_allowhook' can be packed into a single bit --- lapi.c | 5 +++-- ldo.c | 41 +++++++++++++++++++++-------------------- lstate.h | 12 +++++------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/lapi.c b/lapi.c index 2b874530..36962cf3 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.214 2014/05/15 20:28:39 roberto Exp roberto $ +** $Id: lapi.c,v 2.215 2014/06/10 17:41:38 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -968,9 +968,10 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, ci->u.c.ctx = ctx; /* save context */ /* save information for error recovery */ ci->extra = savestack(L, c.func); - ci->u.c.old_allowhook = L->allowhook; ci->u.c.old_errfunc = L->errfunc; L->errfunc = func; + if (L->allowhook) + ci->callstatus |= CIST_OAH; /* save original value of 'allowhook' */ /* mark that function may do error recovery */ ci->callstatus |= CIST_YPCALL; luaD_call(L, c.func, nresults, 1); /* do the call */ diff --git a/ldo.c b/ldo.c index b41855c9..8adaefcd 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.117 2014/06/09 16:32:18 roberto Exp roberto $ +** $Id: ldo.c,v 2.118 2014/06/10 17:41:38 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -416,7 +416,7 @@ void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) { ** Completes the execution of an interrupted C function, calling its ** continuation function. */ -static void finishCcall (lua_State *L) { +static void finishCcall (lua_State *L, int status) { CallInfo *ci = L->ci; int n; lua_assert(ci->u.c.k != NULL); /* must have a continuation */ @@ -428,12 +428,9 @@ static void finishCcall (lua_State *L) { /* finish 'lua_callk'/'lua_pcall' */ adjustresults(L, ci->nresults); /* call continuation function */ - if (!(ci->callstatus & CIST_STAT)) /* no call status? */ - ci->u.c.status = LUA_YIELD; /* 'default' status */ - lua_assert(ci->u.c.status != LUA_OK); - ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED; + ci->callstatus = (ci->callstatus & ~CIST_YPCALL) | CIST_YIELDED; lua_unlock(L); - n = (*ci->u.c.k)(L, ci->u.c.status, ci->u.c.ctx); + n = (*ci->u.c.k)(L, status, ci->u.c.ctx); lua_lock(L); api_checknelems(L, n); /* finish 'luaD_precall' */ @@ -444,13 +441,18 @@ static void finishCcall (lua_State *L) { /* ** Executes "full continuation" (everything in the stack) of a ** previously interrupted coroutine until the stack is empty (or another -** interruption long-jumps out of the loop) +** interruption long-jumps out of the loop). If the coroutine is +** recovering from an error, 'ud' points to the error status, which must +** be passed to the first (only the first) continuation (otherwise the +** default status is LUA_YIELD). */ static void unroll (lua_State *L, void *ud) { - UNUSED(ud); + int status = (ud) ? *(int *)ud : LUA_YIELD; while (L->ci != &L->base_ci) { /* something in the stack */ - if (!isLua(L->ci)) /* C function? */ - finishCcall(L); /* complete its execution */ + if (!isLua(L->ci)) { /* C function? */ + finishCcall(L, status); /* complete its execution */ + status = LUA_YIELD; /* back to default status */ + } else { /* Lua function */ luaV_finishOp(L); /* finish interrupted instruction */ luaV_execute(L); /* execute down to higher C 'boundary' */ @@ -487,12 +489,10 @@ static int recover (lua_State *L, int status) { luaF_close(L, oldtop); seterrorobj(L, status, oldtop); L->ci = ci; - L->allowhook = ci->u.c.old_allowhook; + L->allowhook = (ci->callstatus & CIST_OAH); L->nny = 0; /* should be zero to be yieldable */ luaD_shrinkstack(L); L->errfunc = ci->u.c.old_errfunc; - ci->callstatus |= CIST_STAT; /* call has error status */ - ci->u.c.status = status; /* (here it is) */ return 1; /* continue running the coroutine */ } @@ -536,10 +536,9 @@ static void resume (lua_State *L, void *ud) { else { /* 'common' yield */ if (ci->u.c.k != NULL) { /* does it have a continuation? */ int n; - ci->u.c.status = LUA_YIELD; /* 'default' status */ ci->callstatus |= CIST_YIELDED; lua_unlock(L); - n = (*ci->u.c.k)(L, ci->u.c.status, ci->u.c.ctx); /* call continuation */ + n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ lua_lock(L); api_checknelems(L, n); firstArg = L->top - n; /* yield results come from continuation */ @@ -563,15 +562,17 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { status = luaD_rawrunprotected(L, resume, L->top - nargs); if (status == -1) /* error calling 'lua_resume'? */ status = LUA_ERRRUN; - else { /* yield or regular error */ + else { /* yield or error running coroutine */ while (status != LUA_OK && status != LUA_YIELD) { /* error? */ - if (recover(L, status)) /* recover point? */ - status = luaD_rawrunprotected(L, unroll, NULL); /* run continuation */ + if (recover(L, status)) { /* recover point? */ + /* unroll continuation */ + status = luaD_rawrunprotected(L, unroll, &status); + } else { /* unrecoverable error */ L->status = cast_byte(status); /* mark thread as `dead' */ seterrorobj(L, status, L->top); L->ci->top = L->top; - break; + break; /* stop running it */ } } lua_assert(status == L->status); diff --git a/lstate.h b/lstate.h index 67b43c29..bc9c454b 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.103 2014/05/15 20:41:27 roberto Exp roberto $ +** $Id: lstate.h,v 2.104 2014/06/10 17:41:38 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -60,9 +60,9 @@ typedef struct CallInfo { StkId func; /* function index in the stack */ StkId top; /* top for this function */ struct CallInfo *previous, *next; /* dynamic call link */ + ptrdiff_t extra; short nresults; /* expected number of results from this function */ lu_byte callstatus; - ptrdiff_t extra; union { struct { /* only for Lua functions */ StkId base; /* base for this function */ @@ -72,8 +72,6 @@ typedef struct CallInfo { lua_KFunction k; /* continuation in case of yields */ ptrdiff_t old_errfunc; int ctx; /* context info. in case of yields */ - lu_byte old_allowhook; - lu_byte status; } c; } u; } CallInfo; @@ -88,9 +86,9 @@ typedef struct CallInfo { luaV_execute of previous call */ #define CIST_YIELDED (1<<3) /* call reentered after suspension */ #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ -#define CIST_STAT (1<<5) /* call has an error status (pcall) */ -#define CIST_TAIL (1<<6) /* call was tail called */ -#define CIST_HOOKYIELD (1<<7) /* last hook called yielded */ +#define CIST_TAIL (1<<5) /* call was tail called */ +#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ +#define CIST_OAH (1<<7) /* original value of 'allowhook' */ #define isLua(ci) ((ci)->callstatus & CIST_LUA)