diff options
-rw-r--r-- | lapi.c | 7 | ||||
-rw-r--r-- | lcorolib.c | 7 | ||||
-rw-r--r-- | ldebug.c | 25 | ||||
-rw-r--r-- | ldo.c | 14 | ||||
-rw-r--r-- | lstate.h | 13 | ||||
-rw-r--r-- | ltests.c | 18 | ||||
-rw-r--r-- | lua.h | 5 |
7 files changed, 31 insertions, 58 deletions
@@ -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 | ||
60 | static TValue *index2value (lua_State *L, int idx) { | 60 | static 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' */ |
@@ -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 | ||
28 | static int auxresume (lua_State *L, lua_State *co, int narg) { | 28 | static 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"); |
@@ -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 | */ | ||
115 | static 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, | |||
209 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | 193 | LUA_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 | } |
@@ -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 | ||
625 | LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { | 624 | LUA_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 */ |
@@ -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 | */ |
93 | typedef struct CallInfo { | 87 | typedef 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; |
@@ -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 | ||
312 | static int lua_checkpc (lua_State *L, CallInfo *ci) { | 312 | static 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 | ||
1618 | static int coresume (lua_State *L) { | 1616 | static 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); |
@@ -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 | */ |
289 | LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx, | 289 | LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx, |
290 | lua_KFunction k); | 290 | lua_KFunction k); |
291 | LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg); | 291 | LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg, |
292 | int *nres); | ||
292 | LUA_API int (lua_status) (lua_State *L); | 293 | LUA_API int (lua_status) (lua_State *L); |
293 | LUA_API int (lua_isyieldable) (lua_State *L); | 294 | LUA_API int (lua_isyieldable) (lua_State *L); |
294 | 295 | ||