diff --git a/src/luerl.erl b/src/luerl.erl index aebcd35..f86509a 100644 --- a/src/luerl.erl +++ b/src/luerl.erl @@ -403,11 +403,11 @@ decode(#tref{}=T, St, In) -> decode_table(T, St, In); decode(#usdref{}=U, St, _) -> decode_userdata(U, St); -decode(#funref{}=Fun, State, _) -> - F = fun(Args) -> +decode(#funref{}=Fun, _, _) -> + F = fun(Args, State) -> {Args1, State1} = encode_list(Args, State), {Ret, State2} = luerl_emul:functioncall(Fun, Args1, State1), - decode_list(Ret, State2) + {decode_list(Ret, State2), State2} end, F; %Just a bare fun decode(#erl_func{code=Fun}, _, _) -> Fun; diff --git a/src/luerl_new.erl b/src/luerl_new.erl index 22185b1..3649c2c 100644 --- a/src/luerl_new.erl +++ b/src/luerl_new.erl @@ -423,11 +423,11 @@ decode(#tref{}=T, St, In) -> decode_table(T, St, In); decode(#usdref{}=U, St, _) -> decode_userdata(U, St); -decode(#funref{}=Fun, State, _) -> - F = fun(Args) -> +decode(#funref{}=Fun, _, _) -> + F = fun(Args, State) -> {Args1, State1} = encode_list(Args, State), {Ret, State2} = luerl_emul:functioncall(Fun, Args1, State1), - decode_list(Ret, State2) + {decode_list(Ret, State2), State2} end, F; %Just a bare fun decode(#erl_func{code=Fun}, _, _) -> Fun; diff --git a/test/luerl_funcall_tests.erl b/test/luerl_funcall_tests.erl index 5b37c13..2d85b9e 100644 --- a/test/luerl_funcall_tests.erl +++ b/test/luerl_funcall_tests.erl @@ -67,11 +67,11 @@ define_fun_in_lua_test() -> " end\n" "end\n">>, {_, State1} = luerl:do(Chunk, State), - {[Fun], _State2} = luerl:call_function([mkadder], [1], State1), - {[Fun2], _State3} = luerl:call_function([mkadder], [2], State1), - ?assertEqual([5], Fun([4])), - ?assertEqual([5.0], Fun([4.0])), - ?assertEqual([6], Fun2([4])). + {[Fun], State2} = luerl:call_function([mkadder], [1], State1), + {[Fun2], State3} = luerl:call_function([mkadder], [2], State2), + ?assertMatch({[5], _State}, Fun([4], State3)), + ?assertMatch({[5.0], _State}, Fun([4.0], State3)), + ?assertMatch({[6], _State}, Fun2([4], State3)). define_fun2_in_lua_test() -> State = luerl:init(), @@ -85,15 +85,15 @@ define_fun2_in_lua_test() -> " end\n" "end\n">>, {_, State1} = luerl:do(Chunk, State), - {[Fun], _State2} = luerl:call_function([mklist], [5], State1), - {[Fun2], _State3} = luerl:call_function([mklist], [10], State1), - ?assertEqual([[{1,4}, {2,4}, {3,4}, {4,4}, {5,4}]], - Fun([4])), - ?assertEqual([[{1,4.0}, {2,4.0}, {3,4.0}, {4,4.0}, {5,4.0}]], - Fun([4.0])), - ?assertEqual([[{1,4}, {2,4}, {3,4}, {4,4}, {5,4}, - {6,4}, {7,4}, {8,4}, {9,4}, {10,4}]], - Fun2([4])). + {[Fun], State2} = luerl:call_function([mklist], [5], State1), + {[Fun2], State3} = luerl:call_function([mklist], [10], State2), + ?assertMatch({[[{1,4}, {2,4}, {3,4}, {4,4}, {5,4}]], _State}, + Fun([4], State3)), + ?assertMatch({[[{1,4.0}, {2,4.0}, {3,4.0}, {4,4.0}, {5,4.0}]], _State}, + Fun([4.0], State3)), + ?assertMatch({[[{1,4}, {2,4}, {3,4}, {4,4}, {5,4}, + {6,4}, {7,4}, {8,4}, {9,4}, {10,4}]], _State}, + Fun2([4], State3)). newindex_metamethod_test() -> State = luerl:init(), diff --git a/test/luerl_new_tests.erl b/test/luerl_new_tests.erl index 17c647a..f076989 100644 --- a/test/luerl_new_tests.erl +++ b/test/luerl_new_tests.erl @@ -2,6 +2,31 @@ -include_lib("eunit/include/eunit.hrl"). +external_modify_global_test() -> + % put(luerl_itrace, true), + State = luerl_new:init(), + + ExternalFun = fun([Fun], S) -> + {FunRef, NewState1} = luerl_new:encode(Fun, S), + + {ok, Res, NewState2} = luerl_new:call(FunRef, [], NewState1), + {Res, NewState2} + end, + + {ok, [], State1} = luerl_new:set_table_keys_dec([<<"external_call">>], ExternalFun, State), + + % Define a Lua function that modifies a global variable 'globalVar' + LuaChunk = <<"globalVar = 'before'\n" + "function modify_global(args)\n" + " globalVar = 'after'\n" + "end\n" + "external_call(modify_global)\n" % Pass the function reference + "return globalVar\n">>, + + {ok, Res, _State2} = luerl_new:do_dec(LuaChunk, State1), + + ?assertEqual([<<"after">>], Res). + encode_test() -> State = luerl_new:init(), ?assertMatch({nil, _State}, luerl_new:encode(nil, State)), diff --git a/test/luerl_tests.erl b/test/luerl_tests.erl index 624d95c..73040bf 100644 --- a/test/luerl_tests.erl +++ b/test/luerl_tests.erl @@ -2,6 +2,31 @@ -include_lib("eunit/include/eunit.hrl"). +external_modify_global_test() -> + % put(luerl_itrace, true), + State = luerl:init(), + + ExternalFun = fun([Fun], S) -> + {FunRef, NewState1} = luerl:encode(Fun, S), + + { Res, NewState2} = luerl:call(FunRef, [], NewState1), + {Res, NewState2} + end, + + State1 = luerl:set_table([<<"external_call">>], ExternalFun, State), + + % Define a Lua function that modifies a global variable 'globalVar' + LuaChunk = <<"globalVar = 'before'\n" + "function modify_global(args)\n" + " globalVar = 'after'\n" + "end\n" + "external_call(modify_global)\n" % Pass the function reference + "return globalVar\n">>, + + {Res, _State2} = luerl:do(LuaChunk, State1), + + ?assertEqual([<<"after">>], Res). + encode_test() -> State = luerl:init(), ?assertMatch({nil, _State}, luerl:encode(nil, State)),