lua54/upstream-bugs-test.patch
Callum Farmer 31ade7d3fc Accepting request 943227 from home:gmbr3:Lua
- Update upstream-bugs.patch and upstream-bugs-test.patch to fix
  bugs 9,10,12 for build and tests respectively. Bug 11 changes
  interface of luaD_pretailcall.

OBS-URL: https://build.opensuse.org/request/show/943227
OBS-URL: https://build.opensuse.org/package/show/devel:languages:lua/lua54?expand=0&rev=40
2021-12-30 13:50:02 +00:00

371 lines
10 KiB
Diff

diff --git a/testes/locals.lua b/testes/locals.lua
index 2c67edbdb..6aad5d253 100644
--- a/locals.lua
+++ b/locals.lua
@@ -335,6 +335,29 @@ do
end
+do
+ -- bug in 5.4.3: previous condition (calls cannot be tail in the
+ -- scope of to-be-closed variables) must be valid for tbc variables
+ -- created by 'for' loops.
+
+ local closed = false
+
+ local function foo ()
+ return function () return true end, 0, 0,
+ func2close(function () closed = true end)
+ end
+
+ local function tail() return closed end
+
+ local function foo1 ()
+ for k in foo() do return tail() end
+ end
+
+ assert(foo1() == false)
+ assert(closed == true)
+end
+
+
do print("testing errors in __close")
-- original error is in __close
diff --git a/testes/locals.lua b/testes/locals.lua
index 6aad5d253..6151f64d0 100644
--- a/locals.lua
+++ b/locals.lua
@@ -813,6 +813,65 @@ do
end
+do
+ -- yielding inside closing metamethods while returning
+ -- (bug in 5.4.3)
+
+ local extrares -- result from extra yield (if any)
+
+ local function check (body, extra, ...)
+ local t = table.pack(...) -- expected returns
+ local co = coroutine.wrap(body)
+ if extra then
+ extrares = co() -- runs until first (extra) yield
+ end
+ local res = table.pack(co()) -- runs until yield inside '__close'
+ assert(res.n == 2 and res[2] == nil)
+ local res2 = table.pack(co()) -- runs until end of function
+ assert(res2.n == t.n)
+ for i = 1, #t do
+ if t[i] == "x" then
+ assert(res2[i] == res[1]) -- value that was closed
+ else
+ assert(res2[i] == t[i])
+ end
+ end
+ end
+
+ local function foo ()
+ local x <close> = func2close(coroutine.yield)
+ local extra <close> = func2close(function (self)
+ assert(self == extrares)
+ coroutine.yield(100)
+ end)
+ extrares = extra
+ return table.unpack{10, x, 30}
+ end
+ check(foo, true, 10, "x", 30)
+ assert(extrares == 100)
+
+ local function foo ()
+ local x <close> = func2close(coroutine.yield)
+ return
+ end
+ check(foo, false)
+
+ local function foo ()
+ local x <close> = func2close(coroutine.yield)
+ local y, z = 20, 30
+ return x
+ end
+ check(foo, false, "x")
+
+ local function foo ()
+ local x <close> = func2close(coroutine.yield)
+ local extra <close> = func2close(coroutine.yield)
+ return table.unpack({}, 1, 100) -- 100 nils
+ end
+ check(foo, true, table.unpack({}, 1, 100))
+
+end
+
do
-- yielding inside closing metamethods after an error
diff --git a/testes/locals.lua b/testes/locals.lua
index 6151f64d0..62a88df57 100644
--- a/locals.lua
+++ b/locals.lua
@@ -187,6 +187,8 @@ do -- constants
checkro("y", "local x, y <const>, z = 10, 20, 30; x = 11; y = 12")
checkro("x", "local x <const>, y, z <const> = 10, 20, 30; x = 11")
checkro("z", "local x <const>, y, z <const> = 10, 20, 30; y = 10; z = 11")
+ checkro("foo", "local foo <const> = 10; function foo() end")
+ checkro("foo", "local foo <const> = {}; function foo() end")
checkro("z", [[
local a, z <const>, b = 10;
diff --git a/testes/bitwise.lua b/testes/bitwise.lua
index 59781f5df..9509f7f04 100644
--- a/bitwise.lua
+++ b/bitwise.lua
@@ -45,6 +45,11 @@ assert(-1 >> numbits == 0 and
-1 << numbits == 0 and
-1 << -numbits == 0)
+assert(1 >> math.mininteger == 0)
+assert(1 >> math.maxinteger == 0)
+assert(1 << math.mininteger == 0)
+assert(1 << math.maxinteger == 0)
+
assert((2^30 - 1) << 2^30 == 0)
assert((2^30 - 1) >> 2^30 == 0)
diff --git a/testes/errors.lua b/testes/errors.lua
index 825f37c29..a7dc479a2 100644
--- a/errors.lua
+++ b/errors.lua
@@ -228,6 +228,22 @@ do -- named objects (field '__name')
checkmessage("return {} < XX", "table with My Type")
checkmessage("return XX < io.stdin", "My Type with FILE*")
_G.XX = nil
+
+ if T then -- extra tests for 'luaL_tolstring'
+ -- bug in 5.4.3; 'luaL_tolstring' with negative indices
+ local x = setmetatable({}, {__name="TABLE"})
+ assert(T.testC("Ltolstring -1; return 1", x) == tostring(x))
+
+ local a, b = T.testC("pushint 10; Ltolstring -2; return 2", x)
+ assert(a == 10 and b == tostring(x))
+
+ setmetatable(x, {__tostring=function (o)
+ assert(o == x)
+ return "ABC"
+ end})
+ a, b, c = T.testC("pushint 10; Ltolstring -2; return 3", x)
+ assert(a == x and b == 10 and c == "ABC")
+ end
end
-- global functions
diff --git a/ltests.c b/ltests.c
index a50f78304..97834e380 100644
--- a/ltests/ltests.c
+++ b/ltests/ltests.c
@@ -1743,6 +1743,9 @@ static struct X { int x; } x;
(void)s1; /* to avoid warnings */
lua_longassert((s == NULL && s1 == NULL) || strcmp(s, s1) == 0);
}
+ else if EQ("Ltolstring") {
+ luaL_tolstring(L1, getindex, NULL);
+ }
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)
diff --git a/testes/api.lua b/testes/api.lua
index c1bcb4b7b..bd85a923c 100644
--- a/api.lua
+++ b/api.lua
@@ -804,15 +804,14 @@ F = function (x)
d = nil
assert(debug.getmetatable(x).__gc == F)
assert(load("table.insert({}, {})"))() -- create more garbage
- collectgarbage() -- force a GC during GC
- assert(debug.getmetatable(x).__gc == F) -- previous GC did not mess this?
+ assert(not collectgarbage()) -- GC during GC (no op)
local dummy = {} -- create more garbage during GC
if A ~= nil then
assert(type(A) == "userdata")
assert(T.udataval(A) == B)
debug.getmetatable(A) -- just access it
end
- A = x -- ressucita userdata
+ A = x -- ressurect userdata
B = udval
return 1,2,3
end
diff --git a/testes/gc.lua b/testes/gc.lua
index 2332c939a..d865cb28d 100644
--- a/gc.lua
+++ b/gc.lua
@@ -676,11 +676,13 @@ end
-- just to make sure
assert(collectgarbage'isrunning')
-do -- check that the collector is reentrant in incremental mode
+do -- check that the collector is not reentrant in incremental mode
+ local res = true
setmetatable({}, {__gc = function ()
- collectgarbage()
+ res = collectgarbage()
end})
collectgarbage()
+ assert(not res)
end
diff --git a/testes/main.lua b/testes/main.lua
index 52c779541..9def63860 100644
--- a/main.lua
+++ b/main.lua
@@ -261,6 +261,34 @@ u2 = setmetatable({}, {__gc = function () error("ZYX") end})
RUN('lua -W %s 2> %s', prog, out)
checkprogout("ZYX)\nXYZ)\n")
+-- bug since 5.2: finalizer called when closing a state could
+-- subvert finalization order
+prepfile[[
+-- should be called last
+print("creating 1")
+setmetatable({}, {__gc = function () print(1) end})
+
+print("creating 2")
+setmetatable({}, {__gc = function ()
+ print("2")
+ print("creating 3")
+ -- this finalizer should not be called, as object will be
+ -- created after 'lua_close' has been called
+ setmetatable({}, {__gc = function () print(3) end})
+ print(collectgarbage()) -- cannot call collector here
+ os.exit(0, true)
+end})
+]]
+RUN('lua -W %s > %s', prog, out)
+checkout[[
+creating 1
+creating 2
+2
+creating 3
+nil
+1
+]]
+
-- test many arguments
prepfile[[print(({...})[30])]]