lua-users home
lua-l archive

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


> Sorry, I read the callTM function's source code for several times,
> but still don't quite understand the example "entering a Lua funcion
> and then calling a metamethod".
> Will it generates invalid value under L->top ?
> If it does, why only do the clear during atomic phase ?
> Would you give me more detail, thank you very much.

When entering a Lua function, Lua adds to L->top the stack size it needs
(that is, it allocates an "activation record" for the function), without
clearing that space. Usually, Lua uses this space in a stack discipline,
but sometimes (e.g., when calling a metamethod), it pushes values
after this activation record. That means that, when the gc runs,
the entire activation record must have valid values, as the gc
has no means to know what parts are being used.

We could clear the entire activation record each time we call a
function, but that would be expensive. It is cheaper to clear it only
on the atomic phase. It is safe to clear it only in the atomic phase
because, before that, no value can be collected. So, whatever *garbage"
exists in those unused slots, they are valid values. Only when we are
about to start sweeping (and, therfore, actually invalidating values) we
need to clear that to ensure that it still contains only vaild values.

Note that scheme is conservative. Sometimes things can stay longer
than necessary in the stack, because Lua only clears the activation
record of the currently active function (the last in the stack).
Other values (in "inner" activation records) can be kept alive longer.
See the next example:

local x = setmetatable({}, {__index = function ()
  collectgarbage(); print(1) end})
local a, b, c, d, e
do
  local t = setmetatable({}, {__gc = function () print("hi") end})
end

print(x[1])       -- should collect 't', but it doesn't
print(2)
collectgarbage()  -- now it collects 't'
print(3)


-- Roberto