aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c7
-rw-r--r--lcorolib.c7
-rw-r--r--ldebug.c25
-rw-r--r--ldo.c14
-rw-r--r--lstate.h13
-rw-r--r--ltests.c18
-rw-r--r--lua.h5
7 files changed, 31 insertions, 58 deletions
diff --git a/lapi.c b/lapi.c
index 0f88e8de..8d4d5e7d 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.271 2017/10/11 12:38:45 roberto Exp roberto $ 2** $Id: lapi.c,v 2.272 2017/11/01 18:20:48 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*/
@@ -58,10 +58,9 @@ const char lua_ident[] =
58 58
59 59
60static TValue *index2value (lua_State *L, int idx) { 60static TValue *index2value (lua_State *L, int idx) {
61 CallInfo *ci = L->ci;
62 if (idx > 0) { 61 if (idx > 0) {
63 StkId o = L->func + idx; 62 StkId o = L->func + idx;
64 api_check(L, idx <= ci->top - (L->func + 1), "unacceptable index"); 63 api_check(L, idx <= L->ci->top - (L->func + 1), "unacceptable index");
65 if (o >= L->top) return NONVALIDVALUE; 64 if (o >= L->top) return NONVALIDVALUE;
66 else return s2v(o); 65 else return s2v(o);
67 } 66 }
@@ -1000,7 +999,7 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
1000 ci->u.c.k = k; /* save continuation */ 999 ci->u.c.k = k; /* save continuation */
1001 ci->u.c.ctx = ctx; /* save context */ 1000 ci->u.c.ctx = ctx; /* save context */
1002 /* save information for error recovery */ 1001 /* save information for error recovery */
1003 ci->extra = savestack(L, c.func); 1002 ci->u2.funcidx = savestack(L, c.func);
1004 ci->u.c.old_errfunc = L->errfunc; 1003 ci->u.c.old_errfunc = L->errfunc;
1005 L->errfunc = func; 1004 L->errfunc = func;
1006 setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */ 1005 setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */
diff --git a/lcorolib.c b/lcorolib.c
index 95467264..49a3cf28 100644
--- a/lcorolib.c
+++ b/lcorolib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcorolib.c,v 1.9 2014/11/02 19:19:04 roberto Exp roberto $ 2** $Id: lcorolib.c,v 1.10 2016/04/11 19:19:55 roberto Exp roberto $
3** Coroutine Library 3** Coroutine Library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -26,7 +26,7 @@ static lua_State *getco (lua_State *L) {
26 26
27 27
28static int auxresume (lua_State *L, lua_State *co, int narg) { 28static int auxresume (lua_State *L, lua_State *co, int narg) {
29 int status; 29 int status, nres;
30 if (!lua_checkstack(co, narg)) { 30 if (!lua_checkstack(co, narg)) {
31 lua_pushliteral(L, "too many arguments to resume"); 31 lua_pushliteral(L, "too many arguments to resume");
32 return -1; /* error flag */ 32 return -1; /* error flag */
@@ -36,9 +36,8 @@ static int auxresume (lua_State *L, lua_State *co, int narg) {
36 return -1; /* error flag */ 36 return -1; /* error flag */
37 } 37 }
38 lua_xmove(L, co, narg); 38 lua_xmove(L, co, narg);
39 status = lua_resume(co, L, narg); 39 status = lua_resume(co, L, narg, &nres);
40 if (status == LUA_OK || status == LUA_YIELD) { 40 if (status == LUA_OK || status == LUA_YIELD) {
41 int nres = lua_gettop(co);
42 if (!lua_checkstack(L, nres + 1)) { 41 if (!lua_checkstack(L, nres + 1)) {
43 lua_pop(co, nres); /* remove results anyway */ 42 lua_pop(co, nres); /* remove results anyway */
44 lua_pushliteral(L, "too many results to resume"); 43 lua_pushliteral(L, "too many results to resume");
diff --git a/ldebug.c b/ldebug.c
index 9b6f3bbe..5ca78bd1 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.133 2017/10/31 17:14:02 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.134 2017/11/01 18:20:48 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -107,22 +107,6 @@ static int currentline (CallInfo *ci) {
107 107
108 108
109/* 109/*
110** If function yielded, its 'func' can be in the 'extra' field. The
111** next function restores 'func' to its correct value for debugging
112** purposes. (It exchanges 'func' and 'extra'; so, when called again,
113** after debugging, it also "re-restores" ** 'func' to its altered value.
114*/
115static void swapextra (lua_State *L) {
116 if (L->status == LUA_YIELD) {
117 CallInfo *ci = L->ci; /* get function that yielded */
118 StkId temp = ci->func; /* exchange its 'func' and 'extra' values */
119 L->func = ci->func = restorestack(L, ci->extra);
120 ci->extra = savestack(L, temp);
121 }
122}
123
124
125/*
126** This function can be called asynchronously (e.g. during a signal). 110** This function can be called asynchronously (e.g. during a signal).
127** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by 111** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by
128** 'resethookcount') are for debug only, and it is no problem if they 112** 'resethookcount') are for debug only, and it is no problem if they
@@ -209,7 +193,6 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
209LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { 193LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
210 const char *name; 194 const char *name;
211 lua_lock(L); 195 lua_lock(L);
212 swapextra(L);
213 if (ar == NULL) { /* information about non-active function? */ 196 if (ar == NULL) { /* information about non-active function? */
214 if (!isLfunction(s2v(L->top - 1))) /* not a Lua function? */ 197 if (!isLfunction(s2v(L->top - 1))) /* not a Lua function? */
215 name = NULL; 198 name = NULL;
@@ -224,7 +207,6 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
224 api_incr_top(L); 207 api_incr_top(L);
225 } 208 }
226 } 209 }
227 swapextra(L);
228 lua_unlock(L); 210 lua_unlock(L);
229 return name; 211 return name;
230} 212}
@@ -234,13 +216,11 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
234 StkId pos = NULL; /* to avoid warnings */ 216 StkId pos = NULL; /* to avoid warnings */
235 const char *name; 217 const char *name;
236 lua_lock(L); 218 lua_lock(L);
237 swapextra(L);
238 name = findlocal(L, ar->i_ci, n, &pos); 219 name = findlocal(L, ar->i_ci, n, &pos);
239 if (name) { 220 if (name) {
240 setobjs2s(L, pos, L->top - 1); 221 setobjs2s(L, pos, L->top - 1);
241 L->top--; /* pop value */ 222 L->top--; /* pop value */
242 } 223 }
243 swapextra(L);
244 lua_unlock(L); 224 lua_unlock(L);
245 return name; 225 return name;
246} 226}
@@ -361,7 +341,6 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
361 CallInfo *ci; 341 CallInfo *ci;
362 TValue *func; 342 TValue *func;
363 lua_lock(L); 343 lua_lock(L);
364 swapextra(L);
365 if (*what == '>') { 344 if (*what == '>') {
366 ci = NULL; 345 ci = NULL;
367 func = s2v(L->top - 1); 346 func = s2v(L->top - 1);
@@ -380,7 +359,6 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
380 setobj2s(L, L->top, func); 359 setobj2s(L, L->top, func);
381 api_incr_top(L); 360 api_incr_top(L);
382 } 361 }
383 swapextra(L); /* correct before option 'L', which can raise a mem. error */
384 if (strchr(what, 'L')) 362 if (strchr(what, 'L'))
385 collectvalidlines(L, cl); 363 collectvalidlines(L, cl);
386 lua_unlock(L); 364 lua_unlock(L);
@@ -790,7 +768,6 @@ void luaG_traceexec (lua_State *L) {
790 L->hookcount = 1; /* undo decrement to zero */ 768 L->hookcount = 1; /* undo decrement to zero */
791 ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ 769 ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
792 ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ 770 ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
793 L->func = ci->func = L->top - 1; /* protect stack below results */
794 luaD_throw(L, LUA_YIELD); 771 luaD_throw(L, LUA_YIELD);
795 } 772 }
796} 773}
diff --git a/ldo.c b/ldo.c
index 46d6dcec..8c2fca13 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.163 2017/10/31 17:54:35 roberto Exp roberto $ 2** $Id: ldo.c,v 2.164 2017/11/01 18:20:48 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*/
@@ -559,7 +559,7 @@ static int recover (lua_State *L, int status) {
559 CallInfo *ci = findpcall(L); 559 CallInfo *ci = findpcall(L);
560 if (ci == NULL) return 0; /* no recovery point */ 560 if (ci == NULL) return 0; /* no recovery point */
561 /* "finish" luaD_pcall */ 561 /* "finish" luaD_pcall */
562 oldtop = restorestack(L, ci->extra); 562 oldtop = restorestack(L, ci->u2.funcidx);
563 luaF_close(L, oldtop); 563 luaF_close(L, oldtop);
564 seterrorobj(L, status, oldtop); 564 seterrorobj(L, status, oldtop);
565 L->ci = ci; 565 L->ci = ci;
@@ -604,7 +604,6 @@ static void resume (lua_State *L, void *ud) {
604 else { /* resuming from previous yield */ 604 else { /* resuming from previous yield */
605 lua_assert(L->status == LUA_YIELD); 605 lua_assert(L->status == LUA_YIELD);
606 L->status = LUA_OK; /* mark that it is running (again) */ 606 L->status = LUA_OK; /* mark that it is running (again) */
607 L->func = ci->func = restorestack(L, ci->extra);
608 if (isLua(ci)) /* yielded inside a hook? */ 607 if (isLua(ci)) /* yielded inside a hook? */
609 luaV_execute(L); /* just continue running Lua code */ 608 luaV_execute(L); /* just continue running Lua code */
610 else { /* 'common' yield */ 609 else { /* 'common' yield */
@@ -622,7 +621,8 @@ static void resume (lua_State *L, void *ud) {
622} 621}
623 622
624 623
625LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { 624LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
625 int *nresults) {
626 int status; 626 int status;
627 unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */ 627 unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */
628 lua_lock(L); 628 lua_lock(L);
@@ -653,6 +653,8 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
653 } 653 }
654 else lua_assert(status == L->status); /* normal end or yield */ 654 else lua_assert(status == L->status); /* normal end or yield */
655 } 655 }
656 *nresults = (status == LUA_YIELD) ? L->ci->u2.nyield
657 : L->top - (L->func + 1);
656 L->nny = oldnny; /* restore 'nny' */ 658 L->nny = oldnny; /* restore 'nny' */
657 L->nCcalls--; 659 L->nCcalls--;
658 lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); 660 lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
@@ -679,14 +681,14 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
679 luaG_runerror(L, "attempt to yield from outside a coroutine"); 681 luaG_runerror(L, "attempt to yield from outside a coroutine");
680 } 682 }
681 L->status = LUA_YIELD; 683 L->status = LUA_YIELD;
682 ci->extra = savestack(L, L->func); /* save current 'func' */
683 if (isLua(ci)) { /* inside a hook? */ 684 if (isLua(ci)) { /* inside a hook? */
684 api_check(L, k == NULL, "hooks cannot continue after yielding"); 685 api_check(L, k == NULL, "hooks cannot continue after yielding");
686 ci->u2.nyield = 0; /* no results */
685 } 687 }
686 else { 688 else {
687 if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ 689 if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
688 ci->u.c.ctx = ctx; /* save context */ 690 ci->u.c.ctx = ctx; /* save context */
689 L->func = ci->func = L->top - nresults - 1; /* protect stack below results */ 691 ci->u2.nyield = nresults; /* save number of results */
690 luaD_throw(L, LUA_YIELD); 692 luaD_throw(L, LUA_YIELD);
691 } 693 }
692 lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ 694 lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */
diff --git a/lstate.h b/lstate.h
index 76ce110f..8b9eb606 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.144 2017/07/27 13:50:16 roberto Exp roberto $ 2** $Id: lstate.h,v 2.145 2017/10/31 17:54:35 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*/
@@ -83,12 +83,6 @@ typedef struct stringtable {
83 83
84/* 84/*
85** Information about a call. 85** Information about a call.
86** When a thread yields, 'func' is adjusted to pretend that the
87** top function has only the yielded values in its stack; in that
88** case, the actual 'func' value is saved in field 'extra'.
89** When a function calls another with a continuation, 'extra' keeps
90** the function index so that, in case of errors, the continuation
91** function can be called with the correct top.
92*/ 86*/
93typedef struct CallInfo { 87typedef struct CallInfo {
94 StkId func; /* function index in the stack */ 88 StkId func; /* function index in the stack */
@@ -104,7 +98,10 @@ typedef struct CallInfo {
104 lua_KContext ctx; /* context info. in case of yields */ 98 lua_KContext ctx; /* context info. in case of yields */
105 } c; 99 } c;
106 } u; 100 } u;
107 ptrdiff_t extra; 101 union {
102 ptrdiff_t funcidx; /* called-function index */
103 int nyield; /* number of values yielded */
104 } u2;
108 short nresults; /* expected number of results from this function */ 105 short nresults; /* expected number of results from this function */
109 unsigned short callstatus; 106 unsigned short callstatus;
110} CallInfo; 107} CallInfo;
diff --git a/ltests.c b/ltests.c
index 94b4cd31..d05fc3b1 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.225 2017/10/04 21:56:32 roberto Exp roberto $ 2** $Id: ltests.c,v 2.226 2017/11/01 18:20:48 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*/
@@ -309,13 +309,10 @@ static void checkLclosure (global_State *g, LClosure *cl) {
309} 309}
310 310
311 311
312static int lua_checkpc (lua_State *L, CallInfo *ci) { 312static int lua_checkpc (CallInfo *ci) {
313 if (!isLua(ci)) return 1; 313 if (!isLua(ci)) return 1;
314 else { 314 else {
315 /* if function yielded (inside a hook), real 'func' is in 'extra' field */ 315 StkId f = ci->func;
316 StkId f = (L->status != LUA_YIELD || ci != L->ci)
317 ? ci->func
318 : restorestack(L, ci->extra);
319 Proto *p = clLvalue(s2v(f))->p; 316 Proto *p = clLvalue(s2v(f))->p;
320 return p->code <= ci->u.l.savedpc && 317 return p->code <= ci->u.l.savedpc &&
321 ci->u.l.savedpc <= p->code + p->sizecode; 318 ci->u.l.savedpc <= p->code + p->sizecode;
@@ -332,7 +329,7 @@ static void checkstack (global_State *g, lua_State *L1) {
332 lua_assert(upisopen(uv)); /* must be open */ 329 lua_assert(upisopen(uv)); /* must be open */
333 for (ci = L1->ci; ci != NULL; ci = ci->previous) { 330 for (ci = L1->ci; ci != NULL; ci = ci->previous) {
334 lua_assert(ci->top <= L1->stack_last); 331 lua_assert(ci->top <= L1->stack_last);
335 lua_assert(lua_checkpc(L1, ci)); 332 lua_assert(lua_checkpc(ci));
336 } 333 }
337 if (L1->stack) { /* complete thread? */ 334 if (L1->stack) { /* complete thread? */
338 for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++) 335 for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++)
@@ -1411,7 +1408,8 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
1411 } 1408 }
1412 else if EQ("resume") { 1409 else if EQ("resume") {
1413 int i = getindex; 1410 int i = getindex;
1414 status = lua_resume(lua_tothread(L1, i), L, getnum); 1411 int nres;
1412 status = lua_resume(lua_tothread(L1, i), L, getnum, &nres);
1415 } 1413 }
1416 else if EQ("return") { 1414 else if EQ("return") {
1417 int n = getnum; 1415 int n = getnum;
@@ -1616,10 +1614,10 @@ static int sethook (lua_State *L) {
1616 1614
1617 1615
1618static int coresume (lua_State *L) { 1616static int coresume (lua_State *L) {
1619 int status; 1617 int status, nres;
1620 lua_State *co = lua_tothread(L, 1); 1618 lua_State *co = lua_tothread(L, 1);
1621 luaL_argcheck(L, co, 1, "coroutine expected"); 1619 luaL_argcheck(L, co, 1, "coroutine expected");
1622 status = lua_resume(co, L, 0); 1620 status = lua_resume(co, L, 0, &nres);
1623 if (status != LUA_OK && status != LUA_YIELD) { 1621 if (status != LUA_OK && status != LUA_YIELD) {
1624 lua_pushboolean(L, 0); 1622 lua_pushboolean(L, 0);
1625 lua_insert(L, -2); 1623 lua_insert(L, -2);
diff --git a/lua.h b/lua.h
index eb76a27f..be99e14c 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.h,v 1.335 2017/05/26 19:14:29 roberto Exp roberto $ 2** $Id: lua.h,v 1.336 2017/07/27 13:36:54 roberto Exp roberto $
3** Lua - A Scripting Language 3** Lua - A Scripting 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
@@ -288,7 +288,8 @@ LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
288*/ 288*/
289LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx, 289LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx,
290 lua_KFunction k); 290 lua_KFunction k);
291LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg); 291LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg,
292 int *nres);
292LUA_API int (lua_status) (lua_State *L); 293LUA_API int (lua_status) (lua_State *L);
293LUA_API int (lua_isyieldable) (lua_State *L); 294LUA_API int (lua_isyieldable) (lua_State *L);
294 295