rvirding / luerl

Lua in Erlang
Apache License 2.0
1.02k stars 140 forks source link

Garbage collector removes environment for functions stored in a table in _G #148

Closed markmeeus closed 9 months ago

markmeeus commented 1 year ago

The following Lua script creates a function and stores that function in a global table rememberedFunctions This anonymous function is created with an environment to hold an argument from the outer function.

code = """
rememberedFunction = {}
function rememberFunction(fun)
  rememberedFunction["myFunction"] = fun
end

function runIt(arg)
  rememberFunction(function()
    return "it " .. arg
  end)
end

runIt("works")
"""

luerl_state = :luerl_sandbox.init()

# run the code
{:ok, [], luerl_state} = :luerl_new.do(code, luerl_state)
# collect garbage
luerl_state = :luerl_new.gc(luerl_state)
# call the function
{:ok, res, _} = :luerl_new.do("return rememberedFunction.myFunction();", luerl_state)
# expect "it works"
IO.inspect({"res:", res})

When calling gc(), the garbage collector removes this env data, when the function is later called the operation push_env_var (to add the arg to the string) it crashes with the following error.

 (KeyError) key 0 not found in: %{}
    :erlang.map_get(0, %{})
    (luerl 1.0.0) /Users/markmeeus/Documents/projects/github/codeinthesky/deps/luerl/src/luerl_heap.erl:97: :luerl_heap.get_env_var/3
    (luerl 1.0.0) /Users/markmeeus/Documents/projects/github/codeinthesky/deps/luerl/src/luerl_emul.erl:378: :luerl_emul.emul_1/7
    (luerl 1.0.0) /Users/markmeeus/Documents/projects/github/codeinthesky/deps/luerl/src/luerl_emul.erl:319: :luerl_emul.functioncall/3
rvirding commented 1 year ago

This is a tricky one. I will try to find out what is going on here and fix it. What I don't straight off understand why it hasn't been detected earlierl

rvirding commented 10 months ago

@markmeeus It took a while, quite a while actually, but this has now been fixed. It in the latest commit to develop, d70abaa. At least you example code runs.

markmeeus commented 10 months ago

That's great! Thanks.