Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix luerl_new:decode returning incorrect state #191

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from

Conversation

davydog187
Copy link
Collaborator

@davydog187 davydog187 commented Oct 22, 2024

Callbacks passed to functions implemented in Erlang as erl_func and the likes were not updating state correctly. It turns out that this issue is caused by decoded funref's closing over the wrong State variable.

For example, imagine the following Lua program

globalVar = "before"

function modify_global()
  globalVar = "after"
end

external_call(modify_global)

return globalVar

external_call is a function implemented in Erlang as

ExternalFun = fun([Fun], S) ->
    {FunRef, NewState1} = luerl_new:encode(Fun, S),
    {ok, Res, NewState2} = luerl_new:call(FunRef, [], NewState1),
    {Res, NewState2}
end,

State = luerl_new:init(),
{ok, [], State1} = luerl_new:set_table_keys_dec([<<"external_call">>], ExternalFun, State),

This program returns

% Expected
["after"]

% Actual
["before"]
  • Write a test case that reproduces the problem
  • Fix the root cause
  • Implement for luerl interface

@davydog187
Copy link
Collaborator Author

I should note that the same issue happens if globalVar is an integer instead of a table

Callbacks passed to functions implemented in Erlang as `erl_func` in the
likes were not updating state correctly.

For example, imagine the following Lua program

```lua
globalVar = { a = 1 }

function modify_global()
  globalVar['b'] = 2
end

external_call(modify_global)

return globalVar
```

`external_call` is a function implemented in Erlang as

```erlang
ExternalFun = fun([Fun], S) ->
    {FunRef, NewState1} = luerl_new:encode(Fun, S),
    io:format("Function ref: ~p~n", [FunRef]),

    {ok, Res, NewState2} = luerl_new:call(FunRef, [], NewState1),
    {Res, NewState2}
end,

State = luerl_new:init(),
{ok, [], State1} = luerl_new:set_table_keys_dec([<<"external_call">>], ExternalFun, State),
```

This program returns

```erlang
% Expected
[[{<<"a">>, 1}, {<<"b">>, 2}]]

% Actual
[[{<<"a">>, 1}}]]
```

- [X] Write a test case that reproduces the problem
- [ ] Fix the root cause
davydog187 added a commit to tv-labs/lua that referenced this pull request Oct 22, 2024
This tracks rvirding/luerl#191 which fixes a
decoder bug causing state issues when mixing Elixir and Lua functions.
@davydog187 davydog187 changed the title Fix callbacks not modifying Luerl state Fix luerl_new:decode returning incorrect state Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant