Compare commits
10 Commits
508d7afc7d
...
b0e619426d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0e619426d | ||
|
|
06777b4ffc | ||
|
|
8148fa61b6 | ||
|
|
ea404f7ebf | ||
|
|
135922521d | ||
|
|
db11036d1a | ||
|
|
9788b313db | ||
|
|
b07366fdc6 | ||
|
|
6d88b9c460 | ||
|
|
b46f3dc542 |
@ -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
|
||||
232
backport-Bug-Recursion-in-getobjname-can-stack-overflow.patch
Normal file
232
backport-Bug-Recursion-in-getobjname-can-stack-overflow.patch
Normal 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
|
||||
@ -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
|
||||
117
backport-C-functions-can-be-tail-called-too.patch
Normal file
117
backport-C-functions-can-be-tail-called-too.patch
Normal 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
|
||||
|
||||
34
backport-CVE-2021-45985.patch
Normal file
34
backport-CVE-2021-45985.patch
Normal 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
|
||||
|
||||
|
||||
95
backport-Emergency-new-version-5.4.6.patch
Normal file
95
backport-Emergency-new-version-5.4.6.patch
Normal 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
|
||||
|
||||
203
backport-More-uniform-implementation-for-tail-calls.patch
Normal file
203
backport-More-uniform-implementation-for-tail-calls.patch
Normal 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
|
||||
|
||||
|
||||
107
backport-Removed-goto-s-in-luaD_precall.patch
Normal file
107
backport-Removed-goto-s-in-luaD_precall.patch
Normal 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
|
||||
|
||||
|
||||
172
backport-Simpler-implementation-for-tail-calls.patch
Normal file
172
backport-Simpler-implementation-for-tail-calls.patch
Normal 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
|
||||
|
||||
|
||||
139
backport-Simplification-in-the-parameters-of-luaD_precall.patch
Normal file
139
backport-Simplification-in-the-parameters-of-luaD_precall.patch
Normal 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
|
||||
|
||||
|
||||
189
backport-Undo-simplification-of-tail-calls-commit-901d760.patch
Normal file
189
backport-Undo-simplification-of-tail-calls-commit-901d760.patch
Normal 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
|
||||
|
||||
|
||||
183
backport-Using-inline-in-some-functions.patch
Normal file
183
backport-Using-inline-in-some-functions.patch
Normal 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
|
||||
|
||||
|
||||
90
backport-luaD_tryfuncTM-checks-stack-space-by-itself.patch
Normal file
90
backport-luaD_tryfuncTM-checks-stack-space-by-itself.patch
Normal 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
|
||||
|
||||
|
||||
44
lua.spec
44
lua.spec
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user