diff options
| -rw-r--r-- | lapi.c | 81 | ||||
| -rw-r--r-- | lapi.h | 9 | ||||
| -rw-r--r-- | ldebug.c | 161 | ||||
| -rw-r--r-- | ldo.c | 190 | ||||
| -rw-r--r-- | ldo.h | 5 | ||||
| -rw-r--r-- | lgc.c | 6 | ||||
| -rw-r--r-- | lobject.h | 32 | ||||
| -rw-r--r-- | lstate.c | 63 | ||||
| -rw-r--r-- | lstate.h | 50 | ||||
| -rw-r--r-- | ltests.c | 23 | ||||
| -rw-r--r-- | ltm.c | 6 | ||||
| -rw-r--r-- | lua.h | 5 | ||||
| -rw-r--r-- | lvm.c | 133 |
13 files changed, 394 insertions, 370 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 2.274 2017/11/03 12:12:30 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.273 2017/11/02 11:28:56 roberto Exp $ |
| 3 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -10,7 +10,6 @@ | |||
| 10 | #include "lprefix.h" | 10 | #include "lprefix.h" |
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | #include <limits.h> | ||
| 14 | #include <stdarg.h> | 13 | #include <stdarg.h> |
| 15 | #include <string.h> | 14 | #include <string.h> |
| 16 | 15 | ||
| @@ -59,14 +58,15 @@ const char lua_ident[] = | |||
| 59 | 58 | ||
| 60 | 59 | ||
| 61 | 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) { | 62 | if (idx > 0) { |
| 63 | StkId o = L->func + idx; | 63 | StkId o = ci->func + idx; |
| 64 | api_check(L, idx < L->func->stkci.framesize, "unacceptable index"); | 64 | api_check(L, idx <= L->ci->top - (ci->func + 1), "unacceptable index"); |
| 65 | if (o >= L->top) return NONVALIDVALUE; | 65 | if (o >= L->top) return NONVALIDVALUE; |
| 66 | else return s2v(o); | 66 | else return s2v(o); |
| 67 | } | 67 | } |
| 68 | else if (!ispseudo(idx)) { /* negative index */ | 68 | else if (!ispseudo(idx)) { /* negative index */ |
| 69 | api_check(L, idx != 0 && -idx < L->func->stkci.framesize, "invalid index"); | 69 | api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); |
| 70 | return s2v(L->top + idx); | 70 | return s2v(L->top + idx); |
| 71 | } | 71 | } |
| 72 | else if (idx == LUA_REGISTRYINDEX) | 72 | else if (idx == LUA_REGISTRYINDEX) |
| @@ -74,10 +74,10 @@ static TValue *index2value (lua_State *L, int idx) { | |||
| 74 | else { /* upvalues */ | 74 | else { /* upvalues */ |
| 75 | idx = LUA_REGISTRYINDEX - idx; | 75 | idx = LUA_REGISTRYINDEX - idx; |
| 76 | api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); | 76 | api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); |
| 77 | if (ttislcf(s2v(L->func))) /* light C function? */ | 77 | if (ttislcf(s2v(ci->func))) /* light C function? */ |
| 78 | return NONVALIDVALUE; /* it has no upvalues */ | 78 | return NONVALIDVALUE; /* it has no upvalues */ |
| 79 | else { | 79 | else { |
| 80 | CClosure *func = clCvalue(s2v(L->func)); | 80 | CClosure *func = clCvalue(s2v(ci->func)); |
| 81 | return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE; | 81 | return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE; |
| 82 | } | 82 | } |
| 83 | } | 83 | } |
| @@ -85,13 +85,14 @@ static TValue *index2value (lua_State *L, int idx) { | |||
| 85 | 85 | ||
| 86 | 86 | ||
| 87 | static StkId index2stack (lua_State *L, int idx) { | 87 | static StkId index2stack (lua_State *L, int idx) { |
| 88 | CallInfo *ci = L->ci; | ||
| 88 | if (idx > 0) { | 89 | if (idx > 0) { |
| 89 | StkId o = L->func + idx; | 90 | StkId o = ci->func + idx; |
| 90 | api_check(L, o < L->top, "unacceptable index"); | 91 | api_check(L, o < L->top, "unacceptable index"); |
| 91 | return o; | 92 | return o; |
| 92 | } | 93 | } |
| 93 | else { /* non-positive index */ | 94 | else { /* non-positive index */ |
| 94 | api_check(L, idx != 0 && -idx <= L->top - (L->func + 1), "invalid index"); | 95 | api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); |
| 95 | api_check(L, !ispseudo(idx), "invalid index"); | 96 | api_check(L, !ispseudo(idx), "invalid index"); |
| 96 | return L->top + idx; | 97 | return L->top + idx; |
| 97 | } | 98 | } |
| @@ -110,12 +111,10 @@ static void growstack (lua_State *L, void *ud) { | |||
| 110 | 111 | ||
| 111 | LUA_API int lua_checkstack (lua_State *L, int n) { | 112 | LUA_API int lua_checkstack (lua_State *L, int n) { |
| 112 | int res; | 113 | int res; |
| 113 | int frameuse = L->top - L->func; | 114 | CallInfo *ci = L->ci; |
| 114 | lua_lock(L); | 115 | lua_lock(L); |
| 115 | api_check(L, n >= 0, "negative 'n'"); | 116 | api_check(L, n >= 0, "negative 'n'"); |
| 116 | if (n >= USHRT_MAX - frameuse) | 117 | if (L->stack_last - L->top > n) /* stack large enough? */ |
| 117 | res = 0; /* frame size overflow */ | ||
| 118 | else if (L->stack_last - L->top > n) /* stack large enough? */ | ||
| 119 | res = 1; /* yes; check is OK */ | 118 | res = 1; /* yes; check is OK */ |
| 120 | else { /* no; need to grow stack */ | 119 | else { /* no; need to grow stack */ |
| 121 | int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; | 120 | int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; |
| @@ -124,8 +123,8 @@ LUA_API int lua_checkstack (lua_State *L, int n) { | |||
| 124 | else /* try to grow stack */ | 123 | else /* try to grow stack */ |
| 125 | res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK); | 124 | res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK); |
| 126 | } | 125 | } |
| 127 | if (res && L->func->stkci.framesize < frameuse + n) | 126 | if (res && ci->top < L->top + n) |
| 128 | L->func->stkci.framesize = frameuse + n; /* adjust frame size */ | 127 | ci->top = L->top + n; /* adjust frame top */ |
| 129 | lua_unlock(L); | 128 | lua_unlock(L); |
| 130 | return res; | 129 | return res; |
| 131 | } | 130 | } |
| @@ -137,7 +136,7 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { | |||
| 137 | lua_lock(to); | 136 | lua_lock(to); |
| 138 | api_checknelems(from, n); | 137 | api_checknelems(from, n); |
| 139 | api_check(from, G(from) == G(to), "moving among independent states"); | 138 | api_check(from, G(from) == G(to), "moving among independent states"); |
| 140 | api_check(from, functop(to->func) - to->top >= n, "stack overflow"); | 139 | api_check(from, to->ci->top - to->top >= n, "stack overflow"); |
| 141 | from->top -= n; | 140 | from->top -= n; |
| 142 | for (i = 0; i < n; i++) { | 141 | for (i = 0; i < n; i++) { |
| 143 | setobjs2s(to, to->top, from->top + i); | 142 | setobjs2s(to, to->top, from->top + i); |
| @@ -176,17 +175,17 @@ LUA_API const lua_Number *lua_version (lua_State *L) { | |||
| 176 | LUA_API int lua_absindex (lua_State *L, int idx) { | 175 | LUA_API int lua_absindex (lua_State *L, int idx) { |
| 177 | return (idx > 0 || ispseudo(idx)) | 176 | return (idx > 0 || ispseudo(idx)) |
| 178 | ? idx | 177 | ? idx |
| 179 | : cast_int(L->top - L->func) + idx; | 178 | : cast_int(L->top - L->ci->func) + idx; |
| 180 | } | 179 | } |
| 181 | 180 | ||
| 182 | 181 | ||
| 183 | LUA_API int lua_gettop (lua_State *L) { | 182 | LUA_API int lua_gettop (lua_State *L) { |
| 184 | return cast_int(L->top - (L->func + 1)); | 183 | return cast_int(L->top - (L->ci->func + 1)); |
| 185 | } | 184 | } |
| 186 | 185 | ||
| 187 | 186 | ||
| 188 | LUA_API void lua_settop (lua_State *L, int idx) { | 187 | LUA_API void lua_settop (lua_State *L, int idx) { |
| 189 | StkId func = L->func; | 188 | StkId func = L->ci->func; |
| 190 | lua_lock(L); | 189 | lua_lock(L); |
| 191 | if (idx >= 0) { | 190 | if (idx >= 0) { |
| 192 | api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); | 191 | api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); |
| @@ -244,7 +243,7 @@ LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { | |||
| 244 | api_checkvalidindex(L, to); | 243 | api_checkvalidindex(L, to); |
| 245 | setobj(L, to, fr); | 244 | setobj(L, to, fr); |
| 246 | if (isupvalue(toidx)) /* function upvalue? */ | 245 | if (isupvalue(toidx)) /* function upvalue? */ |
| 247 | luaC_barrier(L, clCvalue(s2v(L->func)), fr); | 246 | luaC_barrier(L, clCvalue(s2v(L->ci->func)), fr); |
| 248 | /* LUA_REGISTRYINDEX does not need gc barrier | 247 | /* LUA_REGISTRYINDEX does not need gc barrier |
| 249 | (collector revisits it before finishing collection) */ | 248 | (collector revisits it before finishing collection) */ |
| 250 | lua_unlock(L); | 249 | lua_unlock(L); |
| @@ -932,24 +931,23 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) { | |||
| 932 | 931 | ||
| 933 | 932 | ||
| 934 | #define checkresults(L,na,nr) \ | 933 | #define checkresults(L,na,nr) \ |
| 935 | api_check(L, (nr) == LUA_MULTRET || \ | 934 | api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \ |
| 936 | (functop(L->func) - L->top >= (nr) - (na)), \ | 935 | "results from function overflow current stack size") |
| 937 | "results from function overflow current frame size") | ||
| 938 | 936 | ||
| 939 | 937 | ||
| 940 | LUA_API void lua_callk (lua_State *L, int nargs, int nresults, | 938 | LUA_API void lua_callk (lua_State *L, int nargs, int nresults, |
| 941 | lua_KContext ctx, lua_KFunction k) { | 939 | lua_KContext ctx, lua_KFunction k) { |
| 942 | StkId func; | 940 | StkId func; |
| 943 | lua_lock(L); | 941 | lua_lock(L); |
| 944 | api_check(L, k == NULL || !isLua(L->func), | 942 | api_check(L, k == NULL || !isLua(L->ci), |
| 945 | "cannot use continuations inside hooks"); | 943 | "cannot use continuations inside hooks"); |
| 946 | api_checknelems(L, nargs+1); | 944 | api_checknelems(L, nargs+1); |
| 947 | api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); | 945 | api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); |
| 948 | checkresults(L, nargs, nresults); | 946 | checkresults(L, nargs, nresults); |
| 949 | func = L->top - (nargs+1); | 947 | func = L->top - (nargs+1); |
| 950 | if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ | 948 | if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ |
| 951 | L->func->stkci.u.c.k = k; /* save continuation */ | 949 | L->ci->u.c.k = k; /* save continuation */ |
| 952 | L->func->stkci.u.c.ctx = ctx; /* save context */ | 950 | L->ci->u.c.ctx = ctx; /* save context */ |
| 953 | luaD_call(L, func, nresults); /* do the call */ | 951 | luaD_call(L, func, nresults); /* do the call */ |
| 954 | } | 952 | } |
| 955 | else /* no continuation or no yieldable */ | 953 | else /* no continuation or no yieldable */ |
| @@ -980,38 +978,37 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, | |||
| 980 | lua_KContext ctx, lua_KFunction k) { | 978 | lua_KContext ctx, lua_KFunction k) { |
| 981 | struct CallS c; | 979 | struct CallS c; |
| 982 | int status; | 980 | int status; |
| 983 | ptrdiff_t efunc; | 981 | ptrdiff_t func; |
| 984 | lua_lock(L); | 982 | lua_lock(L); |
| 985 | api_check(L, k == NULL || !isLua(L->func), | 983 | api_check(L, k == NULL || !isLua(L->ci), |
| 986 | "cannot use continuations inside hooks"); | 984 | "cannot use continuations inside hooks"); |
| 987 | api_checknelems(L, nargs+1); | 985 | api_checknelems(L, nargs+1); |
| 988 | api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); | 986 | api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); |
| 989 | checkresults(L, nargs, nresults); | 987 | checkresults(L, nargs, nresults); |
| 990 | if (errfunc == 0) | 988 | if (errfunc == 0) |
| 991 | efunc = 0; | 989 | func = 0; |
| 992 | else { | 990 | else { |
| 993 | StkId o = index2stack(L, errfunc); | 991 | StkId o = index2stack(L, errfunc); |
| 994 | efunc = savestack(L, o); | 992 | func = savestack(L, o); |
| 995 | } | 993 | } |
| 996 | c.func = L->top - (nargs+1); /* function to be called */ | 994 | c.func = L->top - (nargs+1); /* function to be called */ |
| 997 | if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */ | 995 | if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */ |
| 998 | c.nresults = nresults; /* do a 'conventional' protected call */ | 996 | c.nresults = nresults; /* do a 'conventional' protected call */ |
| 999 | status = luaD_pcall(L, f_call, &c, savestack(L, c.func), efunc); | 997 | status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); |
| 1000 | } | 998 | } |
| 1001 | else { /* prepare continuation (call is already protected by 'resume') */ | 999 | else { /* prepare continuation (call is already protected by 'resume') */ |
| 1002 | StkId func = L->func; | 1000 | CallInfo *ci = L->ci; |
| 1003 | func->stkci.u.c.k = k; /* save continuation */ | 1001 | ci->u.c.k = k; /* save continuation */ |
| 1004 | func->stkci.u.c.ctx = ctx; /* save context */ | 1002 | ci->u.c.ctx = ctx; /* save context */ |
| 1005 | /* save information for error recovery */ | 1003 | /* save information for error recovery */ |
| 1006 | func->stkci.u2.funcidx = c.func - func; | 1004 | ci->u2.funcidx = savestack(L, c.func); |
| 1007 | func->stkci.u.c.old_errfunc = L->errfunc; | 1005 | ci->u.c.old_errfunc = L->errfunc; |
| 1008 | L->errfunc = efunc; | 1006 | L->errfunc = func; |
| 1009 | setoah(callstatus(func), L->allowhook); /* save value of 'allowhook' */ | 1007 | setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */ |
| 1010 | callstatus(func) |= CIST_YPCALL; /* function can do error recovery */ | 1008 | ci->callstatus |= CIST_YPCALL; /* function can do error recovery */ |
| 1011 | luaD_call(L, c.func, nresults); /* do the call */ | 1009 | luaD_call(L, c.func, nresults); /* do the call */ |
| 1012 | func = L->func; /* previous call can reallocate stack */ | 1010 | ci->callstatus &= ~CIST_YPCALL; |
| 1013 | callstatus(func) &= ~CIST_YPCALL; | 1011 | L->errfunc = ci->u.c.old_errfunc; |
| 1014 | L->errfunc = func->stkci.u.c.old_errfunc; | ||
| 1015 | status = LUA_OK; /* if it is here, there were no errors */ | 1012 | status = LUA_OK; /* if it is here, there were no errors */ |
| 1016 | } | 1013 | } |
| 1017 | adjustresults(L, nresults); | 1014 | adjustresults(L, nresults); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.h,v 2.10 2017/11/01 18:20:48 roberto Exp roberto $ | 2 | ** $Id: lapi.h,v 2.10 2017/11/01 18:20:48 roberto Exp $ |
| 3 | ** Auxiliary functions from Lua API | 3 | ** Auxiliary functions from Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -11,14 +11,13 @@ | |||
| 11 | #include "llimits.h" | 11 | #include "llimits.h" |
| 12 | #include "lstate.h" | 12 | #include "lstate.h" |
| 13 | 13 | ||
| 14 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= functop(L->func), \ | 14 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ |
| 15 | "stack overflow");} | 15 | "stack overflow");} |
| 16 | 16 | ||
| 17 | #define adjustresults(L,nres) \ | 17 | #define adjustresults(L,nres) \ |
| 18 | { if ((nres) == LUA_MULTRET && functop(L->func) < L->top) \ | 18 | { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } |
| 19 | setfunctop(L->func, L->top); } | ||
| 20 | 19 | ||
| 21 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->func), \ | 20 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ |
| 22 | "not enough elements in the stack") | 21 | "not enough elements in the stack") |
| 23 | 22 | ||
| 24 | 23 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 2.138 2017/11/03 19:33:22 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.135 2017/11/02 11:28:56 roberto Exp $ |
| 3 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -34,17 +34,17 @@ | |||
| 34 | #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL) | 34 | #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL) |
| 35 | 35 | ||
| 36 | 36 | ||
| 37 | /* Active Lua function (given stack function) */ | 37 | /* Active Lua function (given call info) */ |
| 38 | #define ci_func(func) (clLvalue(s2v(func))) | 38 | #define ci_func(ci) (clLvalue(s2v((ci)->func))) |
| 39 | 39 | ||
| 40 | 40 | ||
| 41 | static const char *funcnamefromcode (lua_State *L, StkId stkf, | 41 | static const char *funcnamefromcode (lua_State *L, CallInfo *ci, |
| 42 | const char **name); | 42 | const char **name); |
| 43 | 43 | ||
| 44 | 44 | ||
| 45 | static int currentpc (StkId func) { | 45 | static int currentpc (CallInfo *ci) { |
| 46 | lua_assert(isLua(func)); | 46 | lua_assert(isLua(ci)); |
| 47 | return pcRel(func->stkci.u.l.savedpc, ci_func(func)->p); | 47 | return pcRel(ci->u.l.savedpc, ci_func(ci)->p); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | 50 | ||
| @@ -101,8 +101,8 @@ int luaG_getfuncline (Proto *f, int pc) { | |||
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | 103 | ||
| 104 | static int currentline (StkId func) { | 104 | static int currentline (CallInfo *ci) { |
| 105 | return luaG_getfuncline(ci_func(func)->p, currentpc(func)); | 105 | return luaG_getfuncline(ci_func(ci)->p, currentpc(ci)); |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | 108 | ||
| @@ -120,8 +120,8 @@ LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { | |||
| 120 | mask = 0; | 120 | mask = 0; |
| 121 | func = NULL; | 121 | func = NULL; |
| 122 | } | 122 | } |
| 123 | if (isLua(L->func)) | 123 | if (isLua(L->ci)) |
| 124 | L->oldpc = L->func->stkci.u.l.savedpc; | 124 | L->oldpc = L->ci->u.l.savedpc; |
| 125 | L->hook = func; | 125 | L->hook = func; |
| 126 | L->basehookcount = count; | 126 | L->basehookcount = count; |
| 127 | resethookcount(L); | 127 | resethookcount(L); |
| @@ -146,17 +146,14 @@ LUA_API int lua_gethookcount (lua_State *L) { | |||
| 146 | 146 | ||
| 147 | LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { | 147 | LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { |
| 148 | int status; | 148 | int status; |
| 149 | StkId func; | 149 | CallInfo *ci; |
| 150 | if (level < 0) return 0; /* invalid (negative) level */ | 150 | if (level < 0) return 0; /* invalid (negative) level */ |
| 151 | lua_lock(L); | 151 | lua_lock(L); |
| 152 | for (func = L->func; | 152 | for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) |
| 153 | level > 0 && func->stkci.previous != 0; | ||
| 154 | func -= func->stkci.previous) | ||
| 155 | level--; | 153 | level--; |
| 156 | if (level == 0 && func->stkci.previous != 0) { /* level found? */ | 154 | if (level == 0 && ci != &L->base_ci) { /* level found? */ |
| 157 | status = 1; | 155 | status = 1; |
| 158 | ar->i_actf = func - L->stack; | 156 | ar->i_ci = ci; |
| 159 | ar->i_actL = L; | ||
| 160 | } | 157 | } |
| 161 | else status = 0; /* no such level */ | 158 | else status = 0; /* no such level */ |
| 162 | lua_unlock(L); | 159 | lua_unlock(L); |
| @@ -171,34 +168,24 @@ static const char *upvalname (Proto *p, int uv) { | |||
| 171 | } | 168 | } |
| 172 | 169 | ||
| 173 | 170 | ||
| 174 | static StkId findcalled (lua_State *L, StkId caller) { | 171 | static const char *findlocal (lua_State *L, CallInfo *ci, int n, |
| 175 | StkId func = L->func; | 172 | StkId *pos) { |
| 176 | for (;;) { | ||
| 177 | StkId previous = func - func->stkci.previous; | ||
| 178 | lua_assert(previous < func); | ||
| 179 | if (previous == caller) | ||
| 180 | return func; | ||
| 181 | else | ||
| 182 | func = previous; | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | |||
| 187 | static const char *findlocal (lua_State *L, const lua_Debug *ar, | ||
| 188 | int n, StkId *pos) { | ||
| 189 | const char *name = NULL; | 173 | const char *name = NULL; |
| 190 | StkId stkf = ar->i_actL->stack + ar->i_actf; | 174 | StkId base; |
| 191 | if (isLua(stkf)) { | 175 | if (isLua(ci)) { |
| 192 | name = luaF_getlocalname(ci_func(stkf)->p, n, currentpc(stkf)); | 176 | base = ci->func + 1; |
| 177 | name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); | ||
| 193 | } | 178 | } |
| 179 | else | ||
| 180 | base = ci->func + 1; | ||
| 194 | if (name == NULL) { /* no 'standard' name? */ | 181 | if (name == NULL) { /* no 'standard' name? */ |
| 195 | StkId limit = (stkf == L->func) ? L->top : findcalled(L, stkf); | 182 | StkId limit = (ci == L->ci) ? L->top : ci->next->func; |
| 196 | if (limit - stkf > n && n > 0) /* is 'n' inside 'ci' stack? */ | 183 | if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ |
| 197 | name = "(*temporary)"; /* generic name for any valid slot */ | 184 | name = "(*temporary)"; /* generic name for any valid slot */ |
| 198 | else | 185 | else |
| 199 | return NULL; /* no name */ | 186 | return NULL; /* no name */ |
| 200 | } | 187 | } |
| 201 | *pos = stkf + n; | 188 | *pos = base + (n - 1); |
| 202 | return name; | 189 | return name; |
| 203 | } | 190 | } |
| 204 | 191 | ||
| @@ -214,7 +201,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
| 214 | } | 201 | } |
| 215 | else { /* active function; get information through 'ar' */ | 202 | else { /* active function; get information through 'ar' */ |
| 216 | StkId pos = NULL; /* to avoid warnings */ | 203 | StkId pos = NULL; /* to avoid warnings */ |
| 217 | name = findlocal(L, ar, n, &pos); | 204 | name = findlocal(L, ar->i_ci, n, &pos); |
| 218 | if (name) { | 205 | if (name) { |
| 219 | setobjs2s(L, L->top, pos); | 206 | setobjs2s(L, L->top, pos); |
| 220 | api_incr_top(L); | 207 | api_incr_top(L); |
| @@ -229,7 +216,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
| 229 | StkId pos = NULL; /* to avoid warnings */ | 216 | StkId pos = NULL; /* to avoid warnings */ |
| 230 | const char *name; | 217 | const char *name; |
| 231 | lua_lock(L); | 218 | lua_lock(L); |
| 232 | name = findlocal(L, ar, n, &pos); | 219 | name = findlocal(L, ar->i_ci, n, &pos); |
| 233 | if (name) { | 220 | if (name) { |
| 234 | setobjs2s(L, pos, L->top - 1); | 221 | setobjs2s(L, pos, L->top - 1); |
| 235 | L->top--; /* pop value */ | 222 | L->top--; /* pop value */ |
| @@ -287,25 +274,22 @@ static void collectvalidlines (lua_State *L, Closure *f) { | |||
| 287 | } | 274 | } |
| 288 | 275 | ||
| 289 | 276 | ||
| 290 | static const char *getfuncname (lua_State *L, StkId stkf, const char **name) { | 277 | static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { |
| 291 | if (stkf == NULL) /* no function? */ | 278 | if (ci == NULL) /* no 'ci'? */ |
| 292 | return NULL; /* no info */ | 279 | return NULL; /* no info */ |
| 293 | else if (callstatus(stkf) & CIST_FIN) { /* is this a finalizer? */ | 280 | else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */ |
| 294 | *name = "__gc"; | 281 | *name = "__gc"; |
| 295 | return "metamethod"; /* report it as such */ | 282 | return "metamethod"; /* report it as such */ |
| 296 | } | 283 | } |
| 297 | /* calling function is a known Lua function? */ | 284 | /* calling function is a known Lua function? */ |
| 298 | else { | 285 | else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) |
| 299 | StkId previous = stkf - stkf->stkci.previous; | 286 | return funcnamefromcode(L, ci->previous, name); |
| 300 | if (!(callstatus(stkf) & CIST_TAIL) && isLua(previous)) | 287 | else return NULL; /* no way to find a name */ |
| 301 | return funcnamefromcode(L, previous, name); | ||
| 302 | else return NULL; /* no way to find a name */ | ||
| 303 | } | ||
| 304 | } | 288 | } |
| 305 | 289 | ||
| 306 | 290 | ||
| 307 | static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | 291 | static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, |
| 308 | Closure *f, StkId stkf) { | 292 | Closure *f, CallInfo *ci) { |
| 309 | int status = 1; | 293 | int status = 1; |
| 310 | for (; *what; what++) { | 294 | for (; *what; what++) { |
| 311 | switch (*what) { | 295 | switch (*what) { |
| @@ -314,7 +298,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
| 314 | break; | 298 | break; |
| 315 | } | 299 | } |
| 316 | case 'l': { | 300 | case 'l': { |
| 317 | ar->currentline = (stkf && isLua(stkf)) ? currentline(stkf) : -1; | 301 | ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1; |
| 318 | break; | 302 | break; |
| 319 | } | 303 | } |
| 320 | case 'u': { | 304 | case 'u': { |
| @@ -330,11 +314,11 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
| 330 | break; | 314 | break; |
| 331 | } | 315 | } |
| 332 | case 't': { | 316 | case 't': { |
| 333 | ar->istailcall = (stkf) ? callstatus(stkf) & CIST_TAIL : 0; | 317 | ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; |
| 334 | break; | 318 | break; |
| 335 | } | 319 | } |
| 336 | case 'n': { | 320 | case 'n': { |
| 337 | ar->namewhat = getfuncname(L, stkf, &ar->name); | 321 | ar->namewhat = getfuncname(L, ci, &ar->name); |
| 338 | if (ar->namewhat == NULL) { | 322 | if (ar->namewhat == NULL) { |
| 339 | ar->namewhat = ""; /* not found */ | 323 | ar->namewhat = ""; /* not found */ |
| 340 | ar->name = NULL; | 324 | ar->name = NULL; |
| @@ -354,23 +338,23 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
| 354 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | 338 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { |
| 355 | int status; | 339 | int status; |
| 356 | Closure *cl; | 340 | Closure *cl; |
| 357 | StkId stkf; | 341 | CallInfo *ci; |
| 358 | TValue *func; | 342 | TValue *func; |
| 359 | lua_lock(L); | 343 | lua_lock(L); |
| 360 | if (*what == '>') { | 344 | if (*what == '>') { |
| 361 | stkf = NULL; | 345 | ci = NULL; |
| 362 | func = s2v(L->top - 1); | 346 | func = s2v(L->top - 1); |
| 363 | api_check(L, ttisfunction(func), "function expected"); | 347 | api_check(L, ttisfunction(func), "function expected"); |
| 364 | what++; /* skip the '>' */ | 348 | what++; /* skip the '>' */ |
| 365 | L->top--; /* pop function */ | 349 | L->top--; /* pop function */ |
| 366 | } | 350 | } |
| 367 | else { | 351 | else { |
| 368 | stkf = ar->i_actL->stack + ar->i_actf; | 352 | ci = ar->i_ci; |
| 369 | func = s2v(stkf); | 353 | func = s2v(ci->func); |
| 370 | lua_assert(ttisfunction(func)); | 354 | lua_assert(ttisfunction(func)); |
| 371 | } | 355 | } |
| 372 | cl = ttisclosure(func) ? clvalue(func) : NULL; | 356 | cl = ttisclosure(func) ? clvalue(func) : NULL; |
| 373 | status = auxgetinfo(L, what, ar, cl, stkf); | 357 | status = auxgetinfo(L, what, ar, cl, ci); |
| 374 | if (strchr(what, 'f')) { | 358 | if (strchr(what, 'f')) { |
| 375 | setobj2s(L, L->top, func); | 359 | setobj2s(L, L->top, func); |
| 376 | api_incr_top(L); | 360 | api_incr_top(L); |
| @@ -559,13 +543,13 @@ static const char *gxf (Proto *p, int pc, Instruction i, int isup) { | |||
| 559 | ** Returns what the name is (e.g., "for iterator", "method", | 543 | ** Returns what the name is (e.g., "for iterator", "method", |
| 560 | ** "metamethod") and sets '*name' to point to the name. | 544 | ** "metamethod") and sets '*name' to point to the name. |
| 561 | */ | 545 | */ |
| 562 | static const char *funcnamefromcode (lua_State *L, StkId stkf, | 546 | static const char *funcnamefromcode (lua_State *L, CallInfo *ci, |
| 563 | const char **name) { | 547 | const char **name) { |
| 564 | TMS tm = (TMS)0; /* (initial value avoids warnings) */ | 548 | TMS tm = (TMS)0; /* (initial value avoids warnings) */ |
| 565 | Proto *p = ci_func(stkf)->p; /* calling function */ | 549 | Proto *p = ci_func(ci)->p; /* calling function */ |
| 566 | int pc = currentpc(stkf); /* calling instruction index */ | 550 | int pc = currentpc(ci); /* calling instruction index */ |
| 567 | Instruction i = p->code[pc]; /* calling instruction */ | 551 | Instruction i = p->code[pc]; /* calling instruction */ |
| 568 | if (callstatus(stkf) & CIST_HOOKED) { /* was it called inside a hook? */ | 552 | if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ |
| 569 | *name = "?"; | 553 | *name = "?"; |
| 570 | return "hook"; | 554 | return "hook"; |
| 571 | } | 555 | } |
| @@ -621,10 +605,10 @@ static const char *funcnamefromcode (lua_State *L, StkId stkf, | |||
| 621 | ** not ISO C, but it should not crash a program; the subsequent | 605 | ** not ISO C, but it should not crash a program; the subsequent |
| 622 | ** checks are ISO C and ensure a correct result. | 606 | ** checks are ISO C and ensure a correct result. |
| 623 | */ | 607 | */ |
| 624 | static int isinstack (lua_State *L, const TValue *o) { | 608 | static int isinstack (CallInfo *ci, const TValue *o) { |
| 625 | StkId base = L->stack; | 609 | StkId base = ci->func + 1; |
| 626 | ptrdiff_t i = cast(StkId, o) - base; | 610 | ptrdiff_t i = cast(StkId, o) - base; |
| 627 | return (0 <= i && i < (L->top - base) && s2v(base + i) == o); | 611 | return (0 <= i && i < (ci->top - base) && s2v(base + i) == o); |
| 628 | } | 612 | } |
| 629 | 613 | ||
| 630 | 614 | ||
| @@ -633,9 +617,9 @@ static int isinstack (lua_State *L, const TValue *o) { | |||
| 633 | ** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on | 617 | ** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on |
| 634 | ** upvalues.) | 618 | ** upvalues.) |
| 635 | */ | 619 | */ |
| 636 | static const char *getupvalname (StkId stkf, const TValue *o, | 620 | static const char *getupvalname (CallInfo *ci, const TValue *o, |
| 637 | const char **name) { | 621 | const char **name) { |
| 638 | LClosure *c = ci_func(stkf); | 622 | LClosure *c = ci_func(ci); |
| 639 | int i; | 623 | int i; |
| 640 | for (i = 0; i < c->nupvalues; i++) { | 624 | for (i = 0; i < c->nupvalues; i++) { |
| 641 | if (c->upvals[i]->v == o) { | 625 | if (c->upvals[i]->v == o) { |
| @@ -649,13 +633,13 @@ static const char *getupvalname (StkId stkf, const TValue *o, | |||
| 649 | 633 | ||
| 650 | static const char *varinfo (lua_State *L, const TValue *o) { | 634 | static const char *varinfo (lua_State *L, const TValue *o) { |
| 651 | const char *name = NULL; /* to avoid warnings */ | 635 | const char *name = NULL; /* to avoid warnings */ |
| 652 | StkId stkf = L->func; | 636 | CallInfo *ci = L->ci; |
| 653 | const char *kind = NULL; | 637 | const char *kind = NULL; |
| 654 | if (isLua(stkf)) { | 638 | if (isLua(ci)) { |
| 655 | kind = getupvalname(stkf, o, &name); /* check whether 'o' is an upvalue */ | 639 | kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ |
| 656 | if (!kind && isinstack(L, o)) /* no? try a register */ | 640 | if (!kind && isinstack(ci, o)) /* no? try a register */ |
| 657 | kind = getobjname(ci_func(stkf)->p, currentpc(stkf), | 641 | kind = getobjname(ci_func(ci)->p, currentpc(ci), |
| 658 | cast_int(cast(StkId, o) - (stkf + 1)), &name); | 642 | cast_int(cast(StkId, o) - (ci->func + 1)), &name); |
| 659 | } | 643 | } |
| 660 | return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : ""; | 644 | return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : ""; |
| 661 | } | 645 | } |
| @@ -728,16 +712,15 @@ l_noret luaG_errormsg (lua_State *L) { | |||
| 728 | 712 | ||
| 729 | 713 | ||
| 730 | l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { | 714 | l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { |
| 731 | StkId func; | 715 | CallInfo *ci = L->ci; |
| 732 | const char *msg; | 716 | const char *msg; |
| 733 | va_list argp; | 717 | va_list argp; |
| 734 | luaC_checkGC(L); /* error message uses memory */ | 718 | luaC_checkGC(L); /* error message uses memory */ |
| 735 | va_start(argp, fmt); | 719 | va_start(argp, fmt); |
| 736 | msg = luaO_pushvfstring(L, fmt, argp); /* format message */ | 720 | msg = luaO_pushvfstring(L, fmt, argp); /* format message */ |
| 737 | va_end(argp); | 721 | va_end(argp); |
| 738 | func = L->func; /* previous calls can change the stack */ | 722 | if (isLua(ci)) /* if Lua function, add source:line information */ |
| 739 | if (isLua(func)) /* if Lua function, add source:line information */ | 723 | luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci)); |
| 740 | luaG_addinfo(L, msg, ci_func(func)->p->source, currentline(func)); | ||
| 741 | luaG_errormsg(L); | 724 | luaG_errormsg(L); |
| 742 | } | 725 | } |
| 743 | 726 | ||
| @@ -756,37 +739,35 @@ static int changedline (Proto *p, int oldpc, int newpc) { | |||
| 756 | 739 | ||
| 757 | 740 | ||
| 758 | void luaG_traceexec (lua_State *L) { | 741 | void luaG_traceexec (lua_State *L) { |
| 759 | StkId func = L->func; | 742 | CallInfo *ci = L->ci; |
| 760 | lu_byte mask = L->hookmask; | 743 | lu_byte mask = L->hookmask; |
| 761 | int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); | 744 | int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); |
| 762 | if (counthook) | 745 | if (counthook) |
| 763 | resethookcount(L); /* reset count */ | 746 | resethookcount(L); /* reset count */ |
| 764 | else if (!(mask & LUA_MASKLINE)) | 747 | else if (!(mask & LUA_MASKLINE)) |
| 765 | return; /* no line hook and count != 0; nothing to be done */ | 748 | return; /* no line hook and count != 0; nothing to be done */ |
| 766 | if (callstatus(func) & CIST_HOOKYIELD) { /* called hook last time? */ | 749 | if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ |
| 767 | callstatus(func) &= ~CIST_HOOKYIELD; /* erase mark */ | 750 | ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ |
| 768 | return; /* do not call hook again (VM yielded, so it did not move) */ | 751 | return; /* do not call hook again (VM yielded, so it did not move) */ |
| 769 | } | 752 | } |
| 770 | if (counthook) | 753 | if (counthook) |
| 771 | luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ | 754 | luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ |
| 772 | if (mask & LUA_MASKLINE) { | 755 | if (mask & LUA_MASKLINE) { |
| 773 | Proto *p = ci_func(func)->p; | 756 | Proto *p = ci_func(ci)->p; |
| 774 | int npc = pcRel(func->stkci.u.l.savedpc, p); | 757 | int npc = pcRel(ci->u.l.savedpc, p); |
| 775 | if (npc == 0 || /* call linehook when enter a new function, */ | 758 | if (npc == 0 || /* call linehook when enter a new function, */ |
| 776 | func->stkci.u.l.savedpc <= L->oldpc || /* when jump back (loop), */ | 759 | ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ |
| 777 | changedline(p, pcRel(L->oldpc, p), npc)) { /* when enter new line */ | 760 | changedline(p, pcRel(L->oldpc, p), npc)) { /* enter new line */ |
| 778 | int newline = luaG_getfuncline(p, npc); /* new line */ | 761 | int newline = luaG_getfuncline(p, npc); /* new line */ |
| 779 | luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ | 762 | luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ |
| 780 | } | 763 | } |
| 781 | } | 764 | } |
| 782 | func = L->func; /* previous calls can reallocate stack */ | 765 | L->oldpc = ci->u.l.savedpc; |
| 783 | L->oldpc = func->stkci.u.l.savedpc; | ||
| 784 | if (L->status == LUA_YIELD) { /* did hook yield? */ | 766 | if (L->status == LUA_YIELD) { /* did hook yield? */ |
| 785 | if (counthook) | 767 | if (counthook) |
| 786 | L->hookcount = 1; /* undo decrement to zero */ | 768 | L->hookcount = 1; /* undo decrement to zero */ |
| 787 | /* undo increment (resume will increment it again) */ | 769 | ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ |
| 788 | func->stkci.u.l.savedpc--; | 770 | ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ |
| 789 | callstatus(func) |= CIST_HOOKYIELD; /* mark that it yielded */ | ||
| 790 | luaD_throw(L, LUA_YIELD); | 771 | luaD_throw(L, LUA_YIELD); |
| 791 | } | 772 | } |
| 792 | } | 773 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 2.168 2017/11/03 20:41:05 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.165 2017/11/02 11:28:56 roberto Exp $ |
| 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 | */ |
| @@ -123,8 +123,8 @@ l_noret luaD_throw (lua_State *L, int errcode) { | |||
| 123 | else { /* no handler at all; abort */ | 123 | else { /* no handler at all; abort */ |
| 124 | if (g->panic) { /* panic function? */ | 124 | if (g->panic) { /* panic function? */ |
| 125 | seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */ | 125 | seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */ |
| 126 | if (functop(L->func) < L->top) /* check invariant */ | 126 | if (L->ci->top < L->top) |
| 127 | setfunctop(L->func, L->top); | 127 | L->ci->top = L->top; /* pushing msg. can break this invariant */ |
| 128 | lua_unlock(L); | 128 | lua_unlock(L); |
| 129 | g->panic(L); /* call panic function (last chance to jump out) */ | 129 | g->panic(L); /* call panic function (last chance to jump out) */ |
| 130 | } | 130 | } |
| @@ -157,11 +157,15 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | |||
| 157 | ** =================================================================== | 157 | ** =================================================================== |
| 158 | */ | 158 | */ |
| 159 | static void correctstack (lua_State *L, StkId oldstack) { | 159 | static void correctstack (lua_State *L, StkId oldstack) { |
| 160 | CallInfo *ci; | ||
| 160 | UpVal *up; | 161 | UpVal *up; |
| 161 | L->top = (L->top - oldstack) + L->stack; | 162 | L->top = (L->top - oldstack) + L->stack; |
| 162 | L->func = (L->func - oldstack) + L->stack; | ||
| 163 | for (up = L->openupval; up != NULL; up = up->u.open.next) | 163 | for (up = L->openupval; up != NULL; up = up->u.open.next) |
| 164 | up->v = s2v((uplevel(up) - oldstack) + L->stack); | 164 | up->v = s2v((uplevel(up) - oldstack) + L->stack); |
| 165 | for (ci = L->ci; ci != NULL; ci = ci->previous) { | ||
| 166 | ci->top = (ci->top - oldstack) + L->stack; | ||
| 167 | ci->func = (ci->func - oldstack) + L->stack; | ||
| 168 | } | ||
| 165 | } | 169 | } |
| 166 | 170 | ||
| 167 | 171 | ||
| @@ -203,11 +207,10 @@ void luaD_growstack (lua_State *L, int n) { | |||
| 203 | 207 | ||
| 204 | 208 | ||
| 205 | static int stackinuse (lua_State *L) { | 209 | static int stackinuse (lua_State *L) { |
| 210 | CallInfo *ci; | ||
| 206 | StkId lim = L->top; | 211 | StkId lim = L->top; |
| 207 | StkId func = L->func; | 212 | for (ci = L->ci; ci != NULL; ci = ci->previous) { |
| 208 | for (; func->stkci.previous != 0; func -= func->stkci.previous) { | 213 | if (lim < ci->top) lim = ci->top; |
| 209 | if (lim < functop(func)) | ||
| 210 | lim = functop(func); | ||
| 211 | } | 214 | } |
| 212 | lua_assert(lim <= L->stack_last); | 215 | lua_assert(lim <= L->stack_last); |
| 213 | return cast_int(lim - L->stack) + 1; /* part of stack in use */ | 216 | return cast_int(lim - L->stack) + 1; /* part of stack in use */ |
| @@ -219,6 +222,10 @@ void luaD_shrinkstack (lua_State *L) { | |||
| 219 | int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; | 222 | int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; |
| 220 | if (goodsize > LUAI_MAXSTACK) | 223 | if (goodsize > LUAI_MAXSTACK) |
| 221 | goodsize = LUAI_MAXSTACK; /* respect stack limit */ | 224 | goodsize = LUAI_MAXSTACK; /* respect stack limit */ |
| 225 | if (L->stacksize > LUAI_MAXSTACK) /* had been handling stack overflow? */ | ||
| 226 | luaE_freeCI(L); /* free all CIs (list grew because of an error) */ | ||
| 227 | else | ||
| 228 | luaE_shrinkCI(L); /* shrink list */ | ||
| 222 | /* if thread is currently not handling a stack overflow and its | 229 | /* if thread is currently not handling a stack overflow and its |
| 223 | good size is smaller than current size, shrink its stack */ | 230 | good size is smaller than current size, shrink its stack */ |
| 224 | if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && | 231 | if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && |
| @@ -245,46 +252,40 @@ void luaD_inctop (lua_State *L) { | |||
| 245 | void luaD_hook (lua_State *L, int event, int line) { | 252 | void luaD_hook (lua_State *L, int event, int line) { |
| 246 | lua_Hook hook = L->hook; | 253 | lua_Hook hook = L->hook; |
| 247 | if (hook && L->allowhook) { /* make sure there is a hook */ | 254 | if (hook && L->allowhook) { /* make sure there is a hook */ |
| 255 | CallInfo *ci = L->ci; | ||
| 248 | ptrdiff_t top = savestack(L, L->top); | 256 | ptrdiff_t top = savestack(L, L->top); |
| 249 | int origframesize = L->func->stkci.framesize; | 257 | ptrdiff_t ci_top = savestack(L, ci->top); |
| 250 | int tmpframesize; /* frame size to run hook */ | ||
| 251 | lua_Debug ar; | 258 | lua_Debug ar; |
| 252 | ar.event = event; | 259 | ar.event = event; |
| 253 | ar.currentline = line; | 260 | ar.currentline = line; |
| 254 | ar.i_actf = L->func - L->stack; | 261 | ar.i_ci = ci; |
| 255 | ar.i_actL = L; | ||
| 256 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 262 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
| 257 | tmpframesize = L->top - L->func + LUA_MINSTACK; | 263 | ci->top = L->top + LUA_MINSTACK; |
| 258 | if (tmpframesize > origframesize) /* need to grow frame? */ | 264 | lua_assert(ci->top <= L->stack_last); |
| 259 | L->func->stkci.framesize = tmpframesize; | ||
| 260 | lua_assert(functop(L->func) <= L->stack_last); | ||
| 261 | L->allowhook = 0; /* cannot call hooks inside a hook */ | 265 | L->allowhook = 0; /* cannot call hooks inside a hook */ |
| 262 | callstatus(L->func) |= CIST_HOOKED; | 266 | ci->callstatus |= CIST_HOOKED; |
| 263 | lua_unlock(L); | 267 | lua_unlock(L); |
| 264 | (*hook)(L, &ar); | 268 | (*hook)(L, &ar); |
| 265 | lua_lock(L); | 269 | lua_lock(L); |
| 266 | lua_assert(!L->allowhook); | 270 | lua_assert(!L->allowhook); |
| 267 | L->allowhook = 1; | 271 | L->allowhook = 1; |
| 268 | L->func->stkci.framesize = origframesize; | 272 | ci->top = restorestack(L, ci_top); |
| 269 | L->top = restorestack(L, top); | 273 | L->top = restorestack(L, top); |
| 270 | callstatus(L->func) &= ~CIST_HOOKED; | 274 | ci->callstatus &= ~CIST_HOOKED; |
| 271 | } | 275 | } |
| 272 | } | 276 | } |
| 273 | 277 | ||
| 274 | 278 | ||
| 275 | static void callhook (lua_State *L) { | 279 | static void callhook (lua_State *L, CallInfo *ci) { |
| 276 | int hook = LUA_HOOKCALL; | 280 | int hook = LUA_HOOKCALL; |
| 277 | StkId func = L->func; | 281 | ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ |
| 278 | StkId previous = func - L->func->stkci.previous; | 282 | if (isLua(ci->previous) && |
| 279 | func->stkci.u.l.savedpc++; /* hooks assume 'pc' is already incremented */ | 283 | GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) { |
| 280 | if (isLua(previous) && | 284 | ci->callstatus |= CIST_TAIL; |
| 281 | GET_OPCODE(*(previous->stkci.u.l.savedpc - 1)) == OP_TAILCALL) { | ||
| 282 | callstatus(L->func) |= CIST_TAIL; | ||
| 283 | hook = LUA_HOOKTAILCALL; | 285 | hook = LUA_HOOKTAILCALL; |
| 284 | } | 286 | } |
| 285 | luaD_hook(L, hook, -1); | 287 | luaD_hook(L, hook, -1); |
| 286 | func = L->func; /* previous call can change stack */ | 288 | ci->u.l.savedpc--; /* correct 'pc' */ |
| 287 | func->stkci.u.l.savedpc--; /* correct 'pc' */ | ||
| 288 | } | 289 | } |
| 289 | 290 | ||
| 290 | 291 | ||
| @@ -355,25 +356,28 @@ static int moveresults (lua_State *L, StkId firstResult, StkId res, | |||
| 355 | ** moves current number of results to proper place; returns 0 iff call | 356 | ** moves current number of results to proper place; returns 0 iff call |
| 356 | ** wanted multiple (variable number of) results. | 357 | ** wanted multiple (variable number of) results. |
| 357 | */ | 358 | */ |
| 358 | int luaD_poscall (lua_State *L, StkId firstResult, int nres) { | 359 | int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { |
| 359 | StkId res = L->func; /* res == final position of 1st result */ | 360 | StkId res; |
| 360 | int wanted = res->stkci.nresults; | 361 | int wanted = ci->nresults; |
| 361 | if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { | 362 | if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { |
| 362 | if (L->hookmask & LUA_MASKRET) { | 363 | if (L->hookmask & LUA_MASKRET) { |
| 363 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ | 364 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ |
| 364 | luaD_hook(L, LUA_HOOKRET, -1); | 365 | luaD_hook(L, LUA_HOOKRET, -1); |
| 365 | firstResult = restorestack(L, fr); | 366 | firstResult = restorestack(L, fr); |
| 366 | res = L->func; | ||
| 367 | } | 367 | } |
| 368 | /* 'oldpc' for caller function */ | 368 | L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ |
| 369 | L->oldpc = (res - res->stkci.previous)->stkci.u.l.savedpc; | ||
| 370 | } | 369 | } |
| 371 | L->func = res - res->stkci.previous; | 370 | res = ci->func; /* res == final position of 1st result */ |
| 371 | L->ci = ci->previous; /* back to caller */ | ||
| 372 | /* move results to proper place */ | 372 | /* move results to proper place */ |
| 373 | return moveresults(L, firstResult, res, nres, wanted); | 373 | return moveresults(L, firstResult, res, nres, wanted); |
| 374 | } | 374 | } |
| 375 | 375 | ||
| 376 | 376 | ||
| 377 | |||
| 378 | #define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) | ||
| 379 | |||
| 380 | |||
| 377 | /* | 381 | /* |
| 378 | ** Prepares a function call: checks the stack, creates a new CallInfo | 382 | ** Prepares a function call: checks the stack, creates a new CallInfo |
| 379 | ** entry, fills in the relevant information, calls hook if needed. | 383 | ** entry, fills in the relevant information, calls hook if needed. |
| @@ -384,6 +388,7 @@ int luaD_poscall (lua_State *L, StkId firstResult, int nres) { | |||
| 384 | int luaD_precall (lua_State *L, StkId func, int nresults) { | 388 | int luaD_precall (lua_State *L, StkId func, int nresults) { |
| 385 | lua_CFunction f; | 389 | lua_CFunction f; |
| 386 | TValue *funcv = s2v(func); | 390 | TValue *funcv = s2v(func); |
| 391 | CallInfo *ci; | ||
| 387 | switch (ttype(funcv)) { | 392 | switch (ttype(funcv)) { |
| 388 | case LUA_TCCL: /* C closure */ | 393 | case LUA_TCCL: /* C closure */ |
| 389 | f = clCvalue(funcv)->f; | 394 | f = clCvalue(funcv)->f; |
| @@ -393,19 +398,19 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
| 393 | Cfunc: { | 398 | Cfunc: { |
| 394 | int n; /* number of returns */ | 399 | int n; /* number of returns */ |
| 395 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ | 400 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ |
| 396 | func->stkci.nresults = nresults; | 401 | ci = next_ci(L); /* now 'enter' new function */ |
| 397 | func->stkci.previous = func - L->func; | 402 | ci->nresults = nresults; |
| 398 | L->func = func; | 403 | ci->func = func; |
| 399 | setfunctop(func, L->top + LUA_MINSTACK); | 404 | ci->top = L->top + LUA_MINSTACK; |
| 400 | lua_assert(functop(func) <= L->stack_last); | 405 | lua_assert(ci->top <= L->stack_last); |
| 401 | callstatus(func) = 0; | 406 | ci->callstatus = 0; |
| 402 | if (L->hookmask & LUA_MASKCALL) | 407 | if (L->hookmask & LUA_MASKCALL) |
| 403 | luaD_hook(L, LUA_HOOKCALL, -1); | 408 | luaD_hook(L, LUA_HOOKCALL, -1); |
| 404 | lua_unlock(L); | 409 | lua_unlock(L); |
| 405 | n = (*f)(L); /* do the actual call */ | 410 | n = (*f)(L); /* do the actual call */ |
| 406 | lua_lock(L); | 411 | lua_lock(L); |
| 407 | api_checknelems(L, n); | 412 | api_checknelems(L, n); |
| 408 | luaD_poscall(L, L->top - n, n); | 413 | luaD_poscall(L, ci, L->top - n, n); |
| 409 | return 1; | 414 | return 1; |
| 410 | } | 415 | } |
| 411 | case LUA_TLCL: { /* Lua function: prepare its call */ | 416 | case LUA_TLCL: { /* Lua function: prepare its call */ |
| @@ -417,16 +422,15 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
| 417 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ | 422 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ |
| 418 | if (p->is_vararg) | 423 | if (p->is_vararg) |
| 419 | luaT_adjustvarargs(L, p, n); | 424 | luaT_adjustvarargs(L, p, n); |
| 420 | func->stkci.nresults = nresults; | 425 | ci = next_ci(L); /* now 'enter' new function */ |
| 421 | func->stkci.previous = func - L->func; | 426 | ci->nresults = nresults; |
| 422 | func->stkci.framesize = fsize + 1; /* size includes function itself */ | 427 | ci->func = func; |
| 423 | L->func = func; | 428 | L->top = ci->top = func + 1 + fsize; |
| 424 | L->top = func + 1 + fsize; | 429 | lua_assert(ci->top <= L->stack_last); |
| 425 | lua_assert(functop(func) <= L->stack_last); | 430 | ci->u.l.savedpc = p->code; /* starting point */ |
| 426 | func->stkci.u.l.savedpc = p->code; /* starting point */ | 431 | ci->callstatus = CIST_LUA; |
| 427 | callstatus(func) = 0; | ||
| 428 | if (L->hookmask & LUA_MASKCALL) | 432 | if (L->hookmask & LUA_MASKCALL) |
| 429 | callhook(L); | 433 | callhook(L, ci); |
| 430 | return 0; | 434 | return 0; |
| 431 | } | 435 | } |
| 432 | default: { /* not a function */ | 436 | default: { /* not a function */ |
| @@ -483,25 +487,24 @@ void luaD_callnoyield (lua_State *L, StkId func, int nResults) { | |||
| 483 | ** continuation function. | 487 | ** continuation function. |
| 484 | */ | 488 | */ |
| 485 | static void finishCcall (lua_State *L, int status) { | 489 | static void finishCcall (lua_State *L, int status) { |
| 486 | StkId func = L->func; | 490 | CallInfo *ci = L->ci; |
| 487 | int n; | 491 | int n; |
| 488 | /* must have a continuation and must be able to call it */ | 492 | /* must have a continuation and must be able to call it */ |
| 489 | lua_assert(func->stkci.u.c.k != NULL && L->nny == 0); | 493 | lua_assert(ci->u.c.k != NULL && L->nny == 0); |
| 490 | /* error status can only happen in a protected call */ | 494 | /* error status can only happen in a protected call */ |
| 491 | lua_assert((callstatus(func) & CIST_YPCALL) || status == LUA_YIELD); | 495 | lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); |
| 492 | if (callstatus(func) & CIST_YPCALL) { /* was inside a pcall? */ | 496 | if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ |
| 493 | callstatus(func) &= ~CIST_YPCALL; /* continuation is also inside it */ | 497 | ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */ |
| 494 | L->errfunc = func->stkci.u.c.old_errfunc; /* with same error function */ | 498 | L->errfunc = ci->u.c.old_errfunc; /* with the same error function */ |
| 495 | } | 499 | } |
| 496 | /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already | 500 | /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already |
| 497 | handled */ | 501 | handled */ |
| 498 | adjustresults(L, func->stkci.nresults); | 502 | adjustresults(L, ci->nresults); |
| 499 | lua_unlock(L); | 503 | lua_unlock(L); |
| 500 | /* call continuation function */ | 504 | n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ |
| 501 | n = (*func->stkci.u.c.k)(L, status, func->stkci.u.c.ctx); | ||
| 502 | lua_lock(L); | 505 | lua_lock(L); |
| 503 | api_checknelems(L, n); | 506 | api_checknelems(L, n); |
| 504 | luaD_poscall(L, L->top - n, n); /* finish 'luaD_precall' */ | 507 | luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */ |
| 505 | } | 508 | } |
| 506 | 509 | ||
| 507 | 510 | ||
| @@ -516,8 +519,8 @@ static void finishCcall (lua_State *L, int status) { | |||
| 516 | static void unroll (lua_State *L, void *ud) { | 519 | static void unroll (lua_State *L, void *ud) { |
| 517 | if (ud != NULL) /* error status? */ | 520 | if (ud != NULL) /* error status? */ |
| 518 | finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */ | 521 | finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */ |
| 519 | while (L->func != L->stack) { /* something in the stack */ | 522 | while (L->ci != &L->base_ci) { /* something in the stack */ |
| 520 | if (!isLua(L->func)) /* C function? */ | 523 | if (!isLua(L->ci)) /* C function? */ |
| 521 | finishCcall(L, LUA_YIELD); /* complete its execution */ | 524 | finishCcall(L, LUA_YIELD); /* complete its execution */ |
| 522 | else { /* Lua function */ | 525 | else { /* Lua function */ |
| 523 | luaV_finishOp(L); /* finish interrupted instruction */ | 526 | luaV_finishOp(L); /* finish interrupted instruction */ |
| @@ -531,13 +534,11 @@ static void unroll (lua_State *L, void *ud) { | |||
| 531 | ** Try to find a suspended protected call (a "recover point") for the | 534 | ** Try to find a suspended protected call (a "recover point") for the |
| 532 | ** given thread. | 535 | ** given thread. |
| 533 | */ | 536 | */ |
| 534 | static StkId findpcall (lua_State *L) { | 537 | static CallInfo *findpcall (lua_State *L) { |
| 535 | StkId func; | 538 | CallInfo *ci; |
| 536 | for (func = L->func; | 539 | for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ |
| 537 | func->stkci.previous != 0; | 540 | if (ci->callstatus & CIST_YPCALL) |
| 538 | func -= func->stkci.previous) { | 541 | return ci; |
| 539 | if (callstatus(func) & CIST_YPCALL) | ||
| 540 | return func; | ||
| 541 | } | 542 | } |
| 542 | return NULL; /* no pending pcall */ | 543 | return NULL; /* no pending pcall */ |
| 543 | } | 544 | } |
| @@ -550,17 +551,17 @@ static StkId findpcall (lua_State *L) { | |||
| 550 | */ | 551 | */ |
| 551 | static int recover (lua_State *L, int status) { | 552 | static int recover (lua_State *L, int status) { |
| 552 | StkId oldtop; | 553 | StkId oldtop; |
| 553 | StkId recf = findpcall(L); | 554 | CallInfo *ci = findpcall(L); |
| 554 | if (recf == NULL) return 0; /* no recovery point */ | 555 | if (ci == NULL) return 0; /* no recovery point */ |
| 555 | /* "finish" luaD_pcall */ | 556 | /* "finish" luaD_pcall */ |
| 556 | oldtop = recf + recf->stkci.u2.funcidx; | 557 | oldtop = restorestack(L, ci->u2.funcidx); |
| 557 | luaF_close(L, oldtop); | 558 | luaF_close(L, oldtop); |
| 558 | seterrorobj(L, status, oldtop); | 559 | seterrorobj(L, status, oldtop); |
| 559 | L->func = recf; | 560 | L->ci = ci; |
| 560 | L->allowhook = getoah(callstatus(recf)); /* restore original 'allowhook' */ | 561 | L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ |
| 561 | L->nny = 0; /* should be zero to be yieldable */ | 562 | L->nny = 0; /* should be zero to be yieldable */ |
| 562 | luaD_shrinkstack(L); | 563 | luaD_shrinkstack(L); |
| 563 | L->errfunc = recf->stkci.u.c.old_errfunc; | 564 | L->errfunc = ci->u.c.old_errfunc; |
| 564 | return 1; /* continue running the coroutine */ | 565 | return 1; /* continue running the coroutine */ |
| 565 | } | 566 | } |
| 566 | 567 | ||
| @@ -589,7 +590,7 @@ static int resume_error (lua_State *L, const char *msg, int narg) { | |||
| 589 | static void resume (lua_State *L, void *ud) { | 590 | static void resume (lua_State *L, void *ud) { |
| 590 | int n = *(cast(int*, ud)); /* number of arguments */ | 591 | int n = *(cast(int*, ud)); /* number of arguments */ |
| 591 | StkId firstArg = L->top - n; /* first argument */ | 592 | StkId firstArg = L->top - n; /* first argument */ |
| 592 | StkId func = L->func; | 593 | CallInfo *ci = L->ci; |
| 593 | if (L->status == LUA_OK) { /* starting a coroutine? */ | 594 | if (L->status == LUA_OK) { /* starting a coroutine? */ |
| 594 | if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ | 595 | if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ |
| 595 | luaV_execute(L); /* call it */ | 596 | luaV_execute(L); /* call it */ |
| @@ -597,18 +598,17 @@ static void resume (lua_State *L, void *ud) { | |||
| 597 | else { /* resuming from previous yield */ | 598 | else { /* resuming from previous yield */ |
| 598 | lua_assert(L->status == LUA_YIELD); | 599 | lua_assert(L->status == LUA_YIELD); |
| 599 | L->status = LUA_OK; /* mark that it is running (again) */ | 600 | L->status = LUA_OK; /* mark that it is running (again) */ |
| 600 | if (isLua(func)) /* yielded inside a hook? */ | 601 | if (isLua(ci)) /* yielded inside a hook? */ |
| 601 | luaV_execute(L); /* just continue running Lua code */ | 602 | luaV_execute(L); /* just continue running Lua code */ |
| 602 | else { /* 'common' yield */ | 603 | else { /* 'common' yield */ |
| 603 | if (func->stkci.u.c.k != NULL) { /* does it have a continuation? */ | 604 | if (ci->u.c.k != NULL) { /* does it have a continuation function? */ |
| 604 | lua_unlock(L); | 605 | lua_unlock(L); |
| 605 | /* call continuation */ | 606 | n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ |
| 606 | n = (*func->stkci.u.c.k)(L, LUA_YIELD, func->stkci.u.c.ctx); | ||
| 607 | lua_lock(L); | 607 | lua_lock(L); |
| 608 | api_checknelems(L, n); | 608 | api_checknelems(L, n); |
| 609 | firstArg = L->top - n; /* yield results come from continuation */ | 609 | firstArg = L->top - n; /* yield results come from continuation */ |
| 610 | } | 610 | } |
| 611 | luaD_poscall(L, firstArg, n); /* finish 'luaD_precall' */ | 611 | luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */ |
| 612 | } | 612 | } |
| 613 | unroll(L, NULL); /* run continuation */ | 613 | unroll(L, NULL); /* run continuation */ |
| 614 | } | 614 | } |
| @@ -621,7 +621,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, | |||
| 621 | unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */ | 621 | unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */ |
| 622 | lua_lock(L); | 622 | lua_lock(L); |
| 623 | if (L->status == LUA_OK) { /* may be starting a coroutine */ | 623 | if (L->status == LUA_OK) { /* may be starting a coroutine */ |
| 624 | if (L->func != L->stack) /* not in base level? */ | 624 | if (L->ci != &L->base_ci) /* not in base level? */ |
| 625 | return resume_error(L, "cannot resume non-suspended coroutine", nargs); | 625 | return resume_error(L, "cannot resume non-suspended coroutine", nargs); |
| 626 | } | 626 | } |
| 627 | else if (L->status != LUA_YIELD) | 627 | else if (L->status != LUA_YIELD) |
| @@ -643,12 +643,12 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, | |||
| 643 | if (errorstatus(status)) { /* unrecoverable error? */ | 643 | if (errorstatus(status)) { /* unrecoverable error? */ |
| 644 | L->status = cast_byte(status); /* mark thread as 'dead' */ | 644 | L->status = cast_byte(status); /* mark thread as 'dead' */ |
| 645 | seterrorobj(L, status, L->top); /* push error message */ | 645 | seterrorobj(L, status, L->top); /* push error message */ |
| 646 | L->func->stkci.framesize = L->top - L->func; | 646 | L->ci->top = L->top; |
| 647 | } | 647 | } |
| 648 | else lua_assert(status == L->status); /* normal end or yield */ | 648 | else lua_assert(status == L->status); /* normal end or yield */ |
| 649 | } | 649 | } |
| 650 | *nresults = (status == LUA_YIELD) ? L->func->stkci.u2.nyield | 650 | *nresults = (status == LUA_YIELD) ? L->ci->u2.nyield |
| 651 | : L->top - (L->func + 1); | 651 | : L->top - (L->ci->func + 1); |
| 652 | L->nny = oldnny; /* restore 'nny' */ | 652 | L->nny = oldnny; /* restore 'nny' */ |
| 653 | L->nCcalls--; | 653 | L->nCcalls--; |
| 654 | lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); | 654 | lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); |
| @@ -664,7 +664,7 @@ LUA_API int lua_isyieldable (lua_State *L) { | |||
| 664 | 664 | ||
| 665 | LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, | 665 | LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, |
| 666 | lua_KFunction k) { | 666 | lua_KFunction k) { |
| 667 | StkId func = L->func; | 667 | CallInfo *ci = L->ci; |
| 668 | luai_userstateyield(L, nresults); | 668 | luai_userstateyield(L, nresults); |
| 669 | lua_lock(L); | 669 | lua_lock(L); |
| 670 | api_checknelems(L, nresults); | 670 | api_checknelems(L, nresults); |
| @@ -675,17 +675,17 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, | |||
| 675 | luaG_runerror(L, "attempt to yield from outside a coroutine"); | 675 | luaG_runerror(L, "attempt to yield from outside a coroutine"); |
| 676 | } | 676 | } |
| 677 | L->status = LUA_YIELD; | 677 | L->status = LUA_YIELD; |
| 678 | if (isLua(func)) { /* inside a hook? */ | 678 | if (isLua(ci)) { /* inside a hook? */ |
| 679 | api_check(L, k == NULL, "hooks cannot continue after yielding"); | 679 | api_check(L, k == NULL, "hooks cannot continue after yielding"); |
| 680 | func->stkci.u2.nyield = 0; /* no results */ | 680 | ci->u2.nyield = 0; /* no results */ |
| 681 | } | 681 | } |
| 682 | else { | 682 | else { |
| 683 | if ((func->stkci.u.c.k = k) != NULL) /* is there a continuation? */ | 683 | if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ |
| 684 | func->stkci.u.c.ctx = ctx; /* save context */ | 684 | ci->u.c.ctx = ctx; /* save context */ |
| 685 | func->stkci.u2.nyield = nresults; /* save number of results */ | 685 | ci->u2.nyield = nresults; /* save number of results */ |
| 686 | luaD_throw(L, LUA_YIELD); | 686 | luaD_throw(L, LUA_YIELD); |
| 687 | } | 687 | } |
| 688 | lua_assert(callstatus(func) & CIST_HOOKED); /* must be inside a hook */ | 688 | lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ |
| 689 | lua_unlock(L); | 689 | lua_unlock(L); |
| 690 | return 0; /* return to 'luaD_hook' */ | 690 | return 0; /* return to 'luaD_hook' */ |
| 691 | } | 691 | } |
| @@ -694,7 +694,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, | |||
| 694 | int luaD_pcall (lua_State *L, Pfunc func, void *u, | 694 | int luaD_pcall (lua_State *L, Pfunc func, void *u, |
| 695 | ptrdiff_t old_top, ptrdiff_t ef) { | 695 | ptrdiff_t old_top, ptrdiff_t ef) { |
| 696 | int status; | 696 | int status; |
| 697 | ptrdiff_t oldfunc = savestack(L, L->func); | 697 | CallInfo *old_ci = L->ci; |
| 698 | lu_byte old_allowhooks = L->allowhook; | 698 | lu_byte old_allowhooks = L->allowhook; |
| 699 | unsigned short old_nny = L->nny; | 699 | unsigned short old_nny = L->nny; |
| 700 | ptrdiff_t old_errfunc = L->errfunc; | 700 | ptrdiff_t old_errfunc = L->errfunc; |
| @@ -704,7 +704,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, | |||
| 704 | StkId oldtop = restorestack(L, old_top); | 704 | StkId oldtop = restorestack(L, old_top); |
| 705 | luaF_close(L, oldtop); /* close possible pending closures */ | 705 | luaF_close(L, oldtop); /* close possible pending closures */ |
| 706 | seterrorobj(L, status, oldtop); | 706 | seterrorobj(L, status, oldtop); |
| 707 | L->func = restorestack(L, oldfunc); | 707 | L->ci = old_ci; |
| 708 | L->allowhook = old_allowhooks; | 708 | L->allowhook = old_allowhooks; |
| 709 | L->nny = old_nny; | 709 | L->nny = old_nny; |
| 710 | luaD_shrinkstack(L); | 710 | luaD_shrinkstack(L); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.h,v 2.31 2017/06/29 15:06:44 roberto Exp roberto $ | 2 | ** $Id: ldo.h,v 2.31 2017/06/29 15:06:44 roberto Exp $ |
| 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 | */ |
| @@ -52,7 +52,8 @@ LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); | |||
| 52 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); | 52 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); |
| 53 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, | 53 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, |
| 54 | ptrdiff_t oldtop, ptrdiff_t ef); | 54 | ptrdiff_t oldtop, ptrdiff_t ef); |
| 55 | LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult, int nres); | 55 | LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, |
| 56 | int nres); | ||
| 56 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); | 57 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); |
| 57 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); | 58 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); |
| 58 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); | 59 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.236 2017/10/31 15:29:28 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.236 2017/10/31 15:29:28 roberto Exp $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -866,9 +866,9 @@ static void GCTM (lua_State *L, int propagateerrors) { | |||
| 866 | setobj2s(L, L->top, tm); /* push finalizer... */ | 866 | setobj2s(L, L->top, tm); /* push finalizer... */ |
| 867 | setobj2s(L, L->top + 1, &v); /* ... and its argument */ | 867 | setobj2s(L, L->top + 1, &v); /* ... and its argument */ |
| 868 | L->top += 2; /* and (next line) call the finalizer */ | 868 | L->top += 2; /* and (next line) call the finalizer */ |
| 869 | callstatus(L->func) |= CIST_FIN; /* will run a finalizer */ | 869 | L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ |
| 870 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); | 870 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); |
| 871 | callstatus(L->func) &= ~CIST_FIN; /* not running a finalizer anymore */ | 871 | L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ |
| 872 | L->allowhook = oldah; /* restore hooks */ | 872 | L->allowhook = oldah; /* restore hooks */ |
| 873 | g->gcrunning = running; /* restore state */ | 873 | g->gcrunning = running; /* restore state */ |
| 874 | if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ | 874 | if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 2.128 2017/11/03 17:22:54 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 2.125 2017/06/29 15:06:44 roberto Exp $ |
| 3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -311,39 +311,9 @@ typedef struct TValue { | |||
| 311 | 311 | ||
| 312 | typedef union StackValue { | 312 | typedef union StackValue { |
| 313 | TValue val; | 313 | TValue val; |
| 314 | struct { | ||
| 315 | TValuefields; | ||
| 316 | lu_byte callstatus_; | ||
| 317 | char nresults; /* expected number of results from this function */ | ||
| 318 | union { | ||
| 319 | unsigned char funcidx; /* called-function index */ | ||
| 320 | unsigned char nyield; /* number of values yielded */ | ||
| 321 | } u2; | ||
| 322 | unsigned short previous; /* difference to previous 'func' */ | ||
| 323 | unsigned short framesize; /* stack space available for this function */ | ||
| 324 | union { | ||
| 325 | struct { /* only for Lua functions */ | ||
| 326 | const Instruction *savedpc; | ||
| 327 | } l; | ||
| 328 | struct { /* only for C functions */ | ||
| 329 | lua_KFunction k; /* continuation in case of yields */ | ||
| 330 | int old_errfunc; | ||
| 331 | int ctx; /* context info. in case of yields */ | ||
| 332 | } c; | ||
| 333 | } u; | ||
| 334 | } stkci; | ||
| 335 | } StackValue; | 314 | } StackValue; |
| 336 | 315 | ||
| 337 | 316 | ||
| 338 | #define callstatus(ar) ((ar)->stkci.callstatus_) | ||
| 339 | |||
| 340 | /* top of a function (first element after its frame) */ | ||
| 341 | #define functop(func) ((func) + (func)->stkci.framesize) | ||
| 342 | |||
| 343 | /* set top of a function to a specific value */ | ||
| 344 | #define setfunctop(func,v) ((func)->stkci.framesize = (v) - (func)) | ||
| 345 | |||
| 346 | |||
| 347 | typedef StackValue *StkId; /* index to stack elements */ | 317 | typedef StackValue *StkId; /* index to stack elements */ |
| 348 | 318 | ||
| 349 | /* convert a 'StackValue' to a 'TValue' */ | 319 | /* convert a 'StackValue' to a 'TValue' */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 2.144 2017/11/03 12:12:30 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 2.143 2017/10/31 17:54:35 roberto Exp $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -97,8 +97,51 @@ void luaE_setdebt (global_State *g, l_mem debt) { | |||
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | 99 | ||
| 100 | CallInfo *luaE_extendCI (lua_State *L) { | ||
| 101 | CallInfo *ci = luaM_new(L, CallInfo); | ||
| 102 | lua_assert(L->ci->next == NULL); | ||
| 103 | L->ci->next = ci; | ||
| 104 | ci->previous = L->ci; | ||
| 105 | ci->next = NULL; | ||
| 106 | L->nci++; | ||
| 107 | return ci; | ||
| 108 | } | ||
| 109 | |||
| 110 | |||
| 111 | /* | ||
| 112 | ** free all CallInfo structures not in use by a thread | ||
| 113 | */ | ||
| 114 | void luaE_freeCI (lua_State *L) { | ||
| 115 | CallInfo *ci = L->ci; | ||
| 116 | CallInfo *next = ci->next; | ||
| 117 | ci->next = NULL; | ||
| 118 | while ((ci = next) != NULL) { | ||
| 119 | next = ci->next; | ||
| 120 | luaM_free(L, ci); | ||
| 121 | L->nci--; | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | |||
| 126 | /* | ||
| 127 | ** free half of the CallInfo structures not in use by a thread | ||
| 128 | */ | ||
| 129 | void luaE_shrinkCI (lua_State *L) { | ||
| 130 | CallInfo *ci = L->ci; | ||
| 131 | CallInfo *next2; /* next's next */ | ||
| 132 | /* while there are two nexts */ | ||
| 133 | while (ci->next != NULL && (next2 = ci->next->next) != NULL) { | ||
| 134 | luaM_free(L, ci->next); /* free next */ | ||
| 135 | L->nci--; | ||
| 136 | ci->next = next2; /* remove 'next' from the list */ | ||
| 137 | next2->previous = ci; | ||
| 138 | ci = next2; /* keep next's next */ | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | |||
| 100 | static void stack_init (lua_State *L1, lua_State *L) { | 143 | static void stack_init (lua_State *L1, lua_State *L) { |
| 101 | int i; | 144 | int i; CallInfo *ci; |
| 102 | /* initialize stack array */ | 145 | /* initialize stack array */ |
| 103 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, StackValue); | 146 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, StackValue); |
| 104 | L1->stacksize = BASIC_STACK_SIZE; | 147 | L1->stacksize = BASIC_STACK_SIZE; |
| @@ -106,19 +149,23 @@ static void stack_init (lua_State *L1, lua_State *L) { | |||
| 106 | setnilvalue(s2v(L1->stack + i)); /* erase new stack */ | 149 | setnilvalue(s2v(L1->stack + i)); /* erase new stack */ |
| 107 | L1->top = L1->stack; | 150 | L1->top = L1->stack; |
| 108 | L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; | 151 | L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; |
| 109 | /* initialize first 'function' */ | 152 | /* initialize first ci */ |
| 110 | L1->func = L1->stack; | 153 | ci = &L1->base_ci; |
| 111 | L1->func->stkci.previous = 0; /* end of linked list */ | 154 | ci->next = ci->previous = NULL; |
| 112 | L1->func->stkci.framesize = LUA_MINSTACK + 1; | 155 | ci->callstatus = 0; |
| 113 | callstatus(L1->func) = 0; | 156 | ci->func = L1->top; |
| 114 | setnilvalue(s2v(L1->top)); /* 'function' entry for this 'ci' */ | 157 | setnilvalue(s2v(L1->top)); /* 'function' entry for this 'ci' */ |
| 115 | L1->top++; | 158 | L1->top++; |
| 159 | ci->top = L1->top + LUA_MINSTACK; | ||
| 160 | L1->ci = ci; | ||
| 116 | } | 161 | } |
| 117 | 162 | ||
| 118 | 163 | ||
| 119 | static void freestack (lua_State *L) { | 164 | static void freestack (lua_State *L) { |
| 120 | if (L->stack == NULL) | 165 | if (L->stack == NULL) |
| 121 | return; /* stack not completely built yet */ | 166 | return; /* stack not completely built yet */ |
| 167 | L->ci = &L->base_ci; /* free the entire 'ci' list */ | ||
| 168 | luaE_freeCI(L); | ||
| 122 | lua_assert(L->nci == 0); | 169 | lua_assert(L->nci == 0); |
| 123 | luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ | 170 | luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ |
| 124 | } | 171 | } |
| @@ -168,7 +215,7 @@ static void f_luaopen (lua_State *L, void *ud) { | |||
| 168 | static void preinit_thread (lua_State *L, global_State *g) { | 215 | static void preinit_thread (lua_State *L, global_State *g) { |
| 169 | G(L) = g; | 216 | G(L) = g; |
| 170 | L->stack = NULL; | 217 | L->stack = NULL; |
| 171 | L->func = NULL; | 218 | L->ci = NULL; |
| 172 | L->nci = 0; | 219 | L->nci = 0; |
| 173 | L->stacksize = 0; | 220 | L->stacksize = 0; |
| 174 | L->twups = L; /* thread has no upvalues */ | 221 | L->twups = L; /* thread has no upvalues */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 2.148 2017/11/03 17:22:54 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.146 2017/11/02 11:28:56 roberto Exp $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -81,21 +81,47 @@ typedef struct stringtable { | |||
| 81 | } stringtable; | 81 | } stringtable; |
| 82 | 82 | ||
| 83 | 83 | ||
| 84 | /* | ||
| 85 | ** Information about a call. | ||
| 86 | */ | ||
| 87 | typedef struct CallInfo { | ||
| 88 | StkId func; /* function index in the stack */ | ||
| 89 | StkId top; /* top for this function */ | ||
| 90 | struct CallInfo *previous, *next; /* dynamic call link */ | ||
| 91 | union { | ||
| 92 | struct { /* only for Lua functions */ | ||
| 93 | const Instruction *savedpc; | ||
| 94 | } l; | ||
| 95 | struct { /* only for C functions */ | ||
| 96 | lua_KFunction k; /* continuation in case of yields */ | ||
| 97 | ptrdiff_t old_errfunc; | ||
| 98 | lua_KContext ctx; /* context info. in case of yields */ | ||
| 99 | } c; | ||
| 100 | } u; | ||
| 101 | union { | ||
| 102 | int funcidx; /* called-function index */ | ||
| 103 | int nyield; /* number of values yielded */ | ||
| 104 | } u2; | ||
| 105 | short nresults; /* expected number of results from this function */ | ||
| 106 | unsigned short callstatus; | ||
| 107 | } CallInfo; | ||
| 108 | |||
| 84 | 109 | ||
| 85 | /* | 110 | /* |
| 86 | ** Bits in CallInfo status | 111 | ** Bits in CallInfo status |
| 87 | */ | 112 | */ |
| 88 | #define CIST_OAH (1<<0) /* original value of 'allowhook' */ | 113 | #define CIST_OAH (1<<0) /* original value of 'allowhook' */ |
| 89 | #define CIST_HOOKED (1<<1) /* call is running a debug hook */ | 114 | #define CIST_LUA (1<<1) /* call is running a Lua function */ |
| 90 | #define CIST_FRESH (1<<2) /* call is running on a fresh invocation | 115 | #define CIST_HOOKED (1<<2) /* call is running a debug hook */ |
| 116 | #define CIST_FRESH (1<<3) /* call is running on a fresh invocation | ||
| 91 | of luaV_execute */ | 117 | of luaV_execute */ |
| 92 | #define CIST_YPCALL (1<<3) /* call is a yieldable protected call */ | 118 | #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ |
| 93 | #define CIST_TAIL (1<<4) /* call was tail called */ | 119 | #define CIST_TAIL (1<<5) /* call was tail called */ |
| 94 | #define CIST_HOOKYIELD (1<<5) /* last hook called yielded */ | 120 | #define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ |
| 95 | #define CIST_LEQ (1<<6) /* using __lt for __le */ | 121 | #define CIST_LEQ (1<<7) /* using __lt for __le */ |
| 96 | #define CIST_FIN (1<<7) /* call is running a finalizer */ | 122 | #define CIST_FIN (1<<8) /* call is running a finalizer */ |
| 97 | 123 | ||
| 98 | #define isLua(func) isLfunction(s2v(func)) | 124 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) |
| 99 | 125 | ||
| 100 | /* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ | 126 | /* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ |
| 101 | #define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) | 127 | #define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) |
| @@ -162,7 +188,7 @@ struct lua_State { | |||
| 162 | lu_byte status; | 188 | lu_byte status; |
| 163 | StkId top; /* first free slot in the stack */ | 189 | StkId top; /* first free slot in the stack */ |
| 164 | global_State *l_G; | 190 | global_State *l_G; |
| 165 | StkId func; /* current function */ | 191 | CallInfo *ci; /* call info for current function */ |
| 166 | const Instruction *oldpc; /* last pc traced */ | 192 | const Instruction *oldpc; /* last pc traced */ |
| 167 | StkId stack_last; /* last free slot in the stack */ | 193 | StkId stack_last; /* last free slot in the stack */ |
| 168 | StkId stack; /* stack base */ | 194 | StkId stack; /* stack base */ |
| @@ -170,6 +196,7 @@ struct lua_State { | |||
| 170 | GCObject *gclist; | 196 | GCObject *gclist; |
| 171 | struct lua_State *twups; /* list of threads with open upvalues */ | 197 | struct lua_State *twups; /* list of threads with open upvalues */ |
| 172 | struct lua_longjmp *errorJmp; /* current error recover point */ | 198 | struct lua_longjmp *errorJmp; /* current error recover point */ |
| 199 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ | ||
| 173 | volatile lua_Hook hook; | 200 | volatile lua_Hook hook; |
| 174 | ptrdiff_t errfunc; /* current error handling function (stack index) */ | 201 | ptrdiff_t errfunc; /* current error handling function (stack index) */ |
| 175 | int stacksize; | 202 | int stacksize; |
| @@ -225,6 +252,9 @@ union GCUnion { | |||
| 225 | 252 | ||
| 226 | LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); | 253 | LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); |
| 227 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); | 254 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); |
| 255 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); | ||
| 256 | LUAI_FUNC void luaE_freeCI (lua_State *L); | ||
| 257 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); | ||
| 228 | 258 | ||
| 229 | 259 | ||
| 230 | #endif | 260 | #endif |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltests.c,v 2.228 2017/11/03 12:12:30 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.227 2017/11/02 11:28:56 roberto Exp $ |
| 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 | */ |
| @@ -46,7 +46,7 @@ void *l_Trick = 0; | |||
| 46 | int islocked = 0; | 46 | int islocked = 0; |
| 47 | 47 | ||
| 48 | 48 | ||
| 49 | #define obj_at(L,k) s2v(L->func + (k)) | 49 | #define obj_at(L,k) s2v(L->ci->func + (k)) |
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | static int runC (lua_State *L, lua_State *L1, const char *pc); | 52 | static int runC (lua_State *L, lua_State *L1, const char *pc); |
| @@ -309,27 +309,28 @@ static void checkLclosure (global_State *g, LClosure *cl) { | |||
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | 311 | ||
| 312 | static int lua_checkpc (StkId func) { | 312 | static int lua_checkpc (CallInfo *ci) { |
| 313 | if (!isLua(func)) return 1; | 313 | if (!isLua(ci)) return 1; |
| 314 | else { | 314 | else { |
| 315 | Proto *p = clLvalue(s2v(func))->p; | 315 | StkId f = ci->func; |
| 316 | return p->code <= func->stkci.u.l.savedpc && | 316 | Proto *p = clLvalue(s2v(f))->p; |
| 317 | func->stkci.u.l.savedpc <= p->code + p->sizecode; | 317 | return p->code <= ci->u.l.savedpc && |
| 318 | ci->u.l.savedpc <= p->code + p->sizecode; | ||
| 318 | } | 319 | } |
| 319 | } | 320 | } |
| 320 | 321 | ||
| 321 | 322 | ||
| 322 | static void checkstack (global_State *g, lua_State *L1) { | 323 | static void checkstack (global_State *g, lua_State *L1) { |
| 323 | StkId o; | 324 | StkId o; |
| 325 | CallInfo *ci; | ||
| 324 | UpVal *uv; | 326 | UpVal *uv; |
| 325 | lua_assert(!isdead(g, L1)); | 327 | lua_assert(!isdead(g, L1)); |
| 326 | for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next) | 328 | for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next) |
| 327 | lua_assert(upisopen(uv)); /* must be open */ | 329 | lua_assert(upisopen(uv)); /* must be open */ |
| 328 | for (o = L1->func; o->stkci.previous != 0; o -= o->stkci.previous) { | 330 | for (ci = L1->ci; ci != NULL; ci = ci->previous) { |
| 329 | lua_assert(functop(o) <= L1->stack_last); | 331 | lua_assert(ci->top <= L1->stack_last); |
| 330 | lua_assert(lua_checkpc(o)); | 332 | lua_assert(lua_checkpc(ci)); |
| 331 | } | 333 | } |
| 332 | lua_assert(o == L1->stack); | ||
| 333 | if (L1->stack) { /* complete thread? */ | 334 | if (L1->stack) { /* complete thread? */ |
| 334 | for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++) | 335 | for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++) |
| 335 | checkliveness(L1, s2v(o)); /* entire stack must have valid values */ | 336 | checkliveness(L1, s2v(o)); /* entire stack must have valid values */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.c,v 2.45 2017/10/04 15:49:05 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 2.45 2017/10/04 15:49:05 roberto Exp $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -108,7 +108,7 @@ void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, | |||
| 108 | setobj2s(L, func + 3, p3); /* 3rd argument */ | 108 | setobj2s(L, func + 3, p3); /* 3rd argument */ |
| 109 | L->top += 4; | 109 | L->top += 4; |
| 110 | /* metamethod may yield only when called from Lua code */ | 110 | /* metamethod may yield only when called from Lua code */ |
| 111 | if (isLua(L->func)) | 111 | if (isLua(L->ci)) |
| 112 | luaD_call(L, func, 0); | 112 | luaD_call(L, func, 0); |
| 113 | else | 113 | else |
| 114 | luaD_callnoyield(L, func, 0); | 114 | luaD_callnoyield(L, func, 0); |
| @@ -124,7 +124,7 @@ void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1, | |||
| 124 | setobj2s(L, func + 2, p2); /* 2nd argument */ | 124 | setobj2s(L, func + 2, p2); /* 2nd argument */ |
| 125 | L->top += 3; | 125 | L->top += 3; |
| 126 | /* metamethod may yield only when called from Lua code */ | 126 | /* metamethod may yield only when called from Lua code */ |
| 127 | if (isLua(L->func)) | 127 | if (isLua(L->ci)) |
| 128 | luaD_call(L, func, 1); | 128 | luaD_call(L, func, 1); |
| 129 | else | 129 | else |
| 130 | luaD_callnoyield(L, func, 1); | 130 | luaD_callnoyield(L, func, 1); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.h,v 1.337 2017/11/02 11:28:56 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.337 2017/11/02 11:28:56 roberto Exp $ |
| 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 |
| @@ -456,8 +456,7 @@ struct lua_Debug { | |||
| 456 | char istailcall; /* (t) */ | 456 | char istailcall; /* (t) */ |
| 457 | char short_src[LUA_IDSIZE]; /* (S) */ | 457 | char short_src[LUA_IDSIZE]; /* (S) */ |
| 458 | /* private part */ | 458 | /* private part */ |
| 459 | int i_actf; /* active function */ | 459 | struct CallInfo *i_ci; /* active function */ |
| 460 | lua_State *i_actL; /* where active function is active */ | ||
| 461 | }; | 460 | }; |
| 462 | 461 | ||
| 463 | /* }====================================================================== */ | 462 | /* }====================================================================== */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.304 2017/11/03 19:33:22 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.301 2017/11/01 18:20:48 roberto Exp $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -390,9 +390,9 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { | |||
| 390 | else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */ | 390 | else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */ |
| 391 | return res; | 391 | return res; |
| 392 | else { /* try 'lt': */ | 392 | else { /* try 'lt': */ |
| 393 | callstatus(L->func) |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ | 393 | L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ |
| 394 | res = luaT_callorderTM(L, r, l, TM_LT); | 394 | res = luaT_callorderTM(L, r, l, TM_LT); |
| 395 | callstatus(L->func) ^= CIST_LEQ; /* clear mark */ | 395 | L->ci->callstatus ^= CIST_LEQ; /* clear mark */ |
| 396 | if (res < 0) | 396 | if (res < 0) |
| 397 | luaG_ordererror(L, l, r); | 397 | luaG_ordererror(L, l, r); |
| 398 | return !res; /* result is negated */ | 398 | return !res; /* result is negated */ |
| @@ -654,14 +654,13 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, | |||
| 654 | } | 654 | } |
| 655 | 655 | ||
| 656 | 656 | ||
| 657 | #define basepc(base) ((base - 1)->stkci.u.l.savedpc) | ||
| 658 | |||
| 659 | /* | 657 | /* |
| 660 | ** finish execution of an opcode interrupted by an yield | 658 | ** finish execution of an opcode interrupted by an yield |
| 661 | */ | 659 | */ |
| 662 | void luaV_finishOp (lua_State *L) { | 660 | void luaV_finishOp (lua_State *L) { |
| 663 | StkId base = L->func + 1; | 661 | CallInfo *ci = L->ci; |
| 664 | Instruction inst = *(basepc(base) - 1); /* interrupted instruction */ | 662 | StkId base = ci->func + 1; |
| 663 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ | ||
| 665 | OpCode op = GET_OPCODE(inst); | 664 | OpCode op = GET_OPCODE(inst); |
| 666 | switch (op) { /* finish its execution */ | 665 | switch (op) { /* finish its execution */ |
| 667 | case OP_ADDI: case OP_SUBI: | 666 | case OP_ADDI: case OP_SUBI: |
| @@ -680,14 +679,14 @@ void luaV_finishOp (lua_State *L) { | |||
| 680 | case OP_LE: case OP_LT: case OP_EQ: { | 679 | case OP_LE: case OP_LT: case OP_EQ: { |
| 681 | int res = !l_isfalse(s2v(L->top - 1)); | 680 | int res = !l_isfalse(s2v(L->top - 1)); |
| 682 | L->top--; | 681 | L->top--; |
| 683 | if (callstatus(base - 1) & CIST_LEQ) { /* "<=" using "<" ? */ | 682 | if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ |
| 684 | lua_assert(op == OP_LE); | 683 | lua_assert(op == OP_LE); |
| 685 | callstatus(base - 1) ^= CIST_LEQ; /* clear mark */ | 684 | ci->callstatus ^= CIST_LEQ; /* clear mark */ |
| 686 | res = !res; /* negate result */ | 685 | res = !res; /* negate result */ |
| 687 | } | 686 | } |
| 688 | lua_assert(GET_OPCODE(*basepc(base)) == OP_JMP); | 687 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); |
| 689 | if (res != GETARG_A(inst)) /* condition failed? */ | 688 | if (res != GETARG_A(inst)) /* condition failed? */ |
| 690 | basepc(base)++; /* skip jump instruction */ | 689 | ci->u.l.savedpc++; /* skip jump instruction */ |
| 691 | break; | 690 | break; |
| 692 | } | 691 | } |
| 693 | case OP_CONCAT: { | 692 | case OP_CONCAT: { |
| @@ -700,18 +699,18 @@ void luaV_finishOp (lua_State *L) { | |||
| 700 | luaV_concat(L, total); /* concat them (may yield again) */ | 699 | luaV_concat(L, total); /* concat them (may yield again) */ |
| 701 | } | 700 | } |
| 702 | /* move final result to final position */ | 701 | /* move final result to final position */ |
| 703 | setobjs2s(L, L->func + 1 + GETARG_A(inst), L->top - 1); | 702 | setobjs2s(L, ci->func + 1 + GETARG_A(inst), L->top - 1); |
| 704 | L->top = functop(base - 1); /* restore top */ | 703 | L->top = ci->top; /* restore top */ |
| 705 | break; | 704 | break; |
| 706 | } | 705 | } |
| 707 | case OP_TFORCALL: { | 706 | case OP_TFORCALL: { |
| 708 | lua_assert(GET_OPCODE(*basepc(base)) == OP_TFORLOOP); | 707 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); |
| 709 | L->top = functop(base - 1); /* correct top */ | 708 | L->top = ci->top; /* correct top */ |
| 710 | break; | 709 | break; |
| 711 | } | 710 | } |
| 712 | case OP_CALL: { | 711 | case OP_CALL: { |
| 713 | if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ | 712 | if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ |
| 714 | L->top = functop(base - 1); /* adjust results */ | 713 | L->top = ci->top; /* adjust results */ |
| 715 | break; | 714 | break; |
| 716 | } | 715 | } |
| 717 | case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: | 716 | case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: |
| @@ -754,33 +753,31 @@ void luaV_finishOp (lua_State *L) { | |||
| 754 | ** Execute a jump instruction. The 'updatemask' allows signals to stop | 753 | ** Execute a jump instruction. The 'updatemask' allows signals to stop |
| 755 | ** tight loops. (Without it, the local copy of 'mask' could never change.) | 754 | ** tight loops. (Without it, the local copy of 'mask' could never change.) |
| 756 | */ | 755 | */ |
| 757 | #define dojump(i,e) { pc += GETARG_sBx(i) + e; updatemask(L); } | 756 | #define dojump(ci,i,e) { pc += GETARG_sBx(i) + e; updatemask(L); } |
| 758 | 757 | ||
| 759 | 758 | ||
| 760 | /* for test instructions, execute the jump instruction that follows it */ | 759 | /* for test instructions, execute the jump instruction that follows it */ |
| 761 | #define donextjump() { i = *pc; dojump(i, 1); } | 760 | #define donextjump(ci) { i = *pc; dojump(ci, i, 1); } |
| 762 | 761 | ||
| 763 | /* | 762 | /* |
| 764 | ** Whenever code can raise errors (including memory errors), the global | 763 | ** Whenever code can raise errors (including memory errors), the global |
| 765 | ** 'pc' must be correct to report occasional errors. | 764 | ** 'pc' must be correct to report occasional errors. |
| 766 | */ | 765 | */ |
| 767 | #define savepc(base) (basepc(base) = pc) | 766 | #define savepc(L) (ci->u.l.savedpc = pc) |
| 768 | |||
| 769 | 767 | ||
| 770 | /* update internal copies to its correct values */ | ||
| 771 | #define updatestate() (base = L->func + 1, updatemask(L)) | ||
| 772 | 768 | ||
| 773 | /* | 769 | /* |
| 774 | ** Protect code that, in general, can raise errors, reallocate the | 770 | ** Protect code that, in general, can raise errors, reallocate the |
| 775 | ** stack, and change the hooks. | 771 | ** stack, and change the hooks. |
| 776 | */ | 772 | */ |
| 777 | #define Protect(code) { savepc(base); {code;}; updatestate(); } | 773 | #define Protect(code) \ |
| 774 | { savepc(L); {code;}; base = ci->func + 1; updatemask(L); } | ||
| 778 | 775 | ||
| 779 | 776 | ||
| 780 | #define checkGC(L,c) \ | 777 | #define checkGC(L,c) \ |
| 781 | { luaC_condGC(L, L->top = (c), /* limit of live values */ \ | 778 | { luaC_condGC(L, L->top = (c), /* limit of live values */ \ |
| 782 | {updatestate(); L->top = functop(base - 1);}); /* restore top */ \ | 779 | Protect(L->top = ci->top)); /* restore top */ \ |
| 783 | luai_threadyield(L); } | 780 | luai_threadyield(L); } |
| 784 | 781 | ||
| 785 | 782 | ||
| 786 | /* fetch an instruction and prepare its execution */ | 783 | /* fetch an instruction and prepare its execution */ |
| @@ -796,23 +793,26 @@ void luaV_finishOp (lua_State *L) { | |||
| 796 | 793 | ||
| 797 | 794 | ||
| 798 | void luaV_execute (lua_State *L) { | 795 | void luaV_execute (lua_State *L) { |
| 796 | CallInfo *ci = L->ci; | ||
| 799 | LClosure *cl; | 797 | LClosure *cl; |
| 800 | TValue *k; | 798 | TValue *k; |
| 801 | StkId base = L->func + 1; /* local copy of 'L->func + 1' */ | 799 | StkId base; /* local copy of 'ci->func + 1' */ |
| 802 | int mask; /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */ | 800 | int mask; /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */ |
| 803 | const Instruction *pc; /* local copy of 'basepc(base)' */ | 801 | const Instruction *pc; /* local copy of 'ci->u.l.savedpc' */ |
| 804 | callstatus(base - 1) |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */ | 802 | ci->callstatus |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */ |
| 805 | newframe: /* reentry point when frame changes (call/return) */ | 803 | newframe: /* reentry point when frame changes (call/return) */ |
| 806 | cl = clLvalue(s2v(L->func)); /* local reference to function's closure */ | 804 | lua_assert(ci == L->ci); |
| 805 | cl = clLvalue(s2v(ci->func)); /* local reference to function's closure */ | ||
| 807 | k = cl->p->k; /* local reference to function's constant table */ | 806 | k = cl->p->k; /* local reference to function's constant table */ |
| 808 | updatemask(L); | 807 | updatemask(L); |
| 809 | pc = basepc(base); | 808 | base = ci->func + 1; |
| 809 | pc = ci->u.l.savedpc; | ||
| 810 | /* main loop of interpreter */ | 810 | /* main loop of interpreter */ |
| 811 | for (;;) { | 811 | for (;;) { |
| 812 | Instruction i; | 812 | Instruction i; |
| 813 | StkId ra; | 813 | StkId ra; |
| 814 | vmfetch(); | 814 | vmfetch(); |
| 815 | lua_assert(base == L->func + 1); | 815 | lua_assert(base == ci->func + 1); |
| 816 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); | 816 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); |
| 817 | vmdispatch (GET_OPCODE(i)) { | 817 | vmdispatch (GET_OPCODE(i)) { |
| 818 | vmcase(OP_MOVE) { | 818 | vmcase(OP_MOVE) { |
| @@ -970,7 +970,7 @@ void luaV_execute (lua_State *L) { | |||
| 970 | int b = GETARG_B(i); | 970 | int b = GETARG_B(i); |
| 971 | int c = GETARG_C(i); | 971 | int c = GETARG_C(i); |
| 972 | Table *t; | 972 | Table *t; |
| 973 | savepc(base); /* in case of allocation errors */ | 973 | savepc(L); /* in case of allocation errors */ |
| 974 | t = luaH_new(L); | 974 | t = luaH_new(L); |
| 975 | sethvalue2s(L, ra, t); | 975 | sethvalue2s(L, ra, t); |
| 976 | if (b != 0 || c != 0) | 976 | if (b != 0 || c != 0) |
| @@ -1276,7 +1276,7 @@ void luaV_execute (lua_State *L) { | |||
| 1276 | rb = base + b; | 1276 | rb = base + b; |
| 1277 | setobjs2s(L, ra, rb); | 1277 | setobjs2s(L, ra, rb); |
| 1278 | checkGC(L, (ra >= rb ? ra + 1 : rb)); | 1278 | checkGC(L, (ra >= rb ? ra + 1 : rb)); |
| 1279 | L->top = functop(base - 1); /* restore top */ | 1279 | L->top = ci->top; /* restore top */ |
| 1280 | vmbreak; | 1280 | vmbreak; |
| 1281 | } | 1281 | } |
| 1282 | vmcase(OP_CLOSE) { | 1282 | vmcase(OP_CLOSE) { |
| @@ -1284,7 +1284,7 @@ void luaV_execute (lua_State *L) { | |||
| 1284 | vmbreak; | 1284 | vmbreak; |
| 1285 | } | 1285 | } |
| 1286 | vmcase(OP_JMP) { | 1286 | vmcase(OP_JMP) { |
| 1287 | dojump(i, 0); | 1287 | dojump(ci, i, 0); |
| 1288 | vmbreak; | 1288 | vmbreak; |
| 1289 | } | 1289 | } |
| 1290 | vmcase(OP_EQ) { | 1290 | vmcase(OP_EQ) { |
| @@ -1294,7 +1294,7 @@ void luaV_execute (lua_State *L) { | |||
| 1294 | if (luaV_equalobj(L, rb, rc) != GETARG_A(i)) | 1294 | if (luaV_equalobj(L, rb, rc) != GETARG_A(i)) |
| 1295 | pc++; | 1295 | pc++; |
| 1296 | else | 1296 | else |
| 1297 | donextjump(); | 1297 | donextjump(ci); |
| 1298 | ) | 1298 | ) |
| 1299 | vmbreak; | 1299 | vmbreak; |
| 1300 | } | 1300 | } |
| @@ -1310,7 +1310,7 @@ void luaV_execute (lua_State *L) { | |||
| 1310 | if (res != GETARG_A(i)) | 1310 | if (res != GETARG_A(i)) |
| 1311 | pc++; | 1311 | pc++; |
| 1312 | else | 1312 | else |
| 1313 | donextjump(); | 1313 | donextjump(ci); |
| 1314 | vmbreak; | 1314 | vmbreak; |
| 1315 | } | 1315 | } |
| 1316 | vmcase(OP_LE) { | 1316 | vmcase(OP_LE) { |
| @@ -1325,14 +1325,14 @@ void luaV_execute (lua_State *L) { | |||
| 1325 | if (res != GETARG_A(i)) | 1325 | if (res != GETARG_A(i)) |
| 1326 | pc++; | 1326 | pc++; |
| 1327 | else | 1327 | else |
| 1328 | donextjump(); | 1328 | donextjump(ci); |
| 1329 | vmbreak; | 1329 | vmbreak; |
| 1330 | } | 1330 | } |
| 1331 | vmcase(OP_TEST) { | 1331 | vmcase(OP_TEST) { |
| 1332 | if (GETARG_C(i) ? l_isfalse(s2v(ra)) : !l_isfalse(s2v(ra))) | 1332 | if (GETARG_C(i) ? l_isfalse(s2v(ra)) : !l_isfalse(s2v(ra))) |
| 1333 | pc++; | 1333 | pc++; |
| 1334 | else | 1334 | else |
| 1335 | donextjump(); | 1335 | donextjump(ci); |
| 1336 | vmbreak; | 1336 | vmbreak; |
| 1337 | } | 1337 | } |
| 1338 | vmcase(OP_TESTSET) { | 1338 | vmcase(OP_TESTSET) { |
| @@ -1341,7 +1341,7 @@ void luaV_execute (lua_State *L) { | |||
| 1341 | pc++; | 1341 | pc++; |
| 1342 | else { | 1342 | else { |
| 1343 | setobj2s(L, ra, rb); | 1343 | setobj2s(L, ra, rb); |
| 1344 | donextjump(); | 1344 | donextjump(ci); |
| 1345 | } | 1345 | } |
| 1346 | vmbreak; | 1346 | vmbreak; |
| 1347 | } | 1347 | } |
| @@ -1355,11 +1355,11 @@ void luaV_execute (lua_State *L) { | |||
| 1355 | Protect(isC = luaD_precall(L, ra, nresults)); | 1355 | Protect(isC = luaD_precall(L, ra, nresults)); |
| 1356 | if (isC) { /* C function? */ | 1356 | if (isC) { /* C function? */ |
| 1357 | if (nresults >= 0) /* fixed number of results? */ | 1357 | if (nresults >= 0) /* fixed number of results? */ |
| 1358 | L->top = functop(base - 1); /* correct top */ | 1358 | L->top = ci->top; /* correct top */ |
| 1359 | /* else leave top for next instruction */ | 1359 | /* else leave top for next instruction */ |
| 1360 | } | 1360 | } |
| 1361 | else { /* Lua function */ | 1361 | else { /* Lua function */ |
| 1362 | base = L->func + 1; | 1362 | ci = L->ci; |
| 1363 | goto newframe; /* restart luaV_execute over new Lua function */ | 1363 | goto newframe; /* restart luaV_execute over new Lua function */ |
| 1364 | } | 1364 | } |
| 1365 | vmbreak; | 1365 | vmbreak; |
| @@ -1368,14 +1368,16 @@ void luaV_execute (lua_State *L) { | |||
| 1368 | int b = GETARG_B(i); | 1368 | int b = GETARG_B(i); |
| 1369 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | 1369 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
| 1370 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); | 1370 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); |
| 1371 | savepc(base); | 1371 | savepc(L); |
| 1372 | if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ | 1372 | if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ |
| 1373 | updatestate(); /* update 'base' */ | 1373 | Protect((void)0); /* update 'base' */ |
| 1374 | } | 1374 | } |
| 1375 | else { | 1375 | else { |
| 1376 | /* tail call: put called frame (n) in place of caller one (o) */ | 1376 | /* tail call: put called frame (n) in place of caller one (o) */ |
| 1377 | StkId nfunc = L->func; /* called function */ | 1377 | CallInfo *nci = L->ci; /* called frame (new) */ |
| 1378 | StkId ofunc = nfunc - nfunc->stkci.previous; /* caller function */ | 1378 | CallInfo *oci = nci->previous; /* caller frame (old) */ |
| 1379 | StkId nfunc = nci->func; /* called function */ | ||
| 1380 | StkId ofunc = oci->func; /* caller function */ | ||
| 1379 | /* last stack slot filled by 'precall' */ | 1381 | /* last stack slot filled by 'precall' */ |
| 1380 | StkId lim = nfunc + 1 + getproto(s2v(nfunc))->numparams; | 1382 | StkId lim = nfunc + 1 + getproto(s2v(nfunc))->numparams; |
| 1381 | int aux; | 1383 | int aux; |
| @@ -1384,13 +1386,11 @@ void luaV_execute (lua_State *L) { | |||
| 1384 | /* move new frame into old one */ | 1386 | /* move new frame into old one */ |
| 1385 | for (aux = 0; nfunc + aux < lim; aux++) | 1387 | for (aux = 0; nfunc + aux < lim; aux++) |
| 1386 | setobjs2s(L, ofunc + aux, nfunc + aux); | 1388 | setobjs2s(L, ofunc + aux, nfunc + aux); |
| 1387 | ofunc->stkci.framesize = L->top - nfunc; | 1389 | oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ |
| 1388 | L->top = functop(ofunc); /* correct top */ | 1390 | oci->u.l.savedpc = nci->u.l.savedpc; |
| 1389 | ofunc->stkci.u.l.savedpc = nfunc->stkci.u.l.savedpc; | 1391 | oci->callstatus |= CIST_TAIL; /* function was tail called */ |
| 1390 | callstatus(ofunc) |= CIST_TAIL; /* function was tail called */ | 1392 | ci = L->ci = oci; /* remove new frame */ |
| 1391 | base = ofunc + 1; | 1393 | lua_assert(L->top == ofunc + 1 + getproto(s2v(ofunc))->maxstacksize); |
| 1392 | L->func = ofunc; | ||
| 1393 | lua_assert(L->top == base + getproto(s2v(ofunc))->maxstacksize); | ||
| 1394 | goto newframe; /* restart luaV_execute over new Lua function */ | 1394 | goto newframe; /* restart luaV_execute over new Lua function */ |
| 1395 | } | 1395 | } |
| 1396 | vmbreak; | 1396 | vmbreak; |
| @@ -1398,16 +1398,16 @@ void luaV_execute (lua_State *L) { | |||
| 1398 | vmcase(OP_RETURN) { | 1398 | vmcase(OP_RETURN) { |
| 1399 | int b = GETARG_B(i); | 1399 | int b = GETARG_B(i); |
| 1400 | if (cl->p->sizep > 0) luaF_close(L, base); | 1400 | if (cl->p->sizep > 0) luaF_close(L, base); |
| 1401 | savepc(base); | 1401 | savepc(L); |
| 1402 | b = luaD_poscall(L, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))); | 1402 | b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))); |
| 1403 | if (callstatus(base - 1) & CIST_FRESH) /* local 'base' still from callee */ | 1403 | if (ci->callstatus & CIST_FRESH) /* local 'ci' still from callee */ |
| 1404 | return; /* external invocation: return */ | 1404 | return; /* external invocation: return */ |
| 1405 | else { /* invocation via reentry: continue execution */ | 1405 | else { /* invocation via reentry: continue execution */ |
| 1406 | base = L->func + 1; | 1406 | ci = L->ci; |
| 1407 | if (b) L->top = functop(base - 1); | 1407 | if (b) L->top = ci->top; |
| 1408 | lua_assert(isLua(base - 1)); | 1408 | lua_assert(isLua(ci)); |
| 1409 | lua_assert(GET_OPCODE(*(basepc(base) - 1)) == OP_CALL); | 1409 | lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); |
| 1410 | goto newframe; /* restart luaV_execute over previous Lua function */ | 1410 | goto newframe; /* restart luaV_execute over new Lua function */ |
| 1411 | } | 1411 | } |
| 1412 | } | 1412 | } |
| 1413 | vmcase(OP_FORLOOP) { | 1413 | vmcase(OP_FORLOOP) { |
| @@ -1451,7 +1451,7 @@ void luaV_execute (lua_State *L) { | |||
| 1451 | } | 1451 | } |
| 1452 | else { /* try making all values floats */ | 1452 | else { /* try making all values floats */ |
| 1453 | lua_Number ninit; lua_Number nlimit; lua_Number nstep; | 1453 | lua_Number ninit; lua_Number nlimit; lua_Number nstep; |
| 1454 | savepc(base); /* in case of errors */ | 1454 | savepc(L); /* in case of errors */ |
| 1455 | if (!tonumber(plimit, &nlimit)) | 1455 | if (!tonumber(plimit, &nlimit)) |
| 1456 | luaG_runerror(L, "'for' limit must be a number"); | 1456 | luaG_runerror(L, "'for' limit must be a number"); |
| 1457 | setfltvalue(plimit, nlimit); | 1457 | setfltvalue(plimit, nlimit); |
| @@ -1472,7 +1472,7 @@ void luaV_execute (lua_State *L) { | |||
| 1472 | setobjs2s(L, cb, ra); | 1472 | setobjs2s(L, cb, ra); |
| 1473 | L->top = cb + 3; /* func. + 2 args (state and index) */ | 1473 | L->top = cb + 3; /* func. + 2 args (state and index) */ |
| 1474 | Protect(luaD_call(L, cb, GETARG_C(i))); | 1474 | Protect(luaD_call(L, cb, GETARG_C(i))); |
| 1475 | L->top = functop(base - 1); | 1475 | L->top = ci->top; |
| 1476 | i = *(pc++); /* go to next instruction */ | 1476 | i = *(pc++); /* go to next instruction */ |
| 1477 | ra = RA(i); | 1477 | ra = RA(i); |
| 1478 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); | 1478 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); |
| @@ -1497,7 +1497,7 @@ void luaV_execute (lua_State *L) { | |||
| 1497 | } | 1497 | } |
| 1498 | h = hvalue(s2v(ra)); | 1498 | h = hvalue(s2v(ra)); |
| 1499 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; | 1499 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; |
| 1500 | savepc(base); /* in case of allocation errors */ | 1500 | savepc(L); /* in case of allocation errors */ |
| 1501 | if (last > h->sizearray) /* needs more space? */ | 1501 | if (last > h->sizearray) /* needs more space? */ |
| 1502 | luaH_resizearray(L, h, last); /* preallocate it at once */ | 1502 | luaH_resizearray(L, h, last); /* preallocate it at once */ |
| 1503 | for (; n > 0; n--) { | 1503 | for (; n > 0; n--) { |
| @@ -1506,15 +1506,14 @@ void luaV_execute (lua_State *L) { | |||
| 1506 | last--; | 1506 | last--; |
| 1507 | luaC_barrierback(L, h, val); | 1507 | luaC_barrierback(L, h, val); |
| 1508 | } | 1508 | } |
| 1509 | /* correct top (in case of previous open call) */ | 1509 | L->top = ci->top; /* correct top (in case of previous open call) */ |
| 1510 | L->top = functop(base - 1); | ||
| 1511 | vmbreak; | 1510 | vmbreak; |
| 1512 | } | 1511 | } |
| 1513 | vmcase(OP_CLOSURE) { | 1512 | vmcase(OP_CLOSURE) { |
| 1514 | Proto *p = cl->p->p[GETARG_Bx(i)]; | 1513 | Proto *p = cl->p->p[GETARG_Bx(i)]; |
| 1515 | LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */ | 1514 | LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */ |
| 1516 | if (ncl == NULL) { /* no match? */ | 1515 | if (ncl == NULL) { /* no match? */ |
| 1517 | savepc(base); /* in case of allocation errors */ | 1516 | savepc(L); /* in case of allocation errors */ |
| 1518 | pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ | 1517 | pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ |
| 1519 | } | 1518 | } |
| 1520 | else | 1519 | else |
