Add default init function in fcode pass instead of in assembler

This commit is contained in:
Ulf Norell 2019-08-21 11:41:19 +02:00
parent cfd036b199
commit cbc8909954
2 changed files with 29 additions and 29 deletions

View File

@ -226,6 +226,9 @@ init_type_env() ->
["Chain", "ttl"] => ?type({variant, [[integer], [integer]]})
}.
is_no_code(Env) ->
proplists:get_value(no_code, maps:get(options, Env, []), false).
%% -- Compilation ------------------------------------------------------------
-spec to_fcode(env(), aeso_syntax:ast()) -> fcode().
@ -244,7 +247,7 @@ to_fcode(Env, [{contract, Attrs, {con, _, Main}, Decls}]) ->
state_type => StateType,
event_type => EventType,
payable => Payable,
functions => add_init_function(Env1,
functions => add_init_function(Env1, StateType,
add_event_function(Env1, EventType, Funs)) };
to_fcode(Env, [{contract, _, {con, _, Con}, Decls} | Code]) ->
Env1 = decls_to_fcode(Env#{ context => {abstract_contract, Con} }, Decls),
@ -268,7 +271,7 @@ decls_to_fcode(Env, Decls) ->
-spec decl_to_fcode(env(), aeso_syntax:decl()) -> env().
decl_to_fcode(Env, {type_decl, _, _, _}) -> Env;
decl_to_fcode(Env = #{context := {main_contract, _}}, {fun_decl, Ann, {id, _, Name}, _}) ->
case proplists:get_value(no_code, maps:get(options, Env, []), false) of
case is_no_code(Env) of
false -> fcode_error({missing_definition, Name, lists:keydelete(entrypoint, 1, Ann)});
true -> Env
end;
@ -852,16 +855,30 @@ builtin_to_fcode(Builtin, Args) ->
%% -- Init function --
add_init_function(_Env, Funs) ->
add_init_function(Env, StateType, Funs0) ->
case is_no_code(Env) of
true -> Funs0;
false ->
Funs = add_default_init_function(Env, StateType, Funs0),
InitName = {entrypoint, <<"init">>},
InitFun = #{ args := InitArgs } =
case maps:get(InitName, Funs, none) of
none -> #{ attrs => [], args => [], return => {tuple, []}, body => {tuple, []} };
Info -> Info
end,
InitFun = #{ args := InitArgs } = maps:get(InitName, Funs, none),
Vars = [ {var, X} || {X, _} <- InitArgs ],
Funs#{ init => InitFun#{ return => {tuple, []},
body => {builtin, set_state, [{def, InitName, Vars}]} } }.
body => {builtin, set_state, [{def, InitName, Vars}]} } }
end.
add_default_init_function(_Env, StateType, Funs) ->
InitName = {entrypoint, <<"init">>},
case maps:get(InitName, Funs, none) of
%% Only add default init function if state is unit.
none when StateType == {tuple, []} ->
Funs#{ InitName => #{attrs => [],
args => [],
return => {tuple, []},
body => {tuple, []}} };
none -> fcode_error(missing_init_function);
_ -> Funs
end.
%% -- Event function --

View File

@ -130,12 +130,10 @@ debug(Tag, Options, Fmt, Args) ->
%% @doc Main entry point.
compile(FCode, Options) ->
#{ contract_name := ContractName,
state_type := StateType,
functions := Functions } = FCode,
SFuns = functions_to_scode(ContractName, Functions, Options),
SFuns1 = optimize_scode(SFuns, Options),
SFuns2 = add_default_init_function(SFuns1, StateType),
FateCode = to_basic_blocks(SFuns2),
FateCode = to_basic_blocks(SFuns1),
debug(compile, Options, "~s\n", [aeb_fate_asm:pp(FateCode)]),
FateCode.
@ -196,21 +194,6 @@ type_to_scode({tvar, X}) ->
J -> {tvar, J}
end.
add_default_init_function(SFuns, StateType) when StateType /= {tuple, []} ->
%% Only add default if the type is unit.
SFuns;
add_default_init_function(SFuns, {tuple, []}) ->
%% Only add default if the init function is not present
InitName = make_function_name({entrypoint, <<"init">>}),
case maps:find(InitName, SFuns) of
{ok, _} ->
SFuns;
error ->
Sig = {[], {tuple, []}},
Body = [tuple(0)],
SFuns#{ InitName => {[], Sig, Body} }
end.
%% -- Phase I ----------------------------------------------------------------
%% Icode to structured assembly