[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Iterate over vararg
- From: Andrew Gierth <andrew@...>
- Date: Thu, 20 Dec 2018 11:55:47 +0000
>>>>> "Gabriel" == Gabriel Bertilson <arboreous.philologist@gmail.com> writes:
Gabriel> I guess without a table, the arguments can be stored as
Gabriel> upvalues. The following makes an iterator generator that sets
Gabriel> its arguments as upvalues to a closure, with the total number
Gabriel> of upvalues as the first upvalue. (Is there a way to avoid
Gabriel> that first upvalue?)
Yes. Quoth the docs (for 5.3 at least):
The first upvalue associated with a function is at index
lua_upvalueindex(1), and so on. Any access to lua_upvalueindex(n),
where n is greater than the number of upvalues of the current
function (but not greater than 256, which is one plus the maximum
number of upvalues in a closure), produces an acceptable but invalid
index.
This means that if there are n upvalues, then lua_upvalueindex(n+1) is
always an acceptable index, which means it's safe to call lua_type on
it, which will return LUA_TNONE since it's an invalid index. Whereas
upvalues 1..n will have types other than LUA_TNONE.
Gabriel> Then the closure receives an unused first argument and a
Gabriel> second argument i, and it returns the i-plus-one-th argument
Gabriel> to the original function (similar to the behavior of the
Gabriel> function returned by ipairs). Not sure if this is more or less
Gabriel> efficient memory-wise than using a table.
I don't see any obvious reason why it would be more efficient - creating
the closure is allocating an object, after all, and it seems that
closures with upvalues probably would be more overhead than tables. But
I've not tried it.
--
Andrew.