mirror of
https://github.com/lua/lua
synced 2024-11-22 12:51:30 +03:00
more fields moved out of 'CallInfo'
This commit is contained in:
parent
ba36180fd7
commit
54eb35a8aa
45
lapi.c
45
lapi.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lapi.c,v 2.272 2017/11/01 18:20:48 roberto Exp roberto $
|
||||
** $Id: lapi.c,v 2.273 2017/11/02 11:28:56 roberto Exp roberto $
|
||||
** Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -10,6 +10,7 @@
|
||||
#include "lprefix.h"
|
||||
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -60,12 +61,12 @@ const char lua_ident[] =
|
||||
static TValue *index2value (lua_State *L, int idx) {
|
||||
if (idx > 0) {
|
||||
StkId o = L->func + idx;
|
||||
api_check(L, idx <= L->ci->top - (L->func + 1), "unacceptable index");
|
||||
api_check(L, idx < L->func->stkci.framesize, "unacceptable index");
|
||||
if (o >= L->top) return NONVALIDVALUE;
|
||||
else return s2v(o);
|
||||
}
|
||||
else if (!ispseudo(idx)) { /* negative index */
|
||||
api_check(L, idx != 0 && -idx <= L->top - (L->func + 1), "invalid index");
|
||||
api_check(L, idx != 0 && -idx < L->func->stkci.framesize, "invalid index");
|
||||
return s2v(L->top + idx);
|
||||
}
|
||||
else if (idx == LUA_REGISTRYINDEX)
|
||||
@ -109,10 +110,12 @@ static void growstack (lua_State *L, void *ud) {
|
||||
|
||||
LUA_API int lua_checkstack (lua_State *L, int n) {
|
||||
int res;
|
||||
CallInfo *ci = L->ci;
|
||||
int frameuse = L->top - L->func;
|
||||
lua_lock(L);
|
||||
api_check(L, n >= 0, "negative 'n'");
|
||||
if (L->stack_last - L->top > n) /* stack large enough? */
|
||||
if (n >= USHRT_MAX - frameuse)
|
||||
res = 0; /* frame size overflow */
|
||||
else if (L->stack_last - L->top > n) /* stack large enough? */
|
||||
res = 1; /* yes; check is OK */
|
||||
else { /* no; need to grow stack */
|
||||
int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
|
||||
@ -121,8 +124,8 @@ LUA_API int lua_checkstack (lua_State *L, int n) {
|
||||
else /* try to grow stack */
|
||||
res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK);
|
||||
}
|
||||
if (res && ci->top < L->top + n)
|
||||
ci->top = L->top + n; /* adjust frame top */
|
||||
if (res && L->func->stkci.framesize < frameuse + n)
|
||||
L->func->stkci.framesize = frameuse + n; /* adjust frame size */
|
||||
lua_unlock(L);
|
||||
return res;
|
||||
}
|
||||
@ -134,7 +137,7 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
|
||||
lua_lock(to);
|
||||
api_checknelems(from, n);
|
||||
api_check(from, G(from) == G(to), "moving among independent states");
|
||||
api_check(from, to->ci->top - to->top >= n, "stack overflow");
|
||||
api_check(from, functop(to->func) - to->top >= n, "stack overflow");
|
||||
from->top -= n;
|
||||
for (i = 0; i < n; i++) {
|
||||
setobjs2s(to, to->top, from->top + i);
|
||||
@ -929,15 +932,16 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) {
|
||||
|
||||
|
||||
#define checkresults(L,na,nr) \
|
||||
api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
|
||||
"results from function overflow current stack size")
|
||||
api_check(L, (nr) == LUA_MULTRET || \
|
||||
(functop(L->func) - L->top >= (nr) - (na)), \
|
||||
"results from function overflow current frame size")
|
||||
|
||||
|
||||
LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
|
||||
lua_KContext ctx, lua_KFunction k) {
|
||||
StkId func;
|
||||
lua_lock(L);
|
||||
api_check(L, k == NULL || !isLua(L->ci),
|
||||
api_check(L, k == NULL || !isLua(L->func),
|
||||
"cannot use continuations inside hooks");
|
||||
api_checknelems(L, nargs+1);
|
||||
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,
|
||||
lua_KContext ctx, lua_KFunction k) {
|
||||
struct CallS c;
|
||||
int status;
|
||||
ptrdiff_t func;
|
||||
ptrdiff_t efunc;
|
||||
lua_lock(L);
|
||||
api_check(L, k == NULL || !isLua(L->ci),
|
||||
api_check(L, k == NULL || !isLua(L->func),
|
||||
"cannot use continuations inside hooks");
|
||||
api_checknelems(L, nargs+1);
|
||||
api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
|
||||
checkresults(L, nargs, nresults);
|
||||
if (errfunc == 0)
|
||||
func = 0;
|
||||
efunc = 0;
|
||||
else {
|
||||
StkId o = index2stack(L, errfunc);
|
||||
func = savestack(L, o);
|
||||
efunc = savestack(L, o);
|
||||
}
|
||||
c.func = L->top - (nargs+1); /* function to be called */
|
||||
if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */
|
||||
c.nresults = nresults; /* do a 'conventional' protected call */
|
||||
status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
|
||||
status = luaD_pcall(L, f_call, &c, savestack(L, c.func), efunc);
|
||||
}
|
||||
else { /* prepare continuation (call is already protected by 'resume') */
|
||||
CallInfo *ci = L->ci;
|
||||
StkId func = L->func;
|
||||
ci->u.c.k = k; /* save continuation */
|
||||
ci->u.c.ctx = ctx; /* save context */
|
||||
/* save information for error recovery */
|
||||
ci->u2.funcidx = savestack(L, c.func);
|
||||
ci->u.c.old_errfunc = L->errfunc;
|
||||
L->errfunc = func;
|
||||
setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */
|
||||
ci->callstatus |= CIST_YPCALL; /* function can do error recovery */
|
||||
L->errfunc = efunc;
|
||||
setoah(callstatus(func), L->allowhook); /* save value of 'allowhook' */
|
||||
callstatus(func) |= CIST_YPCALL; /* function can do error recovery */
|
||||
luaD_call(L, c.func, nresults); /* do the call */
|
||||
ci->callstatus &= ~CIST_YPCALL;
|
||||
callstatus(func) &= ~CIST_YPCALL;
|
||||
L->errfunc = ci->u.c.old_errfunc;
|
||||
status = LUA_OK; /* if it is here, there were no errors */
|
||||
}
|
||||
|
7
lapi.h
7
lapi.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lapi.h,v 2.9 2015/03/06 19:49:50 roberto Exp roberto $
|
||||
** $Id: lapi.h,v 2.10 2017/11/01 18:20:48 roberto Exp roberto $
|
||||
** Auxiliary functions from Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -11,11 +11,12 @@
|
||||
#include "llimits.h"
|
||||
#include "lstate.h"
|
||||
|
||||
#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
|
||||
#define api_incr_top(L) {L->top++; api_check(L, L->top <= functop(L->func), \
|
||||
"stack overflow");}
|
||||
|
||||
#define adjustresults(L,nres) \
|
||||
{ if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
|
||||
{ if ((nres) == LUA_MULTRET && functop(L->func) < L->top) \
|
||||
setfunctop(L->func, L->top); }
|
||||
|
||||
#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->func), \
|
||||
"not enough elements in the stack")
|
||||
|
29
ldebug.c
29
ldebug.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldebug.c,v 2.134 2017/11/01 18:20:48 roberto Exp roberto $
|
||||
** $Id: ldebug.c,v 2.135 2017/11/02 11:28:56 roberto Exp roberto $
|
||||
** Debug Interface
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -43,7 +43,7 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
|
||||
|
||||
|
||||
static int currentpc (CallInfo *ci) {
|
||||
lua_assert(isLua(ci));
|
||||
lua_assert(isLua(ci->func));
|
||||
return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
|
||||
mask = 0;
|
||||
func = NULL;
|
||||
}
|
||||
if (isLua(L->ci))
|
||||
if (isLua(L->func))
|
||||
L->oldpc = L->ci->u.l.savedpc;
|
||||
L->hook = func;
|
||||
L->basehookcount = count;
|
||||
@ -172,7 +172,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
|
||||
StkId *pos) {
|
||||
const char *name = NULL;
|
||||
StkId base;
|
||||
if (isLua(ci)) {
|
||||
if (isLua(ci->func)) {
|
||||
base = ci->func + 1;
|
||||
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
|
||||
}
|
||||
@ -277,12 +277,12 @@ static void collectvalidlines (lua_State *L, Closure *f) {
|
||||
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
|
||||
if (ci == NULL) /* no 'ci'? */
|
||||
return NULL; /* no info */
|
||||
else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */
|
||||
else if (callstatus(ci->func) & CIST_FIN) { /* is this a finalizer? */
|
||||
*name = "__gc";
|
||||
return "metamethod"; /* report it as such */
|
||||
}
|
||||
/* calling function is a known Lua function? */
|
||||
else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
|
||||
else if (!(callstatus(ci->func) & CIST_TAIL) && isLua(ci->previous->func))
|
||||
return funcnamefromcode(L, ci->previous, name);
|
||||
else return NULL; /* no way to find a name */
|
||||
}
|
||||
@ -298,7 +298,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
|
||||
ar->currentline = (ci && isLua(ci->func)) ? currentline(ci) : -1;
|
||||
break;
|
||||
}
|
||||
case 'u': {
|
||||
@ -314,7 +314,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
|
||||
break;
|
||||
}
|
||||
case 't': {
|
||||
ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
|
||||
ar->istailcall = (ci) ? callstatus(ci->func) & CIST_TAIL : 0;
|
||||
break;
|
||||
}
|
||||
case 'n': {
|
||||
@ -549,7 +549,7 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
|
||||
Proto *p = ci_func(ci)->p; /* calling function */
|
||||
int pc = currentpc(ci); /* calling instruction index */
|
||||
Instruction i = p->code[pc]; /* calling instruction */
|
||||
if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
|
||||
if (callstatus(ci->func) & CIST_HOOKED) { /* was it called inside a hook? */
|
||||
*name = "?";
|
||||
return "hook";
|
||||
}
|
||||
@ -635,7 +635,7 @@ static const char *varinfo (lua_State *L, const TValue *o) {
|
||||
const char *name = NULL; /* to avoid warnings */
|
||||
CallInfo *ci = L->ci;
|
||||
const char *kind = NULL;
|
||||
if (isLua(ci)) {
|
||||
if (isLua(L->func)) {
|
||||
kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
|
||||
if (!kind && isinstack(L, o)) /* no? try a register */
|
||||
kind = getobjname(ci_func(ci)->p, currentpc(ci),
|
||||
@ -719,7 +719,7 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
|
||||
va_start(argp, fmt);
|
||||
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
|
||||
va_end(argp);
|
||||
if (isLua(ci)) /* if Lua function, add source:line information */
|
||||
if (isLua(L->func)) /* if Lua function, add source:line information */
|
||||
luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci));
|
||||
luaG_errormsg(L);
|
||||
}
|
||||
@ -740,14 +740,15 @@ static int changedline (Proto *p, int oldpc, int newpc) {
|
||||
|
||||
void luaG_traceexec (lua_State *L) {
|
||||
CallInfo *ci = L->ci;
|
||||
StkId func = L->func;
|
||||
lu_byte mask = L->hookmask;
|
||||
int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT));
|
||||
if (counthook)
|
||||
resethookcount(L); /* reset count */
|
||||
else if (!(mask & LUA_MASKLINE))
|
||||
return; /* no line hook and count != 0; nothing to be done */
|
||||
if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */
|
||||
ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
|
||||
if (callstatus(func) & CIST_HOOKYIELD) { /* called hook last time? */
|
||||
callstatus(func) &= ~CIST_HOOKYIELD; /* erase mark */
|
||||
return; /* do not call hook again (VM yielded, so it did not move) */
|
||||
}
|
||||
if (counthook)
|
||||
@ -767,7 +768,7 @@ void luaG_traceexec (lua_State *L) {
|
||||
if (counthook)
|
||||
L->hookcount = 1; /* undo decrement to zero */
|
||||
ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
|
||||
ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
|
||||
callstatus(func) |= CIST_HOOKYIELD; /* mark that it yielded */
|
||||
luaD_throw(L, LUA_YIELD);
|
||||
}
|
||||
}
|
||||
|
80
ldo.c
80
ldo.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldo.c,v 2.164 2017/11/01 18:20:48 roberto Exp roberto $
|
||||
** $Id: ldo.c,v 2.165 2017/11/02 11:28:56 roberto Exp roberto $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -123,8 +123,8 @@ l_noret luaD_throw (lua_State *L, int errcode) {
|
||||
else { /* no handler at all; abort */
|
||||
if (g->panic) { /* panic function? */
|
||||
seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */
|
||||
if (L->ci->top < L->top)
|
||||
L->ci->top = L->top; /* pushing msg. can break this invariant */
|
||||
if (functop(L->func) < L->top) /* check invariant */
|
||||
setfunctop(L->func, L->top);
|
||||
lua_unlock(L);
|
||||
g->panic(L); /* call panic function (last chance to jump out) */
|
||||
}
|
||||
@ -164,7 +164,6 @@ static void correctstack (lua_State *L, StkId oldstack) {
|
||||
for (up = L->openupval; up != NULL; up = up->u.open.next)
|
||||
up->v = s2v((uplevel(up) - oldstack) + L->stack);
|
||||
for (ci = L->ci; ci != NULL; ci = ci->previous) {
|
||||
ci->top = (ci->top - oldstack) + L->stack;
|
||||
ci->func = (ci->func - oldstack) + L->stack;
|
||||
}
|
||||
}
|
||||
@ -208,10 +207,11 @@ void luaD_growstack (lua_State *L, int n) {
|
||||
|
||||
|
||||
static int stackinuse (lua_State *L) {
|
||||
CallInfo *ci;
|
||||
StkId lim = L->top;
|
||||
for (ci = L->ci; ci != NULL; ci = ci->previous) {
|
||||
if (lim < ci->top) lim = ci->top;
|
||||
StkId func = L->func;
|
||||
for (; func->stkci.previous != 0; func -= func->stkci.previous) {
|
||||
if (lim < functop(func))
|
||||
lim = functop(func);
|
||||
}
|
||||
lua_assert(lim <= L->stack_last);
|
||||
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) {
|
||||
if (hook && L->allowhook) { /* make sure there is a hook */
|
||||
CallInfo *ci = L->ci;
|
||||
ptrdiff_t top = savestack(L, L->top);
|
||||
ptrdiff_t ci_top = savestack(L, ci->top);
|
||||
int origframesize = L->func->stkci.framesize;
|
||||
int tmpframesize; /* frame size to run hook */
|
||||
lua_Debug ar;
|
||||
ar.event = event;
|
||||
ar.currentline = line;
|
||||
ar.i_ci = ci;
|
||||
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
||||
ci->top = L->top + LUA_MINSTACK;
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
tmpframesize = L->top - L->func + LUA_MINSTACK;
|
||||
if (tmpframesize > origframesize) /* need to grow frame? */
|
||||
L->func->stkci.framesize = tmpframesize;
|
||||
lua_assert(functop(L->func) <= L->stack_last);
|
||||
L->allowhook = 0; /* cannot call hooks inside a hook */
|
||||
ci->callstatus |= CIST_HOOKED;
|
||||
callstatus(L->func) |= CIST_HOOKED;
|
||||
lua_unlock(L);
|
||||
(*hook)(L, &ar);
|
||||
lua_lock(L);
|
||||
lua_assert(!L->allowhook);
|
||||
L->allowhook = 1;
|
||||
ci->top = restorestack(L, ci_top);
|
||||
L->func->stkci.framesize = origframesize;
|
||||
L->top = restorestack(L, top);
|
||||
ci->callstatus &= ~CIST_HOOKED;
|
||||
callstatus(L->func) &= ~CIST_HOOKED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void callhook (lua_State *L, CallInfo *ci) {
|
||||
int hook = LUA_HOOKCALL;
|
||||
StkId previous = L->func - L->func->stkci.previous;
|
||||
ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
|
||||
if (isLua(ci->previous) &&
|
||||
if (isLua(previous) &&
|
||||
GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
|
||||
ci->callstatus |= CIST_TAIL;
|
||||
callstatus(L->func) |= CIST_TAIL;
|
||||
hook = LUA_HOOKTAILCALL;
|
||||
}
|
||||
luaD_hook(L, hook, -1);
|
||||
@ -358,8 +362,8 @@ static int moveresults (lua_State *L, StkId firstResult, StkId res,
|
||||
** wanted multiple (variable number of) results.
|
||||
*/
|
||||
int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
|
||||
StkId res;
|
||||
int wanted = ci->nresults;
|
||||
StkId res = L->func; /* res == final position of 1st result */
|
||||
int wanted = res->stkci.nresults;
|
||||
if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
|
||||
if (L->hookmask & LUA_MASKRET) {
|
||||
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) {
|
||||
}
|
||||
L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
|
||||
}
|
||||
res = L->func; /* res == final position of 1st result */
|
||||
L->ci = ci->previous; /* back to caller */
|
||||
L->func -= L->func->stkci.previous;
|
||||
lua_assert(L->func == L->ci->func);
|
||||
@ -402,12 +405,12 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
int n; /* number of returns */
|
||||
checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
|
||||
ci = next_ci(L); /* now 'enter' new function */
|
||||
ci->nresults = nresults;
|
||||
func->stkci.nresults = nresults;
|
||||
func->stkci.previous = func - L->func;
|
||||
L->func = ci->func = func;
|
||||
ci->top = L->top + LUA_MINSTACK;
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
ci->callstatus = 0;
|
||||
setfunctop(func, L->top + LUA_MINSTACK);
|
||||
lua_assert(functop(func) <= L->stack_last);
|
||||
callstatus(func) = 0;
|
||||
if (L->hookmask & LUA_MASKCALL)
|
||||
luaD_hook(L, LUA_HOOKCALL, -1);
|
||||
lua_unlock(L);
|
||||
@ -427,13 +430,14 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
if (p->is_vararg)
|
||||
luaT_adjustvarargs(L, p, n);
|
||||
ci = next_ci(L); /* now 'enter' new function */
|
||||
ci->nresults = nresults;
|
||||
func->stkci.nresults = nresults;
|
||||
func->stkci.previous = func - L->func;
|
||||
func->stkci.framesize = fsize + 1; /* size includes function itself */
|
||||
L->func = ci->func = func;
|
||||
L->top = ci->top = func + 1 + fsize;
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
L->top = func + 1 + fsize;
|
||||
lua_assert(functop(func) <= L->stack_last);
|
||||
ci->u.l.savedpc = p->code; /* starting point */
|
||||
ci->callstatus = CIST_LUA;
|
||||
callstatus(func) = 0;
|
||||
if (L->hookmask & LUA_MASKCALL)
|
||||
callhook(L, ci);
|
||||
return 0;
|
||||
@ -493,18 +497,19 @@ void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
|
||||
*/
|
||||
static void finishCcall (lua_State *L, int status) {
|
||||
CallInfo *ci = L->ci;
|
||||
StkId func = L->func;
|
||||
int n;
|
||||
/* must have a continuation and must be able to call it */
|
||||
lua_assert(ci->u.c.k != NULL && L->nny == 0);
|
||||
/* error status can only happen in a protected call */
|
||||
lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD);
|
||||
if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */
|
||||
ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */
|
||||
lua_assert((callstatus(func) & CIST_YPCALL) || status == LUA_YIELD);
|
||||
if (callstatus(func) & CIST_YPCALL) { /* was inside a pcall? */
|
||||
callstatus(func) &= ~CIST_YPCALL; /* continuation is also inside it */
|
||||
L->errfunc = ci->u.c.old_errfunc; /* with the same error function */
|
||||
}
|
||||
/* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
|
||||
handled */
|
||||
adjustresults(L, ci->nresults);
|
||||
adjustresults(L, func->stkci.nresults);
|
||||
lua_unlock(L);
|
||||
n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */
|
||||
lua_lock(L);
|
||||
@ -525,7 +530,7 @@ static void unroll (lua_State *L, void *ud) {
|
||||
if (ud != NULL) /* error status? */
|
||||
finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */
|
||||
while (L->ci != &L->base_ci) { /* something in the stack */
|
||||
if (!isLua(L->ci)) /* C function? */
|
||||
if (!isLua(L->func)) /* C function? */
|
||||
finishCcall(L, LUA_YIELD); /* complete its execution */
|
||||
else { /* Lua function */
|
||||
luaV_finishOp(L); /* finish interrupted instruction */
|
||||
@ -542,7 +547,7 @@ static void unroll (lua_State *L, void *ud) {
|
||||
static CallInfo *findpcall (lua_State *L) {
|
||||
CallInfo *ci;
|
||||
for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */
|
||||
if (ci->callstatus & CIST_YPCALL)
|
||||
if (callstatus(ci->func) & CIST_YPCALL)
|
||||
return ci;
|
||||
}
|
||||
return NULL; /* no pending pcall */
|
||||
@ -564,7 +569,7 @@ static int recover (lua_State *L, int status) {
|
||||
seterrorobj(L, status, oldtop);
|
||||
L->ci = ci;
|
||||
L->func = ci->func;
|
||||
L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
|
||||
L->allowhook = getoah(callstatus(L->func)); /* restore original 'allowhook' */
|
||||
L->nny = 0; /* should be zero to be yieldable */
|
||||
luaD_shrinkstack(L);
|
||||
L->errfunc = ci->u.c.old_errfunc;
|
||||
@ -604,7 +609,7 @@ static void resume (lua_State *L, void *ud) {
|
||||
else { /* resuming from previous yield */
|
||||
lua_assert(L->status == LUA_YIELD);
|
||||
L->status = LUA_OK; /* mark that it is running (again) */
|
||||
if (isLua(ci)) /* yielded inside a hook? */
|
||||
if (isLua(L->func)) /* yielded inside a hook? */
|
||||
luaV_execute(L); /* just continue running Lua code */
|
||||
else { /* 'common' yield */
|
||||
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,
|
||||
if (errorstatus(status)) { /* unrecoverable error? */
|
||||
L->status = cast_byte(status); /* mark thread as 'dead' */
|
||||
seterrorobj(L, status, L->top); /* push error message */
|
||||
L->ci->top = L->top;
|
||||
L->func->stkci.framesize = L->top - L->func;
|
||||
}
|
||||
else lua_assert(status == L->status); /* normal end or yield */
|
||||
}
|
||||
@ -671,6 +676,7 @@ LUA_API int lua_isyieldable (lua_State *L) {
|
||||
LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
|
||||
lua_KFunction k) {
|
||||
CallInfo *ci = L->ci;
|
||||
StkId func = L->func;
|
||||
luai_userstateyield(L, nresults);
|
||||
lua_lock(L);
|
||||
api_checknelems(L, nresults);
|
||||
@ -681,7 +687,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
|
||||
luaG_runerror(L, "attempt to yield from outside a coroutine");
|
||||
}
|
||||
L->status = LUA_YIELD;
|
||||
if (isLua(ci)) { /* inside a hook? */
|
||||
if (isLua(func)) { /* inside a hook? */
|
||||
api_check(L, k == NULL, "hooks cannot continue after yielding");
|
||||
ci->u2.nyield = 0; /* no results */
|
||||
}
|
||||
@ -691,7 +697,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
|
||||
ci->u2.nyield = nresults; /* save number of results */
|
||||
luaD_throw(L, LUA_YIELD);
|
||||
}
|
||||
lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */
|
||||
lua_assert(callstatus(func) & CIST_HOOKED); /* must be inside a hook */
|
||||
lua_unlock(L);
|
||||
return 0; /* return to 'luaD_hook' */
|
||||
}
|
||||
|
6
lgc.c
6
lgc.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lgc.c,v 2.235 2017/10/11 12:38:45 roberto Exp roberto $
|
||||
** $Id: lgc.c,v 2.236 2017/10/31 15:29:28 roberto Exp roberto $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -866,9 +866,9 @@ static void GCTM (lua_State *L, int propagateerrors) {
|
||||
setobj2s(L, L->top, tm); /* push finalizer... */
|
||||
setobj2s(L, L->top + 1, &v); /* ... and its argument */
|
||||
L->top += 2; /* and (next line) call the finalizer */
|
||||
L->ci->callstatus |= CIST_FIN; /* will run a finalizer */
|
||||
callstatus(L->func) |= CIST_FIN; /* will run a finalizer */
|
||||
status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
|
||||
L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */
|
||||
callstatus(L->func) &= ~CIST_FIN; /* not running a finalizer anymore */
|
||||
L->allowhook = oldah; /* restore hooks */
|
||||
g->gcrunning = running; /* restore state */
|
||||
if (status != LUA_OK && propagateerrors) { /* error while running __gc? */
|
||||
|
13
lobject.h
13
lobject.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lobject.h,v 2.125 2017/06/29 15:06:44 roberto Exp roberto $
|
||||
** $Id: lobject.h,v 2.126 2017/10/31 17:54:35 roberto Exp roberto $
|
||||
** Type definitions for Lua objects
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -313,10 +313,21 @@ typedef union StackValue {
|
||||
TValue val;
|
||||
struct {
|
||||
TValuefields;
|
||||
lu_byte callstatus_;
|
||||
unsigned short previous; /* difference to previous 'func' */
|
||||
short nresults; /* expected number of results from this function */
|
||||
unsigned short framesize; /* stack space available for this function */
|
||||
} stkci;
|
||||
} StackValue;
|
||||
|
||||
#define callstatus(ar) ((ar)->stkci.callstatus_)
|
||||
|
||||
/* top of a function (first element after its frame) */
|
||||
#define functop(func) ((func) + (func)->stkci.framesize)
|
||||
|
||||
/* set top of a function to a specific value */
|
||||
#define setfunctop(func,v) ((func)->stkci.framesize = (v) - (func))
|
||||
|
||||
|
||||
typedef StackValue *StkId; /* index to stack elements */
|
||||
|
||||
|
6
lstate.c
6
lstate.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstate.c,v 2.142 2017/10/11 12:38:45 roberto Exp roberto $
|
||||
** $Id: lstate.c,v 2.143 2017/10/31 17:54:35 roberto Exp roberto $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -152,12 +152,12 @@ static void stack_init (lua_State *L1, lua_State *L) {
|
||||
/* initialize first ci */
|
||||
ci = &L1->base_ci;
|
||||
ci->next = ci->previous = NULL;
|
||||
ci->callstatus = 0;
|
||||
L1->func = ci->func = L1->top;
|
||||
L1->func->stkci.previous = 0; /* end of linked list */
|
||||
L1->func->stkci.framesize = LUA_MINSTACK + 1;
|
||||
callstatus(L1->func) = 0;
|
||||
setnilvalue(s2v(L1->top)); /* 'function' entry for this 'ci' */
|
||||
L1->top++;
|
||||
ci->top = L1->top + LUA_MINSTACK;
|
||||
L1->ci = ci;
|
||||
}
|
||||
|
||||
|
22
lstate.h
22
lstate.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstate.h,v 2.145 2017/10/31 17:54:35 roberto Exp roberto $
|
||||
** $Id: lstate.h,v 2.146 2017/11/02 11:28:56 roberto Exp roberto $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -86,7 +86,6 @@ typedef struct stringtable {
|
||||
*/
|
||||
typedef struct CallInfo {
|
||||
StkId func; /* function index in the stack */
|
||||
StkId top; /* top for this function */
|
||||
struct CallInfo *previous, *next; /* dynamic call link */
|
||||
union {
|
||||
struct { /* only for Lua functions */
|
||||
@ -102,8 +101,6 @@ typedef struct CallInfo {
|
||||
ptrdiff_t funcidx; /* called-function index */
|
||||
int nyield; /* number of values yielded */
|
||||
} u2;
|
||||
short nresults; /* expected number of results from this function */
|
||||
unsigned short callstatus;
|
||||
} CallInfo;
|
||||
|
||||
|
||||
@ -111,17 +108,16 @@ typedef struct CallInfo {
|
||||
** Bits in CallInfo status
|
||||
*/
|
||||
#define CIST_OAH (1<<0) /* original value of 'allowhook' */
|
||||
#define CIST_LUA (1<<1) /* call is running a Lua function */
|
||||
#define CIST_HOOKED (1<<2) /* call is running a debug hook */
|
||||
#define CIST_FRESH (1<<3) /* call is running on a fresh invocation
|
||||
#define CIST_HOOKED (1<<1) /* call is running a debug hook */
|
||||
#define CIST_FRESH (1<<2) /* call is running on a fresh invocation
|
||||
of luaV_execute */
|
||||
#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */
|
||||
#define CIST_TAIL (1<<5) /* call was tail called */
|
||||
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
|
||||
#define CIST_LEQ (1<<7) /* using __lt for __le */
|
||||
#define CIST_FIN (1<<8) /* call is running a finalizer */
|
||||
#define CIST_YPCALL (1<<3) /* call is a yieldable protected call */
|
||||
#define CIST_TAIL (1<<4) /* call was tail called */
|
||||
#define CIST_HOOKYIELD (1<<5) /* last hook called yielded */
|
||||
#define CIST_LEQ (1<<6) /* using __lt for __le */
|
||||
#define CIST_FIN (1<<7) /* call is running a finalizer */
|
||||
|
||||
#define isLua(ci) ((ci)->callstatus & CIST_LUA)
|
||||
#define isLua(func) isLfunction(s2v(func))
|
||||
|
||||
/* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */
|
||||
#define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v))
|
||||
|
11
ltests.c
11
ltests.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltests.c,v 2.226 2017/11/01 18:20:48 roberto Exp roberto $
|
||||
** $Id: ltests.c,v 2.227 2017/11/02 11:28:56 roberto Exp roberto $
|
||||
** Internal Module for Debugging of the Lua Implementation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -310,7 +310,7 @@ static void checkLclosure (global_State *g, LClosure *cl) {
|
||||
|
||||
|
||||
static int lua_checkpc (CallInfo *ci) {
|
||||
if (!isLua(ci)) return 1;
|
||||
if (!isLua(ci->func)) return 1;
|
||||
else {
|
||||
StkId f = ci->func;
|
||||
Proto *p = clLvalue(s2v(f))->p;
|
||||
@ -327,10 +327,11 @@ static void checkstack (global_State *g, lua_State *L1) {
|
||||
lua_assert(!isdead(g, L1));
|
||||
for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next)
|
||||
lua_assert(upisopen(uv)); /* must be open */
|
||||
for (ci = L1->ci; ci != NULL; ci = ci->previous) {
|
||||
lua_assert(ci->top <= L1->stack_last);
|
||||
for (ci = L1->ci; ci != NULL; ci = ci->previous)
|
||||
lua_assert(lua_checkpc(ci));
|
||||
}
|
||||
for (o = L1->func; o->stkci.previous != 0; o -= o->stkci.previous)
|
||||
lua_assert(functop(o) <= L1->stack_last);
|
||||
lua_assert(o == L1->stack);
|
||||
if (L1->stack) { /* complete thread? */
|
||||
for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++)
|
||||
checkliveness(L1, s2v(o)); /* entire stack must have valid values */
|
||||
|
6
ltm.c
6
ltm.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltm.c,v 2.44 2017/09/27 18:59:08 roberto Exp roberto $
|
||||
** $Id: ltm.c,v 2.45 2017/10/04 15:49:05 roberto Exp roberto $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -108,7 +108,7 @@ void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
|
||||
setobj2s(L, func + 3, p3); /* 3rd argument */
|
||||
L->top += 4;
|
||||
/* metamethod may yield only when called from Lua code */
|
||||
if (isLua(L->ci))
|
||||
if (isLua(L->func))
|
||||
luaD_call(L, func, 0);
|
||||
else
|
||||
luaD_callnoyield(L, func, 0);
|
||||
@ -124,7 +124,7 @@ void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
|
||||
setobj2s(L, func + 2, p2); /* 2nd argument */
|
||||
L->top += 3;
|
||||
/* metamethod may yield only when called from Lua code */
|
||||
if (isLua(L->ci))
|
||||
if (isLua(L->func))
|
||||
luaD_call(L, func, 1);
|
||||
else
|
||||
luaD_callnoyield(L, func, 1);
|
||||
|
54
lvm.c
54
lvm.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lvm.c,v 2.300 2017/10/31 17:54:35 roberto Exp roberto $
|
||||
** $Id: lvm.c,v 2.301 2017/11/01 18:20:48 roberto Exp roberto $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -390,9 +390,9 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
|
||||
else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */
|
||||
return res;
|
||||
else { /* try 'lt': */
|
||||
L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
|
||||
callstatus(L->func) |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
|
||||
res = luaT_callorderTM(L, r, l, TM_LT);
|
||||
L->ci->callstatus ^= CIST_LEQ; /* clear mark */
|
||||
callstatus(L->func) ^= CIST_LEQ; /* clear mark */
|
||||
if (res < 0)
|
||||
luaG_ordererror(L, l, r);
|
||||
return !res; /* result is negated */
|
||||
@ -679,9 +679,9 @@ void luaV_finishOp (lua_State *L) {
|
||||
case OP_LE: case OP_LT: case OP_EQ: {
|
||||
int res = !l_isfalse(s2v(L->top - 1));
|
||||
L->top--;
|
||||
if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
|
||||
if (callstatus(base - 1) & CIST_LEQ) { /* "<=" using "<" ? */
|
||||
lua_assert(op == OP_LE);
|
||||
ci->callstatus ^= CIST_LEQ; /* clear mark */
|
||||
callstatus(base - 1) ^= CIST_LEQ; /* clear mark */
|
||||
res = !res; /* negate result */
|
||||
}
|
||||
lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
|
||||
@ -700,17 +700,17 @@ void luaV_finishOp (lua_State *L) {
|
||||
}
|
||||
/* move final result to final position */
|
||||
setobjs2s(L, L->func + 1 + GETARG_A(inst), L->top - 1);
|
||||
L->top = ci->top; /* restore top */
|
||||
L->top = functop(base - 1); /* restore top */
|
||||
break;
|
||||
}
|
||||
case OP_TFORCALL: {
|
||||
lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
|
||||
L->top = ci->top; /* correct top */
|
||||
L->top = functop(base - 1); /* correct top */
|
||||
break;
|
||||
}
|
||||
case OP_CALL: {
|
||||
if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */
|
||||
L->top = ci->top; /* adjust results */
|
||||
L->top = functop(base - 1); /* adjust results */
|
||||
break;
|
||||
}
|
||||
case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
|
||||
@ -775,9 +775,9 @@ void luaV_finishOp (lua_State *L) {
|
||||
|
||||
|
||||
#define checkGC(L,c) \
|
||||
{ luaC_condGC(L, L->top = (c), /* limit of live values */ \
|
||||
Protect(L->top = ci->top)); /* restore top */ \
|
||||
luai_threadyield(L); }
|
||||
{ luaC_condGC(L, L->top = (c), /* limit of live values */ \
|
||||
{Protect((void)0); L->top = functop(base - 1);}); /* restore top */ \
|
||||
luai_threadyield(L); }
|
||||
|
||||
|
||||
/* fetch an instruction and prepare its execution */
|
||||
@ -796,16 +796,15 @@ void luaV_execute (lua_State *L) {
|
||||
CallInfo *ci = L->ci;
|
||||
LClosure *cl;
|
||||
TValue *k;
|
||||
StkId base; /* local copy of 'L->func + 1' */
|
||||
StkId base = L->func + 1; /* local copy of 'L->func + 1' */
|
||||
int mask; /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */
|
||||
const Instruction *pc; /* local copy of 'ci->u.l.savedpc' */
|
||||
ci->callstatus |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */
|
||||
callstatus(base - 1) |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */
|
||||
newframe: /* reentry point when frame changes (call/return) */
|
||||
lua_assert(ci == L->ci);
|
||||
cl = clLvalue(s2v(L->func)); /* local reference to function's closure */
|
||||
k = cl->p->k; /* local reference to function's constant table */
|
||||
updatemask(L);
|
||||
base = L->func + 1;
|
||||
pc = ci->u.l.savedpc;
|
||||
/* main loop of interpreter */
|
||||
for (;;) {
|
||||
@ -1276,7 +1275,7 @@ void luaV_execute (lua_State *L) {
|
||||
rb = base + b;
|
||||
setobjs2s(L, ra, rb);
|
||||
checkGC(L, (ra >= rb ? ra + 1 : rb));
|
||||
L->top = ci->top; /* restore top */
|
||||
L->top = functop(base - 1); /* restore top */
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_CLOSE) {
|
||||
@ -1355,11 +1354,12 @@ void luaV_execute (lua_State *L) {
|
||||
Protect(isC = luaD_precall(L, ra, nresults));
|
||||
if (isC) { /* C function? */
|
||||
if (nresults >= 0) /* fixed number of results? */
|
||||
L->top = ci->top; /* correct top */
|
||||
L->top = functop(base - 1); /* correct top */
|
||||
/* else leave top for next instruction */
|
||||
}
|
||||
else { /* Lua function */
|
||||
ci = L->ci;
|
||||
base = L->func + 1;
|
||||
goto newframe; /* restart luaV_execute over new Lua function */
|
||||
}
|
||||
vmbreak;
|
||||
@ -1386,12 +1386,14 @@ void luaV_execute (lua_State *L) {
|
||||
/* move new frame into old one */
|
||||
for (aux = 0; nfunc + aux < lim; aux++)
|
||||
setobjs2s(L, ofunc + aux, nfunc + aux);
|
||||
oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */
|
||||
ofunc->stkci.framesize = L->top - nfunc;
|
||||
L->top = functop(ofunc); /* correct top */
|
||||
oci->u.l.savedpc = nci->u.l.savedpc;
|
||||
oci->callstatus |= CIST_TAIL; /* function was tail called */
|
||||
callstatus(ofunc) |= CIST_TAIL; /* function was tail called */
|
||||
ci = L->ci = oci; /* remove new frame */
|
||||
base = ofunc + 1;
|
||||
L->func = ofunc;
|
||||
lua_assert(L->top == ofunc + 1 + getproto(s2v(ofunc))->maxstacksize);
|
||||
lua_assert(L->top == base + getproto(s2v(ofunc))->maxstacksize);
|
||||
goto newframe; /* restart luaV_execute over new Lua function */
|
||||
}
|
||||
vmbreak;
|
||||
@ -1401,14 +1403,15 @@ void luaV_execute (lua_State *L) {
|
||||
if (cl->p->sizep > 0) luaF_close(L, base);
|
||||
savepc(L);
|
||||
b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
|
||||
if (ci->callstatus & CIST_FRESH) /* local 'ci' still from callee */
|
||||
if (callstatus(base - 1) & CIST_FRESH) /* local 'base' still from callee */
|
||||
return; /* external invocation: return */
|
||||
else { /* invocation via reentry: continue execution */
|
||||
ci = L->ci;
|
||||
if (b) L->top = ci->top;
|
||||
lua_assert(isLua(ci));
|
||||
base = L->func + 1;
|
||||
if (b) L->top = functop(base - 1);
|
||||
lua_assert(isLua(L->func));
|
||||
lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
|
||||
goto newframe; /* restart luaV_execute over new Lua function */
|
||||
goto newframe; /* restart luaV_execute over previous Lua function */
|
||||
}
|
||||
}
|
||||
vmcase(OP_FORLOOP) {
|
||||
@ -1473,7 +1476,7 @@ void luaV_execute (lua_State *L) {
|
||||
setobjs2s(L, cb, ra);
|
||||
L->top = cb + 3; /* func. + 2 args (state and index) */
|
||||
Protect(luaD_call(L, cb, GETARG_C(i)));
|
||||
L->top = ci->top;
|
||||
L->top = functop(base - 1);
|
||||
i = *(pc++); /* go to next instruction */
|
||||
ra = RA(i);
|
||||
lua_assert(GET_OPCODE(i) == OP_TFORLOOP);
|
||||
@ -1507,7 +1510,8 @@ void luaV_execute (lua_State *L) {
|
||||
last--;
|
||||
luaC_barrierback(L, h, val);
|
||||
}
|
||||
L->top = ci->top; /* correct top (in case of previous open call) */
|
||||
/* correct top (in case of previous open call) */
|
||||
L->top = functop(base - 1);
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_CLOSURE) {
|
||||
|
Loading…
Reference in New Issue
Block a user