aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c45
-rw-r--r--lapi.h7
-rw-r--r--ldebug.c29
-rw-r--r--ldo.c80
-rw-r--r--lgc.c6
-rw-r--r--lobject.h13
-rw-r--r--lstate.c6
-rw-r--r--lstate.h22
-rw-r--r--ltests.c11
-rw-r--r--ltm.c6
-rw-r--r--lvm.c54
11 files changed, 152 insertions, 127 deletions
diff --git a/lapi.c b/lapi.c
index 8d4d5e7d..6b6bc565 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.272 2017/11/01 18:20:48 roberto Exp roberto $ 2** $Id: lapi.c,v 2.273 2017/11/02 11:28:56 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -10,6 +10,7 @@
10#include "lprefix.h" 10#include "lprefix.h"
11 11
12 12
13#include <limits.h>
13#include <stdarg.h> 14#include <stdarg.h>
14#include <string.h> 15#include <string.h>
15 16
@@ -60,12 +61,12 @@ const char lua_ident[] =
60static TValue *index2value (lua_State *L, int idx) { 61static TValue *index2value (lua_State *L, int idx) {
61 if (idx > 0) { 62 if (idx > 0) {
62 StkId o = L->func + idx; 63 StkId o = L->func + idx;
63 api_check(L, idx <= L->ci->top - (L->func + 1), "unacceptable index"); 64 api_check(L, idx < L->func->stkci.framesize, "unacceptable index");
64 if (o >= L->top) return NONVALIDVALUE; 65 if (o >= L->top) return NONVALIDVALUE;
65 else return s2v(o); 66 else return s2v(o);
66 } 67 }
67 else if (!ispseudo(idx)) { /* negative index */ 68 else if (!ispseudo(idx)) { /* negative index */
68 api_check(L, idx != 0 && -idx <= L->top - (L->func + 1), "invalid index"); 69 api_check(L, idx != 0 && -idx < L->func->stkci.framesize, "invalid index");
69 return s2v(L->top + idx); 70 return s2v(L->top + idx);
70 } 71 }
71 else if (idx == LUA_REGISTRYINDEX) 72 else if (idx == LUA_REGISTRYINDEX)
@@ -109,10 +110,12 @@ static void growstack (lua_State *L, void *ud) {
109 110
110LUA_API int lua_checkstack (lua_State *L, int n) { 111LUA_API int lua_checkstack (lua_State *L, int n) {
111 int res; 112 int res;
112 CallInfo *ci = L->ci; 113 int frameuse = L->top - L->func;
113 lua_lock(L); 114 lua_lock(L);
114 api_check(L, n >= 0, "negative 'n'"); 115 api_check(L, n >= 0, "negative 'n'");
115 if (L->stack_last - L->top > n) /* stack large enough? */ 116 if (n >= USHRT_MAX - frameuse)
117 res = 0; /* frame size overflow */
118 else if (L->stack_last - L->top > n) /* stack large enough? */
116 res = 1; /* yes; check is OK */ 119 res = 1; /* yes; check is OK */
117 else { /* no; need to grow stack */ 120 else { /* no; need to grow stack */
118 int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; 121 int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
@@ -121,8 +124,8 @@ LUA_API int lua_checkstack (lua_State *L, int n) {
121 else /* try to grow stack */ 124 else /* try to grow stack */
122 res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK); 125 res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK);
123 } 126 }
124 if (res && ci->top < L->top + n) 127 if (res && L->func->stkci.framesize < frameuse + n)
125 ci->top = L->top + n; /* adjust frame top */ 128 L->func->stkci.framesize = frameuse + n; /* adjust frame size */
126 lua_unlock(L); 129 lua_unlock(L);
127 return res; 130 return res;
128} 131}
@@ -134,7 +137,7 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
134 lua_lock(to); 137 lua_lock(to);
135 api_checknelems(from, n); 138 api_checknelems(from, n);
136 api_check(from, G(from) == G(to), "moving among independent states"); 139 api_check(from, G(from) == G(to), "moving among independent states");
137 api_check(from, to->ci->top - to->top >= n, "stack overflow"); 140 api_check(from, functop(to->func) - to->top >= n, "stack overflow");
138 from->top -= n; 141 from->top -= n;
139 for (i = 0; i < n; i++) { 142 for (i = 0; i < n; i++) {
140 setobjs2s(to, to->top, from->top + i); 143 setobjs2s(to, to->top, from->top + i);
@@ -929,15 +932,16 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) {
929 932
930 933
931#define checkresults(L,na,nr) \ 934#define checkresults(L,na,nr) \
932 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \ 935 api_check(L, (nr) == LUA_MULTRET || \
933 "results from function overflow current stack size") 936 (functop(L->func) - L->top >= (nr) - (na)), \
937 "results from function overflow current frame size")
934 938
935 939
936LUA_API void lua_callk (lua_State *L, int nargs, int nresults, 940LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
937 lua_KContext ctx, lua_KFunction k) { 941 lua_KContext ctx, lua_KFunction k) {
938 StkId func; 942 StkId func;
939 lua_lock(L); 943 lua_lock(L);
940 api_check(L, k == NULL || !isLua(L->ci), 944 api_check(L, k == NULL || !isLua(L->func),
941 "cannot use continuations inside hooks"); 945 "cannot use continuations inside hooks");
942 api_checknelems(L, nargs+1); 946 api_checknelems(L, nargs+1);
943 api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); 947 api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
@@ -976,36 +980,37 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
976 lua_KContext ctx, lua_KFunction k) { 980 lua_KContext ctx, lua_KFunction k) {
977 struct CallS c; 981 struct CallS c;
978 int status; 982 int status;
979 ptrdiff_t func; 983 ptrdiff_t efunc;
980 lua_lock(L); 984 lua_lock(L);
981 api_check(L, k == NULL || !isLua(L->ci), 985 api_check(L, k == NULL || !isLua(L->func),
982 "cannot use continuations inside hooks"); 986 "cannot use continuations inside hooks");
983 api_checknelems(L, nargs+1); 987 api_checknelems(L, nargs+1);
984 api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); 988 api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
985 checkresults(L, nargs, nresults); 989 checkresults(L, nargs, nresults);
986 if (errfunc == 0) 990 if (errfunc == 0)
987 func = 0; 991 efunc = 0;
988 else { 992 else {
989 StkId o = index2stack(L, errfunc); 993 StkId o = index2stack(L, errfunc);
990 func = savestack(L, o); 994 efunc = savestack(L, o);
991 } 995 }
992 c.func = L->top - (nargs+1); /* function to be called */ 996 c.func = L->top - (nargs+1); /* function to be called */
993 if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */ 997 if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */
994 c.nresults = nresults; /* do a 'conventional' protected call */ 998 c.nresults = nresults; /* do a 'conventional' protected call */
995 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); 999 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), efunc);
996 } 1000 }
997 else { /* prepare continuation (call is already protected by 'resume') */ 1001 else { /* prepare continuation (call is already protected by 'resume') */
998 CallInfo *ci = L->ci; 1002 CallInfo *ci = L->ci;
1003 StkId func = L->func;
999 ci->u.c.k = k; /* save continuation */ 1004 ci->u.c.k = k; /* save continuation */
1000 ci->u.c.ctx = ctx; /* save context */ 1005 ci->u.c.ctx = ctx; /* save context */
1001 /* save information for error recovery */ 1006 /* save information for error recovery */
1002 ci->u2.funcidx = savestack(L, c.func); 1007 ci->u2.funcidx = savestack(L, c.func);
1003 ci->u.c.old_errfunc = L->errfunc; 1008 ci->u.c.old_errfunc = L->errfunc;
1004 L->errfunc = func; 1009 L->errfunc = efunc;
1005 setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */ 1010 setoah(callstatus(func), L->allowhook); /* save value of 'allowhook' */
1006 ci->callstatus |= CIST_YPCALL; /* function can do error recovery */ 1011 callstatus(func) |= CIST_YPCALL; /* function can do error recovery */
1007 luaD_call(L, c.func, nresults); /* do the call */ 1012 luaD_call(L, c.func, nresults); /* do the call */
1008 ci->callstatus &= ~CIST_YPCALL; 1013 callstatus(func) &= ~CIST_YPCALL;
1009 L->errfunc = ci->u.c.old_errfunc; 1014 L->errfunc = ci->u.c.old_errfunc;
1010 status = LUA_OK; /* if it is here, there were no errors */ 1015 status = LUA_OK; /* if it is here, there were no errors */
1011 } 1016 }
diff --git a/lapi.h b/lapi.h
index ce64a727..d851d161 100644
--- a/lapi.h
+++ b/lapi.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.h,v 2.9 2015/03/06 19:49:50 roberto Exp roberto $ 2** $Id: lapi.h,v 2.10 2017/11/01 18:20:48 roberto Exp roberto $
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,11 +11,12 @@
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 <= L->ci->top, \ 14#define api_incr_top(L) {L->top++; api_check(L, L->top <= functop(L->func), \
15 "stack overflow");} 15 "stack overflow");}
16 16
17#define adjustresults(L,nres) \ 17#define adjustresults(L,nres) \
18 { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } 18 { if ((nres) == LUA_MULTRET && functop(L->func) < L->top) \
19 setfunctop(L->func, L->top); }
19 20
20#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->func), \ 21#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->func), \
21 "not enough elements in the stack") 22 "not enough elements in the stack")
diff --git a/ldebug.c b/ldebug.c
index 5ca78bd1..2db0910c 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.134 2017/11/01 18:20:48 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.135 2017/11/02 11:28:56 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -43,7 +43,7 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
43 43
44 44
45static int currentpc (CallInfo *ci) { 45static int currentpc (CallInfo *ci) {
46 lua_assert(isLua(ci)); 46 lua_assert(isLua(ci->func));
47 return pcRel(ci->u.l.savedpc, ci_func(ci)->p); 47 return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
48} 48}
49 49
@@ -120,7 +120,7 @@ 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->ci)) 123 if (isLua(L->func))
124 L->oldpc = L->ci->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;
@@ -172,7 +172,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
172 StkId *pos) { 172 StkId *pos) {
173 const char *name = NULL; 173 const char *name = NULL;
174 StkId base; 174 StkId base;
175 if (isLua(ci)) { 175 if (isLua(ci->func)) {
176 base = ci->func + 1; 176 base = ci->func + 1;
177 name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); 177 name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
178 } 178 }
@@ -277,12 +277,12 @@ static void collectvalidlines (lua_State *L, Closure *f) {
277static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { 277static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
278 if (ci == NULL) /* no 'ci'? */ 278 if (ci == NULL) /* no 'ci'? */
279 return NULL; /* no info */ 279 return NULL; /* no info */
280 else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */ 280 else if (callstatus(ci->func) & CIST_FIN) { /* is this a finalizer? */
281 *name = "__gc"; 281 *name = "__gc";
282 return "metamethod"; /* report it as such */ 282 return "metamethod"; /* report it as such */
283 } 283 }
284 /* calling function is a known Lua function? */ 284 /* calling function is a known Lua function? */
285 else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) 285 else if (!(callstatus(ci->func) & CIST_TAIL) && isLua(ci->previous->func))
286 return funcnamefromcode(L, ci->previous, name); 286 return funcnamefromcode(L, ci->previous, name);
287 else return NULL; /* no way to find a name */ 287 else return NULL; /* no way to find a name */
288} 288}
@@ -298,7 +298,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
298 break; 298 break;
299 } 299 }
300 case 'l': { 300 case 'l': {
301 ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1; 301 ar->currentline = (ci && isLua(ci->func)) ? currentline(ci) : -1;
302 break; 302 break;
303 } 303 }
304 case 'u': { 304 case 'u': {
@@ -314,7 +314,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
314 break; 314 break;
315 } 315 }
316 case 't': { 316 case 't': {
317 ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; 317 ar->istailcall = (ci) ? callstatus(ci->func) & CIST_TAIL : 0;
318 break; 318 break;
319 } 319 }
320 case 'n': { 320 case 'n': {
@@ -549,7 +549,7 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
549 Proto *p = ci_func(ci)->p; /* calling function */ 549 Proto *p = ci_func(ci)->p; /* calling function */
550 int pc = currentpc(ci); /* calling instruction index */ 550 int pc = currentpc(ci); /* calling instruction index */
551 Instruction i = p->code[pc]; /* calling instruction */ 551 Instruction i = p->code[pc]; /* calling instruction */
552 if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ 552 if (callstatus(ci->func) & CIST_HOOKED) { /* was it called inside a hook? */
553 *name = "?"; 553 *name = "?";
554 return "hook"; 554 return "hook";
555 } 555 }
@@ -635,7 +635,7 @@ static const char *varinfo (lua_State *L, const TValue *o) {
635 const char *name = NULL; /* to avoid warnings */ 635 const char *name = NULL; /* to avoid warnings */
636 CallInfo *ci = L->ci; 636 CallInfo *ci = L->ci;
637 const char *kind = NULL; 637 const char *kind = NULL;
638 if (isLua(ci)) { 638 if (isLua(L->func)) {
639 kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ 639 kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
640 if (!kind && isinstack(L, o)) /* no? try a register */ 640 if (!kind && isinstack(L, o)) /* no? try a register */
641 kind = getobjname(ci_func(ci)->p, currentpc(ci), 641 kind = getobjname(ci_func(ci)->p, currentpc(ci),
@@ -719,7 +719,7 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
719 va_start(argp, fmt); 719 va_start(argp, fmt);
720 msg = luaO_pushvfstring(L, fmt, argp); /* format message */ 720 msg = luaO_pushvfstring(L, fmt, argp); /* format message */
721 va_end(argp); 721 va_end(argp);
722 if (isLua(ci)) /* if Lua function, add source:line information */ 722 if (isLua(L->func)) /* if Lua function, add source:line information */
723 luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci)); 723 luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci));
724 luaG_errormsg(L); 724 luaG_errormsg(L);
725} 725}
@@ -740,14 +740,15 @@ static int changedline (Proto *p, int oldpc, int newpc) {
740 740
741void luaG_traceexec (lua_State *L) { 741void luaG_traceexec (lua_State *L) {
742 CallInfo *ci = L->ci; 742 CallInfo *ci = L->ci;
743 StkId func = L->func;
743 lu_byte mask = L->hookmask; 744 lu_byte mask = L->hookmask;
744 int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); 745 int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT));
745 if (counthook) 746 if (counthook)
746 resethookcount(L); /* reset count */ 747 resethookcount(L); /* reset count */
747 else if (!(mask & LUA_MASKLINE)) 748 else if (!(mask & LUA_MASKLINE))
748 return; /* no line hook and count != 0; nothing to be done */ 749 return; /* no line hook and count != 0; nothing to be done */
749 if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ 750 if (callstatus(func) & CIST_HOOKYIELD) { /* called hook last time? */
750 ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ 751 callstatus(func) &= ~CIST_HOOKYIELD; /* erase mark */
751 return; /* do not call hook again (VM yielded, so it did not move) */ 752 return; /* do not call hook again (VM yielded, so it did not move) */
752 } 753 }
753 if (counthook) 754 if (counthook)
@@ -767,7 +768,7 @@ void luaG_traceexec (lua_State *L) {
767 if (counthook) 768 if (counthook)
768 L->hookcount = 1; /* undo decrement to zero */ 769 L->hookcount = 1; /* undo decrement to zero */
769 ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ 770 ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
770 ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ 771 callstatus(func) |= CIST_HOOKYIELD; /* mark that it yielded */
771 luaD_throw(L, LUA_YIELD); 772 luaD_throw(L, LUA_YIELD);
772 } 773 }
773} 774}
diff --git a/ldo.c b/ldo.c
index 8c2fca13..cbb1e0f3 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.164 2017/11/01 18:20:48 roberto Exp roberto $ 2** $Id: ldo.c,v 2.165 2017/11/02 11:28:56 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -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 (L->ci->top < L->top) 126 if (functop(L->func) < L->top) /* check invariant */
127 L->ci->top = L->top; /* pushing msg. can break this invariant */ 127 setfunctop(L->func, L->top);
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 }
@@ -164,7 +164,6 @@ static void correctstack (lua_State *L, StkId oldstack) {
164 for (up = L->openupval; up != NULL; up = up->u.open.next) 164 for (up = L->openupval; up != NULL; up = up->u.open.next)
165 up->v = s2v((uplevel(up) - oldstack) + L->stack); 165 up->v = s2v((uplevel(up) - oldstack) + L->stack);
166 for (ci = L->ci; ci != NULL; ci = ci->previous) { 166 for (ci = L->ci; ci != NULL; ci = ci->previous) {
167 ci->top = (ci->top - oldstack) + L->stack;
168 ci->func = (ci->func - oldstack) + L->stack; 167 ci->func = (ci->func - oldstack) + L->stack;
169 } 168 }
170} 169}
@@ -208,10 +207,11 @@ void luaD_growstack (lua_State *L, int n) {
208 207
209 208
210static int stackinuse (lua_State *L) { 209static int stackinuse (lua_State *L) {
211 CallInfo *ci;
212 StkId lim = L->top; 210 StkId lim = L->top;
213 for (ci = L->ci; ci != NULL; ci = ci->previous) { 211 StkId func = L->func;
214 if (lim < ci->top) lim = ci->top; 212 for (; func->stkci.previous != 0; func -= func->stkci.previous) {
213 if (lim < functop(func))
214 lim = functop(func);
215 } 215 }
216 lua_assert(lim <= L->stack_last); 216 lua_assert(lim <= L->stack_last);
217 return cast_int(lim - L->stack) + 1; /* part of stack in use */ 217 return cast_int(lim - L->stack) + 1; /* part of stack in use */
@@ -255,34 +255,38 @@ void luaD_hook (lua_State *L, int event, int line) {
255 if (hook && L->allowhook) { /* make sure there is a hook */ 255 if (hook && L->allowhook) { /* make sure there is a hook */
256 CallInfo *ci = L->ci; 256 CallInfo *ci = L->ci;
257 ptrdiff_t top = savestack(L, L->top); 257 ptrdiff_t top = savestack(L, L->top);
258 ptrdiff_t ci_top = savestack(L, ci->top); 258 int origframesize = L->func->stkci.framesize;
259 int tmpframesize; /* frame size to run hook */
259 lua_Debug ar; 260 lua_Debug ar;
260 ar.event = event; 261 ar.event = event;
261 ar.currentline = line; 262 ar.currentline = line;
262 ar.i_ci = ci; 263 ar.i_ci = ci;
263 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 264 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
264 ci->top = L->top + LUA_MINSTACK; 265 tmpframesize = L->top - L->func + LUA_MINSTACK;
265 lua_assert(ci->top <= L->stack_last); 266 if (tmpframesize > origframesize) /* need to grow frame? */
267 L->func->stkci.framesize = tmpframesize;
268 lua_assert(functop(L->func) <= L->stack_last);
266 L->allowhook = 0; /* cannot call hooks inside a hook */ 269 L->allowhook = 0; /* cannot call hooks inside a hook */
267 ci->callstatus |= CIST_HOOKED; 270 callstatus(L->func) |= CIST_HOOKED;
268 lua_unlock(L); 271 lua_unlock(L);
269 (*hook)(L, &ar); 272 (*hook)(L, &ar);
270 lua_lock(L); 273 lua_lock(L);
271 lua_assert(!L->allowhook); 274 lua_assert(!L->allowhook);
272 L->allowhook = 1; 275 L->allowhook = 1;
273 ci->top = restorestack(L, ci_top); 276 L->func->stkci.framesize = origframesize;
274 L->top = restorestack(L, top); 277 L->top = restorestack(L, top);
275 ci->callstatus &= ~CIST_HOOKED; 278 callstatus(L->func) &= ~CIST_HOOKED;
276 } 279 }
277} 280}
278 281
279 282
280static void callhook (lua_State *L, CallInfo *ci) { 283static void callhook (lua_State *L, CallInfo *ci) {
281 int hook = LUA_HOOKCALL; 284 int hook = LUA_HOOKCALL;
285 StkId previous = L->func - L->func->stkci.previous;
282 ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ 286 ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
283 if (isLua(ci->previous) && 287 if (isLua(previous) &&
284 GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) { 288 GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
285 ci->callstatus |= CIST_TAIL; 289 callstatus(L->func) |= CIST_TAIL;
286 hook = LUA_HOOKTAILCALL; 290 hook = LUA_HOOKTAILCALL;
287 } 291 }
288 luaD_hook(L, hook, -1); 292 luaD_hook(L, hook, -1);
@@ -358,8 +362,8 @@ static int moveresults (lua_State *L, StkId firstResult, StkId res,
358** wanted multiple (variable number of) results. 362** wanted multiple (variable number of) results.
359*/ 363*/
360int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { 364int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
361 StkId res; 365 StkId res = L->func; /* res == final position of 1st result */
362 int wanted = ci->nresults; 366 int wanted = res->stkci.nresults;
363 if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { 367 if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
364 if (L->hookmask & LUA_MASKRET) { 368 if (L->hookmask & LUA_MASKRET) {
365 ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ 369 ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
@@ -368,7 +372,6 @@ int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
368 } 372 }
369 L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ 373 L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
370 } 374 }
371 res = L->func; /* res == final position of 1st result */
372 L->ci = ci->previous; /* back to caller */ 375 L->ci = ci->previous; /* back to caller */
373 L->func -= L->func->stkci.previous; 376 L->func -= L->func->stkci.previous;
374 lua_assert(L->func == L->ci->func); 377 lua_assert(L->func == L->ci->func);
@@ -402,12 +405,12 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
402 int n; /* number of returns */ 405 int n; /* number of returns */
403 checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ 406 checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
404 ci = next_ci(L); /* now 'enter' new function */ 407 ci = next_ci(L); /* now 'enter' new function */
405 ci->nresults = nresults; 408 func->stkci.nresults = nresults;
406 func->stkci.previous = func - L->func; 409 func->stkci.previous = func - L->func;
407 L->func = ci->func = func; 410 L->func = ci->func = func;
408 ci->top = L->top + LUA_MINSTACK; 411 setfunctop(func, L->top + LUA_MINSTACK);
409 lua_assert(ci->top <= L->stack_last); 412 lua_assert(functop(func) <= L->stack_last);
410 ci->callstatus = 0; 413 callstatus(func) = 0;
411 if (L->hookmask & LUA_MASKCALL) 414 if (L->hookmask & LUA_MASKCALL)
412 luaD_hook(L, LUA_HOOKCALL, -1); 415 luaD_hook(L, LUA_HOOKCALL, -1);
413 lua_unlock(L); 416 lua_unlock(L);
@@ -427,13 +430,14 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
427 if (p->is_vararg) 430 if (p->is_vararg)
428 luaT_adjustvarargs(L, p, n); 431 luaT_adjustvarargs(L, p, n);
429 ci = next_ci(L); /* now 'enter' new function */ 432 ci = next_ci(L); /* now 'enter' new function */
430 ci->nresults = nresults; 433 func->stkci.nresults = nresults;
431 func->stkci.previous = func - L->func; 434 func->stkci.previous = func - L->func;
435 func->stkci.framesize = fsize + 1; /* size includes function itself */
432 L->func = ci->func = func; 436 L->func = ci->func = func;
433 L->top = ci->top = func + 1 + fsize; 437 L->top = func + 1 + fsize;
434 lua_assert(ci->top <= L->stack_last); 438 lua_assert(functop(func) <= L->stack_last);
435 ci->u.l.savedpc = p->code; /* starting point */ 439 ci->u.l.savedpc = p->code; /* starting point */
436 ci->callstatus = CIST_LUA; 440 callstatus(func) = 0;
437 if (L->hookmask & LUA_MASKCALL) 441 if (L->hookmask & LUA_MASKCALL)
438 callhook(L, ci); 442 callhook(L, ci);
439 return 0; 443 return 0;
@@ -493,18 +497,19 @@ void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
493*/ 497*/
494static void finishCcall (lua_State *L, int status) { 498static void finishCcall (lua_State *L, int status) {
495 CallInfo *ci = L->ci; 499 CallInfo *ci = L->ci;
500 StkId func = L->func;
496 int n; 501 int n;
497 /* must have a continuation and must be able to call it */ 502 /* must have a continuation and must be able to call it */
498 lua_assert(ci->u.c.k != NULL && L->nny == 0); 503 lua_assert(ci->u.c.k != NULL && L->nny == 0);
499 /* error status can only happen in a protected call */ 504 /* error status can only happen in a protected call */
500 lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); 505 lua_assert((callstatus(func) & CIST_YPCALL) || status == LUA_YIELD);
501 if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ 506 if (callstatus(func) & CIST_YPCALL) { /* was inside a pcall? */
502 ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */ 507 callstatus(func) &= ~CIST_YPCALL; /* continuation is also inside it */
503 L->errfunc = ci->u.c.old_errfunc; /* with the same error function */ 508 L->errfunc = ci->u.c.old_errfunc; /* with the same error function */
504 } 509 }
505 /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already 510 /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
506 handled */ 511 handled */
507 adjustresults(L, ci->nresults); 512 adjustresults(L, func->stkci.nresults);
508 lua_unlock(L); 513 lua_unlock(L);
509 n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ 514 n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */
510 lua_lock(L); 515 lua_lock(L);
@@ -525,7 +530,7 @@ static void unroll (lua_State *L, void *ud) {
525 if (ud != NULL) /* error status? */ 530 if (ud != NULL) /* error status? */
526 finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */ 531 finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */
527 while (L->ci != &L->base_ci) { /* something in the stack */ 532 while (L->ci != &L->base_ci) { /* something in the stack */
528 if (!isLua(L->ci)) /* C function? */ 533 if (!isLua(L->func)) /* C function? */
529 finishCcall(L, LUA_YIELD); /* complete its execution */ 534 finishCcall(L, LUA_YIELD); /* complete its execution */
530 else { /* Lua function */ 535 else { /* Lua function */
531 luaV_finishOp(L); /* finish interrupted instruction */ 536 luaV_finishOp(L); /* finish interrupted instruction */
@@ -542,7 +547,7 @@ static void unroll (lua_State *L, void *ud) {
542static CallInfo *findpcall (lua_State *L) { 547static CallInfo *findpcall (lua_State *L) {
543 CallInfo *ci; 548 CallInfo *ci;
544 for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ 549 for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */
545 if (ci->callstatus & CIST_YPCALL) 550 if (callstatus(ci->func) & CIST_YPCALL)
546 return ci; 551 return ci;
547 } 552 }
548 return NULL; /* no pending pcall */ 553 return NULL; /* no pending pcall */
@@ -564,7 +569,7 @@ static int recover (lua_State *L, int status) {
564 seterrorobj(L, status, oldtop); 569 seterrorobj(L, status, oldtop);
565 L->ci = ci; 570 L->ci = ci;
566 L->func = ci->func; 571 L->func = ci->func;
567 L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ 572 L->allowhook = getoah(callstatus(L->func)); /* restore original 'allowhook' */
568 L->nny = 0; /* should be zero to be yieldable */ 573 L->nny = 0; /* should be zero to be yieldable */
569 luaD_shrinkstack(L); 574 luaD_shrinkstack(L);
570 L->errfunc = ci->u.c.old_errfunc; 575 L->errfunc = ci->u.c.old_errfunc;
@@ -604,7 +609,7 @@ static void resume (lua_State *L, void *ud) {
604 else { /* resuming from previous yield */ 609 else { /* resuming from previous yield */
605 lua_assert(L->status == LUA_YIELD); 610 lua_assert(L->status == LUA_YIELD);
606 L->status = LUA_OK; /* mark that it is running (again) */ 611 L->status = LUA_OK; /* mark that it is running (again) */
607 if (isLua(ci)) /* yielded inside a hook? */ 612 if (isLua(L->func)) /* yielded inside a hook? */
608 luaV_execute(L); /* just continue running Lua code */ 613 luaV_execute(L); /* just continue running Lua code */
609 else { /* 'common' yield */ 614 else { /* 'common' yield */
610 if (ci->u.c.k != NULL) { /* does it have a continuation function? */ 615 if (ci->u.c.k != NULL) { /* does it have a continuation function? */
@@ -649,7 +654,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
649 if (errorstatus(status)) { /* unrecoverable error? */ 654 if (errorstatus(status)) { /* unrecoverable error? */
650 L->status = cast_byte(status); /* mark thread as 'dead' */ 655 L->status = cast_byte(status); /* mark thread as 'dead' */
651 seterrorobj(L, status, L->top); /* push error message */ 656 seterrorobj(L, status, L->top); /* push error message */
652 L->ci->top = L->top; 657 L->func->stkci.framesize = L->top - L->func;
653 } 658 }
654 else lua_assert(status == L->status); /* normal end or yield */ 659 else lua_assert(status == L->status); /* normal end or yield */
655 } 660 }
@@ -671,6 +676,7 @@ LUA_API int lua_isyieldable (lua_State *L) {
671LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, 676LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
672 lua_KFunction k) { 677 lua_KFunction k) {
673 CallInfo *ci = L->ci; 678 CallInfo *ci = L->ci;
679 StkId func = L->func;
674 luai_userstateyield(L, nresults); 680 luai_userstateyield(L, nresults);
675 lua_lock(L); 681 lua_lock(L);
676 api_checknelems(L, nresults); 682 api_checknelems(L, nresults);
@@ -681,7 +687,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
681 luaG_runerror(L, "attempt to yield from outside a coroutine"); 687 luaG_runerror(L, "attempt to yield from outside a coroutine");
682 } 688 }
683 L->status = LUA_YIELD; 689 L->status = LUA_YIELD;
684 if (isLua(ci)) { /* inside a hook? */ 690 if (isLua(func)) { /* inside a hook? */
685 api_check(L, k == NULL, "hooks cannot continue after yielding"); 691 api_check(L, k == NULL, "hooks cannot continue after yielding");
686 ci->u2.nyield = 0; /* no results */ 692 ci->u2.nyield = 0; /* no results */
687 } 693 }
@@ -691,7 +697,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
691 ci->u2.nyield = nresults; /* save number of results */ 697 ci->u2.nyield = nresults; /* save number of results */
692 luaD_throw(L, LUA_YIELD); 698 luaD_throw(L, LUA_YIELD);
693 } 699 }
694 lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ 700 lua_assert(callstatus(func) & CIST_HOOKED); /* must be inside a hook */
695 lua_unlock(L); 701 lua_unlock(L);
696 return 0; /* return to 'luaD_hook' */ 702 return 0; /* return to 'luaD_hook' */
697} 703}
diff --git a/lgc.c b/lgc.c
index d9b31958..2155b28d 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.235 2017/10/11 12:38:45 roberto Exp roberto $ 2** $Id: lgc.c,v 2.236 2017/10/31 15:29:28 roberto Exp roberto $
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 L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ 869 callstatus(L->func) |= 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 L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ 871 callstatus(L->func) &= ~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 e3ae0050..66c41e6f 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 2.125 2017/06/29 15:06:44 roberto Exp roberto $ 2** $Id: lobject.h,v 2.126 2017/10/31 17:54:35 roberto Exp roberto $
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*/
@@ -313,10 +313,21 @@ typedef union StackValue {
313 TValue val; 313 TValue val;
314 struct { 314 struct {
315 TValuefields; 315 TValuefields;
316 lu_byte callstatus_;
316 unsigned short previous; /* difference to previous 'func' */ 317 unsigned short previous; /* difference to previous 'func' */
318 short nresults; /* expected number of results from this function */
319 unsigned short framesize; /* stack space available for this function */
317 } stkci; 320 } stkci;
318} StackValue; 321} StackValue;
319 322
323#define callstatus(ar) ((ar)->stkci.callstatus_)
324
325/* top of a function (first element after its frame) */
326#define functop(func) ((func) + (func)->stkci.framesize)
327
328/* set top of a function to a specific value */
329#define setfunctop(func,v) ((func)->stkci.framesize = (v) - (func))
330
320 331
321typedef StackValue *StkId; /* index to stack elements */ 332typedef StackValue *StkId; /* index to stack elements */
322 333
diff --git a/lstate.c b/lstate.c
index c4305ed8..8e3177ca 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.142 2017/10/11 12:38:45 roberto Exp roberto $ 2** $Id: lstate.c,v 2.143 2017/10/31 17:54:35 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -152,12 +152,12 @@ static void stack_init (lua_State *L1, lua_State *L) {
152 /* initialize first ci */ 152 /* initialize first ci */
153 ci = &L1->base_ci; 153 ci = &L1->base_ci;
154 ci->next = ci->previous = NULL; 154 ci->next = ci->previous = NULL;
155 ci->callstatus = 0;
156 L1->func = ci->func = L1->top; 155 L1->func = ci->func = L1->top;
157 L1->func->stkci.previous = 0; /* end of linked list */ 156 L1->func->stkci.previous = 0; /* end of linked list */
157 L1->func->stkci.framesize = LUA_MINSTACK + 1;
158 callstatus(L1->func) = 0;
158 setnilvalue(s2v(L1->top)); /* 'function' entry for this 'ci' */ 159 setnilvalue(s2v(L1->top)); /* 'function' entry for this 'ci' */
159 L1->top++; 160 L1->top++;
160 ci->top = L1->top + LUA_MINSTACK;
161 L1->ci = ci; 161 L1->ci = ci;
162} 162}
163 163
diff --git a/lstate.h b/lstate.h
index 8b9eb606..3d76e9b9 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.145 2017/10/31 17:54:35 roberto Exp roberto $ 2** $Id: lstate.h,v 2.146 2017/11/02 11:28:56 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -86,7 +86,6 @@ typedef struct stringtable {
86*/ 86*/
87typedef struct CallInfo { 87typedef struct CallInfo {
88 StkId func; /* function index in the stack */ 88 StkId func; /* function index in the stack */
89 StkId top; /* top for this function */
90 struct CallInfo *previous, *next; /* dynamic call link */ 89 struct CallInfo *previous, *next; /* dynamic call link */
91 union { 90 union {
92 struct { /* only for Lua functions */ 91 struct { /* only for Lua functions */
@@ -102,8 +101,6 @@ typedef struct CallInfo {
102 ptrdiff_t funcidx; /* called-function index */ 101 ptrdiff_t funcidx; /* called-function index */
103 int nyield; /* number of values yielded */ 102 int nyield; /* number of values yielded */
104 } u2; 103 } u2;
105 short nresults; /* expected number of results from this function */
106 unsigned short callstatus;
107} CallInfo; 104} CallInfo;
108 105
109 106
@@ -111,17 +108,16 @@ typedef struct CallInfo {
111** Bits in CallInfo status 108** Bits in CallInfo status
112*/ 109*/
113#define CIST_OAH (1<<0) /* original value of 'allowhook' */ 110#define CIST_OAH (1<<0) /* original value of 'allowhook' */
114#define CIST_LUA (1<<1) /* call is running a Lua function */ 111#define CIST_HOOKED (1<<1) /* call is running a debug hook */
115#define CIST_HOOKED (1<<2) /* call is running a debug hook */ 112#define CIST_FRESH (1<<2) /* call is running on a fresh invocation
116#define CIST_FRESH (1<<3) /* call is running on a fresh invocation
117 of luaV_execute */ 113 of luaV_execute */
118#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ 114#define CIST_YPCALL (1<<3) /* call is a yieldable protected call */
119#define CIST_TAIL (1<<5) /* call was tail called */ 115#define CIST_TAIL (1<<4) /* call was tail called */
120#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ 116#define CIST_HOOKYIELD (1<<5) /* last hook called yielded */
121#define CIST_LEQ (1<<7) /* using __lt for __le */ 117#define CIST_LEQ (1<<6) /* using __lt for __le */
122#define CIST_FIN (1<<8) /* call is running a finalizer */ 118#define CIST_FIN (1<<7) /* call is running a finalizer */
123 119
124#define isLua(ci) ((ci)->callstatus & CIST_LUA) 120#define isLua(func) isLfunction(s2v(func))
125 121
126/* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ 122/* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */
127#define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) 123#define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v))
diff --git a/ltests.c b/ltests.c
index d05fc3b1..71ad09ea 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.226 2017/11/01 18:20:48 roberto Exp roberto $ 2** $Id: ltests.c,v 2.227 2017/11/02 11:28:56 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -310,7 +310,7 @@ static void checkLclosure (global_State *g, LClosure *cl) {
310 310
311 311
312static int lua_checkpc (CallInfo *ci) { 312static int lua_checkpc (CallInfo *ci) {
313 if (!isLua(ci)) return 1; 313 if (!isLua(ci->func)) return 1;
314 else { 314 else {
315 StkId f = ci->func; 315 StkId f = ci->func;
316 Proto *p = clLvalue(s2v(f))->p; 316 Proto *p = clLvalue(s2v(f))->p;
@@ -327,10 +327,11 @@ static void checkstack (global_State *g, lua_State *L1) {
327 lua_assert(!isdead(g, L1)); 327 lua_assert(!isdead(g, L1));
328 for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next) 328 for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next)
329 lua_assert(upisopen(uv)); /* must be open */ 329 lua_assert(upisopen(uv)); /* must be open */
330 for (ci = L1->ci; ci != NULL; ci = ci->previous) { 330 for (ci = L1->ci; ci != NULL; ci = ci->previous)
331 lua_assert(ci->top <= L1->stack_last);
332 lua_assert(lua_checkpc(ci)); 331 lua_assert(lua_checkpc(ci));
333 } 332 for (o = L1->func; o->stkci.previous != 0; o -= o->stkci.previous)
333 lua_assert(functop(o) <= L1->stack_last);
334 lua_assert(o == L1->stack);
334 if (L1->stack) { /* complete thread? */ 335 if (L1->stack) { /* complete thread? */
335 for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++) 336 for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++)
336 checkliveness(L1, s2v(o)); /* entire stack must have valid values */ 337 checkliveness(L1, s2v(o)); /* entire stack must have valid values */
diff --git a/ltm.c b/ltm.c
index 1534992b..6c13e8d1 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 2.44 2017/09/27 18:59:08 roberto Exp roberto $ 2** $Id: ltm.c,v 2.45 2017/10/04 15:49:05 roberto Exp roberto $
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->ci)) 111 if (isLua(L->func))
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->ci)) 127 if (isLua(L->func))
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/lvm.c b/lvm.c
index 25b953a4..7acb387f 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.300 2017/10/31 17:54:35 roberto Exp roberto $ 2** $Id: lvm.c,v 2.301 2017/11/01 18:20:48 roberto Exp roberto $
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 L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ 393 callstatus(L->func) |= 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 L->ci->callstatus ^= CIST_LEQ; /* clear mark */ 395 callstatus(L->func) ^= 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 */
@@ -679,9 +679,9 @@ void luaV_finishOp (lua_State *L) {
679 case OP_LE: case OP_LT: case OP_EQ: { 679 case OP_LE: case OP_LT: case OP_EQ: {
680 int res = !l_isfalse(s2v(L->top - 1)); 680 int res = !l_isfalse(s2v(L->top - 1));
681 L->top--; 681 L->top--;
682 if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ 682 if (callstatus(base - 1) & CIST_LEQ) { /* "<=" using "<" ? */
683 lua_assert(op == OP_LE); 683 lua_assert(op == OP_LE);
684 ci->callstatus ^= CIST_LEQ; /* clear mark */ 684 callstatus(base - 1) ^= CIST_LEQ; /* clear mark */
685 res = !res; /* negate result */ 685 res = !res; /* negate result */
686 } 686 }
687 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); 687 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
@@ -700,17 +700,17 @@ void luaV_finishOp (lua_State *L) {
700 } 700 }
701 /* move final result to final position */ 701 /* move final result to final position */
702 setobjs2s(L, L->func + 1 + GETARG_A(inst), L->top - 1); 702 setobjs2s(L, L->func + 1 + GETARG_A(inst), L->top - 1);
703 L->top = ci->top; /* restore top */ 703 L->top = functop(base - 1); /* restore top */
704 break; 704 break;
705 } 705 }
706 case OP_TFORCALL: { 706 case OP_TFORCALL: {
707 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); 707 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
708 L->top = ci->top; /* correct top */ 708 L->top = functop(base - 1); /* correct top */
709 break; 709 break;
710 } 710 }
711 case OP_CALL: { 711 case OP_CALL: {
712 if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ 712 if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */
713 L->top = ci->top; /* adjust results */ 713 L->top = functop(base - 1); /* adjust results */
714 break; 714 break;
715 } 715 }
716 case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: 716 case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
@@ -775,9 +775,9 @@ void luaV_finishOp (lua_State *L) {
775 775
776 776
777#define checkGC(L,c) \ 777#define checkGC(L,c) \
778 { luaC_condGC(L, L->top = (c), /* limit of live values */ \ 778 { luaC_condGC(L, L->top = (c), /* limit of live values */ \
779 Protect(L->top = ci->top)); /* restore top */ \ 779 {Protect((void)0); L->top = functop(base - 1);}); /* restore top */ \
780 luai_threadyield(L); } 780 luai_threadyield(L); }
781 781
782 782
783/* fetch an instruction and prepare its execution */ 783/* fetch an instruction and prepare its execution */
@@ -796,16 +796,15 @@ void luaV_execute (lua_State *L) {
796 CallInfo *ci = L->ci; 796 CallInfo *ci = L->ci;
797 LClosure *cl; 797 LClosure *cl;
798 TValue *k; 798 TValue *k;
799 StkId base; /* local copy of 'L->func + 1' */ 799 StkId base = L->func + 1; /* local copy of 'L->func + 1' */
800 int mask; /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */ 800 int mask; /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */
801 const Instruction *pc; /* local copy of 'ci->u.l.savedpc' */ 801 const Instruction *pc; /* local copy of 'ci->u.l.savedpc' */
802 ci->callstatus |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */ 802 callstatus(base - 1) |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */
803 newframe: /* reentry point when frame changes (call/return) */ 803 newframe: /* reentry point when frame changes (call/return) */
804 lua_assert(ci == L->ci); 804 lua_assert(ci == L->ci);
805 cl = clLvalue(s2v(L->func)); /* local reference to function's closure */ 805 cl = clLvalue(s2v(L->func)); /* local reference to function's closure */
806 k = cl->p->k; /* local reference to function's constant table */ 806 k = cl->p->k; /* local reference to function's constant table */
807 updatemask(L); 807 updatemask(L);
808 base = L->func + 1;
809 pc = ci->u.l.savedpc; 808 pc = ci->u.l.savedpc;
810 /* main loop of interpreter */ 809 /* main loop of interpreter */
811 for (;;) { 810 for (;;) {
@@ -1276,7 +1275,7 @@ void luaV_execute (lua_State *L) {
1276 rb = base + b; 1275 rb = base + b;
1277 setobjs2s(L, ra, rb); 1276 setobjs2s(L, ra, rb);
1278 checkGC(L, (ra >= rb ? ra + 1 : rb)); 1277 checkGC(L, (ra >= rb ? ra + 1 : rb));
1279 L->top = ci->top; /* restore top */ 1278 L->top = functop(base - 1); /* restore top */
1280 vmbreak; 1279 vmbreak;
1281 } 1280 }
1282 vmcase(OP_CLOSE) { 1281 vmcase(OP_CLOSE) {
@@ -1355,11 +1354,12 @@ void luaV_execute (lua_State *L) {
1355 Protect(isC = luaD_precall(L, ra, nresults)); 1354 Protect(isC = luaD_precall(L, ra, nresults));
1356 if (isC) { /* C function? */ 1355 if (isC) { /* C function? */
1357 if (nresults >= 0) /* fixed number of results? */ 1356 if (nresults >= 0) /* fixed number of results? */
1358 L->top = ci->top; /* correct top */ 1357 L->top = functop(base - 1); /* correct top */
1359 /* else leave top for next instruction */ 1358 /* else leave top for next instruction */
1360 } 1359 }
1361 else { /* Lua function */ 1360 else { /* Lua function */
1362 ci = L->ci; 1361 ci = L->ci;
1362 base = L->func + 1;
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;
@@ -1386,12 +1386,14 @@ void luaV_execute (lua_State *L) {
1386 /* move new frame into old one */ 1386 /* move new frame into old one */
1387 for (aux = 0; nfunc + aux < lim; aux++) 1387 for (aux = 0; nfunc + aux < lim; aux++)
1388 setobjs2s(L, ofunc + aux, nfunc + aux); 1388 setobjs2s(L, ofunc + aux, nfunc + aux);
1389 oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ 1389 ofunc->stkci.framesize = L->top - nfunc;
1390 L->top = functop(ofunc); /* correct top */
1390 oci->u.l.savedpc = nci->u.l.savedpc; 1391 oci->u.l.savedpc = nci->u.l.savedpc;
1391 oci->callstatus |= CIST_TAIL; /* function was tail called */ 1392 callstatus(ofunc) |= CIST_TAIL; /* function was tail called */
1392 ci = L->ci = oci; /* remove new frame */ 1393 ci = L->ci = oci; /* remove new frame */
1394 base = ofunc + 1;
1393 L->func = ofunc; 1395 L->func = ofunc;
1394 lua_assert(L->top == ofunc + 1 + getproto(s2v(ofunc))->maxstacksize); 1396 lua_assert(L->top == base + getproto(s2v(ofunc))->maxstacksize);
1395 goto newframe; /* restart luaV_execute over new Lua function */ 1397 goto newframe; /* restart luaV_execute over new Lua function */
1396 } 1398 }
1397 vmbreak; 1399 vmbreak;
@@ -1401,14 +1403,15 @@ void luaV_execute (lua_State *L) {
1401 if (cl->p->sizep > 0) luaF_close(L, base); 1403 if (cl->p->sizep > 0) luaF_close(L, base);
1402 savepc(L); 1404 savepc(L);
1403 b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))); 1405 b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
1404 if (ci->callstatus & CIST_FRESH) /* local 'ci' still from callee */ 1406 if (callstatus(base - 1) & CIST_FRESH) /* local 'base' still from callee */
1405 return; /* external invocation: return */ 1407 return; /* external invocation: return */
1406 else { /* invocation via reentry: continue execution */ 1408 else { /* invocation via reentry: continue execution */
1407 ci = L->ci; 1409 ci = L->ci;
1408 if (b) L->top = ci->top; 1410 base = L->func + 1;
1409 lua_assert(isLua(ci)); 1411 if (b) L->top = functop(base - 1);
1412 lua_assert(isLua(L->func));
1410 lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); 1413 lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
1411 goto newframe; /* restart luaV_execute over new Lua function */ 1414 goto newframe; /* restart luaV_execute over previous Lua function */
1412 } 1415 }
1413 } 1416 }
1414 vmcase(OP_FORLOOP) { 1417 vmcase(OP_FORLOOP) {
@@ -1473,7 +1476,7 @@ void luaV_execute (lua_State *L) {
1473 setobjs2s(L, cb, ra); 1476 setobjs2s(L, cb, ra);
1474 L->top = cb + 3; /* func. + 2 args (state and index) */ 1477 L->top = cb + 3; /* func. + 2 args (state and index) */
1475 Protect(luaD_call(L, cb, GETARG_C(i))); 1478 Protect(luaD_call(L, cb, GETARG_C(i)));
1476 L->top = ci->top; 1479 L->top = functop(base - 1);
1477 i = *(pc++); /* go to next instruction */ 1480 i = *(pc++); /* go to next instruction */
1478 ra = RA(i); 1481 ra = RA(i);
1479 lua_assert(GET_OPCODE(i) == OP_TFORLOOP); 1482 lua_assert(GET_OPCODE(i) == OP_TFORLOOP);
@@ -1507,7 +1510,8 @@ void luaV_execute (lua_State *L) {
1507 last--; 1510 last--;
1508 luaC_barrierback(L, h, val); 1511 luaC_barrierback(L, h, val);
1509 } 1512 }
1510 L->top = ci->top; /* correct top (in case of previous open call) */ 1513 /* correct top (in case of previous open call) */
1514 L->top = functop(base - 1);
1511 vmbreak; 1515 vmbreak;
1512 } 1516 }
1513 vmcase(OP_CLOSURE) { 1517 vmcase(OP_CLOSURE) {