aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-03-23 11:26:12 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-03-23 11:26:12 -0300
commit6d0ae11c576106b490a53215c3f227b65ace2776 (patch)
treefcb09763cf7f81036ed277e65dc5c967d77deef4
parent3ca739b418243544ecc1098e34c71f2378bad915 (diff)
downloadlua-6d0ae11c576106b490a53215c3f227b65ace2776.tar.gz
lua-6d0ae11c576106b490a53215c3f227b65ace2776.tar.bz2
lua-6d0ae11c576106b490a53215c3f227b65ace2776.zip
'context' added to suspendable calls
-rw-r--r--lapi.c23
-rw-r--r--lbaselib.c4
-rw-r--r--ldo.c7
-rw-r--r--lstate.h6
-rw-r--r--ltablib.c12
-rw-r--r--lua.h11
6 files changed, 39 insertions, 24 deletions
diff --git a/lapi.c b/lapi.c
index 60dc19f5..eb4fe4f3 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.70 2009/02/19 17:15:13 roberto Exp roberto $ 2** $Id: lapi.c,v 2.71 2009/03/10 17:14:37 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -761,17 +761,28 @@ LUA_API int lua_setfenv (lua_State *L, int idx) {
761 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) 761 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
762 762
763 763
764LUA_API void lua_callcont (lua_State *L, int nargs, int nresults, 764LUA_API int lua_getctx (lua_State *L, int *ctx) {
765 lua_CFunction cont) { 765 if (L->ci->callstatus & CIST_CTX) { /* call has ctx? */
766 *ctx = L->ci->u.c.ctx;
767 return LUA_YIELD;
768 }
769 else return LUA_OK;
770}
771
772
773LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
774 lua_CFunction k) {
766 StkId func; 775 StkId func;
767 lua_lock(L); 776 lua_lock(L);
768 /* cannot use continuations inside hooks */ 777 /* cannot use continuations inside hooks */
769 api_check(L, cont == NULL || !isLua(L->ci)); 778 api_check(L, k == NULL || !isLua(L->ci));
770 api_checknelems(L, nargs+1); 779 api_checknelems(L, nargs+1);
771 checkresults(L, nargs, nresults); 780 checkresults(L, nargs, nresults);
772 func = L->top - (nargs+1); 781 func = L->top - (nargs+1);
773 if (cont) { 782 if (k != NULL) {
774 L->ci->u.c.cont = cont; 783 L->ci->u.c.k = k;
784 L->ci->u.c.ctx = ctx;
785 L->ci->callstatus |= CIST_CTX;
775 luaD_call(L, func, nresults, 1); 786 luaD_call(L, func, nresults, 1);
776 } 787 }
777 else 788 else
diff --git a/lbaselib.c b/lbaselib.c
index f82ac840..fcd6d4a9 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.212 2009/03/13 15:50:03 roberto Exp roberto $ 2** $Id: lbaselib.c,v 1.213 2009/03/16 16:30:50 roberto Exp roberto $
3** Basic library 3** Basic library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -358,7 +358,7 @@ static int luaB_dofile (lua_State *L) {
358 const char *fname = luaL_optstring(L, 1, NULL); 358 const char *fname = luaL_optstring(L, 1, NULL);
359 lua_settop(L, 1); 359 lua_settop(L, 1);
360 if (luaL_loadfile(L, fname) != LUA_OK) lua_error(L); 360 if (luaL_loadfile(L, fname) != LUA_OK) lua_error(L);
361 lua_callcont(L, 0, LUA_MULTRET, dofilecont); 361 lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
362 return dofilecont(L); 362 return dofilecont(L);
363} 363}
364 364
diff --git a/ldo.c b/ldo.c
index bf21e609..b89a2919 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.54 2009/03/04 13:32:29 roberto Exp roberto $ 2** $Id: ldo.c,v 2.55 2009/03/10 17:14:37 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*/
@@ -385,7 +385,7 @@ void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
385 385
386static void finishCcall (lua_State *L) { 386static void finishCcall (lua_State *L) {
387 int n; 387 int n;
388 lua_assert(L->ci->u.c.cont != NULL); /* must have a continuation */ 388 lua_assert(L->ci->u.c.k != NULL); /* must have a continuation */
389 lua_assert(L->nny == 0); 389 lua_assert(L->nny == 0);
390 /* finish 'luaD_call' */ 390 /* finish 'luaD_call' */
391 G(L)->nCcalls--; 391 G(L)->nCcalls--;
@@ -393,7 +393,7 @@ static void finishCcall (lua_State *L) {
393 adjustresults(L, (L->ci + 1)->nresults); 393 adjustresults(L, (L->ci + 1)->nresults);
394 /* call continuation function */ 394 /* call continuation function */
395 lua_unlock(L); 395 lua_unlock(L);
396 n = (*L->ci->u.c.cont)(L); 396 n = (*L->ci->u.c.k)(L);
397 lua_lock(L); 397 lua_lock(L);
398 /* finish 'luaD_precall' */ 398 /* finish 'luaD_precall' */
399 luaD_poscall(L, L->top - n); 399 luaD_poscall(L, L->top - n);
@@ -477,7 +477,6 @@ LUA_API int lua_resume (lua_State *L, int nargs) {
477 return status; 477 return status;
478} 478}
479 479
480
481LUA_API int lua_yield (lua_State *L, int nresults) { 480LUA_API int lua_yield (lua_State *L, int nresults) {
482 luai_userstateyield(L, nresults); 481 luai_userstateyield(L, nresults);
483 lua_lock(L); 482 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 @@
1/* 1/*
2** $Id: lstate.h,v 2.38 2009/03/04 13:32:29 roberto Exp roberto $ 2** $Id: lstate.h,v 2.39 2009/03/10 17:14:37 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -88,7 +88,8 @@ typedef struct CallInfo {
88 int tailcalls; /* number of tail calls lost under this entry */ 88 int tailcalls; /* number of tail calls lost under this entry */
89 } l; 89 } l;
90 struct { /* only for C functions */ 90 struct { /* only for C functions */
91 lua_CFunction cont; /* continuation in case of yields */ 91 int ctx; /* context info. in case of yields */
92 lua_CFunction k; /* continuation in case of yields */
92 } c; 93 } c;
93 } u; 94 } u;
94} CallInfo; 95} CallInfo;
@@ -101,6 +102,7 @@ typedef struct CallInfo {
101#define CIST_HOOKED 2 /* call is running a debug hook */ 102#define CIST_HOOKED 2 /* call is running a debug hook */
102#define CIST_REENTRY 4 /* call is running on same invocation of 103#define CIST_REENTRY 4 /* call is running on same invocation of
103 luaV_execute of previous call */ 104 luaV_execute of previous call */
105#define CIST_CTX 8 /* call has a ctx value */
104 106
105 107
106#define curr_func(L) (clvalue(L->ci->func)) 108#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 @@
1/* 1/*
2** $Id: ltablib.c,v 1.44 2008/04/07 18:43:00 roberto Exp roberto $ 2** $Id: ltablib.c,v 1.45 2009/03/10 17:14:37 roberto Exp roberto $
3** Library for Table Manipulation 3** Library for Table Manipulation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -20,14 +20,16 @@
20 20
21 21
22static int foreachi (lua_State *L) { 22static int foreachi (lua_State *L) {
23 int i;
24 int n = aux_getn(L, 1); 23 int n = aux_getn(L, 1);
24 int i;
25 if (lua_getctx(L, &i) == LUA_YIELD) goto poscall;
25 luaL_checktype(L, 2, LUA_TFUNCTION); 26 luaL_checktype(L, 2, LUA_TFUNCTION);
26 for (i=1; i <= n; i++) { 27 for (i = 1; i <= n; i++) {
27 lua_pushvalue(L, 2); /* function */ 28 lua_pushvalue(L, 2); /* function */
28 lua_pushinteger(L, i); /* 1st argument */ 29 lua_pushinteger(L, i); /* 1st argument */
29 lua_rawgeti(L, 1, i); /* 2nd argument */ 30 lua_rawgeti(L, 1, i); /* 2nd argument */
30 lua_call(L, 2, 1); 31 lua_callk(L, 2, 1, i, foreachi);
32 poscall:
31 if (!lua_isnil(L, -1)) 33 if (!lua_isnil(L, -1))
32 return 1; 34 return 1;
33 lua_pop(L, 1); /* remove nil result */ 35 lua_pop(L, 1); /* remove nil result */
@@ -46,7 +48,7 @@ static int foreachcont (lua_State *L) {
46 lua_pushvalue(L, 2); /* function */ 48 lua_pushvalue(L, 2); /* function */
47 lua_pushvalue(L, -3); /* key */ 49 lua_pushvalue(L, -3); /* key */
48 lua_pushvalue(L, -3); /* value */ 50 lua_pushvalue(L, -3); /* value */
49 lua_callcont(L, 2, 1, &foreachcont); 51 lua_callk(L, 2, 1, 0, foreachcont);
50 } 52 }
51} 53}
52 54
diff --git a/lua.h b/lua.h
index 13d067a5..e9d0785b 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.h,v 1.232 2009/02/18 17:20:56 roberto Exp roberto $ 2** $Id: lua.h,v 1.233 2009/03/10 17:14:37 roberto Exp roberto $
3** Lua - An Extensible Extension Language 3** Lua - An Extensible Extension Language
4** Lua.org, PUC-Rio, Brazil (http://www.lua.org) 4** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
5** See Copyright Notice at the end of this file 5** See Copyright Notice at the end of this file
@@ -203,8 +203,11 @@ LUA_API int (lua_setfenv) (lua_State *L, int idx);
203/* 203/*
204** 'load' and 'call' functions (load and run Lua code) 204** 'load' and 'call' functions (load and run Lua code)
205*/ 205*/
206LUA_API void (lua_callcont) (lua_State *L, int nargs, int nresults, 206LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, int ctx,
207 lua_CFunction cont); 207 lua_CFunction k);
208#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL)
209
210LUA_API int (lua_getctx) (lua_State *L, int *ctx);
208 211
209LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); 212LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
210LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); 213LUA_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);
283 286
284#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) 287#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
285 288
286#define lua_call(L,n,r) lua_callcont(L, (n), (r), NULL);
287
288 289
289 290
290/* 291/*