CLONE compiles

This commit is contained in:
radrow 2021-04-20 09:48:27 +02:00
parent 59b9036a7b
commit 851952987c
6 changed files with 29 additions and 20 deletions

View File

@ -2,7 +2,7 @@
{erl_opts, [debug_info]}.
{deps, [ {aebytecode, {git, "https://github.com/aeternity/aebytecode.git", {ref,"7f0d309"}}}
{deps, [ {aebytecode, {git, "https://github.com/aeternity/aebytecode.git", {ref,"951db9f"}}}
, {getopt, "1.0.1"}
, {eblake2, "1.0.0"}
, {jsx, {git, "https://github.com/talentdeficit/jsx.git",

View File

@ -1,7 +1,7 @@
{"1.1.0",
[{<<"aebytecode">>,
{git,"https://github.com/aeternity/aebytecode.git",
{ref,"7f0d3090d4dc6c4d5fca7645b0c21eb0e65ad208"}},
{ref,"951db9f38412a1f798987403d24c512d82fec8c7"}},
0},
{<<"aeserialization">>,
{git,"https://github.com/aeternity/aeserialization.git",

View File

@ -1468,7 +1468,7 @@ infer_expr(Env, {app, Ann, Fun, Args0} = App) ->
_ ->
NamedArgsVar = fresh_uvar(Ann),
NamedArgs1 = [ infer_named_arg(Env, NamedArgsVar, Arg) || Arg <- NamedArgs ],
NewFun = {typed, _, _, FunType0} = infer_expr(Env, Fun),
NewFun0 = {typed, _, _, FunType0} = infer_expr(Env, Fun),
NewArgs = [infer_expr(Env, A) || A <- Args],
ArgTypes = [T || {typed, _, _, T} <- NewArgs],
FunType =
@ -1491,6 +1491,7 @@ infer_expr(Env, {app, Ann, Fun, Args0} = App) ->
end,
GeneralResultType = fresh_uvar(Ann),
ResultType = fresh_uvar(Ann),
NewFun1 = setelement(4, NewFun0, FunType),
When = {infer_app, Fun, NamedArgs1, Args, FunType, ArgTypes},
unify(Env, FunType, {fun_t, [], NamedArgsVar, ArgTypes, GeneralResultType}, When),
add_named_argument_constraint(
@ -1499,7 +1500,7 @@ infer_expr(Env, {app, Ann, Fun, Args0} = App) ->
general_type = GeneralResultType,
specialized_type = ResultType,
context = {check_return, App} }),
{typed, Ann, {app, Ann, NewFun, NamedArgs1 ++ NewArgs}, dereference(ResultType)}
{typed, Ann, {app, Ann, NewFun1, NamedArgs1 ++ NewArgs}, dereference(ResultType)}
end;
infer_expr(Env, {'if', Attrs, Cond, Then, Else}) ->
NewCond = check_expr(Env, Cond, {id, Attrs, "bool"}),
@ -2381,6 +2382,9 @@ unify1(_Env, {bytes_t, _, Len}, {bytes_t, _, Len}, _When) ->
unify1(Env, {if_t, _, {id, _, Id}, Then1, Else1}, {if_t, _, {id, _, Id}, Then2, Else2}, When) ->
unify(Env, Then1, Then2, When) andalso
unify(Env, Else1, Else2, When);
unify1(Env, {fun_t, _, Named1, _, Result1}, {fun_t, _, Named2, var_args, Result2}, When) ->
error(unify_varargs); %% TODO
unify1(Env, {fun_t, _, Named1, var_args, Result1}, {fun_t, _, Named2, Args2, Result2}, When) ->
error(unify_varargs); %% TODO
unify1(Env, {fun_t, _, Named1, Args1, Result1}, {fun_t, _, Named2, Args2, Result2}, When)

View File

@ -477,6 +477,8 @@ type_to_fcode(_Env, _Sub, {bytes_t, _, N}) ->
{bytes, N};
type_to_fcode(_Env, Sub, {tvar, _, X}) ->
maps:get(X, Sub, {tvar, X});
type_to_fcode(_Env, _Sub, {fun_t, Ann, _, var_args, _}) ->
fcode_error({var_args_not_set, {id, Ann, "a very suspicious function"}});
type_to_fcode(Env, Sub, {fun_t, _, Named, Args, Res}) ->
FNamed = [type_to_fcode(Env, Sub, Arg) || {named_arg_t, _, _, Arg, _} <- Named],
FArgs = [type_to_fcode(Env, Sub, Arg) || Arg <- Args],
@ -692,17 +694,17 @@ expr_to_fcode(Env, _Type, {app, _Ann, {Op, _}, [A]}) when is_atom(Op) ->
end;
%% Function calls
expr_to_fcode(Env, _Type, {app, _, Fun = {typed, _, _, {fun_t, _, NamedArgsT, ArgsT, _}}, Args}) ->
expr_to_fcode(Env, _Type, {app, _, Fun = {typed, _, FunE, {fun_t, _, NamedArgsT, ArgsT, _}}, Args}) ->
Args1 = get_named_args(NamedArgsT, Args),
FArgs = [expr_to_fcode(Env, Arg) || Arg <- Args1],
case expr_to_fcode(Env, Fun) of
{builtin_u, B, _Ar, TypeArgs} -> builtin_to_fcode(state_layout(Env), B, FArgs ++ TypeArgs);
{builtin_u, chain_clone, _Ar} ->
case ArgsT of
[_Con|InitArgs] ->
FInitArgsT = {tuple, [type_to_fcode(Env, T) || T <- InitArgs]},
builtin_to_fcode(state_layout(Env), chain_clone, [FInitArgsT|FArgs]);
[] -> error(wtf) %% FIXME
var_args -> fcode_error({var_args_not_set, FunE});
_ ->
FInitArgsT = {typerep, {tuple, [type_to_fcode(Env, T) || T <- ArgsT]}},
builtin_to_fcode(state_layout(Env), chain_clone, [{lit, FInitArgsT}|FArgs])
end;
{builtin_u, B, _Ar} -> builtin_to_fcode(state_layout(Env), B, FArgs);
{def_u, F, _Ar} -> {def, F, FArgs};

View File

@ -87,6 +87,10 @@ format({higher_order_state, {type_def, Ann, _, _, State}}) ->
Msg = io_lib:format("Invalid state type\n~s\n", [pp_type(2, State)]),
Cxt = "The state cannot contain functions in the AEVM. Use FATE if you need this.\n",
mk_err(pos(Ann), Msg, Cxt);
format({var_args_not_set, Expr}) ->
mk_err( pos(Expr), "Could not deduce type of variadic arguments"
, "When compiling " ++ pp_expr(Expr)
);
format(Err) ->
mk_err(aeso_errors:pos(0, 0), io_lib:format("Unknown error: ~p\n", [Err])).

View File

@ -559,17 +559,9 @@ builtin_to_scode(_Env, auth_tx, []) ->
builtin_to_scode(Env, chain_bytecode_hash, [_Addr] = Args) ->
call_to_scode(Env, aeb_fate_ops:bytecode_hash(?a), Args);
builtin_to_scode(Env, chain_clone,
[InitArgs, _GasCap = {con,[0,1],0,[]}, Prot, Value, Contract | InitArgs]) ->
error(InitArgs),
TypeRep = xd,
call_to_scode(Env, aeb_fate_ops:clone(?a, ?a, ?a, ?a),
[Contract, TypeRep, Value, Prot | InitArgs]
);
builtin_to_scode(Env, chain_clone,
[_GasCap = {con,[0,1],0,[]}, Prot, Value, Contract | InitArgs]) ->
TypeRep = xd,
call_to_scode(Env, aeb_fate_ops:clone(?a, ?a, ?a, ?a),
[Contract, TypeRep, Value, Prot | InitArgs]
[TypeRep, GasCap, Value, Prot, Contract | InitArgs]) ->
call_to_scode(Env, aeb_fate_ops:clone_g(?a, ?a, ?a, ?a, ?a),
[Contract, TypeRep, Value, GasCap, Prot | InitArgs]
);
builtin_to_scode(Env, chain_create,
[_GasCap = {con,[0,1],0,[]}, Prot, Value, Contract | InitArgs]) ->
@ -965,6 +957,10 @@ attributes(I) ->
{'STR_TO_LOWER', A, B} -> Pure(A, [B]);
{'CHAR_TO_INT', A, B} -> Pure(A, [B]);
{'CHAR_FROM_INT', A, B} -> Pure(A, [B]);
{'CREATE', A, B, C} -> Impure(?a, [A, B, C]);
{'CLONE', A, B, C, D} -> Impure(?a, [A, B, C, D]);
{'CLONE_G', A, B, C, D, E} -> Impure(?a, [A, B, C, D, E]);
{'BYTECODE_HASH', A, B} -> Pure(A, [B]);
{'ABORT', A} -> Impure(pc, A);
{'EXIT', A} -> Impure(pc, A);
'NOP' -> Pure(none, [])
@ -1718,6 +1714,9 @@ split_calls(Ref, [I | Code], Acc, Blocks) when element(1, I) == 'CALL';
element(1, I) == 'CALL_R';
element(1, I) == 'CALL_GR';
element(1, I) == 'CALL_PGR';
element(1, I) == 'CREATE';
element(1, I) == 'CLONE';
element(1, I) == 'CLONE_G';
element(1, I) == 'jumpif' ->
split_calls(make_ref(), Code, [], [{Ref, lists:reverse([I | Acc])} | Blocks]);
split_calls(Ref, [{'ABORT', _} = I | _Code], Acc, Blocks) ->