summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldo.c28
-rw-r--r--ltests.c14
-rw-r--r--lua.h6
3 files changed, 39 insertions, 9 deletions
diff --git a/ldo.c b/ldo.c
index e93f68e3..913375b0 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.65 2009/06/01 19:09:26 roberto Exp roberto $ 2** $Id: ldo.c,v 2.66 2009/07/15 17:26:14 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*/
@@ -418,6 +418,16 @@ static void resume (lua_State *L, void *ud) {
418 if (isLua(ci)) /* yielded inside a hook? */ 418 if (isLua(ci)) /* yielded inside a hook? */
419 luaV_execute(L); 419 luaV_execute(L);
420 else { /* 'common' yield */ 420 else { /* 'common' yield */
421 if (ci->u.c.k != NULL) { /* does it have a continuation? */
422 int n;
423 ci->u.c.status = LUA_YIELD; /* 'default' status */
424 ci->callstatus |= CIST_YIELDED;
425 ci->func = restorestack(L, ci->u.c.oldtop);
426 lua_unlock(L);
427 n = (*ci->u.c.k)(L); /* call continuation */
428 lua_lock(L);
429 firstArg = L->top - n;
430 }
421 G(L)->nCcalls--; /* finish 'luaD_call' */ 431 G(L)->nCcalls--; /* finish 'luaD_call' */
422 luaD_poscall(L, firstArg); /* finish 'luaD_precall' */ 432 luaD_poscall(L, firstArg); /* finish 'luaD_precall' */
423 } 433 }
@@ -499,17 +509,25 @@ LUA_API int lua_resume (lua_State *L, int nargs) {
499 return status; 509 return status;
500} 510}
501 511
502LUA_API int lua_yield (lua_State *L, int nresults) { 512LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) {
513 CallInfo *ci = L->ci;
503 luai_userstateyield(L, nresults); 514 luai_userstateyield(L, nresults);
504 lua_lock(L); 515 lua_lock(L);
505 if (L->nny > 0) 516 if (L->nny > 0)
506 luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); 517 luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
507 L->status = LUA_YIELD; 518 L->status = LUA_YIELD;
508 if (!isLua(L->ci)) { /* not inside a hook? */ 519 if (isLua(ci)) { /* inside a hook? */
509 L->ci->func = L->top - nresults - 1; /* protect stack slots below ??? */ 520 api_check(L, k == NULL, "hooks cannot continue after yielding");
521 }
522 else {
523 if ((ci->u.c.k = k) != NULL) { /* is there a continuation? */
524 ci->u.c.ctx = ctx; /* save context */
525 ci->u.c.oldtop = savestack(L, ci->func); /* save current 'func' */
526 }
527 ci->func = L->top - nresults - 1; /* protect stack slots below */
510 luaD_throw(L, LUA_YIELD); 528 luaD_throw(L, LUA_YIELD);
511 } 529 }
512 lua_assert(L->ci->callstatus & CIST_HOOKED); /* must be inside a hook */ 530 lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */
513 lua_unlock(L); 531 lua_unlock(L);
514 return 0; /* otherwise, return to 'luaD_callhook' */ 532 return 0; /* otherwise, return to 'luaD_callhook' */
515} 533}
diff --git a/ltests.c b/ltests.c
index b5b782f5..90050a75 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.69 2009/08/26 17:41:26 roberto Exp roberto $ 2** $Id: ltests.c,v 2.70 2009/09/09 20:44:10 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -836,6 +836,8 @@ static int getnum_aux (lua_State *L, const char **pc) {
836 sig = -1; 836 sig = -1;
837 (*pc)++; 837 (*pc)++;
838 } 838 }
839 if (!lisdigit(cast(unsigned char, **pc)))
840 luaL_error(L, "number expected (%s)", *pc);
839 while (lisdigit(cast(unsigned char, **pc))) res = res*10 + (*(*pc)++) - '0'; 841 while (lisdigit(cast(unsigned char, **pc))) res = res*10 + (*(*pc)++) - '0';
840 return sig*res; 842 return sig*res;
841} 843}
@@ -1033,6 +1035,11 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
1033 else if EQ("yield") { 1035 else if EQ("yield") {
1034 return lua_yield(L1, getnum); 1036 return lua_yield(L1, getnum);
1035 } 1037 }
1038 else if EQ("yieldk") {
1039 int nres = getnum;
1040 int i = getnum;
1041 return lua_yieldk(L1, nres, i, Cfunck);
1042 }
1036 else if EQ("loadstring") { 1043 else if EQ("loadstring") {
1037 size_t sl; 1044 size_t sl;
1038 const char *s = luaL_checklstring(L1, getnum, &sl); 1045 const char *s = luaL_checklstring(L1, getnum, &sl);
@@ -1056,9 +1063,12 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
1056 lua_pushinteger(L1, lua_objlen(L1, i)); 1063 lua_pushinteger(L1, lua_objlen(L1, i));
1057 } 1064 }
1058 else if EQ("getctx") { 1065 else if EQ("getctx") {
1066 static const char *const codes[] = {"OK", "YIELD", "ERRRUN",
1067 "ERRSYNTAX", "ERRMEM", "ERRGCMM", "ERRERR"};
1068
1059 int i = 0; 1069 int i = 0;
1060 int s = lua_getctx(L1, &i); 1070 int s = lua_getctx(L1, &i);
1061 lua_pushinteger(L1, s); 1071 lua_pushstring(L1, codes[s]);
1062 lua_pushinteger(L1, i); 1072 lua_pushinteger(L1, i);
1063 } 1073 }
1064 else if EQ("checkstack") { 1074 else if EQ("checkstack") {
diff --git a/lua.h b/lua.h
index 5887d16c..8e373b20 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.h,v 1.240 2009/06/18 18:59:18 roberto Exp roberto $ 2** $Id: lua.h,v 1.241 2009/07/15 17:26:14 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
@@ -243,7 +243,9 @@ LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
243/* 243/*
244** coroutine functions 244** coroutine functions
245*/ 245*/
246LUA_API int (lua_yield) (lua_State *L, int nresults); 246LUA_API int (lua_yieldk) (lua_State *L, int nresults, int ctx,
247 lua_CFunction k);
248#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL)
247LUA_API int (lua_resume) (lua_State *L, int narg); 249LUA_API int (lua_resume) (lua_State *L, int narg);
248LUA_API int (lua_status) (lua_State *L); 250LUA_API int (lua_status) (lua_State *L);
249 251