Merge pull request #123 from aeternity/PT-167221635-remote-type-check
PT-167221635 remote type check
This commit is contained in:
commit
e566186800
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{erl_opts, [debug_info]}.
|
{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"}
|
, {getopt, "1.0.1"}
|
||||||
, {eblake2, "1.0.0"}
|
, {eblake2, "1.0.0"}
|
||||||
, {jsx, {git, "https://github.com/talentdeficit/jsx.git",
|
, {jsx, {git, "https://github.com/talentdeficit/jsx.git",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{"1.1.0",
|
{"1.1.0",
|
||||||
[{<<"aebytecode">>,
|
[{<<"aebytecode">>,
|
||||||
{git,"https://github.com/aeternity/aebytecode.git",
|
{git,"https://github.com/aeternity/aebytecode.git",
|
||||||
{ref,"3954bd22daa24d4a82a8349325d115cd7b7d1750"}},
|
{ref,"fdd660a2191f19e1bd77cafe0d39c826539c1b6c"}},
|
||||||
0},
|
0},
|
||||||
{<<"aeserialization">>,
|
{<<"aeserialization">>,
|
||||||
{git,"https://github.com/aeternity/aeserialization.git",
|
{git,"https://github.com/aeternity/aeserialization.git",
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
| nil
|
| nil
|
||||||
| {var, var_name()}
|
| {var, var_name()}
|
||||||
| {def, fun_name(), [fexpr()]}
|
| {def, fun_name(), [fexpr()]}
|
||||||
| {remote, fexpr(), fun_name(), [fexpr()]}
|
| {remote, [ftype()], ftype(), fexpr(), fun_name(), [fexpr()]}
|
||||||
| {builtin, builtin(), [fexpr()]}
|
| {builtin, builtin(), [fexpr()]}
|
||||||
| {con, arities(), tag(), [fexpr()]}
|
| {con, arities(), tag(), [fexpr()]}
|
||||||
| {tuple, [fexpr()]}
|
| {tuple, [fexpr()]}
|
||||||
@ -65,7 +65,7 @@
|
|||||||
%% lambdas) are generated by the fcode compiler, but translated
|
%% lambdas) are generated by the fcode compiler, but translated
|
||||||
%% to closures by the lambda lifter.
|
%% to closures by the lambda lifter.
|
||||||
| {def_u, fun_name(), arity()}
|
| {def_u, fun_name(), arity()}
|
||||||
| {remote_u, fexpr(), fun_name(), arity()}
|
| {remote_u, [ftype()], ftype(), fexpr(), fun_name()}
|
||||||
| {builtin_u, builtin(), arity()}
|
| {builtin_u, builtin(), arity()}
|
||||||
| {lam, [var_name()], fexpr()}.
|
| {lam, [var_name()], fexpr()}.
|
||||||
|
|
||||||
@ -405,9 +405,10 @@ expr_to_fcode(Env, Type, {proj, _Ann, Rec = {typed, _, _, RecType}, {id, _, X}})
|
|||||||
{con, _, _} when X == "address" ->
|
{con, _, _} when X == "address" ->
|
||||||
{op, contract_to_address, [expr_to_fcode(Env, Rec)]};
|
{op, contract_to_address, [expr_to_fcode(Env, Rec)]};
|
||||||
{con, _, _} ->
|
{con, _, _} ->
|
||||||
{fun_t, _, Named, Args, _} = Type,
|
{fun_t, _, _, Args, Ret} = Type,
|
||||||
Arity = length(Named) + length(Args),
|
FArgs = [type_to_fcode(Env, Arg) || Arg <- Args],
|
||||||
{remote_u, expr_to_fcode(Env, Rec), {entrypoint, list_to_binary(X)}, Arity};
|
{remote_u, FArgs, type_to_fcode(Env, Ret), expr_to_fcode(Env, Rec),
|
||||||
|
{entrypoint, list_to_binary(X)}};
|
||||||
{record_t, _} ->
|
{record_t, _} ->
|
||||||
{proj, expr_to_fcode(Env, Rec), field_index(Rec, X)}
|
{proj, expr_to_fcode(Env, Rec), field_index(Rec, X)}
|
||||||
end;
|
end;
|
||||||
@ -521,7 +522,7 @@ expr_to_fcode(Env, Type, {app, _Ann, Fun = {typed, _, _, {fun_t, _, NamedArgsT,
|
|||||||
builtin_to_fcode(B, FArgs ++ TypeArgs);
|
builtin_to_fcode(B, FArgs ++ TypeArgs);
|
||||||
{builtin_u, B, _Ar} -> builtin_to_fcode(B, FArgs);
|
{builtin_u, B, _Ar} -> builtin_to_fcode(B, FArgs);
|
||||||
{def_u, F, _Ar} -> {def, F, 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 ->
|
||||||
%% FFun is a closure, with first component the function name and
|
%% FFun is a closure, with first component the function name and
|
||||||
%% second component the environment
|
%% 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}
|
def_u -> {def, F, Args}
|
||||||
end,
|
end,
|
||||||
make_closure([], Xs, Body);
|
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),
|
FVs = free_vars(Ct),
|
||||||
Ct1 = lambda_lift_expr(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],
|
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) ->
|
lambda_lift_expr(Expr) ->
|
||||||
case Expr of
|
case Expr of
|
||||||
{lit, _} -> Expr;
|
{lit, _} -> Expr;
|
||||||
@ -958,7 +960,7 @@ lambda_lift_expr(Expr) ->
|
|||||||
{closure, _, _} -> Expr;
|
{closure, _, _} -> Expr;
|
||||||
{def, D, As} -> {def, D, lambda_lift_exprs(As)};
|
{def, D, As} -> {def, D, lambda_lift_exprs(As)};
|
||||||
{builtin, B, As} -> {builtin, B, 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)};
|
{con, Ar, C, As} -> {con, Ar, C, lambda_lift_exprs(As)};
|
||||||
{tuple, As} -> {tuple, lambda_lift_exprs(As)};
|
{tuple, As} -> {tuple, lambda_lift_exprs(As)};
|
||||||
{proj, A, I} -> {proj, lambda_lift_expr(A), I};
|
{proj, A, I} -> {proj, lambda_lift_expr(A), I};
|
||||||
@ -1153,8 +1155,8 @@ free_vars(Expr) ->
|
|||||||
nil -> [];
|
nil -> [];
|
||||||
{def, _, As} -> free_vars(As);
|
{def, _, As} -> free_vars(As);
|
||||||
{def_u, _, _} -> [];
|
{def_u, _, _} -> [];
|
||||||
{remote, Ct, _, As} -> free_vars([Ct | As]);
|
{remote, _, _, Ct, _, As} -> free_vars([Ct | As]);
|
||||||
{remote_u, Ct, _, _} -> free_vars(Ct);
|
{remote_u, _, _, Ct, _} -> free_vars(Ct);
|
||||||
{builtin, _, As} -> free_vars(As);
|
{builtin, _, As} -> free_vars(As);
|
||||||
{builtin_u, _, _} -> [];
|
{builtin_u, _, _} -> [];
|
||||||
{con, _, _, As} -> free_vars(As);
|
{con, _, _, As} -> free_vars(As);
|
||||||
@ -1197,8 +1199,8 @@ rename(Ren, Expr) ->
|
|||||||
{def_u, _, _} -> Expr;
|
{def_u, _, _} -> Expr;
|
||||||
{builtin, B, Es} -> {builtin, B, [rename(Ren, E) || E <- Es]};
|
{builtin, B, Es} -> {builtin, B, [rename(Ren, E) || E <- Es]};
|
||||||
{builtin_u, _, _} -> Expr;
|
{builtin_u, _, _} -> Expr;
|
||||||
{remote, Ct, F, Es} -> {remote, rename(Ren, Ct), F, [rename(Ren, E) || E <- Es]};
|
{remote, ArgsT, RetT, Ct, F, Es} -> {remote, ArgsT, RetT, rename(Ren, Ct), F, [rename(Ren, E) || E <- Es]};
|
||||||
{remote_u, Ct, F, Ar} -> {remote_u, rename(Ren, Ct), F, Ar};
|
{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]};
|
{con, Ar, I, Es} -> {con, Ar, I, [rename(Ren, E) || E <- Es]};
|
||||||
{tuple, Es} -> {tuple, [rename(Ren, E) || E <- Es]};
|
{tuple, Es} -> {tuple, [rename(Ren, E) || E <- Es]};
|
||||||
{proj, E, I} -> {proj, rename(Ren, E), I};
|
{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_beside([pp_text(B), pp_text("/"), pp_text(N)]);
|
||||||
pp_fexpr({builtin, B, As}) ->
|
pp_fexpr({builtin, B, As}) ->
|
||||||
pp_call(pp_text(B), As);
|
pp_call(pp_text(B), As);
|
||||||
pp_fexpr({remote_u, Ct, Fun, Ar}) ->
|
pp_fexpr({remote_u, ArgsT, RetT, Ct, Fun}) ->
|
||||||
pp_beside([pp_fexpr(Ct), pp_text("."), pp_fun_name(Fun), pp_text("/"), pp_int(Ar)]);
|
pp_beside([pp_fexpr(Ct), pp_text("."), pp_fun_name(Fun), pp_text(" : "), pp_ftype({function, ArgsT, RetT})]);
|
||||||
pp_fexpr({remote, Ct, Fun, As}) ->
|
pp_fexpr({remote, ArgsT, RetT, Ct, Fun, As}) ->
|
||||||
pp_call(pp_beside([pp_fexpr(Ct), pp_text("."), pp_fun_name(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_fexpr({funcall, Fun, As}) ->
|
||||||
pp_call(pp_fexpr(Fun), As);
|
pp_call(pp_fexpr(Fun), As);
|
||||||
pp_fexpr({switch, Split}) -> pp_split(Split).
|
pp_fexpr({switch, Split}) -> pp_split(Split).
|
||||||
|
@ -328,17 +328,19 @@ to_scode(Env, {funcall, Fun, Args}) ->
|
|||||||
to_scode(Env, {builtin, B, Args}) ->
|
to_scode(Env, {builtin, B, Args}) ->
|
||||||
builtin_to_scode(Env, B, Args);
|
builtin_to_scode(Env, B, Args);
|
||||||
|
|
||||||
to_scode(Env, {remote, Ct, Fun, [{builtin, call_gas_left, _}, Value | Args]}) ->
|
to_scode(Env, {remote, ArgsT, RetT, Ct, Fun, [Gas, Value | Args]}) ->
|
||||||
%% Gas is not limited.
|
|
||||||
Lbl = make_function_id(Fun),
|
Lbl = make_function_id(Fun),
|
||||||
Call = aeb_fate_ops:call_r(?a, Lbl, length(Args), ?a), %% No remote tail calls
|
{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_to_scode(Env, Call, [Ct, Value | Args]);
|
||||||
|
_ ->
|
||||||
to_scode(Env, {remote, Ct, Fun, [Gas, Value | Args]}) ->
|
Call = aeb_fate_ops:call_gr(?a, Lbl, ArgType, RetType, ?a, ?a),
|
||||||
%% Gas is limited.
|
call_to_scode(Env, Call, [Ct, Value, Gas | Args])
|
||||||
Lbl = make_function_id(Fun),
|
end;
|
||||||
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]);
|
|
||||||
|
|
||||||
to_scode(Env, {closure, Fun, FVs}) ->
|
to_scode(Env, {closure, Fun, FVs}) ->
|
||||||
to_scode(Env, {tuple, [{lit, {string, make_function_id(Fun)}}, FVs]});
|
to_scode(Env, {tuple, [{lit, {string, make_function_id(Fun)}}, FVs]});
|
||||||
@ -745,8 +747,8 @@ attributes(I) ->
|
|||||||
'RETURN' -> Impure(pc, []);
|
'RETURN' -> Impure(pc, []);
|
||||||
{'RETURNR', A} -> Impure(pc, A);
|
{'RETURNR', A} -> Impure(pc, A);
|
||||||
{'CALL', _} -> Impure(?a, []);
|
{'CALL', _} -> Impure(?a, []);
|
||||||
{'CALL_R', A, _, _, B} -> Impure(?a, [A, B]);
|
{'CALL_R', A, _, B, C, D} -> Impure(?a, [A, B, C, D]);
|
||||||
{'CALL_GR', A, _, _, B, C} -> Impure(?a, [A, B, C]);
|
{'CALL_GR', A, _, B, C, D, E} -> Impure(?a, [A, B, C, D, E]);
|
||||||
{'CALL_T', _} -> Impure(pc, []);
|
{'CALL_T', _} -> Impure(pc, []);
|
||||||
{'CALL_VALUE', A} -> Pure(A, []);
|
{'CALL_VALUE', A} -> Pure(A, []);
|
||||||
{'JUMP', _} -> Impure(pc, []);
|
{'JUMP', _} -> Impure(pc, []);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user