mirror of
https://github.com/lua/lua.git
synced 2026-08-13 00:29:35 +00:00
New conceptual model for vararg
Conceptually, all functions get their vararg arguments in a vararg table. The storing of vararg arguments in the stack is always treated as an optimization.
This commit is contained in:
@@ -702,7 +702,9 @@ else
|
||||
assert(t.currentline == t.linedefined + 2)
|
||||
assert(not debug.getinfo(c, 1)) -- no other level
|
||||
assert(coroutine.resume(c)) -- run next line
|
||||
local n,v = debug.getlocal(c, 0, 2) -- check next local
|
||||
local n,v = debug.getlocal(c, 0, 2) -- check vararg table
|
||||
assert(n == "(vararg table)" and v == nil)
|
||||
local n,v = debug.getlocal(c, 0, 3) -- check next local
|
||||
assert(n == "b" and v == 10)
|
||||
v = {coroutine.resume(c)} -- finish coroutine
|
||||
assert(v[1] == true and v[2] == 2 and v[3] == 3 and v[4] == undef)
|
||||
|
||||
@@ -356,8 +356,8 @@ function f(a,b)
|
||||
global assert, g, string
|
||||
local _, y = debug.getlocal(1, 2)
|
||||
assert(x == a and y == b)
|
||||
assert(debug.setlocal(2, 3, "pera") == "AA".."AA")
|
||||
assert(debug.setlocal(2, 4, "manga") == "B")
|
||||
assert(debug.setlocal(2, 4, "pera") == "AA".."AA")
|
||||
assert(debug.setlocal(2, 5, "manga") == "B")
|
||||
x = debug.getinfo(2)
|
||||
assert(x.func == g and x.what == "Lua" and x.name == 'g' and
|
||||
x.nups == 2 and string.find(x.source, "^@.*db%.lua$"))
|
||||
@@ -392,7 +392,7 @@ function g (...)
|
||||
global *
|
||||
local B = 13
|
||||
global<const> assert
|
||||
local x,y = debug.getlocal(1,5)
|
||||
local x,y = debug.getlocal(1,6)
|
||||
assert(x == 'B' and y == 13)
|
||||
end
|
||||
end
|
||||
@@ -458,7 +458,8 @@ local function collectlocals (level)
|
||||
local tab = {}
|
||||
for i = 1, math.huge do
|
||||
local n, v = debug.getlocal(level + 1, i)
|
||||
if not (n and string.find(n, "^[a-zA-Z0-9_]+$")) then
|
||||
if not (n and string.find(n, "^[a-zA-Z0-9_]+$") or
|
||||
n == "(vararg table)") then
|
||||
break -- consider only real variables
|
||||
end
|
||||
tab[n] = v
|
||||
|
||||
@@ -101,6 +101,38 @@ a,b,c,d,e = f(4)
|
||||
assert(a==nil and b==nil and c==nil and d==nil and e==nil)
|
||||
|
||||
|
||||
do -- vararg expressions using unpack
|
||||
local function aux (a, v, ...t)
|
||||
for k, val in pairs(v) do t[k] = val end
|
||||
return ...
|
||||
end
|
||||
|
||||
local t = table.pack(aux(10, {11, [5] = 24}, 1, 2, 3, nil, 4))
|
||||
assert(t.n == 5 and t[1] == 11 and t[2] == 2 and t[3] == 3
|
||||
and t[4] == nil and t[5] == 24)
|
||||
|
||||
local t = table.pack(aux(nil, {1, [20] = "a", [30] = "b", n = 30}))
|
||||
assert(t.n == 30 and t[1] == 1 and t[20] == "a" and t[30] == "b")
|
||||
-- table has only those four elements
|
||||
assert(next(t, next(t, next(t, next(t, next(t, nil))))) == nil)
|
||||
|
||||
local a, b, c, d = aux(nil, {}, 10, 20, 30)
|
||||
assert(a == 10 and b == 20 and c == 30 and d == nil)
|
||||
|
||||
local function aux (a, b, n, ...t) t.n = n; return b, ... end
|
||||
local t = table.pack(aux(10, 1, 10000))
|
||||
assert(t.n == 10001 and t[1] == 1 and #t == 1)
|
||||
|
||||
local function checkerr (emsg, f, ...)
|
||||
local st, msg = pcall(f, ...)
|
||||
assert(not st and string.find(msg, emsg))
|
||||
end
|
||||
checkerr("no proper 'n'", aux, 1, 1, -1)
|
||||
checkerr("no proper 'n'", aux, 1, 1, math.maxinteger)
|
||||
checkerr("no proper 'n'", aux, 1, 1, math.mininteger)
|
||||
checkerr("no proper 'n'", aux, 1, 1, 1.0)
|
||||
end
|
||||
|
||||
-- varargs for main chunks
|
||||
local f = assert(load[[ return {...} ]])
|
||||
local x = f(2,3)
|
||||
@@ -205,6 +237,7 @@ do -- access to vararg parameter
|
||||
assert(t[k] == v[k])
|
||||
end
|
||||
assert(t.n == v.n)
|
||||
return ...
|
||||
end
|
||||
|
||||
local t = table.pack(10, 20, 30)
|
||||
|
||||
Reference in New Issue
Block a user