!51 upgrade to version 5.4.6
From: @ziyangc Reviewed-by: @hubin95 Signed-off-by: @hubin95
This commit is contained in:
commit
fbc698423c
@ -1,117 +0,0 @@
|
||||
From 04e19712a5d48b84869f9942836ff8314fb0be8e Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Mon, 14 Jun 2021 13:28:21 -0300
|
||||
Subject: [PATCH] C functions can be tail called, too
|
||||
|
||||
A tail call to a C function can have the behavior of a "real" tail
|
||||
call, reusing the stack frame of the caller.
|
||||
|
||||
---
|
||||
src/ldo.c | 43 +++++++++++++++++++++++++------------------
|
||||
src/lvm.c | 9 +--------
|
||||
4 files changed, 29 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/src/ldo.c b/src/ldo.c
|
||||
index a410461b..38540561 100644
|
||||
--- a/src/ldo.c
|
||||
+++ b/src/ldo.c
|
||||
@@ -478,12 +478,31 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
|
||||
** (This is done only when no more errors can occur before entering the
|
||||
** new function, to keep debug information always consistent.)
|
||||
*/
|
||||
-static void moveparams (lua_State *L, StkId prevf, StkId func, int narg) {
|
||||
+static void moveparams (lua_State *L, StkId prevf, StkId func) {
|
||||
int i;
|
||||
- narg++; /* function itself will be moved, too */
|
||||
- for (i = 0; i < narg; i++) /* move down function and arguments */
|
||||
+ for (i = 0; func + i < L->top; i++) /* move down function and arguments */
|
||||
setobjs2s(L, prevf + i, func + i);
|
||||
- L->top = prevf + narg; /* correct top */
|
||||
+ L->top = prevf + i; /* correct top */
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static CallInfo *prepCallInfo (lua_State *L, StkId func, int nresults,
|
||||
+ int delta1, int mask) {
|
||||
+ CallInfo *ci;
|
||||
+ if (delta1) { /* tail call? */
|
||||
+ ci = L->ci; /* reuse stack frame */
|
||||
+ ci->func -= delta1 - 1; /* correct 'func' */
|
||||
+
|
||||
+ ci->callstatus |= mask | CIST_TAIL;
|
||||
+ moveparams(L, ci->func, func);
|
||||
+ }
|
||||
+ else { /* regular call */
|
||||
+ ci = L->ci = next_ci(L); /* new frame */
|
||||
+ ci->func = func;
|
||||
+ ci->nresults = nresults;
|
||||
+ ci->callstatus = mask;
|
||||
+ }
|
||||
+ return ci;
|
||||
}
|
||||
|
||||
|
||||
@@ -512,11 +531,8 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, int delta1) {
|
||||
int n; /* number of returns */
|
||||
CallInfo *ci;
|
||||
checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
|
||||
- L->ci = ci = next_ci(L);
|
||||
- ci->nresults = nresults;
|
||||
- ci->callstatus = CIST_C;
|
||||
+ ci = prepCallInfo(L, func, nresults, delta1, CIST_C);
|
||||
ci->top = L->top + LUA_MINSTACK;
|
||||
- ci->func = func;
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
if (l_unlikely(L->hookmask & LUA_MASKCALL)) {
|
||||
int narg = cast_int(L->top - func) - 1;
|
||||
@@ -536,16 +552,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, int delta1) {
|
||||
int nfixparams = p->numparams;
|
||||
int fsize = p->maxstacksize; /* frame size */
|
||||
checkstackGCp(L, fsize, func);
|
||||
- if (delta1) { /* tail call? */
|
||||
- ci = L->ci; /* reuse stack frame */
|
||||
- ci->func -= delta1 - 1; /* correct 'func' */
|
||||
- moveparams(L, ci->func, func, narg);
|
||||
- }
|
||||
- else { /* regular call */
|
||||
- L->ci = ci = next_ci(L); /* new frame */
|
||||
- ci->func = func;
|
||||
- ci->nresults = nresults;
|
||||
- }
|
||||
+ ci = prepCallInfo(L, func, nresults, delta1, 0);
|
||||
ci->u.l.savedpc = p->code; /* starting point */
|
||||
ci->top = func + 1 + fsize;
|
||||
for (; narg < nfixparams; narg++)
|
||||
diff --git a/src/lvm.c b/src/lvm.c
|
||||
index 485b9caa..62ff70da 100644
|
||||
--- a/src/lvm.c
|
||||
+++ b/src/lvm.c
|
||||
@@ -1636,7 +1636,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
updatetrap(ci); /* C call; nothing else to be done */
|
||||
else { /* Lua call: run function in this same C frame */
|
||||
ci = newci;
|
||||
- ci->callstatus = 0;
|
||||
goto startfunc;
|
||||
}
|
||||
vmbreak;
|
||||
@@ -1655,16 +1654,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
lua_assert(L->tbclist < base); /* no pending tbc variables */
|
||||
lua_assert(base == ci->func + 1);
|
||||
}
|
||||
- if (luaD_precall(L, ra, LUA_MULTRET, delta + 1)) { /* Lua function? */
|
||||
- ci->callstatus |= CIST_TAIL;
|
||||
+ if (luaD_precall(L, ra, LUA_MULTRET, delta + 1)) /* Lua function? */
|
||||
goto startfunc; /* execute the callee */
|
||||
- }
|
||||
else { /* C function */
|
||||
updatetrap(ci);
|
||||
- updatestack(ci); /* stack may have been relocated */
|
||||
- ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
- luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */
|
||||
- updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
||||
goto ret; /* caller returns after the tail call */
|
||||
}
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
From 74d99057a5146755e737c479850f87fd0e3b6868 Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Wed, 3 Nov 2021 15:04:18 -0300
|
||||
Subject: [PATCH] Bug: C stack overflow with coroutines
|
||||
|
||||
'coroutine.resume' did not increment counter of C calls when
|
||||
continuing execution after a protected error (that is,
|
||||
while running 'precover').
|
||||
---
|
||||
lua-5.4.3-tests/cstack.lua | 14 ++++++++++++++
|
||||
src/ldo.c | 6 ++++--
|
||||
2 files changed, 18 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lua-5.4.3-tests/cstack.lua b/lua-5.4.3-tests/cstack.lua
|
||||
index 213d15d..ca76c87 100644
|
||||
--- a/lua-5.4.3-tests/cstack.lua
|
||||
+++ b/lua-5.4.3-tests/cstack.lua
|
||||
@@ -103,6 +103,20 @@ do
|
||||
end
|
||||
|
||||
|
||||
+do -- bug in 5.4.2
|
||||
+ print("nesting coroutines running after recoverable errors")
|
||||
+ local count = 0
|
||||
+ local function foo()
|
||||
+ count = count + 1
|
||||
+ pcall(1) -- create an error
|
||||
+ -- running now inside 'precover' ("protected recover")
|
||||
+ coroutine.wrap(foo)() -- call another coroutine
|
||||
+ end
|
||||
+ checkerror("C stack overflow", foo)
|
||||
+ print("final count: ", count)
|
||||
+end
|
||||
+
|
||||
+
|
||||
if T then
|
||||
print("testing stack recovery")
|
||||
local N = 0 -- trace number of calls
|
||||
diff --git a/src/ldo.c b/src/ldo.c
|
||||
index 7135079..ca558fd 100644
|
||||
--- a/src/ldo.c
|
||||
+++ b/src/ldo.c
|
||||
@@ -728,11 +728,10 @@ static void resume (lua_State *L, void *ud) {
|
||||
StkId firstArg = L->top - n; /* first argument */
|
||||
CallInfo *ci = L->ci;
|
||||
if (L->status == LUA_OK) /* starting a coroutine? */
|
||||
- ccall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */
|
||||
+ ccall(L, firstArg - 1, LUA_MULTRET, 0); /* just call its body */
|
||||
else { /* resuming from previous yield */
|
||||
lua_assert(L->status == LUA_YIELD);
|
||||
L->status = LUA_OK; /* mark that it is running (again) */
|
||||
- luaE_incCstack(L); /* control the C stack */
|
||||
if (isLua(ci)) { /* yielded inside a hook? */
|
||||
L->top = firstArg; /* discard arguments */
|
||||
luaV_execute(L, ci); /* just continue running Lua code */
|
||||
@@ -783,6 +782,9 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
|
||||
else if (L->status != LUA_YIELD) /* ended with errors? */
|
||||
return resume_error(L, "cannot resume dead coroutine", nargs);
|
||||
L->nCcalls = (from) ? getCcalls(from) : 0;
|
||||
+ if (getCcalls(L) >= LUAI_MAXCCALLS)
|
||||
+ return resume_error(L, "C stack overflow", nargs);
|
||||
+ L->nCcalls++;
|
||||
luai_userstateresume(L, nargs);
|
||||
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
|
||||
status = luaD_rawrunprotected(L, resume, &nargs);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
From 1de95e97ef65632a88e08b6184bd9d1ceba7ec2f Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Fri, 10 Dec 2021 10:53:54 -0300
|
||||
Subject: [PATCH] Bug: Lua stack still active when closing a state
|
||||
|
||||
---
|
||||
src/lstate.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/lstate.c b/src/lstate.c
|
||||
index c5e3b43..38da773 100644
|
||||
--- a/src/lstate.c
|
||||
+++ b/src/lstate.c
|
||||
@@ -271,6 +271,7 @@ static void close_state (lua_State *L) {
|
||||
if (!completestate(g)) /* closing a partially built state? */
|
||||
luaC_freeallobjects(L); /* jucst collect its objects */
|
||||
else { /* closing a fully built state */
|
||||
+ L->ci = &L->base_ci; /* unwind CallInfo list */
|
||||
luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */
|
||||
luaC_freeallobjects(L); /* collect all objects */
|
||||
luai_userstateclose(L);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,297 +0,0 @@
|
||||
From 0bfc572e51d9035a615ef6e9523f736c9ffa8e57 Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Mon, 13 Dec 2021 10:41:17 -0300
|
||||
Subject: [PATCH] Bug: GC is not reentrant
|
||||
|
||||
As the GC is not reentrant, finalizers should not be able to invoke it.
|
||||
---
|
||||
lua-5.4.3-tests/api.lua | 5 ++---
|
||||
lua-5.4.3-tests/gc.lua | 6 ++++--
|
||||
src/lapi.c | 17 +++++++++--------
|
||||
src/lbaselib.c | 19 +++++++++++++++++--
|
||||
src/lgc.c | 11 +++++++----
|
||||
src/lgc.h | 9 +++++++++
|
||||
src/lstate.c | 4 ++--
|
||||
src/lstate.h | 2 +-
|
||||
8 files changed, 51 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/lua-5.4.3-tests/api.lua b/lua-5.4.3-tests/api.lua
|
||||
index c1bcb4b..bd85a92 100644
|
||||
--- a/lua-5.4.3-tests/api.lua
|
||||
+++ b/lua-5.4.3-tests/api.lua
|
||||
@@ -804,15 +804,14 @@ F = function (x)
|
||||
d = nil
|
||||
assert(debug.getmetatable(x).__gc == F)
|
||||
assert(load("table.insert({}, {})"))() -- create more garbage
|
||||
- collectgarbage() -- force a GC during GC
|
||||
- assert(debug.getmetatable(x).__gc == F) -- previous GC did not mess this?
|
||||
+ assert(not collectgarbage()) -- GC during GC (no op)
|
||||
local dummy = {} -- create more garbage during GC
|
||||
if A ~= nil then
|
||||
assert(type(A) == "userdata")
|
||||
assert(T.udataval(A) == B)
|
||||
debug.getmetatable(A) -- just access it
|
||||
end
|
||||
- A = x -- ressucita userdata
|
||||
+ A = x -- ressurect userdata
|
||||
B = udval
|
||||
return 1,2,3
|
||||
end
|
||||
diff --git a/lua-5.4.3-tests/gc.lua b/lua-5.4.3-tests/gc.lua
|
||||
index 2332c93..d865cb2 100644
|
||||
--- a/lua-5.4.3-tests/gc.lua
|
||||
+++ b/lua-5.4.3-tests/gc.lua
|
||||
@@ -676,11 +676,13 @@ end
|
||||
-- just to make sure
|
||||
assert(collectgarbage'isrunning')
|
||||
|
||||
-do -- check that the collector is reentrant in incremental mode
|
||||
+do -- check that the collector is not reentrant in incremental mode
|
||||
+ local res = true
|
||||
setmetatable({}, {__gc = function ()
|
||||
- collectgarbage()
|
||||
+ res = collectgarbage()
|
||||
end})
|
||||
collectgarbage()
|
||||
+ assert(not res)
|
||||
end
|
||||
|
||||
|
||||
diff --git a/src/lapi.c b/src/lapi.c
|
||||
index f8f70cd..7b96979 100644
|
||||
--- a/src/lapi.c
|
||||
+++ b/src/lapi.c
|
||||
@@ -1126,18 +1126,19 @@ LUA_API int lua_status (lua_State *L) {
|
||||
LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||
va_list argp;
|
||||
int res = 0;
|
||||
- global_State *g;
|
||||
+ global_State *g = G(L);
|
||||
+ if (g->gcstp & GCSTPGC) /* internal stop? */
|
||||
+ return -1; /* all options are invalid when stopped */
|
||||
lua_lock(L);
|
||||
- g = G(L);
|
||||
va_start(argp, what);
|
||||
switch (what) {
|
||||
case LUA_GCSTOP: {
|
||||
- g->gcrunning = 0;
|
||||
+ g->gcstp = GCSTPUSR; /* stopeed by the user */
|
||||
break;
|
||||
}
|
||||
case LUA_GCRESTART: {
|
||||
luaE_setdebt(g, 0);
|
||||
- g->gcrunning = 1;
|
||||
+ g->gcstp = 0; /* (GCSTPGC must be already zero here) */
|
||||
break;
|
||||
}
|
||||
case LUA_GCCOLLECT: {
|
||||
@@ -1156,8 +1157,8 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||
case LUA_GCSTEP: {
|
||||
int data = va_arg(argp, int);
|
||||
l_mem debt = 1; /* =1 to signal that it did an actual step */
|
||||
- lu_byte oldrunning = g->gcrunning;
|
||||
- g->gcrunning = 1; /* allow GC to run */
|
||||
+ lu_byte oldstp = g->gcstp;
|
||||
+ g->gcstp = 0; /* allow GC to run (GCSTPGC must be zero here) */
|
||||
if (data == 0) {
|
||||
luaE_setdebt(g, 0); /* do a basic step */
|
||||
luaC_step(L);
|
||||
@@ -1167,7 +1168,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||
luaE_setdebt(g, debt);
|
||||
luaC_checkGC(L);
|
||||
}
|
||||
- g->gcrunning = oldrunning; /* restore previous state */
|
||||
+ g->gcstp = oldstp; /* restore previous state */
|
||||
if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */
|
||||
res = 1; /* signal it */
|
||||
break;
|
||||
@@ -1185,7 +1186,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||
break;
|
||||
}
|
||||
case LUA_GCISRUNNING: {
|
||||
- res = g->gcrunning;
|
||||
+ res = gcrunning(g);
|
||||
break;
|
||||
}
|
||||
case LUA_GCGEN: {
|
||||
diff --git a/src/lbaselib.c b/src/lbaselib.c
|
||||
index 83ad306..82abd94 100644
|
||||
--- a/src/lbaselib.c
|
||||
+++ b/src/lbaselib.c
|
||||
@@ -182,12 +182,20 @@ static int luaB_rawset (lua_State *L) {
|
||||
|
||||
|
||||
static int pushmode (lua_State *L, int oldmode) {
|
||||
- lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental"
|
||||
- : "generational");
|
||||
+ if (oldmode == -1)
|
||||
+ luaL_pushfail(L); /* invalid call to 'lua_gc' */
|
||||
+ else
|
||||
+ lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental"
|
||||
+ : "generational");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+/*
|
||||
+** check whether call to 'lua_gc' was valid (not inside a finalizer)
|
||||
+*/
|
||||
+#define checkvalres(res) { if (res == -1) break; }
|
||||
+
|
||||
static int luaB_collectgarbage (lua_State *L) {
|
||||
static const char *const opts[] = {"stop", "restart", "collect",
|
||||
"count", "step", "setpause", "setstepmul",
|
||||
@@ -200,12 +208,14 @@ static int luaB_collectgarbage (lua_State *L) {
|
||||
case LUA_GCCOUNT: {
|
||||
int k = lua_gc(L, o);
|
||||
int b = lua_gc(L, LUA_GCCOUNTB);
|
||||
+ checkvalres(k);
|
||||
lua_pushnumber(L, (lua_Number)k + ((lua_Number)b/1024));
|
||||
return 1;
|
||||
}
|
||||
case LUA_GCSTEP: {
|
||||
int step = (int)luaL_optinteger(L, 2, 0);
|
||||
int res = lua_gc(L, o, step);
|
||||
+ checkvalres(res);
|
||||
lua_pushboolean(L, res);
|
||||
return 1;
|
||||
}
|
||||
@@ -213,11 +223,13 @@ static int luaB_collectgarbage (lua_State *L) {
|
||||
case LUA_GCSETSTEPMUL: {
|
||||
int p = (int)luaL_optinteger(L, 2, 0);
|
||||
int previous = lua_gc(L, o, p);
|
||||
+ checkvalres(previous);
|
||||
lua_pushinteger(L, previous);
|
||||
return 1;
|
||||
}
|
||||
case LUA_GCISRUNNING: {
|
||||
int res = lua_gc(L, o);
|
||||
+ checkvalres(res);
|
||||
lua_pushboolean(L, res);
|
||||
return 1;
|
||||
}
|
||||
@@ -234,10 +246,13 @@ static int luaB_collectgarbage (lua_State *L) {
|
||||
}
|
||||
default: {
|
||||
int res = lua_gc(L, o);
|
||||
+ checkvalres(res);
|
||||
lua_pushinteger(L, res);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
+ luaL_pushfail(L); /* invalid call (inside a finalizer) */
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
|
||||
diff --git a/src/lgc.c b/src/lgc.c
|
||||
index b360eed..7d0b5e4 100644
|
||||
--- a/src/lgc.c
|
||||
+++ b/src/lgc.c
|
||||
@@ -906,16 +906,16 @@ static void GCTM (lua_State *L) {
|
||||
if (!notm(tm)) { /* is there a finalizer? */
|
||||
int status;
|
||||
lu_byte oldah = L->allowhook;
|
||||
- int running = g->gcrunning;
|
||||
+ int oldgcstp = g->gcstp;
|
||||
+ g->gcstp = GCSTPGC; /* avoid GC steps */
|
||||
L->allowhook = 0; /* stop debug hooks during GC metamethod */
|
||||
- g->gcrunning = 0; /* avoid GC steps */
|
||||
setobj2s(L, L->top++, tm); /* push finalizer... */
|
||||
setobj2s(L, L->top++, &v); /* ... and its argument */
|
||||
L->ci->callstatus |= 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 */
|
||||
L->allowhook = oldah; /* restore hooks */
|
||||
- g->gcrunning = running; /* restore state */
|
||||
+ g->gcstp = oldgcstp; /* restore state */
|
||||
if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */
|
||||
luaE_warnerror(L, "__gc metamethod");
|
||||
L->top--; /* pops error object */
|
||||
@@ -1502,9 +1502,11 @@ static void deletelist (lua_State *L, GCObject *p, GCObject *limit) {
|
||||
*/
|
||||
void luaC_freeallobjects (lua_State *L) {
|
||||
global_State *g = G(L);
|
||||
+ g->gcstp = GCSTPGC;
|
||||
luaC_changemode(L, KGC_INC);
|
||||
separatetobefnz(g, 1); /* separate all objects with finalizers */
|
||||
lua_assert(g->finobj == NULL);
|
||||
+ g->gcstp = 0;
|
||||
callallpendingfinalizers(L);
|
||||
deletelist(L, g->allgc, obj2gco(g->mainthread));
|
||||
deletelist(L, g->finobj, NULL);
|
||||
@@ -1647,6 +1649,7 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
|
||||
}
|
||||
|
||||
|
||||
+
|
||||
/*
|
||||
** Performs a basic incremental step. The debt and step size are
|
||||
** converted from bytes to "units of work"; then the function loops
|
||||
@@ -1678,7 +1681,7 @@ static void incstep (lua_State *L, global_State *g) {
|
||||
void luaC_step (lua_State *L) {
|
||||
global_State *g = G(L);
|
||||
lua_assert(!g->gcemergency);
|
||||
- if (g->gcrunning) { /* running? */
|
||||
+ if (gcrunning(g)) { /* running? */
|
||||
if(isdecGCmodegen(g))
|
||||
genstep(L, g);
|
||||
else
|
||||
diff --git a/src/lgc.h b/src/lgc.h
|
||||
index 073e2a4..024a432 100644
|
||||
--- a/src/lgc.h
|
||||
+++ b/src/lgc.h
|
||||
@@ -148,6 +148,15 @@
|
||||
*/
|
||||
#define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0)
|
||||
|
||||
+
|
||||
+/*
|
||||
+** Control when GC is running:
|
||||
+*/
|
||||
+#define GCSTPUSR 1 /* bit true when GC stopped by user */
|
||||
+#define GCSTPGC 2 /* bit true when GC stopped by itself */
|
||||
+#define gcrunning(g) ((g)->gcstp == 0)
|
||||
+
|
||||
+
|
||||
/*
|
||||
** Does one step of collection when debt becomes positive. 'pre'/'pos'
|
||||
** allows some adjustments to be done only when needed. macro
|
||||
diff --git a/src/lstate.c b/src/lstate.c
|
||||
index 38da773..59b4f21 100644
|
||||
--- a/src/lstate.c
|
||||
+++ b/src/lstate.c
|
||||
@@ -236,7 +236,7 @@ static void f_luaopen (lua_State *L, void *ud) {
|
||||
luaS_init(L);
|
||||
luaT_init(L);
|
||||
luaX_init(L);
|
||||
- g->gcrunning = 1; /* allow gc */
|
||||
+ g->gcstp = 0; /* allow gc */
|
||||
setnilvalue(&g->nilvalue); /* now state is complete */
|
||||
luai_userstateopen(L);
|
||||
}
|
||||
@@ -373,7 +373,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
|
||||
g->ud_warn = NULL;
|
||||
g->mainthread = L;
|
||||
g->seed = luai_makeseed(L);
|
||||
- g->gcrunning = 0; /* no GC while building state */
|
||||
+ g->gcstp = GCSTPGC; /* no GC while building state */
|
||||
g->strt.size = g->strt.nuse = 0;
|
||||
g->strt.hash = NULL;
|
||||
setnilvalue(&g->l_registry);
|
||||
diff --git a/src/lstate.h b/src/lstate.h
|
||||
index c1283bb..0d2099f 100644
|
||||
--- a/src/lstate.h
|
||||
+++ b/src/lstate.h
|
||||
@@ -263,7 +263,7 @@ typedef struct global_State {
|
||||
lu_byte gcstopem; /* stops emergency collections */
|
||||
lu_byte genminormul; /* control for minor generational collections */
|
||||
lu_byte genmajormul; /* control for major generational collections */
|
||||
- lu_byte gcrunning; /* true if GC is running */
|
||||
+ lu_byte gcstp; /* control whether GC is running */
|
||||
lu_byte gcemergency; /* true if this is an emergency collection */
|
||||
lu_byte gcpause; /* size of pause between successive GCs */
|
||||
lu_byte gcstepmul; /* GC "speed" */
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
From cf613cdc6fa367257fc61c256f63d917350858b5 Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Wed, 15 Dec 2021 11:29:07 -0300
|
||||
Subject: [PATCH] Bug: finalizers can be called with an invalid stack
|
||||
|
||||
The call to 'checkstackGC' can run finalizers, which will find an
|
||||
inconsistent CallInfo, as 'ci' is half updated at the point of call.
|
||||
|
||||
Reference:https://github.com/lua/lua/commit/cf613cdc6fa367257fc61c256f63d917350858b5
|
||||
Conflict:NA
|
||||
---
|
||||
src/ldo.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/ldo.c b/src/ldo.c
|
||||
index f282a773..a48e35f9 100644
|
||||
--- a/src/ldo.c
|
||||
+++ b/src/ldo.c
|
||||
@@ -530,10 +530,10 @@ int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
|
||||
int fsize = p->maxstacksize; /* frame size */
|
||||
int nfixparams = p->numparams;
|
||||
int i;
|
||||
+ checkstackGCp(L, fsize - delta, func);
|
||||
ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
for (i = 0; i < narg1; i++) /* move down function and arguments */
|
||||
setobjs2s(L, ci->func + i, func + i);
|
||||
- checkstackGC(L, fsize);
|
||||
func = ci->func; /* moved-down function */
|
||||
for (; narg1 <= nfixparams; narg1++)
|
||||
setnilvalue(s2v(func + narg1)); /* complete missing arguments */
|
||||
--
|
||||
2.33.0
|
||||
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
From 1f3c6f4534c6411313361697d98d1145a1f030fa Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Tue, 15 Feb 2022 12:28:46 -0300
|
||||
Subject: [PATCH] Bug: Lua can generate wrong code when _ENV is <const>
|
||||
|
||||
---
|
||||
lua-5.4.3-tests/attrib.lua | 10 ++++++++++
|
||||
src/lparser.c | 1 +
|
||||
2 files changed, 11 insertions(+)
|
||||
|
||||
diff --git a/lua-5.4.3-tests/attrib.lua b/lua-5.4.3-tests/attrib.lua
|
||||
index b1076c7..83821c0 100644
|
||||
--- a/lua-5.4.3-tests/attrib.lua
|
||||
+++ b/lua-5.4.3-tests/attrib.lua
|
||||
@@ -434,6 +434,16 @@ a.aVeryLongName012345678901234567890123456789012345678901234567890123456789 ==
|
||||
10)
|
||||
|
||||
|
||||
+do
|
||||
+ -- _ENV constant
|
||||
+ local function foo ()
|
||||
+ local _ENV <const> = 11
|
||||
+ X = "hi"
|
||||
+ end
|
||||
+ local st, msg = pcall(foo)
|
||||
+ assert(not st and string.find(msg, "number"))
|
||||
+end
|
||||
+
|
||||
|
||||
-- test of large float/integer indices
|
||||
|
||||
diff --git a/src/lparser.c b/src/lparser.c
|
||||
index 284ef1f..0626833 100644
|
||||
--- a/src/lparser.c
|
||||
+++ b/src/lparser.c
|
||||
@@ -457,6 +457,7 @@ static void singlevar (LexState *ls, expdesc *var) {
|
||||
expdesc key;
|
||||
singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
|
||||
lua_assert(var->k != VVOID); /* this one must exist */
|
||||
+ luaK_exp2anyregup(fs, var); /* but could be a constant */
|
||||
codestring(&key, varname); /* key is variable name */
|
||||
luaK_indexed(fs, var, &key); /* env[varname] */
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
From 42d40581dd919fb134c07027ca1ce0844c670daf Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Fri, 20 May 2022 13:14:33 -0300
|
||||
Subject: [PATCH] Save stack space while handling errors
|
||||
|
||||
Because error handling (luaG_errormsg) uses slots from EXTRA_STACK,
|
||||
and some errors can recur (e.g., string overflow while creating an
|
||||
error message in 'luaG_runerror', or a C-stack overflow before calling
|
||||
the message handler), the code should use stack slots with parsimony.
|
||||
|
||||
This commit fixes the bug "Lua-stack overflow when C stack overflows
|
||||
while handling an error".
|
||||
---
|
||||
src/ldebug.c | 5 ++++-
|
||||
src/lvm.c | 6 ++++--
|
||||
2 files changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/ldebug.c b/src/ldebug.c
|
||||
index 1feaab2..5524fae 100644
|
||||
--- a/src/ldebug.c
|
||||
+++ b/src/ldebug.c
|
||||
@@ -783,8 +783,11 @@ 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(ci)) { /* if Lua function, add source:line information */
|
||||
luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
|
||||
+ setobjs2s(L, L->top - 2, L->top - 1); /* remove 'msg' from the stack */
|
||||
+ L->top--;
|
||||
+ }
|
||||
luaG_errormsg(L);
|
||||
}
|
||||
|
||||
diff --git a/src/lvm.c b/src/lvm.c
|
||||
index c9729bc..a965087 100644
|
||||
--- a/src/lvm.c
|
||||
+++ b/src/lvm.c
|
||||
@@ -656,8 +656,10 @@ void luaV_concat (lua_State *L, int total) {
|
||||
/* collect total length and number of strings */
|
||||
for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
|
||||
size_t l = vslen(s2v(top - n - 1));
|
||||
- if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl))
|
||||
+ if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) {
|
||||
+ L->top = top - total; /* pop strings to avoid wasting stack */
|
||||
luaG_runerror(L, "string length overflow");
|
||||
+ }
|
||||
tl += l;
|
||||
}
|
||||
if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */
|
||||
@@ -672,7 +674,7 @@ void luaV_concat (lua_State *L, int total) {
|
||||
setsvalue2s(L, top - n, ts); /* create result */
|
||||
}
|
||||
total -= n-1; /* got 'n' strings to create 1 new */
|
||||
- L->top -= n-1; /* popped 'n' strings and pushed one */
|
||||
+ L->top = top - (n - 1); /* popped 'n' strings and pushed one */
|
||||
} while (total > 1); /* repeat until only 1 result left */
|
||||
}
|
||||
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -1,203 +0,0 @@
|
||||
From 1fce5bea817de50e055a84c153a975f25bfcf493 Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Fri, 29 Oct 2021 13:41:24 -0300
|
||||
Subject: [PATCH] More uniform implementation for tail calls
|
||||
|
||||
'luaD_pretailcall' mimics 'luaD_precall', handling call metamethods
|
||||
and calling C functions directly. That makes the code in the
|
||||
interpreter loop simpler.
|
||||
|
||||
This commit also goes back to emulating the tail call in 'luaD_precall'
|
||||
with a goto, as C compilers may not do proper tail calls and the C
|
||||
stack can overflow much sooner than the Lua stack (which grows as the
|
||||
metamethod is added to it).
|
||||
|
||||
Reference:https://github.com/lua/lua/commit/1fce5bea817de50e055a84c153a975f25bfcf493
|
||||
Conflict:NA
|
||||
---
|
||||
src/ldo.c | 81 ++++++++++++++++++++++++++++++++++++++---------------------
|
||||
src/ldo.h | 2 +-
|
||||
src/lvm.c | 19 ++++----------
|
||||
3 files changed, 58 insertions(+), 44 deletions(-)
|
||||
|
||||
diff --git a/src/ldo.c b/src/ldo.c
|
||||
index 0ac12e74..d0edc8b4 100644
|
||||
--- a/src/ldo.c
|
||||
+++ b/src/ldo.c
|
||||
@@ -475,30 +475,6 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
|
||||
#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L))
|
||||
|
||||
|
||||
-/*
|
||||
-** Prepare a function for a tail call, building its call info on top
|
||||
-** of the current call info. 'narg1' is the number of arguments plus 1
|
||||
-** (so that it includes the function itself).
|
||||
-*/
|
||||
-void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) {
|
||||
- Proto *p = clLvalue(s2v(func))->p;
|
||||
- int fsize = p->maxstacksize; /* frame size */
|
||||
- int nfixparams = p->numparams;
|
||||
- int i;
|
||||
- for (i = 0; i < narg1; i++) /* move down function and arguments */
|
||||
- setobjs2s(L, ci->func + i, func + i);
|
||||
- checkstackGC(L, fsize);
|
||||
- func = ci->func; /* 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->u.l.savedpc = p->code; /* starting point */
|
||||
- ci->callstatus |= CIST_TAIL;
|
||||
- L->top = func + narg1; /* set top */
|
||||
-}
|
||||
-
|
||||
-
|
||||
l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret,
|
||||
int mask, StkId top) {
|
||||
CallInfo *ci = L->ci = next_ci(L); /* new frame */
|
||||
@@ -513,7 +489,7 @@ l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret,
|
||||
/*
|
||||
** precall for C functions
|
||||
*/
|
||||
-l_sinline CallInfo *precallC (lua_State *L, StkId func, int nresults,
|
||||
+l_sinline int precallC (lua_State *L, StkId func, int nresults,
|
||||
lua_CFunction f) {
|
||||
int n; /* number of returns */
|
||||
CallInfo *ci;
|
||||
@@ -530,7 +506,50 @@ l_sinline CallInfo *precallC (lua_State *L, StkId func, int nresults,
|
||||
lua_lock(L);
|
||||
api_checknelems(L, n);
|
||||
luaD_poscall(L, ci, n);
|
||||
- return NULL;
|
||||
+ return n;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+** Prepare a function for a tail call, building its call info on top
|
||||
+** of the current call info. 'narg1' is the number of arguments plus 1
|
||||
+** (so that it includes the function itself). Return the number of
|
||||
+** results, if it was a C function, or -1 for a Lua function.
|
||||
+*/
|
||||
+int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
|
||||
+ int narg1, int delta) {
|
||||
+ retry:
|
||||
+ switch (ttypetag(s2v(func))) {
|
||||
+ case LUA_VCCL: /* C closure */
|
||||
+ return precallC(L, func, LUA_MULTRET, clCvalue(s2v(func))->f);
|
||||
+ case LUA_VLCF: /* light C function */
|
||||
+ return precallC(L, func, LUA_MULTRET, fvalue(s2v(func)));
|
||||
+ case LUA_VLCL: { /* Lua function */
|
||||
+ Proto *p = clLvalue(s2v(func))->p;
|
||||
+ int fsize = p->maxstacksize; /* frame size */
|
||||
+ int nfixparams = p->numparams;
|
||||
+ int i;
|
||||
+ ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
+ for (i = 0; i < narg1; i++) /* move down function and arguments */
|
||||
+ setobjs2s(L, ci->func + i, func + i);
|
||||
+ checkstackGC(L, fsize);
|
||||
+ func = ci->func; /* 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->u.l.savedpc = p->code; /* starting point */
|
||||
+ ci->callstatus |= CIST_TAIL;
|
||||
+ L->top = func + narg1; /* set top */
|
||||
+ return -1;
|
||||
+ }
|
||||
+ default: { /* not a function */
|
||||
+ func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
|
||||
+ /* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */
|
||||
+ narg1++;
|
||||
+ goto retry; /* try again */
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
@@ -543,11 +562,14 @@ l_sinline CallInfo *precallC (lua_State *L, StkId func, int nresults,
|
||||
** original function position.
|
||||
*/
|
||||
CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
+ retry:
|
||||
switch (ttypetag(s2v(func))) {
|
||||
case LUA_VCCL: /* C closure */
|
||||
- return precallC(L, func, nresults, clCvalue(s2v(func))->f);
|
||||
+ precallC(L, func, nresults, clCvalue(s2v(func))->f);
|
||||
+ return NULL;
|
||||
case LUA_VLCF: /* light C function */
|
||||
- return precallC(L, func, nresults, fvalue(s2v(func)));
|
||||
+ precallC(L, func, nresults, fvalue(s2v(func)));
|
||||
+ return NULL;
|
||||
case LUA_VLCL: { /* Lua function */
|
||||
CallInfo *ci;
|
||||
Proto *p = clLvalue(s2v(func))->p;
|
||||
@@ -564,7 +586,8 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
}
|
||||
default: { /* not a function */
|
||||
func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
|
||||
- return luaD_precall(L, func, nresults); /* try again with metamethod */
|
||||
+ /* return luaD_precall(L, func, nresults); */
|
||||
+ goto retry; /* try again with metamethod */
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/ldo.h b/src/ldo.h
|
||||
index 9fb772fe..911e67f6 100644
|
||||
--- a/src/ldo.h
|
||||
+++ b/src/ldo.h
|
||||
@@ -58,7 +58,7 @@ LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
||||
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line,
|
||||
int fTransfer, int nTransfer);
|
||||
LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci);
|
||||
-LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n);
|
||||
+LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1, int delta);
|
||||
LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults);
|
||||
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
|
||||
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
|
||||
diff --git a/src/lvm.c b/src/lvm.c
|
||||
index 49ed3ddf..2ec34400 100644
|
||||
--- a/src/lvm.c
|
||||
+++ b/src/lvm.c
|
||||
@@ -1643,6 +1643,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
}
|
||||
vmcase(OP_TAILCALL) {
|
||||
int b = GETARG_B(i); /* number of arguments + 1 (function) */
|
||||
+ int n; /* number of results when calling a C function */
|
||||
int nparams1 = GETARG_C(i);
|
||||
/* delta is virtual 'func' - real 'func' (vararg functions) */
|
||||
int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
|
||||
@@ -1656,24 +1657,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
lua_assert(L->tbclist < base); /* no pending tbc variables */
|
||||
lua_assert(base == ci->func + 1);
|
||||
}
|
||||
- while (!ttisfunction(s2v(ra))) { /* not a function? */
|
||||
- ra = luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
|
||||
- b++; /* there is now one extra argument */
|
||||
- }
|
||||
- if (!ttisLclosure(s2v(ra))) { /* C function? */
|
||||
- luaD_precall(L, ra, LUA_MULTRET); /* call it */
|
||||
- updatetrap(ci);
|
||||
- updatestack(ci); /* stack may have been relocated */
|
||||
+ if ((n = luaD_pretailcall(L, ci, ra, b, delta)) < 0) /* Lua function? */
|
||||
+ goto startfunc; /* execute the callee */
|
||||
+ else { /* C function? */
|
||||
ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
- luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */
|
||||
+ luaD_poscall(L, ci, n); /* finish caller */
|
||||
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
||||
goto ret; /* caller returns after the tail call */
|
||||
}
|
||||
- else { /* Lua function */
|
||||
- ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
- luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
|
||||
- goto startfunc; /* execute the callee */
|
||||
- }
|
||||
}
|
||||
vmcase(OP_RETURN) {
|
||||
int n = GETARG_B(i) - 1; /* number of results */
|
||||
--
|
||||
2.33.0
|
||||
|
||||
|
||||
@ -1,107 +0,0 @@
|
||||
From 3699446aaf5c7a07af028b1ae43cf52d2d4dda59 Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Mon, 18 Oct 2021 11:58:40 -0300
|
||||
Subject: [PATCH] Removed goto's in 'luaD_precall'
|
||||
|
||||
(plus a detail in src/lauxlib.h.)
|
||||
---
|
||||
src/lauxlib.h | 2 +-
|
||||
src/ldo.c | 51 +++++++++++++++++++++++++++------------------------
|
||||
2 files changed, 28 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/src/lauxlib.h b/src/lauxlib.h
|
||||
index 6f9695e8..5b977e2a 100644
|
||||
--- a/src/lauxlib.h
|
||||
+++ b/src/lauxlib.h
|
||||
@@ -102,7 +102,7 @@ LUALIB_API lua_State *(luaL_newstate) (void);
|
||||
|
||||
LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
|
||||
|
||||
-LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s,
|
||||
+LUALIB_API void (luaL_addgsub) (luaL_Buffer *b, const char *s,
|
||||
const char *p, const char *r);
|
||||
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s,
|
||||
const char *p, const char *r);
|
||||
diff --git a/src/ldo.c b/src/ldo.c
|
||||
index 88b20f95..0ac12e74 100644
|
||||
--- a/src/ldo.c
|
||||
+++ b/src/ldo.c
|
||||
@@ -510,6 +510,30 @@ l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret,
|
||||
}
|
||||
|
||||
|
||||
+/*
|
||||
+** precall for C functions
|
||||
+*/
|
||||
+l_sinline CallInfo *precallC (lua_State *L, StkId func, int nresults,
|
||||
+ lua_CFunction f) {
|
||||
+ int n; /* number of returns */
|
||||
+ 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);
|
||||
+ if (l_unlikely(L->hookmask & LUA_MASKCALL)) {
|
||||
+ int narg = cast_int(L->top - func) - 1;
|
||||
+ luaD_hook(L, LUA_HOOKCALL, -1, 1, narg);
|
||||
+ }
|
||||
+ lua_unlock(L);
|
||||
+ n = (*f)(L); /* do the actual call */
|
||||
+ lua_lock(L);
|
||||
+ api_checknelems(L, n);
|
||||
+ luaD_poscall(L, ci, n);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
** Prepares the call to a function (C or Lua). For C functions, also do
|
||||
** the call. The function to be called is at '*func'. The arguments
|
||||
@@ -519,32 +543,11 @@ l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret,
|
||||
** original function position.
|
||||
*/
|
||||
CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
- lua_CFunction f;
|
||||
- retry:
|
||||
switch (ttypetag(s2v(func))) {
|
||||
case LUA_VCCL: /* C closure */
|
||||
- f = clCvalue(s2v(func))->f;
|
||||
- goto Cfunc;
|
||||
+ return precallC(L, func, nresults, clCvalue(s2v(func))->f);
|
||||
case LUA_VLCF: /* light C function */
|
||||
- f = fvalue(s2v(func));
|
||||
- Cfunc: {
|
||||
- int n; /* number of returns */
|
||||
- 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);
|
||||
- if (l_unlikely(L->hookmask & LUA_MASKCALL)) {
|
||||
- int narg = cast_int(L->top - func) - 1;
|
||||
- luaD_hook(L, LUA_HOOKCALL, -1, 1, narg);
|
||||
- }
|
||||
- lua_unlock(L);
|
||||
- n = (*f)(L); /* do the actual call */
|
||||
- lua_lock(L);
|
||||
- api_checknelems(L, n);
|
||||
- luaD_poscall(L, ci, n);
|
||||
- return NULL;
|
||||
- }
|
||||
+ return precallC(L, func, nresults, fvalue(s2v(func)));
|
||||
case LUA_VLCL: { /* Lua function */
|
||||
CallInfo *ci;
|
||||
Proto *p = clLvalue(s2v(func))->p;
|
||||
@@ -561,7 +564,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
}
|
||||
default: { /* not a function */
|
||||
func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
|
||||
- goto retry; /* try again with metamethod */
|
||||
+ return luaD_precall(L, func, nresults); /* try again with metamethod */
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
|
||||
@ -1,172 +0,0 @@
|
||||
From 901d76009346d76996679c02deee708bf225e91e Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Fri, 11 Jun 2021 13:41:07 -0300
|
||||
Subject: [PATCH] Simpler implementation for tail calls
|
||||
|
||||
Tail calls handled by 'luaD_precall', like regular calls, to avoid
|
||||
code duplication.
|
||||
---
|
||||
src/ldo.c | 48 ++++++++++++++++++++++++------------------------
|
||||
src/ldo.h | 4 ++--
|
||||
src/lvm.c | 20 +++++++-------------
|
||||
3 files changed, 33 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/src/ldo.c b/src/ldo.c
|
||||
index 7135079b..a410461b 100644
|
||||
--- a/src/ldo.c
|
||||
+++ b/src/ldo.c
|
||||
@@ -474,26 +474,16 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
|
||||
|
||||
|
||||
/*
|
||||
-** Prepare a function for a tail call, building its call info on top
|
||||
-** of the current call info. 'narg1' is the number of arguments plus 1
|
||||
-** (so that it includes the function itself).
|
||||
+** In a tail call, move function and parameters to previous call frame.
|
||||
+** (This is done only when no more errors can occur before entering the
|
||||
+** new function, to keep debug information always consistent.)
|
||||
*/
|
||||
-void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) {
|
||||
- Proto *p = clLvalue(s2v(func))->p;
|
||||
- int fsize = p->maxstacksize; /* frame size */
|
||||
- int nfixparams = p->numparams;
|
||||
+static void moveparams (lua_State *L, StkId prevf, StkId func, int narg) {
|
||||
int i;
|
||||
- for (i = 0; i < narg1; i++) /* move down function and arguments */
|
||||
- setobjs2s(L, ci->func + i, func + i);
|
||||
- checkstackGC(L, fsize);
|
||||
- func = ci->func; /* 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->u.l.savedpc = p->code; /* starting point */
|
||||
- ci->callstatus |= CIST_TAIL;
|
||||
- L->top = func + narg1; /* set top */
|
||||
+ narg++; /* function itself will be moved, too */
|
||||
+ for (i = 0; i < narg; i++) /* move down function and arguments */
|
||||
+ setobjs2s(L, prevf + i, func + i);
|
||||
+ L->top = prevf + narg; /* correct top */
|
||||
}
|
||||
|
||||
|
||||
@@ -504,8 +494,12 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) {
|
||||
** to be executed, if it was a Lua function. Otherwise (a C function)
|
||||
** returns NULL, with all the results on the stack, starting at the
|
||||
** original function position.
|
||||
+** For regular calls, 'delta1' is 0. For tail calls, 'delta1' is the
|
||||
+** 'delta' (correction of base for vararg functions) plus 1, so that it
|
||||
+** cannot be zero. Like 'moveparams', this correction can only be done
|
||||
+** when no more errors can occur in the call.
|
||||
*/
|
||||
-CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
+CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, int delta1) {
|
||||
lua_CFunction f;
|
||||
retry:
|
||||
switch (ttypetag(s2v(func))) {
|
||||
@@ -542,12 +536,18 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
int nfixparams = p->numparams;
|
||||
int fsize = p->maxstacksize; /* frame size */
|
||||
checkstackGCp(L, fsize, func);
|
||||
- L->ci = ci = next_ci(L);
|
||||
- ci->nresults = nresults;
|
||||
+ if (delta1) { /* tail call? */
|
||||
+ ci = L->ci; /* reuse stack frame */
|
||||
+ ci->func -= delta1 - 1; /* correct 'func' */
|
||||
+ moveparams(L, ci->func, func, narg);
|
||||
+ }
|
||||
+ else { /* regular call */
|
||||
+ L->ci = ci = next_ci(L); /* new frame */
|
||||
+ ci->func = func;
|
||||
+ ci->nresults = nresults;
|
||||
+ }
|
||||
ci->u.l.savedpc = p->code; /* starting point */
|
||||
ci->top = func + 1 + fsize;
|
||||
- ci->func = func;
|
||||
- L->ci = ci;
|
||||
for (; narg < nfixparams; narg++)
|
||||
setnilvalue(s2v(L->top++)); /* complete missing arguments */
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
@@ -572,7 +572,7 @@ static void ccall (lua_State *L, StkId func, int nResults, int inc) {
|
||||
L->nCcalls += inc;
|
||||
if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
|
||||
luaE_checkcstack(L);
|
||||
- if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */
|
||||
+ if ((ci = luaD_precall(L, func, nResults, 0)) != NULL) { /* Lua function? */
|
||||
ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */
|
||||
luaV_execute(L, ci); /* call it */
|
||||
}
|
||||
diff --git a/src/ldo.h b/src/ldo.h
|
||||
index 6bf0ed86..6edc4450 100644
|
||||
--- a/src/ldo.h
|
||||
+++ b/src/ldo.h
|
||||
@@ -58,8 +58,8 @@ LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
||||
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line,
|
||||
int fTransfer, int nTransfer);
|
||||
LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci);
|
||||
-LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n);
|
||||
-LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults);
|
||||
+LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nresults,
|
||||
+ int delta1);
|
||||
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
|
||||
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
|
||||
LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func);
|
||||
diff --git a/src/lvm.c b/src/lvm.c
|
||||
index e4b1903e..485b9caa 100644
|
||||
--- a/src/lvm.c
|
||||
+++ b/src/lvm.c
|
||||
@@ -1632,11 +1632,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
L->top = ra + b; /* top signals number of arguments */
|
||||
/* else previous instruction set top */
|
||||
savepc(L); /* in case of errors */
|
||||
- if ((newci = luaD_precall(L, ra, nresults)) == NULL)
|
||||
+ if ((newci = luaD_precall(L, ra, nresults, 0)) == NULL)
|
||||
updatetrap(ci); /* C call; nothing else to be done */
|
||||
else { /* Lua call: run function in this same C frame */
|
||||
ci = newci;
|
||||
- ci->callstatus = 0; /* call re-uses 'luaV_execute' */
|
||||
+ ci->callstatus = 0;
|
||||
goto startfunc;
|
||||
}
|
||||
vmbreak;
|
||||
@@ -1648,21 +1648,18 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
|
||||
if (b != 0)
|
||||
L->top = ra + b;
|
||||
- else /* previous instruction set top */
|
||||
- b = cast_int(L->top - ra);
|
||||
+ /* else previous instruction set top */
|
||||
savepc(ci); /* several calls here can raise errors */
|
||||
if (TESTARG_k(i)) {
|
||||
luaF_closeupval(L, base); /* close upvalues from current call */
|
||||
lua_assert(L->tbclist < base); /* no pending tbc variables */
|
||||
lua_assert(base == ci->func + 1);
|
||||
}
|
||||
- while (!ttisfunction(s2v(ra))) { /* not a function? */
|
||||
- luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
|
||||
- b++; /* there is now one extra argument */
|
||||
- checkstackGCp(L, 1, ra);
|
||||
+ if (luaD_precall(L, ra, LUA_MULTRET, delta + 1)) { /* Lua function? */
|
||||
+ ci->callstatus |= CIST_TAIL;
|
||||
+ goto startfunc; /* execute the callee */
|
||||
}
|
||||
- if (!ttisLclosure(s2v(ra))) { /* C function? */
|
||||
- luaD_precall(L, ra, LUA_MULTRET); /* call it */
|
||||
+ else { /* C function */
|
||||
updatetrap(ci);
|
||||
updatestack(ci); /* stack may have been relocated */
|
||||
ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
@@ -1670,9 +1667,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
||||
goto ret; /* caller returns after the tail call */
|
||||
}
|
||||
- ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
- luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
|
||||
- goto startfunc; /* execute the callee */
|
||||
}
|
||||
vmcase(OP_RETURN) {
|
||||
int n = GETARG_B(i) - 1; /* number of results */
|
||||
--
|
||||
2.33.0
|
||||
|
||||
|
||||
@ -1,139 +0,0 @@
|
||||
From dbdc74dc5502c2e05e1c1e2ac894943f418c8431 Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Wed, 30 Jun 2021 12:53:21 -0300
|
||||
Subject: [PATCH] Simplification in the parameters of 'luaD_precall'
|
||||
|
||||
The parameters 'nresults' and 'delta1', in 'luaD_precall', were never
|
||||
meaningful simultaneously. So, they were combined in a single parameter
|
||||
'retdel'.
|
||||
---
|
||||
src/ldo.c | 19 +++++++++----------
|
||||
src/ldo.h | 15 +++++++++++++--
|
||||
src/lvm.c | 4 ++--
|
||||
3 files changed, 24 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/src/ldo.c b/src/ldo.c
|
||||
index 38540561..93fcbb1a 100644
|
||||
--- a/src/ldo.c
|
||||
+++ b/src/ldo.c
|
||||
@@ -486,20 +486,19 @@ static void moveparams (lua_State *L, StkId prevf, StkId func) {
|
||||
}
|
||||
|
||||
|
||||
-static CallInfo *prepCallInfo (lua_State *L, StkId func, int nresults,
|
||||
- int delta1, int mask) {
|
||||
+static CallInfo *prepCallInfo (lua_State *L, StkId func, int retdel,
|
||||
+ int mask) {
|
||||
CallInfo *ci;
|
||||
- if (delta1) { /* tail call? */
|
||||
+ if (isdelta(retdel)) { /* tail call? */
|
||||
ci = L->ci; /* reuse stack frame */
|
||||
- ci->func -= delta1 - 1; /* correct 'func' */
|
||||
-
|
||||
+ ci->func -= retdel2delta(retdel); /* correct 'func' */
|
||||
ci->callstatus |= mask | CIST_TAIL;
|
||||
moveparams(L, ci->func, func);
|
||||
}
|
||||
else { /* regular call */
|
||||
ci = L->ci = next_ci(L); /* new frame */
|
||||
ci->func = func;
|
||||
- ci->nresults = nresults;
|
||||
+ ci->nresults = retdel;
|
||||
ci->callstatus = mask;
|
||||
}
|
||||
return ci;
|
||||
@@ -518,7 +517,7 @@ static CallInfo *prepCallInfo (lua_State *L, StkId func, int nresults,
|
||||
** cannot be zero. Like 'moveparams', this correction can only be done
|
||||
** when no more errors can occur in the call.
|
||||
*/
|
||||
-CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, int delta1) {
|
||||
+CallInfo *luaD_precall (lua_State *L, StkId func, int retdel) {
|
||||
lua_CFunction f;
|
||||
retry:
|
||||
switch (ttypetag(s2v(func))) {
|
||||
@@ -531,7 +530,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, int delta1) {
|
||||
int n; /* number of returns */
|
||||
CallInfo *ci;
|
||||
checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
|
||||
- ci = prepCallInfo(L, func, nresults, delta1, CIST_C);
|
||||
+ ci = prepCallInfo(L, func, retdel, CIST_C);
|
||||
ci->top = L->top + LUA_MINSTACK;
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
if (l_unlikely(L->hookmask & LUA_MASKCALL)) {
|
||||
@@ -552,7 +551,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, int delta1) {
|
||||
int nfixparams = p->numparams;
|
||||
int fsize = p->maxstacksize; /* frame size */
|
||||
checkstackGCp(L, fsize, func);
|
||||
- ci = prepCallInfo(L, func, nresults, delta1, 0);
|
||||
+ ci = prepCallInfo(L, func, retdel, 0);
|
||||
ci->u.l.savedpc = p->code; /* starting point */
|
||||
ci->top = func + 1 + fsize;
|
||||
for (; narg < nfixparams; narg++)
|
||||
@@ -579,7 +578,7 @@ static void ccall (lua_State *L, StkId func, int nResults, int inc) {
|
||||
L->nCcalls += inc;
|
||||
if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
|
||||
luaE_checkcstack(L);
|
||||
- if ((ci = luaD_precall(L, func, nResults, 0)) != NULL) { /* Lua function? */
|
||||
+ if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */
|
||||
ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */
|
||||
luaV_execute(L, ci); /* call it */
|
||||
}
|
||||
diff --git a/src/ldo.h b/src/ldo.h
|
||||
index 6edc4450..49fbb492 100644
|
||||
--- a/src/ldo.h
|
||||
+++ b/src/ldo.h
|
||||
@@ -49,6 +49,18 @@
|
||||
luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0)
|
||||
|
||||
|
||||
+/*
|
||||
+** 'luaD_precall' is used for regular calls, when it needs the
|
||||
+** number of results, and in tail calls, when it needs the 'delta'
|
||||
+** (correction of base for vararg functions). The argument 'retdel'
|
||||
+** codes these two options. A number of results is represented by
|
||||
+** itself, while a delta is represented by 'delta2retdel(delta)'
|
||||
+*/
|
||||
+#define delta2retdel(d) (-(d) + LUA_MULTRET - 1)
|
||||
+#define retdel2delta(d) (-(d) + LUA_MULTRET - 1)
|
||||
+#define isdelta(rd) ((rd) < LUA_MULTRET)
|
||||
+
|
||||
+
|
||||
/* type of protected functions, to be ran by 'runprotected' */
|
||||
typedef void (*Pfunc) (lua_State *L, void *ud);
|
||||
|
||||
@@ -58,8 +70,7 @@ LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
||||
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line,
|
||||
int fTransfer, int nTransfer);
|
||||
LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci);
|
||||
-LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nresults,
|
||||
- int delta1);
|
||||
+LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int retdel);
|
||||
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
|
||||
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
|
||||
LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func);
|
||||
diff --git a/src/lvm.c b/src/lvm.c
|
||||
index 62ff70da..ec83f415 100644
|
||||
--- a/src/lvm.c
|
||||
+++ b/src/lvm.c
|
||||
@@ -1632,7 +1632,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
L->top = ra + b; /* top signals number of arguments */
|
||||
/* else previous instruction set top */
|
||||
savepc(L); /* in case of errors */
|
||||
- if ((newci = luaD_precall(L, ra, nresults, 0)) == NULL)
|
||||
+ if ((newci = luaD_precall(L, ra, nresults)) == NULL)
|
||||
updatetrap(ci); /* C call; nothing else to be done */
|
||||
else { /* Lua call: run function in this same C frame */
|
||||
ci = newci;
|
||||
@@ -1654,7 +1654,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
lua_assert(L->tbclist < base); /* no pending tbc variables */
|
||||
lua_assert(base == ci->func + 1);
|
||||
}
|
||||
- if (luaD_precall(L, ra, LUA_MULTRET, delta + 1)) /* Lua function? */
|
||||
+ if (luaD_precall(L, ra, delta2retdel(delta))) /* Lua function? */
|
||||
goto startfunc; /* execute the callee */
|
||||
else { /* C function */
|
||||
updatetrap(ci);
|
||||
--
|
||||
2.33.0
|
||||
|
||||
|
||||
@ -1,189 +0,0 @@
|
||||
From dbdc74dc5502c2e05e1c1e2ac894943f418c8431 Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Wed, 30 Jun 2021 12:53:21 -0300
|
||||
Subject: [PATCH] Simplification in the parameters of 'luaD_precall'
|
||||
---
|
||||
src/ldo.c | 66 +++++++++++++++++++++++++++----------------------------
|
||||
src/ldo.h | 15 ++-----------
|
||||
src/lvm.c | 20 +++++++++++++----
|
||||
3 files changed, 50 insertions(+), 51 deletions(-)
|
||||
|
||||
diff --git a/src/ldo.c b/src/ldo.c
|
||||
index 17fb398..e2af6dc 100644
|
||||
--- a/src/ldo.c
|
||||
+++ b/src/ldo.c
|
||||
@@ -474,33 +474,36 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
|
||||
|
||||
|
||||
/*
|
||||
-** In a tail call, move function and parameters to previous call frame.
|
||||
-** (This is done only when no more errors can occur before entering the
|
||||
-** new function, to keep debug information always consistent.)
|
||||
+** Prepare a function for a tail call, building its call info on top
|
||||
+** of the current call info. 'narg1' is the number of arguments plus 1
|
||||
+** (so that it includes the function itself).
|
||||
*/
|
||||
-static void moveparams (lua_State *L, StkId prevf, StkId func) {
|
||||
+void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) {
|
||||
+ Proto *p = clLvalue(s2v(func))->p;
|
||||
+ int fsize = p->maxstacksize; /* frame size */
|
||||
+ int nfixparams = p->numparams;
|
||||
int i;
|
||||
- for (i = 0; func + i < L->top; i++) /* move down function and arguments */
|
||||
- setobjs2s(L, prevf + i, func + i);
|
||||
- L->top = prevf + i; /* correct top */
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static CallInfo *prepCallInfo (lua_State *L, StkId func, int retdel,
|
||||
- int mask) {
|
||||
- CallInfo *ci;
|
||||
- if (isdelta(retdel)) { /* tail call? */
|
||||
- ci = L->ci; /* reuse stack frame */
|
||||
- ci->func -= retdel2delta(retdel); /* correct 'func' */
|
||||
- ci->callstatus |= mask | CIST_TAIL;
|
||||
- moveparams(L, ci->func, func);
|
||||
- }
|
||||
- else { /* regular call */
|
||||
- ci = L->ci = next_ci(L); /* new frame */
|
||||
- ci->func = func;
|
||||
- ci->nresults = retdel;
|
||||
- ci->callstatus = mask;
|
||||
- }
|
||||
+ for (i = 0; i < narg1; i++) /* move down function and arguments */
|
||||
+ setobjs2s(L, ci->func + i, func + i);
|
||||
+ checkstackGC(L, fsize);
|
||||
+ func = ci->func; /* 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->u.l.savedpc = p->code; /* starting point */
|
||||
+ ci->callstatus |= CIST_TAIL;
|
||||
+ L->top = func + narg1; /* set top */
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static 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->nresults = nret;
|
||||
+ ci->callstatus = mask;
|
||||
+ ci->top = top;
|
||||
return ci;
|
||||
}
|
||||
|
||||
@@ -512,12 +515,8 @@ static CallInfo *prepCallInfo (lua_State *L, StkId func, int retdel,
|
||||
** to be executed, if it was a Lua function. Otherwise (a C function)
|
||||
** returns NULL, with all the results on the stack, starting at the
|
||||
** original function position.
|
||||
-** For regular calls, 'delta1' is 0. For tail calls, 'delta1' is the
|
||||
-** 'delta' (correction of base for vararg functions) plus 1, so that it
|
||||
-** cannot be zero. Like 'moveparams', this correction can only be done
|
||||
-** when no more errors can occur in the call.
|
||||
*/
|
||||
-CallInfo *luaD_precall (lua_State *L, StkId func, int retdel) {
|
||||
+CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
lua_CFunction f;
|
||||
retry:
|
||||
switch (ttypetag(s2v(func))) {
|
||||
@@ -530,8 +529,8 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int retdel) {
|
||||
int n; /* number of returns */
|
||||
CallInfo *ci;
|
||||
checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
|
||||
- ci = prepCallInfo(L, func, retdel, CIST_C);
|
||||
- ci->top = L->top + LUA_MINSTACK;
|
||||
+ L->ci = ci = prepCallInfo(L, func, nresults, CIST_C,
|
||||
+ L->top + LUA_MINSTACK);
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
if (l_unlikely(L->hookmask & LUA_MASKCALL)) {
|
||||
int narg = cast_int(L->top - func) - 1;
|
||||
@@ -551,9 +550,8 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int retdel) {
|
||||
int nfixparams = p->numparams;
|
||||
int fsize = p->maxstacksize; /* frame size */
|
||||
checkstackGCp(L, fsize, func);
|
||||
- ci = prepCallInfo(L, func, retdel, 0);
|
||||
+ L->ci = ci = prepCallInfo(L, func, nresults, 0, func + 1 + fsize);
|
||||
ci->u.l.savedpc = p->code; /* starting point */
|
||||
- ci->top = func + 1 + fsize;
|
||||
for (; narg < nfixparams; narg++)
|
||||
setnilvalue(s2v(L->top++)); /* complete missing arguments */
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
diff --git a/src/ldo.h b/src/ldo.h
|
||||
index 49fbb49..6bf0ed8 100644
|
||||
--- a/src/ldo.h
|
||||
+++ b/src/ldo.h
|
||||
@@ -49,18 +49,6 @@
|
||||
luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0)
|
||||
|
||||
|
||||
-/*
|
||||
-** 'luaD_precall' is used for regular calls, when it needs the
|
||||
-** number of results, and in tail calls, when it needs the 'delta'
|
||||
-** (correction of base for vararg functions). The argument 'retdel'
|
||||
-** codes these two options. A number of results is represented by
|
||||
-** itself, while a delta is represented by 'delta2retdel(delta)'
|
||||
-*/
|
||||
-#define delta2retdel(d) (-(d) + LUA_MULTRET - 1)
|
||||
-#define retdel2delta(d) (-(d) + LUA_MULTRET - 1)
|
||||
-#define isdelta(rd) ((rd) < LUA_MULTRET)
|
||||
-
|
||||
-
|
||||
/* type of protected functions, to be ran by 'runprotected' */
|
||||
typedef void (*Pfunc) (lua_State *L, void *ud);
|
||||
|
||||
@@ -70,7 +58,8 @@ LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
||||
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line,
|
||||
int fTransfer, int nTransfer);
|
||||
LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci);
|
||||
-LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int retdel);
|
||||
+LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n);
|
||||
+LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults);
|
||||
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
|
||||
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
|
||||
LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func);
|
||||
diff --git a/src/lvm.c b/src/lvm.c
|
||||
index 4fb426c..1541c63 100644
|
||||
--- a/src/lvm.c
|
||||
+++ b/src/lvm.c
|
||||
@@ -1638,19 +1638,31 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
|
||||
if (b != 0)
|
||||
L->top = ra + b;
|
||||
- /* else previous instruction set top */
|
||||
+ else /* previous instruction set top */
|
||||
+ b = cast_int(L->top - ra);
|
||||
savepc(ci); /* several calls here can raise errors */
|
||||
if (TESTARG_k(i)) {
|
||||
luaF_closeupval(L, base); /* close upvalues from current call */
|
||||
lua_assert(L->tbclist < base); /* no pending tbc variables */
|
||||
lua_assert(base == ci->func + 1);
|
||||
}
|
||||
- if (luaD_precall(L, ra, delta2retdel(delta))) /* Lua function? */
|
||||
- goto startfunc; /* execute the callee */
|
||||
- else { /* C function */
|
||||
+ while (!ttisfunction(s2v(ra))) { /* not a function? */
|
||||
+ luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
|
||||
+ b++; /* there is now one extra argument */
|
||||
+ checkstackGCp(L, 1, ra);
|
||||
+ }
|
||||
+ if (!ttisLclosure(s2v(ra))) { /* C function? */
|
||||
+ luaD_precall(L, ra, LUA_MULTRET); /* call it */
|
||||
updatetrap(ci);
|
||||
+ updatestack(ci); /* stack may have been relocated */
|
||||
+ ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
+ luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */
|
||||
+ updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
||||
goto ret; /* caller returns after the tail call */
|
||||
}
|
||||
+ ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
+ luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
|
||||
+ goto startfunc; /* execute the callee */
|
||||
}
|
||||
vmcase(OP_RETURN) {
|
||||
int n = GETARG_B(i) - 1; /* number of results */
|
||||
--
|
||||
2.33.0
|
||||
|
||||
|
||||
@ -1,183 +0,0 @@
|
||||
From 2ff34717227b8046b0fdcb96206f11f5e888664e Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Wed, 15 Sep 2021 11:18:41 -0300
|
||||
Subject: [PATCH] Using 'inline' in some functions
|
||||
|
||||
According to ISO C, "making a function an inline function suggests that
|
||||
calls to the function be as fast as possible." (Not available in C89.)
|
||||
---
|
||||
src/lapi.c | 10 +++++-----
|
||||
src/ldo.c | 8 ++++----
|
||||
src/llimits.h | 14 ++++++++++++++
|
||||
src/lvm.c | 12 ++++++------
|
||||
4 files changed, 29 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/lapi.c b/src/lapi.c
|
||||
index 7b96979..2f59d3c 100644
|
||||
--- a/src/lapi.c
|
||||
+++ b/src/lapi.c
|
||||
@@ -81,7 +81,7 @@ static TValue *index2value (lua_State *L, int idx) {
|
||||
}
|
||||
|
||||
|
||||
-static StkId index2stack (lua_State *L, int idx) {
|
||||
+l_sinline StkId index2stack (lua_State *L, int idx) {
|
||||
CallInfo *ci = L->ci;
|
||||
if (idx > 0) {
|
||||
StkId o = ci->func + idx;
|
||||
@@ -218,7 +218,7 @@ LUA_API void lua_closeslot (lua_State *L, int idx) {
|
||||
** Note that we move(copy) only the value inside the stack.
|
||||
** (We do not move additional fields that may exist.)
|
||||
*/
|
||||
-static void reverse (lua_State *L, StkId from, StkId to) {
|
||||
+l_sinline void reverse (lua_State *L, StkId from, StkId to) {
|
||||
for (; from < to; from++, to--) {
|
||||
TValue temp;
|
||||
setobj(L, &temp, s2v(from));
|
||||
@@ -438,7 +438,7 @@ LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
|
||||
}
|
||||
|
||||
|
||||
-static void *touserdata (const TValue *o) {
|
||||
+l_sinline void *touserdata (const TValue *o) {
|
||||
switch (ttype(o)) {
|
||||
case LUA_TUSERDATA: return getudatamem(uvalue(o));
|
||||
case LUA_TLIGHTUSERDATA: return pvalue(o);
|
||||
@@ -630,7 +630,7 @@ LUA_API int lua_pushthread (lua_State *L) {
|
||||
*/
|
||||
|
||||
|
||||
-static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
|
||||
+l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) {
|
||||
const TValue *slot;
|
||||
TString *str = luaS_new(L, k);
|
||||
if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
|
||||
@@ -705,7 +705,7 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
|
||||
}
|
||||
|
||||
|
||||
-static int finishrawget (lua_State *L, const TValue *val) {
|
||||
+l_sinline int finishrawget (lua_State *L, const TValue *val) {
|
||||
if (isempty(val)) /* avoid copying empty items to the stack */
|
||||
setnilvalue(s2v(L->top));
|
||||
else
|
||||
diff --git a/src/ldo.c b/src/ldo.c
|
||||
index 673b975..bf2d041 100644
|
||||
--- a/src/ldo.c
|
||||
+++ b/src/ldo.c
|
||||
@@ -407,7 +407,7 @@ StkId luaD_tryfuncTM (lua_State *L, StkId func) {
|
||||
** expressions, multiple results for tail calls/single parameters)
|
||||
** separated.
|
||||
*/
|
||||
-static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
|
||||
+l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
|
||||
StkId firstresult;
|
||||
int i;
|
||||
switch (wanted) { /* handle typical cases separately */
|
||||
@@ -499,8 +499,8 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) {
|
||||
}
|
||||
|
||||
|
||||
-static CallInfo *prepCallInfo (lua_State *L, StkId func, int nret,
|
||||
- int mask, StkId top) {
|
||||
+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->nresults = nret;
|
||||
@@ -572,7 +572,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
** number of recursive invocations in the C stack) or nyci (the same
|
||||
** plus increment number of non-yieldable calls).
|
||||
*/
|
||||
-static void ccall (lua_State *L, StkId func, int nResults, int inc) {
|
||||
+l_sinline void ccall (lua_State *L, StkId func, int nResults, int inc) {
|
||||
CallInfo *ci;
|
||||
L->nCcalls += inc;
|
||||
if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
|
||||
diff --git a/src/llimits.h b/src/llimits.h
|
||||
index 025f1c8..6c56ba5 100644
|
||||
--- a/src/llimits.h
|
||||
+++ b/src/llimits.h
|
||||
@@ -165,6 +165,20 @@ typedef LUAI_UACINT l_uacInt;
|
||||
#endif
|
||||
|
||||
|
||||
+/*
|
||||
+** Inline functions
|
||||
+*/
|
||||
+#if !defined(LUA_USE_C89)
|
||||
+#define l_inline inline
|
||||
+#elif defined(__GNUC__)
|
||||
+#define l_inline __inline__
|
||||
+#else
|
||||
+#define l_inline /* empty */
|
||||
+#endif
|
||||
+
|
||||
+#define l_sinline static l_inline
|
||||
+
|
||||
+
|
||||
/*
|
||||
** type for virtual-machine instructions;
|
||||
** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
|
||||
diff --git a/src/lvm.c b/src/lvm.c
|
||||
index c16c2c6..14af102 100644
|
||||
--- a/src/lvm.c
|
||||
+++ b/src/lvm.c
|
||||
@@ -406,7 +406,7 @@ static int l_strcmp (const TString *ls, const TString *rs) {
|
||||
** from float to int.)
|
||||
** When 'f' is NaN, comparisons must result in false.
|
||||
*/
|
||||
-static int LTintfloat (lua_Integer i, lua_Number f) {
|
||||
+l_sinline int LTintfloat (lua_Integer i, lua_Number f) {
|
||||
if (l_intfitsf(i))
|
||||
return luai_numlt(cast_num(i), f); /* compare them as floats */
|
||||
else { /* i < f <=> i < ceil(f) */
|
||||
@@ -423,7 +423,7 @@ static int LTintfloat (lua_Integer i, lua_Number f) {
|
||||
** Check whether integer 'i' is less than or equal to float 'f'.
|
||||
** See comments on previous function.
|
||||
*/
|
||||
-static int LEintfloat (lua_Integer i, lua_Number f) {
|
||||
+l_sinline int LEintfloat (lua_Integer i, lua_Number f) {
|
||||
if (l_intfitsf(i))
|
||||
return luai_numle(cast_num(i), f); /* compare them as floats */
|
||||
else { /* i <= f <=> i <= floor(f) */
|
||||
@@ -440,7 +440,7 @@ static int LEintfloat (lua_Integer i, lua_Number f) {
|
||||
** Check whether float 'f' is less than integer 'i'.
|
||||
** See comments on previous function.
|
||||
*/
|
||||
-static int LTfloatint (lua_Number f, lua_Integer i) {
|
||||
+l_sinline int LTfloatint (lua_Number f, lua_Integer i) {
|
||||
if (l_intfitsf(i))
|
||||
return luai_numlt(f, cast_num(i)); /* compare them as floats */
|
||||
else { /* f < i <=> floor(f) < i */
|
||||
@@ -457,7 +457,7 @@ static int LTfloatint (lua_Number f, lua_Integer i) {
|
||||
** Check whether float 'f' is less than or equal to integer 'i'.
|
||||
** See comments on previous function.
|
||||
*/
|
||||
-static int LEfloatint (lua_Number f, lua_Integer i) {
|
||||
+l_sinline int LEfloatint (lua_Number f, lua_Integer i) {
|
||||
if (l_intfitsf(i))
|
||||
return luai_numle(f, cast_num(i)); /* compare them as floats */
|
||||
else { /* f <= i <=> ceil(f) <= i */
|
||||
@@ -473,7 +473,7 @@ static int LEfloatint (lua_Number f, lua_Integer i) {
|
||||
/*
|
||||
** Return 'l < r', for numbers.
|
||||
*/
|
||||
-static int LTnum (const TValue *l, const TValue *r) {
|
||||
+l_sinline int LTnum (const TValue *l, const TValue *r) {
|
||||
lua_assert(ttisnumber(l) && ttisnumber(r));
|
||||
if (ttisinteger(l)) {
|
||||
lua_Integer li = ivalue(l);
|
||||
@@ -495,7 +495,7 @@ static int LTnum (const TValue *l, const TValue *r) {
|
||||
/*
|
||||
** Return 'l <= r', for numbers.
|
||||
*/
|
||||
-static int LEnum (const TValue *l, const TValue *r) {
|
||||
+l_sinline int LEnum (const TValue *l, const TValue *r) {
|
||||
lua_assert(ttisnumber(l) && ttisnumber(r));
|
||||
if (ttisinteger(l)) {
|
||||
lua_Integer li = ivalue(l);
|
||||
--
|
||||
2.33.0
|
||||
|
||||
|
||||
@ -1,90 +0,0 @@
|
||||
From 91673a8ec0ae55e188a790bd2dfdc99246adf20e Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Wed, 18 Aug 2021 12:05:06 -0300
|
||||
Subject: [PATCH] 'luaD_tryfuncTM' checks stack space by itself
|
||||
---
|
||||
src/ldo.c | 7 ++++---
|
||||
src/ldo.h | 2 +-
|
||||
src/lvm.c | 11 ++++++-----
|
||||
3 files changed, 11 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/ldo.c b/src/ldo.c
|
||||
index fa8d98b2..889cb34b 100644
|
||||
--- a/src/ldo.c
|
||||
+++ b/src/ldo.c
|
||||
@@ -387,15 +387,17 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) {
|
||||
** stack, below original 'func', so that 'luaD_precall' can call it. Raise
|
||||
** an error if there is no '__call' metafield.
|
||||
*/
|
||||
-void luaD_tryfuncTM (lua_State *L, StkId func) {
|
||||
+StkId luaD_tryfuncTM (lua_State *L, StkId func) {
|
||||
const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL);
|
||||
StkId p;
|
||||
+ checkstackGCp(L, 1, func); /* space for metamethod */
|
||||
if (l_unlikely(ttisnil(tm)))
|
||||
luaG_callerror(L, s2v(func)); /* nothing to call */
|
||||
for (p = L->top; p > func; p--) /* open space for metamethod */
|
||||
setobjs2s(L, p, p-1);
|
||||
L->top++; /* stack space pre-allocated by the caller */
|
||||
setobj2s(L, func, tm); /* metamethod is the new function to be called */
|
||||
+ return func;
|
||||
}
|
||||
|
||||
|
||||
@@ -558,8 +560,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
return ci;
|
||||
}
|
||||
default: { /* not a function */
|
||||
- checkstackGCp(L, 1, func); /* space for metamethod */
|
||||
- luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
|
||||
+ func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
|
||||
goto retry; /* try again with metamethod */
|
||||
}
|
||||
}
|
||||
diff --git a/src/ldo.h b/src/ldo.h
|
||||
index 6bf0ed86..9fb772fe 100644
|
||||
--- a/src/ldo.h
|
||||
+++ b/src/ldo.h
|
||||
@@ -62,7 +62,7 @@ LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n);
|
||||
LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults);
|
||||
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
|
||||
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
|
||||
-LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func);
|
||||
+LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func);
|
||||
LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status);
|
||||
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
||||
ptrdiff_t oldtop, ptrdiff_t ef);
|
||||
diff --git a/src/lvm.c b/src/lvm.c
|
||||
index df1dec83..29a211c6 100644
|
||||
--- a/src/lvm.c
|
||||
+++ b/src/lvm.c
|
||||
@@ -1657,9 +1657,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
lua_assert(base == ci->func + 1);
|
||||
}
|
||||
while (!ttisfunction(s2v(ra))) { /* not a function? */
|
||||
- luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
|
||||
+ ra = luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
|
||||
b++; /* there is now one extra argument */
|
||||
- checkstackGCp(L, 1, ra);
|
||||
}
|
||||
if (!ttisLclosure(s2v(ra))) { /* C function? */
|
||||
luaD_precall(L, ra, LUA_MULTRET); /* call it */
|
||||
@@ -1670,9 +1669,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
||||
goto ret; /* caller returns after the tail call */
|
||||
}
|
||||
- ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
- luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
|
||||
- goto startfunc; /* execute the callee */
|
||||
+ else { /* Lua function */
|
||||
+ ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
+ luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
|
||||
+ goto startfunc; /* execute the callee */
|
||||
+ }
|
||||
}
|
||||
vmcase(OP_RETURN) {
|
||||
int n = GETARG_B(i) - 1; /* number of results */
|
||||
--
|
||||
2.33.0
|
||||
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
From 603b2c64add5fbf4b7343525cf109af0c7077695 Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Mon, 23 May 2022 17:50:47 -0300
|
||||
Subject: [PATCH] 'luaV_concat' can use invalidated pointer to stack
|
||||
|
||||
Bug introduced in commit 42d40581.
|
||||
---
|
||||
src/lvm.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/lvm.c b/src/lvm.c
|
||||
index cd992aa..614df05 100644
|
||||
--- a/src/lvm.c
|
||||
+++ b/src/lvm.c
|
||||
@@ -643,7 +643,7 @@ void luaV_concat (lua_State *L, int total) {
|
||||
int n = 2; /* number of elements handled in this pass (at least 2) */
|
||||
if (!(ttisstring(s2v(top - 2)) || cvt2str(s2v(top - 2))) ||
|
||||
!tostring(L, s2v(top - 1)))
|
||||
- luaT_tryconcatTM(L);
|
||||
+ luaT_tryconcatTM(L); /* may invalidate 'top' */
|
||||
else if (isemptystr(s2v(top - 1))) /* second operand is empty? */
|
||||
cast_void(tostring(L, s2v(top - 2))); /* result is first operand */
|
||||
else if (isemptystr(s2v(top - 2))) { /* first operand is empty string? */
|
||||
@@ -673,8 +673,8 @@ void luaV_concat (lua_State *L, int total) {
|
||||
}
|
||||
setsvalue2s(L, top - n, ts); /* create result */
|
||||
}
|
||||
- total -= n-1; /* got 'n' strings to create 1 new */
|
||||
- L->top = top - (n - 1); /* popped 'n' strings and pushed one */
|
||||
+ total -= n - 1; /* got 'n' strings to create one new */
|
||||
+ L->top -= n - 1; /* popped 'n' strings and pushed one */
|
||||
} while (total > 1); /* repeat until only 1 result left */
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
diff -up lua-5.3.0/src/luaconf.h.template.in.idsize lua-5.3.0/src/luaconf.h.template.in
|
||||
--- lua-5.3.0/src/luaconf.h.template.in.idsize 2015-01-15 10:23:20.515801344 -0500
|
||||
+++ lua-5.3.0/src/luaconf.h.template.in 2015-01-15 10:23:48.955651916 -0500
|
||||
@@ -693,7 +693,7 @@
|
||||
@@ of a function in debug information.
|
||||
** CHANGE it if you want a different size.
|
||||
*/
|
||||
-#define LUA_IDSIZE 60
|
||||
+#define LUA_IDSIZE 512
|
||||
|
||||
|
||||
/*
|
||||
Binary file not shown.
BIN
lua-5.4.3.tar.gz
BIN
lua-5.4.3.tar.gz
Binary file not shown.
14
lua-5.4.6-idsize.patch
Normal file
14
lua-5.4.6-idsize.patch
Normal file
@ -0,0 +1,14 @@
|
||||
diff --git a/src/luaconf.h.template.in b/src/luaconf.h.template.in
|
||||
index 1e32333..601d10e 100644
|
||||
--- a/src/luaconf.h.template.in
|
||||
+++ b/src/luaconf.h.template.in
|
||||
@@ -762,7 +762,7 @@
|
||||
** of a function in debug information.
|
||||
** CHANGE it if you want a different size.
|
||||
*/
|
||||
-#define LUA_IDSIZE 60
|
||||
+#define LUA_IDSIZE 512
|
||||
|
||||
|
||||
/*
|
||||
|
||||
BIN
lua-5.4.6-tests.tar.gz
Normal file
BIN
lua-5.4.6-tests.tar.gz
Normal file
Binary file not shown.
BIN
lua-5.4.6.tar.gz
Normal file
BIN
lua-5.4.6.tar.gz
Normal file
Binary file not shown.
43
lua.spec
43
lua.spec
@ -1,12 +1,12 @@
|
||||
%global major_version 5.4
|
||||
# test version is still 5.4.3
|
||||
%global test_version 5.4.3
|
||||
# test version is still 5.4.6
|
||||
%global test_version 5.4.6
|
||||
# Place rpm-macros into proper location.
|
||||
%global macrosdir %(d=%{_rpmconfigdir}/macros.d; [ -d $d ] || d=%{_sysconfdir}/rpm; echo $d)
|
||||
|
||||
Name: lua
|
||||
Version: 5.4.3
|
||||
Release: 11
|
||||
Version: 5.4.6
|
||||
Release: 1
|
||||
Summary: A powerful, efficient, lightweight, embeddable scripting language
|
||||
License: MIT
|
||||
URL: http://www.lua.org/
|
||||
@ -20,24 +20,9 @@ Source3: mit.txt
|
||||
# rpm-macro
|
||||
Source1000: macros.lua
|
||||
Patch0: lua-5.4.0-beta-autotoolize.patch
|
||||
Patch1: lua-5.3.0-idsize.patch
|
||||
Patch1: lua-5.4.6-idsize.patch
|
||||
Patch2: lua-5.2.2-configure-linux.patch
|
||||
Patch3: lua-5.3.0-configure-compat-module.patch
|
||||
Patch6000: backport-CVE-2021-43519.patch
|
||||
Patch6001: backport-CVE-2021-44647.patch
|
||||
Patch6002: backport-CVE-2022-28805.patch
|
||||
Patch6003: backport-CVE-2022-33099.patch
|
||||
Patch6004: backport-CVE-2021-44964.patch
|
||||
Patch6005: backport-luaV_concat-can-use-invalidated-pointer-to-stack.patch
|
||||
Patch6006: backport-Simpler-implementation-for-tail-calls.patch
|
||||
Patch6007: backport-C-functions-can-be-tail-called-too.patch
|
||||
Patch6008: backport-Simplification-in-the-parameters-of-luaD_precall.patch
|
||||
Patch6009: backport-Undo-simplification-of-tail-calls-commit-901d760.patch
|
||||
Patch6010: backport-luaD_tryfuncTM-checks-stack-space-by-itself.patch
|
||||
Patch6011: backport-Using-inline-in-some-functions.patch
|
||||
Patch6012: backport-Removed-goto-s-in-luaD_precall.patch
|
||||
Patch6013: backport-More-uniform-implementation-for-tail-calls.patch
|
||||
Patch6014: backport-CVE-2021-45985.patch
|
||||
|
||||
BuildRequires: automake autoconf libtool readline-devel ncurses-devel
|
||||
|
||||
@ -70,21 +55,6 @@ mv src/luaconf.h src/luaconf.h.template.in
|
||||
%patch1 -p1 -z .idsize
|
||||
%patch2 -p1 -z .configure-linux
|
||||
%patch3 -p1 -z .configure-compat-all
|
||||
%patch6000 -p1
|
||||
%patch6001 -p1
|
||||
%patch6002 -p1
|
||||
%patch6003 -p1
|
||||
%patch6004 -p1
|
||||
%patch6005 -p1
|
||||
%patch6006 -p1
|
||||
%patch6007 -p1
|
||||
%patch6008 -p1
|
||||
%patch6009 -p1
|
||||
%patch6010 -p1
|
||||
%patch6011 -p1
|
||||
%patch6012 -p1
|
||||
%patch6013 -p1
|
||||
%patch6014 -p1
|
||||
|
||||
# Put proper version in configure.ac, patch0 hardcodes 5.3.0
|
||||
sed -i 's|5.3.0|%{version}|g' configure.ac
|
||||
@ -159,6 +129,9 @@ LD_LIBRARY_PATH=$RPM_BUILD_ROOT/%{_libdir} $RPM_BUILD_ROOT/%{_bindir}/lua -e"_U=
|
||||
%{_mandir}/man1/lua*.1*
|
||||
|
||||
%changelog
|
||||
* Mon Oct 30 2023 chenziyang <chenziyang4@huawei.com> - 5.4.6-1
|
||||
- upgrade to version 5.4.6 for 22.03-LTS-Next version because 5.4.3 released 2 years ago
|
||||
|
||||
* Tue Apr 18 2023 chenziyang <chenziyang4@huawei.com> - 5.4.3-11
|
||||
- fix CVE-2021-45985 and other commits because CVE change heavily rely on these commits
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user