[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Size of a non numerical indexed table
- From: Mike Pall <mikelu-0509@...>
- Date: Thu, 1 Sep 2005 19:35:15 +0200
David Given wrote:
> How does ... work, anyway? Does it actually *copy* the data from its original
> place on the stack, or does it do something smarter?
The call frame for a fixarg function looks like this:
ci->func --> func
ci->base --> fixargs
The call frame for a vararg function in Lua 5.1 looks like this:
ci->func --> func
ci->base --> moved fixargs
When calling a vararg function the fixargs are moved upwards after
the last vararg. The remaining gap is cleared with nils (closing
that gap wouldn't pay off since most vararg functions have only
very few fixargs). The varargs themselves are not moved.
Evaluating ... aka OP_VARARG _does_ copy the varargs up to new stack
slots, i.e. f(...) copies them once.
Tailcalls (return f(...)) or vararg returns (return ...) effectively
copy them twice because the slots need to be moved down, too.
> I ask because I found an interesting idiom recently for doing work with large
> amounts of constant data --- it was while writing the BF compiler, oddly
> enough --- reminiscent of some of the structures used in functional
> programming languages:
> function process(item1, item2, ...)
> dosomethingwith(item1, item2)
> return process(...)
This will copy them twice on each recursion. The maximum needed
stack space is twice the number of fixargs+varargs (plus other
overhead) since you are using a tail call.
A similar idiom can be used to both capture and pass on a variable
number of _return_ values:
local function helper(ok, ...)
if not ok then print("ERROR:", ...) end
return ok, ...
local function printpcall(...) -- Dito for coroutine.resume().
I guess in practice most varargs will have less than 10 elements
on average. I wouldn't worry too much about efficiency then.
A table would be more appropriate in case one wants to pass
hundreds or thousands of objects as varargs.