mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-03 03:02:28 +00:00
Bring Lua to 5.4.6. (#1214)
This essentially re-does the work of #875 on top of master. This is what I did to check that Cosmo's Lua extensions still worked: ``` $ build/bootstrap/make MODE=aarch64 o/aarch64/third_party/lua/lua $ ape o/aarch64/third_party/lua/lua >: 10 10 >: 010 8 >: 0b10 2 >: string.byte("\e") 27 >: "Hello, %s" % {"world"} Hello, world >: "*" * 3 *** ``` `luaL_traceback2` was used to show the stack trace with parameter values; it's used in `LuaCallWithTrace`, which is used in Redbean to run Lua code. You should be able to see the extended stack trace by running something like this: `redbean -e "function a(b)c()end a(2)"` (with "params" indicating the extended stack trace): ``` stack traceback: [string "function a(b)c()end a(2)"]:1: in function 'a', params: b = 2; [string "function a(b)c()end a(2)"]:1: in main chunk ``` @pkulchenko confirmed that I get the expected result with the updated code. This is what I did to check that Lua itself still worked: ``` $ cd third_party/lua/test/ $ ape ../../../o/aarch64/third_party/lua/lua all.lua ``` There's one test failure, in `files.lua`: ``` ***** FILE 'files.lua'***** testing i/o ../../../o/aarch64/third_party/lua/lua: files.lua:84: assertion failed! stack traceback: [C]: in function 'assert' files.lua:84: in main chunk (...tail calls...) all.lua:195: in main chunk [C]: in ? .>>> closing state <<< ``` That isn't a result of these changes; the same test is failing in master. The failure is here: ```lua if not _port then -- invalid seek local status, msg, code = io.stdin:seek("set", 1000) assert(not status and type(msg) == "string" and type(code) == "number") end ``` The test expects a seek to offset 1,000 on stdin to fail — but it doesn't. `status` ends up being the new offset rather than `nil`. If I comment out that one test, the remaining tests succeed.
This commit is contained in:
parent
3a599bfbe1
commit
0dbf01bf1d
90 changed files with 2741 additions and 1376 deletions
134
third_party/lua/test/locals.lua
vendored
134
third_party/lua/test/locals.lua
vendored
|
@ -37,7 +37,7 @@ end
|
|||
f = nil
|
||||
|
||||
local f
|
||||
x = 1
|
||||
local x = 1
|
||||
|
||||
a = nil
|
||||
load('local a = {}')()
|
||||
|
@ -152,7 +152,7 @@ local dummy
|
|||
local _ENV = (function (...) return ... end)(_G, dummy) -- {
|
||||
|
||||
do local _ENV = {assert=assert}; assert(true) end
|
||||
mt = {_G = _G}
|
||||
local mt = {_G = _G}
|
||||
local foo,x
|
||||
A = false -- "declare" A
|
||||
do local _ENV = mt
|
||||
|
@ -174,6 +174,8 @@ do local _ENV = {assert=assert, A=10};
|
|||
end
|
||||
assert(x==20)
|
||||
|
||||
A = nil
|
||||
|
||||
|
||||
do -- constants
|
||||
local a<const>, b, c<const> = 10, 20, 30
|
||||
|
@ -187,6 +189,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;
|
||||
|
@ -335,6 +339,49 @@ 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
|
||||
-- bug in 5.4.4: 'break' may generate wrong 'close' instruction when
|
||||
-- leaving a loop block.
|
||||
|
||||
local closed = false
|
||||
|
||||
local o1 = setmetatable({}, {__close=function() closed = true end})
|
||||
|
||||
local function test()
|
||||
for k, v in next, {}, nil, o1 do
|
||||
local function f() return k end -- create an upvalue
|
||||
break
|
||||
end
|
||||
assert(closed)
|
||||
end
|
||||
|
||||
test()
|
||||
end
|
||||
|
||||
|
||||
do print("testing errors in __close")
|
||||
|
||||
-- original error is in __close
|
||||
|
@ -567,6 +614,28 @@ end
|
|||
|
||||
if rawget(_G, "T") then
|
||||
|
||||
do
|
||||
-- bug in 5.4.3
|
||||
-- 'lua_settop' may use a pointer to stack invalidated by 'luaF_close'
|
||||
|
||||
-- reduce stack size
|
||||
collectgarbage(); collectgarbage(); collectgarbage()
|
||||
|
||||
-- force a stack reallocation
|
||||
local function loop (n)
|
||||
if n < 400 then loop(n + 1) end
|
||||
end
|
||||
|
||||
-- close metamethod will reallocate the stack
|
||||
local o = setmetatable({}, {__close = function () loop(0) end})
|
||||
|
||||
local script = [[toclose 2; settop 1; return 1]]
|
||||
|
||||
assert(T.testC(script, o) == script)
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- memory error inside closing function
|
||||
local function foo ()
|
||||
local y <close> = func2close(function () T.alloccount() end)
|
||||
|
@ -644,7 +713,7 @@ if rawget(_G, "T") then
|
|||
|
||||
collectgarbage(); collectgarbage()
|
||||
|
||||
m = T.totalmem()
|
||||
local m = T.totalmem()
|
||||
collectgarbage("stop")
|
||||
|
||||
-- error in the first buffer allocation
|
||||
|
@ -790,6 +859,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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue