lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I am the developer of SilverLua (http://silverlua.codeplex.com/), an
implementation of Lua for XNA Game Studio projects on Xbox 360. For
various reasons that are irrelevant to this discussion, I am not
performing a direct port of the official C implementation, nor do I
have the liberty of looking at the source code. The entire thing is
being written from scratch by me. I'm currently working on
implementing closures, and I ran into a corner case that has me a bit
puzzled.

Below is a fairly standard example of the use of closures in Lua:

function closure_creator()
  local num = 0
  return function()
    num = num + 1
    print(num)
  end
end
closure_creator()() -- prints 1
closure_creator()() -- prints 1
local closure = closure_creator()
closure() -- prints 1
closure() -- prints 2

So the local variable "num" is acknowledged as an upvalue for the
inner function when the inner function gets created. However, I have
managed to create a more convoluted example that confuses me a bit:

local closure_creator
function create_closure_creator()
  local num = 0
  closure_creator = function()
    return function()
      num = num + 1
      print(num)
    end
  end
end
create_closure_creator()
closure_creator()() -- prints 1
closure_creator()() -- prints 2
local closure = closure_creator()
closure() -- prints 3
closure() -- prints 4

The difference is that the variable "num" is not a local variable to
"closure_creator". Rather, it is local to an outer scope and
recognized as an upvalue for "closure_creator", which means a new
instance of it is not instantiated on every call to "closure_creator".
This implies that the Lua compiler is aware that "closure_creator"
uses "num", even though the use is itself contained within another
lexical scope (the innermost function).

How, precisely, does Lua determine which upvalues to assign to each
closure? Are upvalue references simply propagated up through nested
functions?