Remote calls now take typerep arguments
This commit is contained in:
parent
dd26649f7d
commit
522d977be9
@ -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).
|
||||
|
@ -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, []);
|
||||
|
Loading…
x
Reference in New Issue
Block a user