forked from pool/lua54
Accepting request 934302 from home:gmbr3:Lua
- Update upstream-bugs.patch and upstream-bugs-test.patch to fix bugs 7,8 for build and tests respectively. OBS-URL: https://build.opensuse.org/request/show/934302 OBS-URL: https://build.opensuse.org/package/show/devel:languages:lua/lua54?expand=0&rev=39
This commit is contained in:
parent
2ee403b494
commit
4dd8655c8e
@ -1,3 +1,9 @@
|
||||
-------------------------------------------------------------------
|
||||
Sat Nov 27 16:54:20 UTC 2021 - Callum Farmer <gmbr3@opensuse.org>
|
||||
|
||||
- Update upstream-bugs.patch and upstream-bugs-test.patch to fix
|
||||
bugs 7,8 for build and tests respectively.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jul 29 16:31:23 UTC 2021 - Callum Farmer <gmbr3@opensuse.org>
|
||||
|
||||
|
@ -172,3 +172,118 @@ index a50f78304..97834e380 100644
|
||||
else if EQ("type") {
|
||||
lua_pushstring(L1, luaL_typename(L1, getnum));
|
||||
}
|
||||
diff --git a/testes/cstack.lua b/testes/cstack.lua
|
||||
index 213d15d47..ca76c8729 100644
|
||||
--- a/cstack.lua
|
||||
+++ b/cstack.lua
|
||||
@@ -103,6 +103,20 @@ do
|
||||
end
|
||||
|
||||
|
||||
+do -- bug in 5.4.2
|
||||
+ print("nesting coroutines running after recoverable errors")
|
||||
+ local count = 0
|
||||
+ local function foo()
|
||||
+ count = count + 1
|
||||
+ pcall(1) -- create an error
|
||||
+ -- running now inside 'precover' ("protected recover")
|
||||
+ coroutine.wrap(foo)() -- call another coroutine
|
||||
+ end
|
||||
+ checkerror("C stack overflow", foo)
|
||||
+ print("final count: ", count)
|
||||
+end
|
||||
+
|
||||
+
|
||||
if T then
|
||||
print("testing stack recovery")
|
||||
local N = 0 -- trace number of calls
|
||||
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
|
||||
index 461e03770..76c9d6e63 100644
|
||||
--- a/coroutine.lua
|
||||
+++ b/coroutine.lua
|
||||
@@ -136,6 +136,10 @@ do
|
||||
assert(coroutine.status(co) == "dead")
|
||||
local st, msg = coroutine.close(co)
|
||||
assert(st and msg == nil)
|
||||
+ -- also ok to close it again
|
||||
+ st, msg = coroutine.close(co)
|
||||
+ assert(st and msg == nil)
|
||||
+
|
||||
|
||||
-- cannot close the running coroutine
|
||||
local st, msg = pcall(coroutine.close, coroutine.running())
|
||||
@@ -149,6 +153,22 @@ do
|
||||
assert(not st and string.find(msg, "normal"))
|
||||
end))()
|
||||
|
||||
+ -- cannot close a coroutine while closing it
|
||||
+ do
|
||||
+ local co
|
||||
+ co = coroutine.create(
|
||||
+ function()
|
||||
+ local x <close> = func2close(function()
|
||||
+ coroutine.close(co) -- try to close it again
|
||||
+ end)
|
||||
+ coroutine.yield(20)
|
||||
+ end)
|
||||
+ local st, msg = coroutine.resume(co)
|
||||
+ assert(st and msg == 20)
|
||||
+ st, msg = coroutine.close(co)
|
||||
+ assert(not st and string.find(msg, "running coroutine"))
|
||||
+ end
|
||||
+
|
||||
-- to-be-closed variables in coroutines
|
||||
local X
|
||||
|
||||
@@ -158,6 +178,9 @@ do
|
||||
assert(not st and msg == 100)
|
||||
st, msg = coroutine.close(co)
|
||||
assert(not st and msg == 100)
|
||||
+ -- after closing, no more errors
|
||||
+ st, msg = coroutine.close(co)
|
||||
+ assert(st and msg == nil)
|
||||
|
||||
co = coroutine.create(function ()
|
||||
local x <close> = func2close(function (self, err)
|
||||
@@ -189,6 +212,9 @@ do
|
||||
local st, msg = coroutine.close(co)
|
||||
assert(st == false and coroutine.status(co) == "dead" and msg == 200)
|
||||
assert(x == 200)
|
||||
+ -- after closing, no more errors
|
||||
+ st, msg = coroutine.close(co)
|
||||
+ assert(st and msg == nil)
|
||||
end
|
||||
|
||||
do
|
||||
@@ -419,7 +445,7 @@ do
|
||||
|
||||
local X = false
|
||||
A = coroutine.wrap(function()
|
||||
- local _ <close> = setmetatable({}, {__close = function () X = true end})
|
||||
+ local _ <close> = func2close(function () X = true end)
|
||||
return pcall(A, 1)
|
||||
end)
|
||||
st, res = A()
|
||||
@@ -427,6 +453,22 @@ do
|
||||
end
|
||||
|
||||
|
||||
+-- bug in 5.4.1
|
||||
+do
|
||||
+ -- coroutine ran close metamethods with invalid status during a
|
||||
+ -- reset.
|
||||
+ local co
|
||||
+ co = coroutine.wrap(function()
|
||||
+ local x <close> = func2close(function() return pcall(co) end)
|
||||
+ error(111)
|
||||
+ end)
|
||||
+ local st, errobj = pcall(co)
|
||||
+ assert(not st and errobj == 111)
|
||||
+ st, errobj = pcall(co)
|
||||
+ assert(not st and string.find(errobj, "dead coroutine"))
|
||||
+end
|
||||
+
|
||||
+
|
||||
-- attempt to resume 'normal' coroutine
|
||||
local co1, co2
|
||||
co1 = coroutine.create(function () return co2() end)
|
||||
|
@ -218,3 +218,110 @@ index 94835ef93..8ed1da112 100644
|
||||
if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */
|
||||
if (!lua_isstring(L, -1))
|
||||
luaL_error(L, "'__tostring' must return a string");
|
||||
From 74d99057a5146755e737c479850f87fd0e3b6868 Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Wed, 3 Nov 2021 15:04:18 -0300
|
||||
Subject: [PATCH] Bug: C stack overflow with coroutines
|
||||
|
||||
'coroutine.resume' did not increment counter of C calls when
|
||||
continuing execution after a protected error (that is,
|
||||
while running 'precover').
|
||||
---
|
||||
ldo.c | 6 ++++--
|
||||
testes/cstack.lua | 14 ++++++++++++++
|
||||
2 files changed, 18 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ldo.c b/ldo.c
|
||||
index d0edc8b4f..66f890364 100644
|
||||
--- a/src/ldo.c
|
||||
+++ b/src/ldo.c
|
||||
@@ -759,11 +759,10 @@ static void resume (lua_State *L, void *ud) {
|
||||
StkId firstArg = L->top - n; /* first argument */
|
||||
CallInfo *ci = L->ci;
|
||||
if (L->status == LUA_OK) /* starting a coroutine? */
|
||||
- ccall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */
|
||||
+ ccall(L, firstArg - 1, LUA_MULTRET, 0); /* just call its body */
|
||||
else { /* resuming from previous yield */
|
||||
lua_assert(L->status == LUA_YIELD);
|
||||
L->status = LUA_OK; /* mark that it is running (again) */
|
||||
- luaE_incCstack(L); /* control the C stack */
|
||||
if (isLua(ci)) { /* yielded inside a hook? */
|
||||
L->top = firstArg; /* discard arguments */
|
||||
luaV_execute(L, ci); /* just continue running Lua code */
|
||||
@@ -814,6 +813,9 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
|
||||
else if (L->status != LUA_YIELD) /* ended with errors? */
|
||||
return resume_error(L, "cannot resume dead coroutine", nargs);
|
||||
L->nCcalls = (from) ? getCcalls(from) : 0;
|
||||
+ if (getCcalls(L) >= LUAI_MAXCCALLS)
|
||||
+ return resume_error(L, "C stack overflow", nargs);
|
||||
+ L->nCcalls++;
|
||||
luai_userstateresume(L, nargs);
|
||||
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
|
||||
status = luaD_rawrunprotected(L, resume, &nargs);
|
||||
From bfbff3703edae789fa5efa9bf174f8e7cff4ded8 Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
Date: Mon, 8 Nov 2021 11:55:25 -0300
|
||||
Subject: [PATCH] Bug: Wrong status in coroutine during reset
|
||||
|
||||
When closing variables during 'coroutine.close' or 'lua_resetthread',
|
||||
the status of a coroutine must be set to LUA_OK; a coroutine should
|
||||
not run with any other status. (See assertion in 'lua_callk'.)
|
||||
|
||||
After the reset, the status should be kept as normal, as any error
|
||||
was already reported.
|
||||
---
|
||||
lcorolib.c | 4 ++--
|
||||
lstate.c | 4 ++--
|
||||
testes/coroutine.lua | 44 +++++++++++++++++++++++++++++++++++++++++++-
|
||||
3 files changed, 47 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/lcorolib.c b/lcorolib.c
|
||||
index fedbebec3..785a1e81a 100644
|
||||
--- a/src/lcorolib.c
|
||||
+++ b/src/lcorolib.c
|
||||
@@ -78,7 +78,7 @@ static int luaB_auxwrap (lua_State *L) {
|
||||
if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */
|
||||
stat = lua_resetthread(co); /* close its tbc variables */
|
||||
lua_assert(stat != LUA_OK);
|
||||
- lua_xmove(co, L, 1); /* copy error message */
|
||||
+ lua_xmove(co, L, 1); /* move error message to the caller */
|
||||
}
|
||||
if (stat != LUA_ERRMEM && /* not a memory error and ... */
|
||||
lua_type(L, -1) == LUA_TSTRING) { /* ... error object is a string? */
|
||||
@@ -179,7 +179,7 @@ static int luaB_close (lua_State *L) {
|
||||
}
|
||||
else {
|
||||
lua_pushboolean(L, 0);
|
||||
- lua_xmove(co, L, 1); /* copy error message */
|
||||
+ lua_xmove(co, L, 1); /* move error message */
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
diff --git a/lstate.c b/lstate.c
|
||||
index bfc590262..5cb0847c8 100644
|
||||
--- a/src/lstate.c
|
||||
+++ b/src/lstate.c
|
||||
@@ -166,7 +166,7 @@ void luaE_checkcstack (lua_State *L) {
|
||||
if (getCcalls(L) == LUAI_MAXCCALLS)
|
||||
luaG_runerror(L, "C stack overflow");
|
||||
else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11))
|
||||
- luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
|
||||
+ luaD_throw(L, LUA_ERRERR); /* error while handling stack error */
|
||||
}
|
||||
|
||||
|
||||
@@ -330,13 +330,13 @@ int luaE_resetthread (lua_State *L, int status) {
|
||||
ci->callstatus = CIST_C;
|
||||
if (status == LUA_YIELD)
|
||||
status = LUA_OK;
|
||||
+ L->status = LUA_OK; /* so it can run __close metamethods */
|
||||
status = luaD_closeprotected(L, 1, status);
|
||||
if (status != LUA_OK) /* errors? */
|
||||
luaD_seterrorobj(L, status, L->stack + 1);
|
||||
else
|
||||
L->top = L->stack + 1;
|
||||
ci->top = L->top + LUA_MINSTACK;
|
||||
- L->status = cast_byte(status);
|
||||
luaD_reallocstack(L, cast_int(ci->top - L->stack), 0);
|
||||
return status;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user