diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-07 11:25:26 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-07 11:25:26 -0200 |
commit | ad0704e40cc7b3135fedc6d40a522addb039e090 (patch) | |
tree | 4bcd104de4941239e09316efcee5e5e3566b8b81 | |
parent | 5a3f26f85558bedfa439027919d928abfdd00b6d (diff) | |
download | lua-ad0704e40cc7b3135fedc6d40a522addb039e090.tar.gz lua-ad0704e40cc7b3135fedc6d40a522addb039e090.tar.bz2 lua-ad0704e40cc7b3135fedc6d40a522addb039e090.zip |
back to 'CallInfo' (no gains with its removal)
-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 |