Optimization for vararg tables
A vararg table can be virtual. If the vararg table is used only as a base in indexing expressions, the code does not need to create an actual table for it. Instead, it compiles the indexing expressions into direct accesses to the internal vararg data.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
|
||||
print('testing vararg')
|
||||
|
||||
local function f (a, ...=t)
|
||||
local function f (a, ...|t)
|
||||
local x = {n = select('#', ...), ...}
|
||||
assert(x.n == t.n)
|
||||
for i = 1, x.n do
|
||||
@@ -20,7 +20,7 @@ local function c12 (...)
|
||||
return res, 2
|
||||
end
|
||||
|
||||
local function vararg (...=t) return t end
|
||||
local function vararg (... | t) return t end
|
||||
|
||||
local call = function (f, args) return f(table.unpack(args, 1, args.n)) end
|
||||
|
||||
@@ -153,8 +153,8 @@ end
|
||||
|
||||
|
||||
do -- vararg parameter used in nested functions
|
||||
local function foo (... = tab1)
|
||||
return function (... = tab2)
|
||||
local function foo (... | tab1)
|
||||
return function (... | tab2)
|
||||
return {tab1, tab2}
|
||||
end
|
||||
end
|
||||
@@ -165,16 +165,51 @@ do -- vararg parameter used in nested functions
|
||||
end
|
||||
|
||||
do -- vararg parameter is read-only
|
||||
local st, msg = load("return function (... = t) t = 10 end")
|
||||
local st, msg = load("return function (... | t) t = 10 end")
|
||||
assert(string.find(msg, "const variable 't'"))
|
||||
|
||||
local st, msg = load[[
|
||||
local function foo (... = extra)
|
||||
local function foo (... | extra)
|
||||
return function (...) extra = nil end
|
||||
end
|
||||
]]
|
||||
assert(string.find(msg, "const variable 'extra'"))
|
||||
end
|
||||
|
||||
|
||||
do -- _ENV as vararg parameter
|
||||
local st, msg = load[[
|
||||
local function aux (... | _ENV)
|
||||
global <const> a
|
||||
a = 10
|
||||
end ]]
|
||||
assert(string.find(msg, "const variable 'a'"))
|
||||
end
|
||||
|
||||
|
||||
do -- access to vararg parameter
|
||||
local function notab (keys, t, ... | v)
|
||||
for _, k in pairs(keys) do
|
||||
assert(t[k] == v[k])
|
||||
end
|
||||
assert(t.n == v.n)
|
||||
end
|
||||
|
||||
local t = table.pack(10, 20, 30)
|
||||
local keys = {-1, 0, 1, t.n, t.n + 1, 1.0, 1.1, "n", print, "k", "1"}
|
||||
notab(keys, t, 10, 20, 30) -- ensure stack space
|
||||
local m = collectgarbage"count"
|
||||
notab(keys, t, 10, 20, 30)
|
||||
-- 'notab' does not create any table/object
|
||||
assert(m == collectgarbage"count")
|
||||
|
||||
-- writing to the vararg table
|
||||
local function foo (... | t)
|
||||
t[1] = t[1] + 10
|
||||
return t[1]
|
||||
end
|
||||
assert(foo(10, 30) == 20)
|
||||
end
|
||||
|
||||
print('OK')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user