[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Upcoming changes in Lua 5.4
- From: "Soni \"They/Them\" L." <fakedme@...>
- Date: Sun, 21 Jan 2018 13:10:35 -0200
On 2018-01-21 09:53 AM, Philipp Janda wrote:
Am 09.01.2018 um 00:26 schröbte Paige DePol:
Roberto Ierusalimschy <roberto@inf.puc-rio.br> wrote:
One thing I am curious about, Roberto, is the creation of tables to
hold the
vargs. Won't this add significant overhead for the table
allocations vs just
leaving the vargs on the stack?
That was the motivation for stack varargs. But "significant" is quite
relative. Moreover, stack varargs add an overhead (a quite small
one, but
it is not zero) to all functions, even those not varargs. We do not see
vararg functions in critical paths often. Several (most?) vararg
functions
have to create tables (or pay the price of 'select') anyway.
More important, table is the bread-and-butter of Lua. If we start to
demonise them, we are left with little else.
-- Roberto
Very good point about tables, Roberto! I would guess that anyone looking
for performance probably wouldn't be using varargs on critical paths
anyway.
Or resort to C for avoiding the extra memory allocation (or addressing
other performance concerns).
One other thing I wanted to point out (which is related to the array
discussion in another thread):
I find it unfortunate that Lua needs two different array
implementations in its tiny standard library -- one convenient but
limited one (sequences), and a more powerful but inconvenient one
(vararg tables). Now it looks like both implementations will even end
up in the Lua core. Since we apparently can't agree on a single
implementation that will cover all needs, may I propose that the table
library also work for vararg tables in addition to sequences? It seems
strange that the inconvenient array type doesn't have any support
functions in the standard library, and especially inserting or
removing elements are things you might want to do to vararg tables.
Philipp
p.s.: If the concept of n fields of vararg tables ends up in the Lua
core, the length operator could (raw-)inspect n as well. Maybe in time
most Lua code would be able to handle both array types without extra
effort. But that is a proposal for another time.
function push(_ARGS, extra)
return (function(...)
return _ARGS
end)(extra, ...)
end
function pop(_ARGS, extra)
return (function(x, ...)
return _ARGS, x
end)(...)
end
Since tables and varargs are now one and the same, and ... unpacks
varargs at the bytecode level, this makes extremely fast push and pop
functions (as long as you're ok with things like "t = push(t, extra)",
which when using recursion is trivial).
If Lua had function folding (i.e. -O3) and a better bytecode, this could
be made very efficient. Since Lua bytecode is already not sandbox-safe
(there's no validation done on it, and it can and will cause UB (in the
C way) if used incorrectly), there's no reason why we can't have a more
efficient bytecode (besides the debug library, I guess... or do I?).
On that note, indeed, this shouldn't require bytecode manipulation:
https://gist.github.com/corsix/6575486 you just need to be able to
convince something to corrupt the for loop variables in just the right way:
$ lua5.2
Lua 5.2.4 Copyright (C) 1994-2015 Lua.org, PUC-Rio
> local x = print local first = true for i=1, 1, 0 do if first then
debug.setlocal(1, 3, x) debug.setlocal(1, 4, x) first=false else
print(i) break end end
2.1239131134934e-317
> local x = print local first = true for i=1, 1, 0 do if first then
debug.setlocal(1, 3, x) debug.setlocal(1, 4, x) first=false else
print(i) break end end
2.1239131134934e-317
> local x = print local first = true for i=1, 1, 0 do if first then
debug.setlocal(1, 3, x) debug.setlocal(1, 4, x) first=false else
print(i) break end end
2.1239131134934e-317
> local x = {} local first = true for i=1, 1, 0 do if first then
debug.setlocal(1, 3, x) debug.setlocal(1, 4, x) first=false else
print(i) break end end
1.1483223936599e-316
> local x = {} local first = true for i=1, 1, 0 do if first then
debug.setlocal(1, 3, x) debug.setlocal(1, 4, x) first=false else
print(i) break end end
1.1484615225457e-316
> local x = {} local first = true for i=1, 1, 0 do if first then
debug.setlocal(1, 3, x) debug.setlocal(1, 4, x) first=false else
print(i) break end end
1.1485982799165e-316
>
--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.