diff --git a/lapi.c b/lapi.c index 60dc19f5..eb4fe4f3 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.70 2009/02/19 17:15:13 roberto Exp roberto $ +** $Id: lapi.c,v 2.71 2009/03/10 17:14:37 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -761,17 +761,28 @@ LUA_API int lua_setfenv (lua_State *L, int idx) { api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) -LUA_API void lua_callcont (lua_State *L, int nargs, int nresults, - lua_CFunction cont) { +LUA_API int lua_getctx (lua_State *L, int *ctx) { + if (L->ci->callstatus & CIST_CTX) { /* call has ctx? */ + *ctx = L->ci->u.c.ctx; + return LUA_YIELD; + } + else return LUA_OK; +} + + +LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx, + lua_CFunction k) { StkId func; lua_lock(L); /* cannot use continuations inside hooks */ - api_check(L, cont == NULL || !isLua(L->ci)); + api_check(L, k == NULL || !isLua(L->ci)); api_checknelems(L, nargs+1); checkresults(L, nargs, nresults); func = L->top - (nargs+1); - if (cont) { - L->ci->u.c.cont = cont; + if (k != NULL) { + L->ci->u.c.k = k; + L->ci->u.c.ctx = ctx; + L->ci->callstatus |= CIST_CTX; luaD_call(L, func, nresults, 1); } else diff --git a/lbaselib.c b/lbaselib.c index f82ac840..fcd6d4a9 100644 --- a/lbaselib.c +++ b/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.212 2009/03/13 15:50:03 roberto Exp roberto $ +** $Id: lbaselib.c,v 1.213 2009/03/16 16:30:50 roberto Exp roberto $ ** Basic library ** See Copyright Notice in lua.h */ @@ -358,7 +358,7 @@ static int luaB_dofile (lua_State *L) { const char *fname = luaL_optstring(L, 1, NULL); lua_settop(L, 1); if (luaL_loadfile(L, fname) != LUA_OK) lua_error(L); - lua_callcont(L, 0, LUA_MULTRET, dofilecont); + lua_callk(L, 0, LUA_MULTRET, 0, dofilecont); return dofilecont(L); } diff --git a/ldo.c b/ldo.c index bf21e609..b89a2919 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.54 2009/03/04 13:32:29 roberto Exp roberto $ +** $Id: ldo.c,v 2.55 2009/03/10 17:14:37 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -385,7 +385,7 @@ void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) { static void finishCcall (lua_State *L) { int n; - lua_assert(L->ci->u.c.cont != NULL); /* must have a continuation */ + lua_assert(L->ci->u.c.k != NULL); /* must have a continuation */ lua_assert(L->nny == 0); /* finish 'luaD_call' */ G(L)->nCcalls--; @@ -393,7 +393,7 @@ static void finishCcall (lua_State *L) { adjustresults(L, (L->ci + 1)->nresults); /* call continuation function */ lua_unlock(L); - n = (*L->ci->u.c.cont)(L); + n = (*L->ci->u.c.k)(L); lua_lock(L); /* finish 'luaD_precall' */ luaD_poscall(L, L->top - n); @@ -477,7 +477,6 @@ LUA_API int lua_resume (lua_State *L, int nargs) { return status; } - LUA_API int lua_yield (lua_State *L, int nresults) { luai_userstateyield(L, nresults); lua_lock(L); diff --git a/lstate.h b/lstate.h index f27631d0..2cbb95e5 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.38 2009/03/04 13:32:29 roberto Exp roberto $ +** $Id: lstate.h,v 2.39 2009/03/10 17:14:37 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -88,7 +88,8 @@ typedef struct CallInfo { int tailcalls; /* number of tail calls lost under this entry */ } l; struct { /* only for C functions */ - lua_CFunction cont; /* continuation in case of yields */ + int ctx; /* context info. in case of yields */ + lua_CFunction k; /* continuation in case of yields */ } c; } u; } CallInfo; @@ -101,6 +102,7 @@ typedef struct CallInfo { #define CIST_HOOKED 2 /* call is running a debug hook */ #define CIST_REENTRY 4 /* call is running on same invocation of luaV_execute of previous call */ +#define CIST_CTX 8 /* call has a ctx value */ #define curr_func(L) (clvalue(L->ci->func)) diff --git a/ltablib.c b/ltablib.c index 7296fb38..4ea5c2f9 100644 --- a/ltablib.c +++ b/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.44 2008/04/07 18:43:00 roberto Exp roberto $ +** $Id: ltablib.c,v 1.45 2009/03/10 17:14:37 roberto Exp roberto $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -20,14 +20,16 @@ static int foreachi (lua_State *L) { - int i; int n = aux_getn(L, 1); + int i; + if (lua_getctx(L, &i) == LUA_YIELD) goto poscall; luaL_checktype(L, 2, LUA_TFUNCTION); - for (i=1; i <= n; i++) { + for (i = 1; i <= n; i++) { lua_pushvalue(L, 2); /* function */ lua_pushinteger(L, i); /* 1st argument */ lua_rawgeti(L, 1, i); /* 2nd argument */ - lua_call(L, 2, 1); + lua_callk(L, 2, 1, i, foreachi); + poscall: if (!lua_isnil(L, -1)) return 1; lua_pop(L, 1); /* remove nil result */ @@ -46,7 +48,7 @@ static int foreachcont (lua_State *L) { lua_pushvalue(L, 2); /* function */ lua_pushvalue(L, -3); /* key */ lua_pushvalue(L, -3); /* value */ - lua_callcont(L, 2, 1, &foreachcont); + lua_callk(L, 2, 1, 0, foreachcont); } } diff --git a/lua.h b/lua.h index 13d067a5..e9d0785b 100644 --- a/lua.h +++ b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.232 2009/02/18 17:20:56 roberto Exp roberto $ +** $Id: lua.h,v 1.233 2009/03/10 17:14:37 roberto Exp roberto $ ** Lua - An Extensible Extension Language ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** See Copyright Notice at the end of this file @@ -203,8 +203,11 @@ LUA_API int (lua_setfenv) (lua_State *L, int idx); /* ** 'load' and 'call' functions (load and run Lua code) */ -LUA_API void (lua_callcont) (lua_State *L, int nargs, int nresults, - lua_CFunction cont); +LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, int ctx, + lua_CFunction k); +#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) + +LUA_API int (lua_getctx) (lua_State *L, int *ctx); LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); @@ -283,8 +286,6 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); #define lua_tostring(L,i) lua_tolstring(L, (i), NULL) -#define lua_call(L,n,r) lua_callcont(L, (n), (r), NULL); - /*