diff --git a/rebar.config b/rebar.config index e399269..07f9c84 100644 --- a/rebar.config +++ b/rebar.config @@ -2,7 +2,7 @@ {erl_opts, [debug_info]}. -{deps, [ {aebytecode, {git, "https://github.com/aeternity/aebytecode.git", {ref,"3954bd2"}}} +{deps, [ {aebytecode, {git, "https://github.com/aeternity/aebytecode.git", {ref,"fdd660a"}}} , {getopt, "1.0.1"} , {eblake2, "1.0.0"} , {jsx, {git, "https://github.com/talentdeficit/jsx.git", diff --git a/rebar.lock b/rebar.lock index f0dfdfa..39c6dc1 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,7 +1,7 @@ {"1.1.0", [{<<"aebytecode">>, {git,"https://github.com/aeternity/aebytecode.git", - {ref,"3954bd22daa24d4a82a8349325d115cd7b7d1750"}}, + {ref,"fdd660a2191f19e1bd77cafe0d39c826539c1b6c"}}, 0}, {<<"aeserialization">>, {git,"https://github.com/aeternity/aeserialization.git", diff --git a/src/aeso_ast_to_fcode.erl b/src/aeso_ast_to_fcode.erl index 4572b02..c8e8cda 100644 --- a/src/aeso_ast_to_fcode.erl +++ b/src/aeso_ast_to_fcode.erl @@ -50,7 +50,7 @@ | nil | {var, var_name()} | {def, fun_name(), [fexpr()]} - | {remote, fexpr(), fun_name(), [fexpr()]} + | {remote, [ftype()], ftype(), fexpr(), fun_name(), [fexpr()]} | {builtin, builtin(), [fexpr()]} | {con, arities(), tag(), [fexpr()]} | {tuple, [fexpr()]} @@ -65,7 +65,7 @@ %% lambdas) are generated by the fcode compiler, but translated %% to closures by the lambda lifter. | {def_u, fun_name(), arity()} - | {remote_u, fexpr(), fun_name(), arity()} + | {remote_u, [ftype()], ftype(), fexpr(), fun_name()} | {builtin_u, builtin(), arity()} | {lam, [var_name()], fexpr()}. @@ -405,9 +405,10 @@ expr_to_fcode(Env, Type, {proj, _Ann, Rec = {typed, _, _, RecType}, {id, _, X}}) {con, _, _} when X == "address" -> {op, contract_to_address, [expr_to_fcode(Env, Rec)]}; {con, _, _} -> - {fun_t, _, Named, Args, _} = Type, - Arity = length(Named) + length(Args), - {remote_u, expr_to_fcode(Env, Rec), {entrypoint, list_to_binary(X)}, Arity}; + {fun_t, _, _, Args, Ret} = Type, + FArgs = [type_to_fcode(Env, Arg) || Arg <- Args], + {remote_u, FArgs, type_to_fcode(Env, Ret), expr_to_fcode(Env, Rec), + {entrypoint, list_to_binary(X)}}; {record_t, _} -> {proj, expr_to_fcode(Env, Rec), field_index(Rec, X)} end; @@ -521,7 +522,7 @@ expr_to_fcode(Env, Type, {app, _Ann, Fun = {typed, _, _, {fun_t, _, NamedArgsT, builtin_to_fcode(B, FArgs ++ TypeArgs); {builtin_u, B, _Ar} -> builtin_to_fcode(B, FArgs); {def_u, F, _Ar} -> {def, F, FArgs}; - {remote_u, Ct, RFun, _Ar} -> {remote, Ct, RFun, FArgs}; + {remote_u, ArgsT, RetT, Ct, RFun} -> {remote, ArgsT, RetT, Ct, RFun, FArgs}; FFun -> %% FFun is a closure, with first component the function name and %% second component the environment @@ -944,12 +945,13 @@ lambda_lift_expr({Tag, F, Ar}) when Tag == def_u; Tag == builtin_u -> def_u -> {def, F, Args} end, make_closure([], Xs, Body); -lambda_lift_expr({remote_u, Ct, F, Ar}) -> +lambda_lift_expr({remote_u, ArgsT, RetT, Ct, F}) -> FVs = free_vars(Ct), Ct1 = lambda_lift_expr(Ct), - Xs = [ lists:concat(["arg", I]) || I <- lists:seq(1, Ar) ], + GasAndValueArgs = 2, + Xs = [ lists:concat(["arg", I]) || I <- lists:seq(1, length(ArgsT) + GasAndValueArgs) ], Args = [{var, X} || X <- Xs], - make_closure(FVs, Xs, {remote, Ct1, F, Args}); + make_closure(FVs, Xs, {remote, ArgsT, RetT, Ct1, F, Args}); lambda_lift_expr(Expr) -> case Expr of {lit, _} -> Expr; @@ -958,7 +960,7 @@ lambda_lift_expr(Expr) -> {closure, _, _} -> Expr; {def, D, As} -> {def, D, lambda_lift_exprs(As)}; {builtin, B, As} -> {builtin, B, lambda_lift_exprs(As)}; - {remote, Ct, F, As} -> {remote, lambda_lift_expr(Ct), F, lambda_lift_exprs(As)}; + {remote, ArgsT, RetT, Ct, F, As} -> {remote, ArgsT, RetT, lambda_lift_expr(Ct), F, lambda_lift_exprs(As)}; {con, Ar, C, As} -> {con, Ar, C, lambda_lift_exprs(As)}; {tuple, As} -> {tuple, lambda_lift_exprs(As)}; {proj, A, I} -> {proj, lambda_lift_expr(A), I}; @@ -1153,8 +1155,8 @@ free_vars(Expr) -> nil -> []; {def, _, As} -> free_vars(As); {def_u, _, _} -> []; - {remote, Ct, _, As} -> free_vars([Ct | As]); - {remote_u, Ct, _, _} -> free_vars(Ct); + {remote, _, _, Ct, _, As} -> free_vars([Ct | As]); + {remote_u, _, _, Ct, _} -> free_vars(Ct); {builtin, _, As} -> free_vars(As); {builtin_u, _, _} -> []; {con, _, _, As} -> free_vars(As); @@ -1197,8 +1199,8 @@ rename(Ren, Expr) -> {def_u, _, _} -> Expr; {builtin, B, Es} -> {builtin, B, [rename(Ren, E) || E <- Es]}; {builtin_u, _, _} -> Expr; - {remote, Ct, F, Es} -> {remote, rename(Ren, Ct), F, [rename(Ren, E) || E <- Es]}; - {remote_u, Ct, F, Ar} -> {remote_u, rename(Ren, Ct), F, Ar}; + {remote, ArgsT, RetT, Ct, F, Es} -> {remote, ArgsT, RetT, rename(Ren, Ct), F, [rename(Ren, E) || E <- Es]}; + {remote_u, ArgsT, RetT, Ct, F} -> {remote_u, ArgsT, RetT, rename(Ren, Ct), F}; {con, Ar, I, Es} -> {con, Ar, I, [rename(Ren, E) || E <- Es]}; {tuple, Es} -> {tuple, [rename(Ren, E) || E <- Es]}; {proj, E, I} -> {proj, rename(Ren, E), I}; @@ -1412,10 +1414,10 @@ pp_fexpr({builtin_u, B, N}) -> pp_beside([pp_text(B), pp_text("/"), pp_text(N)]); pp_fexpr({builtin, B, As}) -> pp_call(pp_text(B), As); -pp_fexpr({remote_u, Ct, Fun, Ar}) -> - pp_beside([pp_fexpr(Ct), pp_text("."), pp_fun_name(Fun), pp_text("/"), pp_int(Ar)]); -pp_fexpr({remote, Ct, Fun, As}) -> - pp_call(pp_beside([pp_fexpr(Ct), pp_text("."), pp_fun_name(Fun)]), As); +pp_fexpr({remote_u, ArgsT, RetT, Ct, Fun}) -> + pp_beside([pp_fexpr(Ct), pp_text("."), pp_fun_name(Fun), pp_text(" : "), pp_ftype({function, ArgsT, RetT})]); +pp_fexpr({remote, ArgsT, RetT, Ct, Fun, As}) -> + pp_call(pp_parens(pp_beside([pp_fexpr(Ct), pp_text("."), pp_fun_name(Fun), pp_text(" : "), pp_ftype({function, ArgsT, RetT})])), As); pp_fexpr({funcall, Fun, As}) -> pp_call(pp_fexpr(Fun), As); pp_fexpr({switch, Split}) -> pp_split(Split). diff --git a/src/aeso_fcode_to_fate.erl b/src/aeso_fcode_to_fate.erl index 5dc930f..d7a88e3 100644 --- a/src/aeso_fcode_to_fate.erl +++ b/src/aeso_fcode_to_fate.erl @@ -328,17 +328,19 @@ to_scode(Env, {funcall, Fun, Args}) -> to_scode(Env, {builtin, B, Args}) -> builtin_to_scode(Env, B, Args); -to_scode(Env, {remote, Ct, Fun, [{builtin, call_gas_left, _}, Value | Args]}) -> - %% Gas is not limited. - Lbl = make_function_id(Fun), - Call = aeb_fate_ops:call_r(?a, Lbl, length(Args), ?a), %% No remote tail calls - call_to_scode(Env, Call, [Ct, Value | Args]); - -to_scode(Env, {remote, Ct, Fun, [Gas, Value | Args]}) -> - %% Gas is limited. +to_scode(Env, {remote, ArgsT, RetT, Ct, Fun, [Gas, Value | Args]}) -> Lbl = make_function_id(Fun), - Call = aeb_fate_ops:call_gr(?a, Lbl, length(Args), ?a, ?a), %% No remote tail calls - call_to_scode(Env, Call, [Ct, Value, Gas | Args]); + {ArgTypes, RetType0} = typesig_to_scode([{"_", T} || T <- ArgsT], RetT), + ArgType = ?i(aeb_fate_data:make_typerep({tuple, ArgTypes})), + RetType = ?i(aeb_fate_data:make_typerep(RetType0)), + case Gas of + {builtin, call_gas_left, _} -> + Call = aeb_fate_ops:call_r(?a, Lbl, ArgType, RetType, ?a), + call_to_scode(Env, Call, [Ct, Value | Args]); + _ -> + Call = aeb_fate_ops:call_gr(?a, Lbl, ArgType, RetType, ?a, ?a), + call_to_scode(Env, Call, [Ct, Value, Gas | Args]) + end; to_scode(Env, {closure, Fun, FVs}) -> to_scode(Env, {tuple, [{lit, {string, make_function_id(Fun)}}, FVs]}); @@ -745,8 +747,8 @@ attributes(I) -> 'RETURN' -> Impure(pc, []); {'RETURNR', A} -> Impure(pc, A); {'CALL', _} -> Impure(?a, []); - {'CALL_R', A, _, _, B} -> Impure(?a, [A, B]); - {'CALL_GR', A, _, _, B, C} -> Impure(?a, [A, B, C]); + {'CALL_R', A, _, B, C, D} -> Impure(?a, [A, B, C, D]); + {'CALL_GR', A, _, B, C, D, E} -> Impure(?a, [A, B, C, D, E]); {'CALL_T', _} -> Impure(pc, []); {'CALL_VALUE', A} -> Pure(A, []); {'JUMP', _} -> Impure(pc, []);