aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-11-07 11:25:26 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-11-07 11:25:26 -0200
commitad0704e40cc7b3135fedc6d40a522addb039e090 (patch)
tree4bcd104de4941239e09316efcee5e5e3566b8b81
parent5a3f26f85558bedfa439027919d928abfdd00b6d (diff)
downloadlua-ad0704e40cc7b3135fedc6d40a522addb039e090.tar.gz
lua-ad0704e40cc7b3135fedc6d40a522addb039e090.tar.bz2
lua-ad0704e40cc7b3135fedc6d40a522addb039e090.zip
back to 'CallInfo' (no gains with its removal)
-rw-r--r--lapi.c81
-rw-r--r--lapi.h9
-rw-r--r--ldebug.c161
-rw-r--r--ldo.c190
-rw-r--r--ldo.h5
-rw-r--r--lgc.c6
-rw-r--r--lobject.h32
-rw-r--r--lstate.c63
-rw-r--r--lstate.h50
-rw-r--r--ltests.c23
-rw-r--r--ltm.c6
-rw-r--r--lua.h5
-rw-r--r--lvm.c133
13 files changed, 394 insertions, 370 deletions
diff --git a/lapi.c b/lapi.c
index 8750cefa..1c1e8f9e 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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
61static TValue *index2value (lua_State *L, int idx) { 60static 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
87static StkId index2stack (lua_State *L, int idx) { 87static 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
111LUA_API int lua_checkstack (lua_State *L, int n) { 112LUA_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) {
176LUA_API int lua_absindex (lua_State *L, int idx) { 175LUA_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
183LUA_API int lua_gettop (lua_State *L) { 182LUA_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
188LUA_API void lua_settop (lua_State *L, int idx) { 187LUA_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
940LUA_API void lua_callk (lua_State *L, int nargs, int nresults, 938LUA_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);
diff --git a/lapi.h b/lapi.h
index d851d161..77ebb300 100644
--- a/lapi.h
+++ b/lapi.h
@@ -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
diff --git a/ldebug.c b/ldebug.c
index 100b9b7a..83ddde72 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -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
41static const char *funcnamefromcode (lua_State *L, StkId stkf, 41static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
42 const char **name); 42 const char **name);
43 43
44 44
45static int currentpc (StkId func) { 45static 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
104static int currentline (StkId func) { 104static 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
147LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { 147LUA_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
174static StkId findcalled (lua_State *L, StkId caller) { 171static 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
187static 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
290static const char *getfuncname (lua_State *L, StkId stkf, const char **name) { 277static 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
307static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, 291static 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,
354LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { 338LUA_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*/
562static const char *funcnamefromcode (lua_State *L, StkId stkf, 546static 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*/
624static int isinstack (lua_State *L, const TValue *o) { 608static 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*/
636static const char *getupvalname (StkId stkf, const TValue *o, 620static 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
650static const char *varinfo (lua_State *L, const TValue *o) { 634static 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
730l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { 714l_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
758void luaG_traceexec (lua_State *L) { 741void 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}
diff --git a/ldo.c b/ldo.c
index bb189565..efdcbc1b 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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*/
159static void correctstack (lua_State *L, StkId oldstack) { 159static 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
205static int stackinuse (lua_State *L) { 209static 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) {
245void luaD_hook (lua_State *L, int event, int line) { 252void 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
275static void callhook (lua_State *L) { 279static 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*/
358int luaD_poscall (lua_State *L, StkId firstResult, int nres) { 359int 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) {
384int luaD_precall (lua_State *L, StkId func, int nresults) { 388int 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*/
485static void finishCcall (lua_State *L, int status) { 489static 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) {
516static void unroll (lua_State *L, void *ud) { 519static 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*/
534static StkId findpcall (lua_State *L) { 537static 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*/
551static int recover (lua_State *L, int status) { 552static 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) {
589static void resume (lua_State *L, void *ud) { 590static 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
665LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, 665LUA_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,
694int luaD_pcall (lua_State *L, Pfunc func, void *u, 694int 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);
diff --git a/ldo.h b/ldo.h
index 4c03d594..3dc16d71 100644
--- a/ldo.h
+++ b/ldo.h
@@ -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);
52LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); 52LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
53LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 53LUAI_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);
55LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult, int nres); 55LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult,
56 int nres);
56LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); 57LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
57LUAI_FUNC void luaD_growstack (lua_State *L, int n); 58LUAI_FUNC void luaD_growstack (lua_State *L, int n);
58LUAI_FUNC void luaD_shrinkstack (lua_State *L); 59LUAI_FUNC void luaD_shrinkstack (lua_State *L);
diff --git a/lgc.c b/lgc.c
index 2155b28d..036020ae 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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? */
diff --git a/lobject.h b/lobject.h
index 56dfebba..372ec13b 100644
--- a/lobject.h
+++ b/lobject.h
@@ -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
312typedef union StackValue { 312typedef 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
347typedef StackValue *StkId; /* index to stack elements */ 317typedef StackValue *StkId; /* index to stack elements */
348 318
349/* convert a 'StackValue' to a 'TValue' */ 319/* convert a 'StackValue' to a 'TValue' */
diff --git a/lstate.c b/lstate.c
index 76daa2e7..7f67527b 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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
100CallInfo *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*/
114void 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*/
129void 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
100static void stack_init (lua_State *L1, lua_State *L) { 143static 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
119static void freestack (lua_State *L) { 164static 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) {
168static void preinit_thread (lua_State *L, global_State *g) { 215static 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 */
diff --git a/lstate.h b/lstate.h
index 07cb3d3d..4798474c 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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*/
87typedef 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
226LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); 253LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
227LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 254LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
255LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
256LUAI_FUNC void luaE_freeCI (lua_State *L);
257LUAI_FUNC void luaE_shrinkCI (lua_State *L);
228 258
229 259
230#endif 260#endif
diff --git a/ltests.c b/ltests.c
index ebf73840..bee734f3 100644
--- a/ltests.c
+++ b/ltests.c
@@ -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;
46int islocked = 0; 46int 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
52static int runC (lua_State *L, lua_State *L1, const char *pc); 52static 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
312static int lua_checkpc (StkId func) { 312static 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
322static void checkstack (global_State *g, lua_State *L1) { 323static 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 */
diff --git a/ltm.c b/ltm.c
index 6c13e8d1..91f622e4 100644
--- a/ltm.c
+++ b/ltm.c
@@ -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);
diff --git a/lua.h b/lua.h
index fe97e8a6..2d8ff838 100644
--- a/lua.h
+++ b/lua.h
@@ -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/* }====================================================================== */
diff --git a/lvm.c b/lvm.c
index b1cf4666..b5e1c813 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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*/
662void luaV_finishOp (lua_State *L) { 660void 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
798void luaV_execute (lua_State *L) { 795void 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