Compare commits

..

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
b0e619426d
!64 [sync] PR-61: add lua_closethread to adapt interfacechange
From: @openeuler-sync-bot 
Reviewed-by: @hubin95 
Signed-off-by: @hubin95
2024-05-08 08:49:01 +00:00
fly_fzc
06777b4ffc add lua_closethread to adapt interfacechange
(cherry picked from commit 690ab5519504edef7971b6e8ab759681d8d34cea)
2024-05-08 15:56:39 +08:00
openeuler-ci-bot
8148fa61b6
!58 [sync] PR-54: fix Segmentation fault
From: @openeuler-sync-bot 
Reviewed-by: @hubin95 
Signed-off-by: @hubin95
2024-05-08 03:37:19 +00:00
markeryang
ea404f7ebf fix Segmentation fault
(cherry picked from commit ce0052987074899905de4be63c7c8ddc9de9e60e)
2024-05-08 11:04:20 +08:00
openeuler-ci-bot
135922521d
!55 [sync] PR-48: add sw_64 support
From: @openeuler-sync-bot 
Reviewed-by: @hubin95 
Signed-off-by: @hubin95
2024-01-18 04:26:43 +00:00
panchenbo
db11036d1a add sw_64 support
(cherry picked from commit d52cb62719f372056b75741ca0a4b207a2c1d99b)
2024-01-18 11:25:26 +08:00
openeuler-ci-bot
9788b313db
!44 [sync] PR-42: Fix CVE-2021-45985
From: @openeuler-sync-bot 
Reviewed-by: @hubin95 
Signed-off-by: @hubin95
2023-04-19 03:06:34 +00:00
Chen Ziyang
b07366fdc6 fix CVE-2021-45985
(cherry picked from commit 89c61e7fa4b57456285e2cde7143c2cdf053d79e)
2023-04-19 10:41:15 +08:00
openeuler-ci-bot
6d88b9c460
!38 [sync] PR-37: add support for LoongArch
From: @openeuler-sync-bot 
Reviewed-by: @lvying6 
Signed-off-by: @lvying6
2023-01-04 02:38:21 +00:00
lyn1001
b46f3dc542 add support for LoongArch
(cherry picked from commit 9255caa48a2ac34c40be7e7e3a8a282ffa762501)
2022-12-26 14:59:45 +08:00
15 changed files with 1803 additions and 1 deletions

View File

@ -0,0 +1,79 @@
From ab859fe59b464a038a45552921cb2b23892343af Mon Sep 17 00:00:00 2001
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Fri, 17 Mar 2023 15:52:09 -0300
Subject: [PATCH] Bug: Loading a corrupted binary file can segfault
The size of the list of upvalue names are stored separated from the
size of the list of upvalues, but they share the same array.
---
lua-5.4.3-tests/calls.lua | 14 ++++++++++++++
src/ldump.c | 8 ++++++--
src/lundump.c | 2 ++
3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/lua-5.4.3-tests/calls.lua b/lua-5.4.3-tests/calls.lua
index ff72d8f..65b6858 100644
--- a/lua-5.4.3-tests/calls.lua
+++ b/lua-5.4.3-tests/calls.lua
@@ -327,6 +327,20 @@ do -- another bug (in 5.4.0)
end
+do -- another bug (since 5.2)
+ -- corrupted binary dump: list of upvalue names is larger than number
+ -- of upvalues, overflowing the array of upvalues.
+ local code =
+ "\x1b\x4c\x75\x61\x54\x00\x19\x93\x0d\x0a\x1a\x0a\x04\x08\x08\x78\x56\z
+ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x77\x40\x00\x86\x40\z
+ \x74\x65\x6d\x70\x81\x81\x01\x00\x02\x82\x48\x00\x02\x00\xc7\x00\x01\z
+ \x00\x80\x80\x80\x82\x00\x00\x80\x81\x82\x78\x80\x82\x81\x86\x40\x74\z
+ \x65\x6d\x70"
+
+ assert(load(code)) -- segfaults in previous versions
+end
+
+
x = string.dump(load("x = 1; return x"))
a = assert(load(read1(x), nil, "b"))
assert(a() == 1 and _G.x == 1)
diff --git a/src/ldump.c b/src/ldump.c
index f848b66..f231691 100644
--- a/src/ldump.c
+++ b/src/ldump.c
@@ -10,6 +10,7 @@
#include "lprefix.h"
+#include <limits.h>
#include <stddef.h>
#include "lua.h"
@@ -55,8 +56,11 @@ static void dumpByte (DumpState *D, int y) {
}
-/* dumpInt Buff Size */
-#define DIBS ((sizeof(size_t) * 8 / 7) + 1)
+/*
+** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6"
+** rounds up the division.)
+*/
+#define DIBS ((sizeof(size_t) * CHAR_BIT + 6) / 7)
static void dumpSize (DumpState *D, size_t x) {
lu_byte buff[DIBS];
diff --git a/src/lundump.c b/src/lundump.c
index 5aa55c4..8013e66 100644
--- a/src/lundump.c
+++ b/src/lundump.c
@@ -248,6 +248,8 @@ static void loadDebug (LoadState *S, Proto *f) {
f->locvars[i].endpc = loadInt(S);
}
n = loadInt(S);
+ if (n != 0) /* does it have debug information? */
+ n = f->sizeupvalues; /* must be this many */
for (i = 0; i < n; i++)
f->upvalues[i].name = loadStringN(S, f);
}
--
2.33.0

View File

@ -0,0 +1,232 @@
From 7923dbbf72da303ca1cca17efd24725668992f15 Mon Sep 17 00:00:00 2001
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Wed, 1 Nov 2023 12:00:54 -0300
Subject: [PATCH] Bug: Recursion in 'getobjname' can stack overflow
'getobjname' now broken in two, a basic version that handles locals,
upvalues, and constants, and a full version, which uses the basic
version to handle table accesses (globals and fields).
---
lua-5.4.3-tests/errors.lua | 3 +
src/ldebug.c | 154 ++++++++++++++++++++-----------------
2 files changed, 87 insertions(+), 70 deletions(-)
diff --git a/lua-5.4.3-tests/errors.lua b/lua-5.4.3-tests/errors.lua
index a3d0676..5cef9e1 100644
--- a/lua-5.4.3-tests/errors.lua
+++ b/lua-5.4.3-tests/errors.lua
@@ -121,6 +121,9 @@ assert(not string.find(doit"a={13}; local bbbb=1; a[bbbb](3)", "'bbbb'"))
checkmessage("a={13}; local bbbb=1; a[bbbb](3)", "number")
checkmessage("a=(1)..{}", "a table value")
+-- bug in 5.4.6
+checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'")
+
-- calls
checkmessage("local a; a(13)", "local 'a'")
checkmessage([[
diff --git a/src/ldebug.c b/src/ldebug.c
index 5524fae..c605a8a 100644
--- a/src/ldebug.c
+++ b/src/ldebug.c
@@ -416,41 +416,6 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
** =======================================================
*/
-static const char *getobjname (const Proto *p, int lastpc, int reg,
- const char **name);
-
-
-/*
-** Find a "name" for the constant 'c'.
-*/
-static void kname (const Proto *p, int c, const char **name) {
- TValue *kvalue = &p->k[c];
- *name = (ttisstring(kvalue)) ? svalue(kvalue) : "?";
-}
-
-
-/*
-** Find a "name" for the register 'c'.
-*/
-static void rname (const Proto *p, int pc, int c, const char **name) {
- const char *what = getobjname(p, pc, c, name); /* search for 'c' */
- if (!(what && *what == 'c')) /* did not find a constant name? */
- *name = "?";
-}
-
-
-/*
-** Find a "name" for a 'C' value in an RK instruction.
-*/
-static void rkname (const Proto *p, int pc, Instruction i, const char **name) {
- int c = GETARG_C(i); /* key index */
- if (GETARG_k(i)) /* is 'c' a constant? */
- kname(p, c, name);
- else /* 'c' is a register */
- rname(p, pc, c, name);
-}
-
-
static int filterpc (int pc, int jmptarget) {
if (pc < jmptarget) /* is code conditional (inside a jump)? */
return -1; /* cannot know who sets that register */
@@ -508,28 +473,29 @@ static int findsetreg (const Proto *p, int lastpc, int reg) {
/*
-** Check whether table being indexed by instruction 'i' is the
-** environment '_ENV'
+** Find a "name" for the constant 'c'.
*/
-static const char *gxf (const Proto *p, int pc, Instruction i, int isup) {
- int t = GETARG_B(i); /* table index */
- const char *name; /* name of indexed variable */
- if (isup) /* is an upvalue? */
- name = upvalname(p, t);
- else
- getobjname(p, pc, t, &name);
- return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field";
+static const char *kname (const Proto *p, int index, const char **name) {
+ TValue *kvalue = &p->k[index];
+ if (ttisstring(kvalue)) {
+ *name = getstr(tsvalue(kvalue));
+ return "constant";
+ }
+ else {
+ *name = "?";
+ return NULL;
+ }
}
-static const char *getobjname (const Proto *p, int lastpc, int reg,
- const char **name) {
- int pc;
- *name = luaF_getlocalname(p, reg + 1, lastpc);
+static const char *basicgetobjname (const Proto *p, int *ppc, int reg,
+ const char **name) {
+ int pc = *ppc;
+ *name = luaF_getlocalname(p, reg + 1, pc);
if (*name) /* is a local? */
return "local";
/* else try symbolic execution */
- pc = findsetreg(p, lastpc, reg);
+ *ppc = pc = findsetreg(p, pc, reg);
if (pc != -1) { /* could find instruction? */
Instruction i = p->code[pc];
OpCode op = GET_OPCODE(i);
@@ -537,18 +503,80 @@ static const char *getobjname (const Proto *p, int lastpc, int reg,
case OP_MOVE: {
int b = GETARG_B(i); /* move from 'b' to 'a' */
if (b < GETARG_A(i))
- return getobjname(p, pc, b, name); /* get name for 'b' */
+ return basicgetobjname(p, ppc, b, name); /* get name for 'b' */
break;
}
+ case OP_GETUPVAL: {
+ *name = upvalname(p, GETARG_B(i));
+ return "upvalue";
+ }
+ case OP_LOADK: return kname(p, GETARG_Bx(i), name);
+ case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name);
+ default: break;
+ }
+ }
+ return NULL; /* could not find reasonable name */
+}
+
+
+/*
+** Find a "name" for the register 'c'.
+*/
+static void rname (const Proto *p, int pc, int c, const char **name) {
+ const char *what = basicgetobjname(p, &pc, c, name); /* search for 'c' */
+ if (!(what && *what == 'c')) /* did not find a constant name? */
+ *name = "?";
+}
+
+
+/*
+** Find a "name" for a 'C' value in an RK instruction.
+*/
+static void rkname (const Proto *p, int pc, Instruction i, const char **name) {
+ int c = GETARG_C(i); /* key index */
+ if (GETARG_k(i)) /* is 'c' a constant? */
+ kname(p, c, name);
+ else /* 'c' is a register */
+ rname(p, pc, c, name);
+}
+
+
+/*
+** Check whether table being indexed by instruction 'i' is the
+** environment '_ENV'
+*/
+static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) {
+ int t = GETARG_B(i); /* table index */
+ const char *name; /* name of indexed variable */
+ if (isup) /* is 't' an upvalue? */
+ name = upvalname(p, t);
+ else /* 't' is a register */
+ basicgetobjname(p, &pc, t, &name);
+ return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field";
+}
+
+
+/*
+** Extend 'basicgetobjname' to handle table accesses
+*/
+static const char *getobjname (const Proto *p, int lastpc, int reg,
+ const char **name) {
+ const char *kind = basicgetobjname(p, &lastpc, reg, name);
+ if (kind != NULL)
+ return kind;
+ else if (lastpc != -1) { /* could find instruction? */
+ Instruction i = p->code[lastpc];
+ OpCode op = GET_OPCODE(i);
+ switch (op) {
case OP_GETTABUP: {
int k = GETARG_C(i); /* key index */
kname(p, k, name);
- return gxf(p, pc, i, 1);
+ return isEnv(p, lastpc, i, 1);
}
case OP_GETTABLE: {
int k = GETARG_C(i); /* key index */
- rname(p, pc, k, name);
- return gxf(p, pc, i, 0);
+ rname(p, lastpc, k, name);
+ return isEnv(p, lastpc, i, 0);
}
case OP_GETI: {
*name = "integer index";
@@ -557,24 +585,10 @@ static const char *getobjname (const Proto *p, int lastpc, int reg,
case OP_GETFIELD: {
int k = GETARG_C(i); /* key index */
kname(p, k, name);
- return gxf(p, pc, i, 0);
- }
- case OP_GETUPVAL: {
- *name = upvalname(p, GETARG_B(i));
- return "upvalue";
- }
- case OP_LOADK:
- case OP_LOADKX: {
- int b = (op == OP_LOADK) ? GETARG_Bx(i)
- : GETARG_Ax(p->code[pc + 1]);
- if (ttisstring(&p->k[b])) {
- *name = svalue(&p->k[b]);
- return "constant";
- }
- break;
+ return isEnv(p, lastpc, i, 0);
}
case OP_SELF: {
- rkname(p, pc, i, name);
+ rkname(p, lastpc, i, name);
return "method";
}
default: break; /* go through to return NULL */
--
2.33.0

View File

@ -0,0 +1,116 @@
From 1e64c1391f9a14115b5cc82066dbf545ae73ee27 Mon Sep 17 00:00:00 2001
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Tue, 25 Oct 2022 16:44:06 -0300
Subject: [PATCH] Bug: stack overflow with nesting of coroutine.close
---
lua-5.4.3-tests/cstack.lua | 26 ++++++++++++++++++++++++++
lua-5.4.3-tests/ltests/ltests.c | 2 +-
src/lcorolib.c | 4 ++--
src/lstate.c | 3 ++-
src/lua.h | 2 +-
5 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/lua-5.4.3-tests/cstack.lua b/lua-5.4.3-tests/cstack.lua
index ca76c87..97afe9f 100644
--- a/lua-5.4.3-tests/cstack.lua
+++ b/lua-5.4.3-tests/cstack.lua
@@ -84,6 +84,32 @@ do -- bug in 5.4.0
end
+do -- bug since 5.4.0
+ local count = 0
+ print("chain of 'coroutine.close'")
+ -- create N coroutines forming a list so that each one, when closed,
+ -- closes the previous one. (With a large enough N, previous Lua
+ -- versions crash in this test.)
+ local coro = false
+ for i = 1, 1000 do
+ local previous = coro
+ coro = coroutine.create(function()
+ local cc <close> = setmetatable({}, {__close=function()
+ count = count + 1
+ if previous then
+ assert(coroutine.close(previous))
+ end
+ end})
+ coroutine.yield() -- leaves 'cc' pending to be closed
+ end)
+ assert(coroutine.resume(coro)) -- start it and run until it yields
+ end
+ local st, msg = coroutine.close(coro)
+ assert(not st and string.find(msg, "C stack overflow"))
+ print("final count: ", count)
+end
+
+
do
print("nesting of resuming yielded coroutines")
local count = 0
diff --git a/lua-5.4.3-tests/ltests/ltests.c b/lua-5.4.3-tests/ltests/ltests.c
index a50f783..ef6168b 100644
--- a/lua-5.4.3-tests/ltests/ltests.c
+++ b/lua-5.4.3-tests/ltests/ltests.c
@@ -1533,7 +1533,7 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
lua_newthread(L1);
}
else if EQ("resetthread") {
- lua_pushinteger(L1, lua_resetthread(L1));
+ lua_pushinteger(L1, lua_resetthread(L1, L));
}
else if EQ("newuserdata") {
lua_newuserdata(L1, getnum);
diff --git a/src/lcorolib.c b/src/lcorolib.c
index fedbebe..c62acf2 100644
--- a/src/lcorolib.c
+++ b/src/lcorolib.c
@@ -76,7 +76,7 @@ static int luaB_auxwrap (lua_State *L) {
if (l_unlikely(r < 0)) { /* error? */
int stat = lua_status(co);
if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */
- stat = lua_resetthread(co); /* close its tbc variables */
+ stat = lua_resetthread(co, L); /* close its tbc variables */
lua_assert(stat != LUA_OK);
lua_xmove(co, L, 1); /* copy error message */
}
@@ -172,7 +172,7 @@ static int luaB_close (lua_State *L) {
int status = auxstatus(L, co);
switch (status) {
case COS_DEAD: case COS_YIELD: {
- status = lua_resetthread(co);
+ status = lua_resetthread(co, L);
if (status == LUA_OK) {
lua_pushboolean(L, 1);
return 1;
diff --git a/src/lstate.c b/src/lstate.c
index 59b4f21..4df1fd7 100644
--- a/src/lstate.c
+++ b/src/lstate.c
@@ -343,9 +343,10 @@ int luaE_resetthread (lua_State *L, int status) {
}
-LUA_API int lua_resetthread (lua_State *L) {
+LUA_API int lua_resetthread (lua_State *L, lua_State *from) {
int status;
lua_lock(L);
+ L->nCcalls = (from) ? getCcalls(from) : 0;
status = luaE_resetthread(L, L->status);
lua_unlock(L);
return status;
diff --git a/src/lua.h b/src/lua.h
index 820535b..17ecfe5 100644
--- a/src/lua.h
+++ b/src/lua.h
@@ -153,7 +153,7 @@ extern const char lua_ident[];
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
LUA_API void (lua_close) (lua_State *L);
LUA_API lua_State *(lua_newthread) (lua_State *L);
-LUA_API int (lua_resetthread) (lua_State *L);
+LUA_API int (lua_resetthread) (lua_State *L, lua_State *from);
LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
--
2.33.0

View File

@ -0,0 +1,117 @@
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

View File

@ -0,0 +1,34 @@
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

View File

@ -0,0 +1,95 @@
From 6443185167c77adcc8552a3fee7edab7895db1a9 Mon Sep 17 00:00:00 2001
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Tue, 2 May 2023 16:41:43 -0300
Subject: [PATCH] "Emergency" new version 5.4.6
'lua_resetthread' is back to its original signature, to avoid
incompatibilities in the ABI between releases of the same version.
New function 'lua_closethread' added with the "correct" signature.
---
src/lcorolib.c | 4 ++--
src/lstate.c | 10 +++++++++-
lua-5.4.3-tests/ltests/ltests.c | 2 +-
src/lua.h | 3 ++-
4 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/src/lcorolib.c b/src/lcorolib.c
index 40b880b1..c64adf08 100644
--- a/src/lcorolib.c
+++ b/src/lcorolib.c
@@ -76,7 +76,7 @@ static int luaB_auxwrap (lua_State *L) {
if (l_unlikely(r < 0)) { /* error? */
int stat = lua_status(co);
if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */
- stat = lua_resetthread(co, L); /* close its tbc variables */
+ stat = lua_closethread(co, L); /* close its tbc variables */
lua_assert(stat != LUA_OK);
lua_xmove(co, L, 1); /* copy error message */
}
@@ -172,7 +172,7 @@ static int luaB_close (lua_State *L) {
int status = auxstatus(L, co);
switch (status) {
case COS_DEAD: case COS_YIELD: {
- status = lua_resetthread(co, L);
+ status = lua_closethread(co, L);
if (status == LUA_OK) {
lua_pushboolean(L, 1);
return 1;
diff --git a/src/lstate.c b/src/lstate.c
index 1fbefb4b..1e925e5a 100644
--- a/src/lstate.c
+++ b/src/lstate.c
@@ -339,7 +339,7 @@ int luaE_resetthread (lua_State *L, int status) {
}
-LUA_API int lua_resetthread (lua_State *L, lua_State *from) {
+LUA_API int lua_closethread (lua_State *L, lua_State *from) {
int status;
lua_lock(L);
L->nCcalls = (from) ? getCcalls(from) : 0;
@@ -349,6 +349,14 @@ LUA_API int lua_resetthread (lua_State *L, lua_State *from) {
}
+/*
+** Deprecated! Use 'lua_closethread' instead.
+*/
+LUA_API int lua_resetthread (lua_State *L) {
+ return lua_closethread(L, NULL);
+}
+
+
LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
int i;
lua_State *L;
diff --git a/lua-5.4.3-tests/ltests/ltests.c b/lua-5.4.3-tests/ltests/ltests.c
index 4a0a6af1..7d184c0d 100644
--- a/lua-5.4.3-tests/ltests/ltests.c
+++ b/lua-5.4.3-tests/ltests/ltests.c
@@ -1533,7 +1533,7 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
lua_newthread(L1);
}
else if EQ("resetthread") {
- lua_pushinteger(L1, lua_resetthread(L1, L));
+ lua_pushinteger(L1, lua_resetthread(L1)); /* deprecated */
}
else if EQ("newuserdata") {
lua_newuserdata(L1, getnum);
diff --git a/src/lua.h b/src/lua.h
index 01927c6d..fd16cf80 100644
--- a/src/lua.h
+++ b/src/lua.h
@@ -163,7 +163,8 @@ extern const char lua_ident[];
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
LUA_API void (lua_close) (lua_State *L);
LUA_API lua_State *(lua_newthread) (lua_State *L);
-LUA_API int (lua_resetthread) (lua_State *L, lua_State *from);
+LUA_API int (lua_closethread) (lua_State *L, lua_State *from);
+LUA_API int (lua_resetthread) (lua_State *L); /* Deprecated! */
LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
--
2.33.0

View File

@ -0,0 +1,203 @@
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

View File

@ -0,0 +1,107 @@
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

View File

@ -0,0 +1,172 @@
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

View File

@ -0,0 +1,139 @@
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

View File

@ -0,0 +1,189 @@
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

View File

@ -0,0 +1,183 @@
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

View File

@ -0,0 +1,90 @@
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

View File

@ -6,7 +6,7 @@
Name: lua
Version: 5.4.3
Release: 9
Release: 14
Summary: A powerful, efficient, lightweight, embeddable scripting language
License: MIT
URL: http://www.lua.org/
@ -29,6 +29,19 @@ 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
Patch6015: backport-Bug-stack-overflow-with-nesting-of-coroutine.close.patch
Patch6016: backport-Bug-Loading-a-corrupted-binary-file-can-segfault.patch
Patch6017: backport-Bug-Recursion-in-getobjname-can-stack-overflow.patch
Patch6018: backport-Emergency-new-version-5.4.6.patch
BuildRequires: automake autoconf libtool readline-devel ncurses-devel
@ -67,6 +80,19 @@ mv src/luaconf.h src/luaconf.h.template.in
%patch6003 -p1
%patch6004 -p1
%patch6005 -p1
%patch6006 -p1
%patch6007 -p1
%patch6008 -p1
%patch6009 -p1
%patch6010 -p1
%patch6011 -p1
%patch6012 -p1
%patch6013 -p1
%patch6014 -p1
%patch6015 -p1
%patch6016 -p1
%patch6017 -p1
%patch6018 -p1
# Put proper version in configure.ac, patch0 hardcodes 5.3.0
sed -i 's|5.3.0|%{version}|g' configure.ac
@ -141,6 +167,21 @@ LD_LIBRARY_PATH=$RPM_BUILD_ROOT/%{_libdir} $RPM_BUILD_ROOT/%{_bindir}/lua -e"_U=
%{_mandir}/man1/lua*.1*
%changelog
* Wed May 08 2024 fuanan <fuanan3@h-partners.com> - 5.4.3-14
- add lua_closethread to adapt interfacechange
* Thu Jan 18 2024 yanglongkang <yanglongkang@h-partners.com> - 5.4.3-13
- fix Segmentation fault
* Tue Aug 22 2023 panchenbo <panchenbo@kylinsec.com.cn> - 5.4.3-12
- add sw_64 support
* 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
* Mon Dec 26 2022 liyanan <liyanan32@h-partners.com> - 5.4.3-10
- add support for LoongArch
* Wed Sep 21 2022 renhongxun <renhongxun@h-partners.com> - 5.4.3-9
- bugfix with upstream patch
@ -182,3 +223,4 @@ LD_LIBRARY_PATH=$RPM_BUILD_ROOT/%{_libdir} $RPM_BUILD_ROOT/%{_bindir}/lua -e"_U=
* Tue Sep 10 2019 openEuler Buildteam <buildteam@openeuler.org> - 5.3.5-3
- Package init

View File

@ -38,6 +38,8 @@
#include "luaconf-arm.h"
#elif defined(__alpha__)
#include "luaconf-alpha.h"
#elif defined(__sw_64)
#include "luaconf-sw_64.h"
#elif defined(__sparc__) && defined (__arch64__)
#include "luaconf-sparc64.h"
#elif defined(__sparc__)
@ -54,6 +56,8 @@
#include "luaconf-mips.h"
#elif defined(__riscv)
#include "luaconf-riscv64.h"
#elif defined(__loongarch64)
#include "luaconf-loongarch64.h"
#else
#error "The lua-devel package is not usable with the architecture."
#endif