8ce8cc4141
- Add upstream-bugs.patch and upstream-bugs-test.patch to fix bugs 1,2,3 for build and tests respectively. OBS-URL: https://build.opensuse.org/request/show/886618 OBS-URL: https://build.opensuse.org/package/show/devel:languages:lua/lua54?expand=0&rev=30
150 lines
5.3 KiB
Diff
150 lines
5.3 KiB
Diff
From 47cffdc723c2e0c6dfaf62b7775ca1c1d338c0a4 Mon Sep 17 00:00:00 2001
|
|
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
Date: Wed, 7 Apr 2021 14:59:26 -0300
|
|
Subject: [PATCH] Bug: tbc variables in "for" loops don't avoid tail calls
|
|
|
|
---
|
|
lparser.c | 21 +++++++++++++++------
|
|
testes/locals.lua | 23 +++++++++++++++++++++++
|
|
2 files changed, 38 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/lparser.c b/lparser.c
|
|
index 284ef1f0c..df9473c27 100644
|
|
--- a/src/lparser.c
|
|
+++ b/src/lparser.c
|
|
@@ -416,6 +416,17 @@ static void markupval (FuncState *fs, int level) {
|
|
}
|
|
|
|
|
|
+/*
|
|
+** Mark that current block has a to-be-closed variable.
|
|
+*/
|
|
+static void marktobeclosed (FuncState *fs) {
|
|
+ BlockCnt *bl = fs->bl;
|
|
+ bl->upval = 1;
|
|
+ bl->insidetbc = 1;
|
|
+ fs->needclose = 1;
|
|
+}
|
|
+
|
|
+
|
|
/*
|
|
** Find a variable with the given name 'n'. If it is an upvalue, add
|
|
** this upvalue into all intermediate functions. If it is a global, set
|
|
@@ -1599,7 +1610,7 @@ static void forlist (LexState *ls, TString *indexname) {
|
|
line = ls->linenumber;
|
|
adjust_assign(ls, 4, explist(ls, &e), &e);
|
|
adjustlocalvars(ls, 4); /* control variables */
|
|
- markupval(fs, fs->nactvar); /* last control var. must be closed */
|
|
+ marktobeclosed(fs); /* last control var. must be closed */
|
|
luaK_checkstack(fs, 3); /* extra space to call generator */
|
|
forbody(ls, base, line, nvars - 4, 1);
|
|
}
|
|
@@ -1703,11 +1714,9 @@ static int getlocalattribute (LexState *ls) {
|
|
}
|
|
|
|
|
|
-static void checktoclose (LexState *ls, int level) {
|
|
+static void checktoclose (FuncState *fs, int level) {
|
|
if (level != -1) { /* is there a to-be-closed variable? */
|
|
- FuncState *fs = ls->fs;
|
|
- markupval(fs, level + 1);
|
|
- fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */
|
|
+ marktobeclosed(fs);
|
|
luaK_codeABC(fs, OP_TBC, reglevel(fs, level), 0, 0);
|
|
}
|
|
}
|
|
@@ -1751,7 +1760,7 @@ static void localstat (LexState *ls) {
|
|
adjust_assign(ls, nvars, nexps, &e);
|
|
adjustlocalvars(ls, nvars);
|
|
}
|
|
- checktoclose(ls, toclose);
|
|
+ checktoclose(fs, toclose);
|
|
}
|
|
|
|
|
|
From d205f3a4847bc8b835fda91f51ba1cf45b796baf Mon Sep 17 00:00:00 2001
|
|
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
Date: Sat, 10 Apr 2021 10:19:21 -0300
|
|
Subject: [PATCH] Bug: Lua source should not use C99 comments ("//")
|
|
|
|
---
|
|
lvm.c | 6 ++++--
|
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/lvm.c b/lvm.c
|
|
index c9729bcca..16e01d683 100644
|
|
--- a/src/lvm.c
|
|
+++ b/src/lvm.c
|
|
@@ -1156,8 +1156,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|
Instruction i; /* instruction being executed */
|
|
StkId ra; /* instruction's A register */
|
|
vmfetch();
|
|
-// low-level line tracing for debugging Lua
|
|
-// printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p)));
|
|
+ #if 0
|
|
+ /* low-level line tracing for debugging Lua */
|
|
+ printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p)));
|
|
+ #endif
|
|
lua_assert(base == ci->func + 1);
|
|
lua_assert(base <= L->top && L->top < L->stack_last);
|
|
/* invalidate top for instructions not expecting it */
|
|
From 681297187ec45268e872b26753c441586c12bdd8 Mon Sep 17 00:00:00 2001
|
|
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
Date: Fri, 16 Apr 2021 15:41:44 -0300
|
|
Subject: [PATCH] Bug: yielding in '__close' mess up number of returns
|
|
|
|
Yielding in a __close metamethod called when returning vararg results
|
|
changes the top and so messes up the number of returned values.
|
|
---
|
|
lstate.h | 2 +-
|
|
lvm.c | 12 +++++++++-
|
|
testes/locals.lua | 59 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
3 files changed, 71 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/lstate.h b/lstate.h
|
|
index c1283bb6b..44cf939cb 100644
|
|
--- a/src/lstate.h
|
|
+++ b/src/lstate.h
|
|
@@ -165,7 +165,7 @@ typedef struct stringtable {
|
|
** - field 'nyield' is used only while a function is "doing" an
|
|
** yield (from the yield until the next resume);
|
|
** - field 'nres' is used only while closing tbc variables when
|
|
-** returning from a C function;
|
|
+** returning from a function;
|
|
** - field 'transferinfo' is used only during call/returnhooks,
|
|
** before the function starts or after it ends.
|
|
*/
|
|
diff --git a/lvm.c b/lvm.c
|
|
index 16e01d683..e4b1903e7 100644
|
|
--- a/src/lvm.c
|
|
+++ b/src/lvm.c
|
|
@@ -847,10 +847,19 @@ void luaV_finishOp (lua_State *L) {
|
|
luaV_concat(L, total); /* concat them (may yield again) */
|
|
break;
|
|
}
|
|
- case OP_CLOSE: case OP_RETURN: { /* yielded closing variables */
|
|
+ case OP_CLOSE: { /* yielded closing variables */
|
|
ci->u.l.savedpc--; /* repeat instruction to close other vars. */
|
|
break;
|
|
}
|
|
+ case OP_RETURN: { /* yielded closing variables */
|
|
+ StkId ra = base + GETARG_A(inst);
|
|
+ /* adjust top to signal correct number of returns, in case the
|
|
+ return is "up to top" ('isIT') */
|
|
+ L->top = ra + ci->u2.nres;
|
|
+ /* repeat instruction to close other vars. and complete the return */
|
|
+ ci->u.l.savedpc--;
|
|
+ break;
|
|
+ }
|
|
default: {
|
|
/* only these other opcodes can yield */
|
|
lua_assert(op == OP_TFORCALL || op == OP_CALL ||
|
|
@@ -1672,6 +1681,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|
n = cast_int(L->top - ra); /* get what is available */
|
|
savepc(ci);
|
|
if (TESTARG_k(i)) { /* may there be open upvalues? */
|
|
+ ci->u2.nres = n; /* save number of returns */
|
|
if (L->top < ci->top)
|
|
L->top = ci->top;
|
|
luaF_close(L, base, CLOSEKTOP, 1);
|