summaryrefslogtreecommitdiff
path: root/source/luametatex/source/luacore/lua54/src/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/luametatex/source/luacore/lua54/src/ldo.c')
-rw-r--r--source/luametatex/source/luacore/lua54/src/ldo.c175
1 files changed, 99 insertions, 76 deletions
diff --git a/source/luametatex/source/luacore/lua54/src/ldo.c b/source/luametatex/source/luacore/lua54/src/ldo.c
index 419b3db93..c30cde76f 100644
--- a/source/luametatex/source/luacore/lua54/src/ldo.c
+++ b/source/luametatex/source/luacore/lua54/src/ldo.c
@@ -104,11 +104,11 @@ void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
}
default: {
lua_assert(errorstatus(errcode)); /* real error */
- setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
+ setobjs2s(L, oldtop, L->top.p - 1); /* error message on current top */
break;
}
}
- L->top = oldtop + 1;
+ L->top.p = oldtop + 1;
}
@@ -121,7 +121,7 @@ l_noret luaD_throw (lua_State *L, int errcode) {
global_State *g = G(L);
errcode = luaE_resetthread(L, errcode); /* close all upvalues */
if (g->mainthread->errorJmp) { /* main thread has a handler? */
- setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */
+ setobjs2s(L, g->mainthread->top.p++, L->top.p - 1); /* copy error obj. */
luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
}
else { /* no handler at all; abort */
@@ -157,16 +157,38 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
** Stack reallocation
** ===================================================================
*/
-static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
+
+
+/*
+** Change all pointers to the stack into offsets.
+*/
+static void relstack (lua_State *L) {
CallInfo *ci;
UpVal *up;
- L->top = (L->top - oldstack) + newstack;
- L->tbclist = (L->tbclist - oldstack) + newstack;
+ L->top.offset = savestack(L, L->top.p);
+ L->tbclist.offset = savestack(L, L->tbclist.p);
for (up = L->openupval; up != NULL; up = up->u.open.next)
- up->v = s2v((uplevel(up) - oldstack) + newstack);
+ up->v.offset = savestack(L, uplevel(up));
for (ci = L->ci; ci != NULL; ci = ci->previous) {
- ci->top = (ci->top - oldstack) + newstack;
- ci->func = (ci->func - oldstack) + newstack;
+ ci->top.offset = savestack(L, ci->top.p);
+ ci->func.offset = savestack(L, ci->func.p);
+ }
+}
+
+
+/*
+** Change back all offsets into pointers.
+*/
+static void correctstack (lua_State *L) {
+ CallInfo *ci;
+ UpVal *up;
+ L->top.p = restorestack(L, L->top.offset);
+ L->tbclist.p = restorestack(L, L->tbclist.offset);
+ for (up = L->openupval; up != NULL; up = up->u.open.next)
+ up->v.p = s2v(restorestack(L, up->v.offset));
+ for (ci = L->ci; ci != NULL; ci = ci->previous) {
+ ci->top.p = restorestack(L, ci->top.offset);
+ ci->func.p = restorestack(L, ci->func.offset);
if (isLua(ci))
ci->u.l.trap = 1; /* signal to update 'trap' in 'luaV_execute' */
}
@@ -176,38 +198,39 @@ static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
/* some space for error handling */
#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
-
/*
-** Reallocate the stack to a new size, correcting all pointers into
-** it. (There are pointers to a stack from its upvalues, from its list
-** of call infos, plus a few individual pointers.) The reallocation is
-** done in two steps (allocation + free) because the correction must be
-** done while both addresses (the old stack and the new one) are valid.
-** (In ISO C, any pointer use after the pointer has been deallocated is
-** undefined behavior.)
+** Reallocate the stack to a new size, correcting all pointers into it.
+** In ISO C, any pointer use after the pointer has been deallocated is
+** undefined behavior. So, before the reallocation, all pointers are
+** changed to offsets, and after the reallocation they are changed back
+** to pointers. As during the reallocation the pointers are invalid, the
+** reallocation cannot run emergency collections.
+**
** In case of allocation error, raise an error or return false according
** to 'raiseerror'.
*/
int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
int oldsize = stacksize(L);
int i;
- StkId newstack = luaM_reallocvector(L, NULL, 0,
- newsize + EXTRA_STACK, StackValue);
+ StkId newstack;
+ int oldgcstop = G(L)->gcstopem;
lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
+ relstack(L); /* change pointers to offsets */
+ G(L)->gcstopem = 1; /* stop emergency collection */
+ newstack = luaM_reallocvector(L, L->stack.p, oldsize + EXTRA_STACK,
+ newsize + EXTRA_STACK, StackValue);
+ G(L)->gcstopem = oldgcstop; /* restore emergency collection */
if (l_unlikely(newstack == NULL)) { /* reallocation failed? */
+ correctstack(L); /* change offsets back to pointers */
if (raiseerror)
luaM_error(L);
else return 0; /* do not raise an error */
}
- /* number of elements to be copied to the new stack */
- i = ((oldsize <= newsize) ? oldsize : newsize) + EXTRA_STACK;
- memcpy(newstack, L->stack, i * sizeof(StackValue));
- for (; i < newsize + EXTRA_STACK; i++)
+ L->stack.p = newstack;
+ correctstack(L); /* change offsets back to pointers */
+ L->stack_last.p = L->stack.p + newsize;
+ for (i = oldsize + EXTRA_STACK; i < newsize + EXTRA_STACK; i++)
setnilvalue(s2v(newstack + i)); /* erase new segment */
- correctstack(L, L->stack, newstack);
- luaM_freearray(L, L->stack, oldsize + EXTRA_STACK);
- L->stack = newstack;
- L->stack_last = L->stack + newsize;
return 1;
}
@@ -229,7 +252,7 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) {
}
else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */
int newsize = 2 * size; /* tentative new size */
- int needed = cast_int(L->top - L->stack) + n;
+ int needed = cast_int(L->top.p - L->stack.p) + n;
if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */
newsize = LUAI_MAXSTACK;
if (newsize < needed) /* but must respect what was asked for */
@@ -253,12 +276,12 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) {
static int stackinuse (lua_State *L) {
CallInfo *ci;
int res;
- StkId lim = L->top;
+ StkId lim = L->top.p;
for (ci = L->ci; ci != NULL; ci = ci->previous) {
- if (lim < ci->top) lim = ci->top;
+ if (lim < ci->top.p) lim = ci->top.p;
}
- lua_assert(lim <= L->stack_last + EXTRA_STACK);
- res = cast_int(lim - L->stack) + 1; /* part of stack in use */
+ lua_assert(lim <= L->stack_last.p + EXTRA_STACK);
+ res = cast_int(lim - L->stack.p) + 1; /* part of stack in use */
if (res < LUA_MINSTACK)
res = LUA_MINSTACK; /* ensure a minimum size */
return res;
@@ -295,7 +318,7 @@ void luaD_shrinkstack (lua_State *L) {
void luaD_inctop (lua_State *L) {
luaD_checkstack(L, 1);
- L->top++;
+ L->top.p++;
}
/* }================================================================== */
@@ -312,8 +335,8 @@ void luaD_hook (lua_State *L, int event, int line,
if (hook && L->allowhook) { /* make sure there is a hook */
int mask = CIST_HOOKED;
CallInfo *ci = L->ci;
- ptrdiff_t top = savestack(L, L->top); /* preserve original 'top' */
- ptrdiff_t ci_top = savestack(L, ci->top); /* idem for 'ci->top' */
+ ptrdiff_t top = savestack(L, L->top.p); /* preserve original 'top' */
+ ptrdiff_t ci_top = savestack(L, ci->top.p); /* idem for 'ci->top' */
lua_Debug ar;
ar.event = event;
ar.currentline = line;
@@ -323,11 +346,11 @@ void luaD_hook (lua_State *L, int event, int line,
ci->u2.transferinfo.ftransfer = ftransfer;
ci->u2.transferinfo.ntransfer = ntransfer;
}
- if (isLua(ci) && L->top < ci->top)
- L->top = ci->top; /* protect entire activation register */
+ if (isLua(ci) && L->top.p < ci->top.p)
+ L->top.p = ci->top.p; /* protect entire activation register */
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
- if (ci->top < L->top + LUA_MINSTACK)
- ci->top = L->top + LUA_MINSTACK;
+ if (ci->top.p < L->top.p + LUA_MINSTACK)
+ ci->top.p = L->top.p + LUA_MINSTACK;
L->allowhook = 0; /* cannot call hooks inside a hook */
ci->callstatus |= mask;
lua_unlock(L);
@@ -335,8 +358,8 @@ void luaD_hook (lua_State *L, int event, int line,
lua_lock(L);
lua_assert(!L->allowhook);
L->allowhook = 1;
- ci->top = restorestack(L, ci_top);
- L->top = restorestack(L, top);
+ ci->top.p = restorestack(L, ci_top);
+ L->top.p = restorestack(L, top);
ci->callstatus &= ~mask;
}
}
@@ -367,7 +390,7 @@ void luaD_hookcall (lua_State *L, CallInfo *ci) {
*/
static void rethook (lua_State *L, CallInfo *ci, int nres) {
if (L->hookmask & LUA_MASKRET) { /* is return hook on? */
- StkId firstres = L->top - nres; /* index of first result */
+ StkId firstres = L->top.p - nres; /* index of first result */
int delta = 0; /* correction for vararg functions */
int ftransfer;
if (isLua(ci)) {
@@ -375,10 +398,10 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) {
if (p->is_vararg)
delta = ci->u.l.nextraargs + p->numparams + 1;
}
- ci->func += delta; /* if vararg, back to virtual 'func' */
- ftransfer = cast(unsigned short, firstres - ci->func);
+ ci->func.p += delta; /* if vararg, back to virtual 'func' */
+ ftransfer = cast(unsigned short, firstres - ci->func.p);
luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */
- ci->func -= delta;
+ ci->func.p -= delta;
}
if (isLua(ci = ci->previous))
L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* set 'oldpc' */
@@ -397,9 +420,9 @@ StkId luaD_tryfuncTM (lua_State *L, StkId func) {
tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); /* (after previous GC) */
if (l_unlikely(ttisnil(tm)))
luaG_callerror(L, s2v(func)); /* nothing to call */
- for (p = L->top; p > func; p--) /* open space for metamethod */
+ for (p = L->top.p; p > func; p--) /* open space for metamethod */
setobjs2s(L, p, p-1);
- L->top++; /* stack space pre-allocated by the caller */
+ L->top.p++; /* stack space pre-allocated by the caller */
setobj2s(L, func, tm); /* metamethod is the new function to be called */
return func;
}
@@ -416,14 +439,14 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
int i;
switch (wanted) { /* handle typical cases separately */
case 0: /* no values needed */
- L->top = res;
+ L->top.p = res;
return;
case 1: /* one value needed */
if (nres == 0) /* no results? */
setnilvalue(s2v(res)); /* adjust with nil */
else /* at least one result */
- setobjs2s(L, res, L->top - nres); /* move it to proper place */
- L->top = res + 1;
+ setobjs2s(L, res, L->top.p - nres); /* move it to proper place */
+ L->top.p = res + 1;
return;
case LUA_MULTRET:
wanted = nres; /* we want all results */
@@ -446,14 +469,14 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
break;
}
/* generic case */
- firstresult = L->top - nres; /* index of first result */
+ firstresult = L->top.p - nres; /* index of first result */
if (nres > wanted) /* extra results? */
nres = wanted; /* don't need them */
for (i = 0; i < nres; i++) /* move all results to correct place */
setobjs2s(L, res + i, firstresult + i);
for (; i < wanted; i++) /* complete wanted number of results */
setnilvalue(s2v(res + i));
- L->top = res + wanted; /* top points after the last result */
+ L->top.p = res + wanted; /* top points after the last result */
}
@@ -468,7 +491,7 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
if (l_unlikely(L->hookmask && !hastocloseCfunc(wanted)))
rethook(L, ci, nres);
/* move results to proper place */
- moveresults(L, ci->func, nres, wanted);
+ moveresults(L, ci->func.p, nres, wanted);
/* function cannot be in any of these cases when returning */
lua_assert(!(ci->callstatus &
(CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET)));
@@ -483,10 +506,10 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret,
int mask, StkId top) {
CallInfo *ci = L->ci = next_ci(L); /* new frame */
- ci->func = func;
+ ci->func.p = func;
ci->nresults = nret;
ci->callstatus = mask;
- ci->top = top;
+ ci->top.p = top;
return ci;
}
@@ -500,10 +523,10 @@ l_sinline int precallC (lua_State *L, StkId func, int nresults,
CallInfo *ci;
checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
L->ci = ci = prepCallInfo(L, func, nresults, CIST_C,
- L->top + LUA_MINSTACK);
- lua_assert(ci->top <= L->stack_last);
+ L->top.p + LUA_MINSTACK);
+ lua_assert(ci->top.p <= L->stack_last.p);
if (l_unlikely(L->hookmask & LUA_MASKCALL)) {
- int narg = cast_int(L->top - func) - 1;
+ int narg = cast_int(L->top.p - func) - 1;
luaD_hook(L, LUA_HOOKCALL, -1, 1, narg);
}
lua_unlock(L);
@@ -535,17 +558,17 @@ int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
int nfixparams = p->numparams;
int i;
checkstackGCp(L, fsize - delta, func);
- ci->func -= delta; /* restore 'func' (if vararg) */
+ ci->func.p -= delta; /* restore 'func' (if vararg) */
for (i = 0; i < narg1; i++) /* move down function and arguments */
- setobjs2s(L, ci->func + i, func + i);
- func = ci->func; /* moved-down function */
+ setobjs2s(L, ci->func.p + i, func + i);
+ func = ci->func.p; /* moved-down function */
for (; narg1 <= nfixparams; narg1++)
setnilvalue(s2v(func + narg1)); /* complete missing arguments */
- ci->top = func + 1 + fsize; /* top for new function */
- lua_assert(ci->top <= L->stack_last);
+ ci->top.p = func + 1 + fsize; /* top for new function */
+ lua_assert(ci->top.p <= L->stack_last.p);
ci->u.l.savedpc = p->code; /* starting point */
ci->callstatus |= CIST_TAIL;
- L->top = func + narg1; /* set top */
+ L->top.p = func + narg1; /* set top */
return -1;
}
default: { /* not a function */
@@ -578,15 +601,15 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
case LUA_VLCL: { /* Lua function */
CallInfo *ci;
Proto *p = clLvalue(s2v(func))->p;
- int narg = cast_int(L->top - func) - 1; /* number of real arguments */
+ int narg = cast_int(L->top.p - func) - 1; /* number of real arguments */
int nfixparams = p->numparams;
int fsize = p->maxstacksize; /* frame size */
checkstackGCp(L, fsize, func);
L->ci = ci = prepCallInfo(L, func, nresults, 0, func + 1 + fsize);
ci->u.l.savedpc = p->code; /* starting point */
for (; narg < nfixparams; narg++)
- setnilvalue(s2v(L->top++)); /* complete missing arguments */
- lua_assert(ci->top <= L->stack_last);
+ setnilvalue(s2v(L->top.p++)); /* complete missing arguments */
+ lua_assert(ci->top.p <= L->stack_last.p);
return ci;
}
default: { /* not a function */
@@ -748,8 +771,8 @@ static CallInfo *findpcall (lua_State *L) {
** coroutine error handler and should not kill the coroutine.)
*/
static int resume_error (lua_State *L, const char *msg, int narg) {
- L->top -= narg; /* remove args from the stack */
- setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
+ L->top.p -= narg; /* remove args from the stack */
+ setsvalue2s(L, L->top.p, luaS_new(L, msg)); /* push error message */
api_incr_top(L);
lua_unlock(L);
return LUA_ERRRUN;
@@ -765,7 +788,7 @@ static int resume_error (lua_State *L, const char *msg, int narg) {
*/
static void resume (lua_State *L, void *ud) {
int n = *(cast(int*, ud)); /* number of arguments */
- StkId firstArg = L->top - n; /* first argument */
+ StkId firstArg = L->top.p - n; /* first argument */
CallInfo *ci = L->ci;
if (L->status == LUA_OK) /* starting a coroutine? */
ccall(L, firstArg - 1, LUA_MULTRET, 0); /* just call its body */
@@ -773,7 +796,7 @@ static void resume (lua_State *L, void *ud) {
lua_assert(L->status == LUA_YIELD);
L->status = LUA_OK; /* mark that it is running (again) */
if (isLua(ci)) { /* yielded inside a hook? */
- L->top = firstArg; /* discard arguments */
+ L->top.p = firstArg; /* discard arguments */
luaV_execute(L, ci); /* just continue running Lua code */
}
else { /* 'common' yield */
@@ -816,7 +839,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
if (L->status == LUA_OK) { /* may be starting a coroutine */
if (L->ci != &L->base_ci) /* not in base level? */
return resume_error(L, "cannot resume non-suspended coroutine", nargs);
- else if (L->top - (L->ci->func + 1) == nargs) /* no function? */
+ else if (L->top.p - (L->ci->func.p + 1) == nargs) /* no function? */
return resume_error(L, "cannot resume dead coroutine", nargs);
}
else if (L->status != LUA_YIELD) /* ended with errors? */
@@ -834,11 +857,11 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
lua_assert(status == L->status); /* normal end or yield */
else { /* unrecoverable error */
L->status = cast_byte(status); /* mark thread as 'dead' */
- luaD_seterrorobj(L, status, L->top); /* push error message */
- L->ci->top = L->top;
+ luaD_seterrorobj(L, status, L->top.p); /* push error message */
+ L->ci->top.p = L->top.p;
}
*nresults = (status == LUA_YIELD) ? L->ci->u2.nyield
- : cast_int(L->top - (L->ci->func + 1));
+ : cast_int(L->top.p - (L->ci->func.p + 1));
lua_unlock(L);
return status;
}
@@ -993,7 +1016,7 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
p.dyd.label.arr = NULL; p.dyd.label.size = 0;
luaZ_initbuffer(L, &p.buff);
- status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
+ status = luaD_pcall(L, f_parser, &p, savestack(L, L->top.p), L->errfunc);
luaZ_freebuffer(L, &p.buff);
luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);