aboutsummaryrefslogtreecommitdiff
path: root/testes
diff options
context:
space:
mode:
authorRoberto I <roberto@inf.puc-rio.br>2025-09-24 18:33:08 -0300
committerRoberto I <roberto@inf.puc-rio.br>2025-09-24 18:33:08 -0300
commit25c54fe60e22d05cdfaa48c64372d354efa59547 (patch)
tree3ccaeded5e4363db358f73b7c8fc6b9f414a2f2a /testes
parent0cc3c9447cca9abae9738ee77c24d88801c3916c (diff)
downloadlua-25c54fe60e22d05cdfaa48c64372d354efa59547.tar.gz
lua-25c54fe60e22d05cdfaa48c64372d354efa59547.tar.bz2
lua-25c54fe60e22d05cdfaa48c64372d354efa59547.zip
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.
Diffstat (limited to 'testes')
-rw-r--r--testes/locals.lua6
-rw-r--r--testes/vararg.lua47
2 files changed, 43 insertions, 10 deletions
diff --git a/testes/locals.lua b/testes/locals.lua
index 02f41980..5222802f 100644
--- a/testes/locals.lua
+++ b/testes/locals.lua
@@ -310,8 +310,7 @@ do -- testing presence of second argument
310 local function foo (howtoclose, obj, n) 310 local function foo (howtoclose, obj, n)
311 local ca -- copy of 'a' visible inside its close metamethod 311 local ca -- copy of 'a' visible inside its close metamethod
312 do 312 do
313 local a <close> = func2close(function (...) 313 local a <close> = func2close(function (... | t)
314 local t = table.pack(...)
315 assert(select("#", ...) == n) 314 assert(select("#", ...) == n)
316 assert(t.n == n and t[1] == ca and (t.n < 2 or t[2] == obj)) 315 assert(t.n == n and t[1] == ca and (t.n < 2 or t[2] == obj))
317 ca = 15 -- final value to be returned if howtoclose=="scope" 316 ca = 15 -- final value to be returned if howtoclose=="scope"
@@ -911,8 +910,7 @@ do
911 910
912 local extrares -- result from extra yield (if any) 911 local extrares -- result from extra yield (if any)
913 912
914 local function check (body, extra, ...) 913 local function check (body, extra, ...|t)
915 local t = table.pack(...) -- expected returns
916 local co = coroutine.wrap(body) 914 local co = coroutine.wrap(body)
917 if extra then 915 if extra then
918 extrares = co() -- runs until first (extra) yield 916 extrares = co() -- runs until first (extra) yield
diff --git a/testes/vararg.lua b/testes/vararg.lua
index 92f720cb..5711f78b 100644
--- a/testes/vararg.lua
+++ b/testes/vararg.lua
@@ -3,7 +3,7 @@
3 3
4print('testing vararg') 4print('testing vararg')
5 5
6local function f (a, ...=t) 6local function f (a, ...|t)
7 local x = {n = select('#', ...), ...} 7 local x = {n = select('#', ...), ...}
8 assert(x.n == t.n) 8 assert(x.n == t.n)
9 for i = 1, x.n do 9 for i = 1, x.n do
@@ -20,7 +20,7 @@ local function c12 (...)
20 return res, 2 20 return res, 2
21end 21end
22 22
23local function vararg (...=t) return t end 23local function vararg (... | t) return t end
24 24
25local call = function (f, args) return f(table.unpack(args, 1, args.n)) end 25local call = function (f, args) return f(table.unpack(args, 1, args.n)) end
26 26
@@ -153,8 +153,8 @@ end
153 153
154 154
155do -- vararg parameter used in nested functions 155do -- vararg parameter used in nested functions
156 local function foo (... = tab1) 156 local function foo (... | tab1)
157 return function (... = tab2) 157 return function (... | tab2)
158 return {tab1, tab2} 158 return {tab1, tab2}
159 end 159 end
160 end 160 end
@@ -165,16 +165,51 @@ do -- vararg parameter used in nested functions
165end 165end
166 166
167do -- vararg parameter is read-only 167do -- vararg parameter is read-only
168 local st, msg = load("return function (... = t) t = 10 end") 168 local st, msg = load("return function (... | t) t = 10 end")
169 assert(string.find(msg, "const variable 't'")) 169 assert(string.find(msg, "const variable 't'"))
170 170
171 local st, msg = load[[ 171 local st, msg = load[[
172 local function foo (... = extra) 172 local function foo (... | extra)
173 return function (...) extra = nil end 173 return function (...) extra = nil end
174 end 174 end
175 ]] 175 ]]
176 assert(string.find(msg, "const variable 'extra'")) 176 assert(string.find(msg, "const variable 'extra'"))
177end 177end
178 178
179
180do -- _ENV as vararg parameter
181 local st, msg = load[[
182 local function aux (... | _ENV)
183 global <const> a
184 a = 10
185 end ]]
186 assert(string.find(msg, "const variable 'a'"))
187end
188
189
190do -- access to vararg parameter
191 local function notab (keys, t, ... | v)
192 for _, k in pairs(keys) do
193 assert(t[k] == v[k])
194 end
195 assert(t.n == v.n)
196 end
197
198 local t = table.pack(10, 20, 30)
199 local keys = {-1, 0, 1, t.n, t.n + 1, 1.0, 1.1, "n", print, "k", "1"}
200 notab(keys, t, 10, 20, 30) -- ensure stack space
201 local m = collectgarbage"count"
202 notab(keys, t, 10, 20, 30)
203 -- 'notab' does not create any table/object
204 assert(m == collectgarbage"count")
205
206 -- writing to the vararg table
207 local function foo (... | t)
208 t[1] = t[1] + 10
209 return t[1]
210 end
211 assert(foo(10, 30) == 20)
212end
213
179print('OK') 214print('OK')
180 215