Make variables registers optional

This commit is contained in:
Gaith Hallak 2022-10-25 08:14:40 +03:00
parent d84e21a5ad
commit ee37e187e8
3 changed files with 32 additions and 17 deletions

View File

@ -160,7 +160,7 @@
context => context(), context => context(),
vars => [var_name()], vars => [var_name()],
functions := #{ fun_name() => fun_def() }, functions := #{ fun_name() => fun_def() },
saved_fresh_names := #{ var_name() => var_name() } saved_fresh_names => #{ var_name() => var_name() }
}. }.
-define(HASH_BYTES, 32). -define(HASH_BYTES, 32).
@ -171,8 +171,7 @@
%% and produces Fate intermediate code. %% and produces Fate intermediate code.
-spec ast_to_fcode(aeso_syntax:ast(), [option()]) -> {env(), fcode()}. -spec ast_to_fcode(aeso_syntax:ast(), [option()]) -> {env(), fcode()}.
ast_to_fcode(Code, Options) -> ast_to_fcode(Code, Options) ->
init_fresh_names(), init_fresh_names(Options),
init_saved_fresh_names(),
{Env1, FCode1} = to_fcode(init_env(Options), Code), {Env1, FCode1} = to_fcode(init_env(Options), Code),
FCode2 = optimize(FCode1, Options), FCode2 = optimize(FCode1, Options),
Env2 = Env1#{ child_con_env := Env2 = Env1#{ child_con_env :=
@ -180,9 +179,12 @@ ast_to_fcode(Code, Options) ->
fun (_, FC) -> optimize(FC, Options) end, fun (_, FC) -> optimize(FC, Options) end,
maps:get(child_con_env, Env1) maps:get(child_con_env, Env1)
)}, )},
Env3 = Env2#{ saved_fresh_names := get(saved_fresh_names) }, Env3 =
clear_fresh_names(), case proplists:get_value(debug_info, Options, false) of
clear_saved_fresh_names(), true -> Env2#{ saved_fresh_names => get(saved_fresh_names) };
false -> Env2
end,
clear_fresh_names(Options),
{Env3, FCode2}. {Env3, FCode2}.
optimize(FCode1, Options) -> optimize(FCode1, Options) ->
@ -1733,10 +1735,12 @@ resolve_fun(#{ fun_env := Funs, builtins := Builtin } = Env, Q) ->
{{Fun, Ar}, _} -> {def_u, Fun, Ar} {{Fun, Ar}, _} -> {def_u, Fun, Ar}
end. end.
init_fresh_names() -> init_fresh_names(Options) ->
proplists:get_value(debug_info, Options, false) andalso init_saved_fresh_names(),
put('%fresh', 0). put('%fresh', 0).
clear_fresh_names() -> clear_fresh_names(Options) ->
proplists:get_value(debug_info, Options, false) andalso clear_saved_fresh_names(),
erase('%fresh'). erase('%fresh').
init_saved_fresh_names() -> init_saved_fresh_names() ->
@ -1748,8 +1752,10 @@ clear_saved_fresh_names() ->
-spec fresh_name_save(string()) -> var_name(). -spec fresh_name_save(string()) -> var_name().
fresh_name_save(Name) -> fresh_name_save(Name) ->
Fresh = fresh_name(), Fresh = fresh_name(),
Old = get(saved_fresh_names), case get(saved_fresh_names) of
put(saved_fresh_names, Old#{Fresh => Name}), undefined -> ok;
Old -> put(saved_fresh_names, Old#{Fresh => Name})
end,
Fresh. Fresh.
-spec fresh_name() -> var_name(). -spec fresh_name() -> var_name().

View File

@ -112,9 +112,11 @@ from_string(ContractString, Options) ->
from_string1(ContractString, Options) -> from_string1(ContractString, Options) ->
#{ fcode := FCode #{ fcode := FCode
, fcode_env := #{child_con_env := ChildContracts, saved_fresh_names := SavedFreshNames} , fcode_env := FCodeEnv
, folded_typed_ast := FoldedTypedAst , folded_typed_ast := FoldedTypedAst
, warnings := Warnings } = string_to_code(ContractString, Options), , warnings := Warnings } = string_to_code(ContractString, Options),
#{ child_con_env := ChildContracts } = FCodeEnv,
SavedFreshNames = maps:get(saved_fresh_names, FCodeEnv, #{}),
{FateCode, VarsRegs} = aeso_fcode_to_fate:compile(ChildContracts, FCode, SavedFreshNames, Options), {FateCode, VarsRegs} = aeso_fcode_to_fate:compile(ChildContracts, FCode, SavedFreshNames, Options),
pp_assembler(FateCode, Options), pp_assembler(FateCode, Options),
ByteCode = aeb_fate_code:serialize(FateCode, []), ByteCode = aeb_fate_code:serialize(FateCode, []),
@ -126,10 +128,15 @@ from_string1(ContractString, Options) ->
fate_code => FateCode, fate_code => FateCode,
abi_version => aeb_fate_abi:abi_version(), abi_version => aeb_fate_abi:abi_version(),
payable => maps:get(payable, FCode), payable => maps:get(payable, FCode),
variables_registers => VarsRegs,
warnings => Warnings warnings => Warnings
}, },
{ok, maybe_generate_aci(Res, FoldedTypedAst, Options)}. ResDbg = Res#{variables_registers => VarsRegs},
FinalRes =
case proplists:get_value(debug_info, Options, false) of
true -> ResDbg;
false -> Res
end,
{ok, maybe_generate_aci(FinalRes, FoldedTypedAst, Options)}.
maybe_generate_aci(Result, FoldedTypedAst, Options) -> maybe_generate_aci(Result, FoldedTypedAst, Options) ->
case proplists:get_value(aci, Options) of case proplists:get_value(aci, Options) of
@ -184,9 +191,9 @@ check_call1(ContractString0, FunName, Args, Options) ->
try try
%% First check the contract without the __call function %% First check the contract without the __call function
#{fcode := OrgFcode #{fcode := OrgFcode
, fcode_env := #{child_con_env := ChildContracts, saved_fresh_names := SavedFreshNames} , fcode_env := #{child_con_env := ChildContracts}
, ast := Ast} = string_to_code(ContractString0, Options), , ast := Ast} = string_to_code(ContractString0, Options),
{FateCode, _VarsRegs} = aeso_fcode_to_fate:compile(ChildContracts, OrgFcode, SavedFreshNames, []), {FateCode, _} = aeso_fcode_to_fate:compile(ChildContracts, OrgFcode, #{}, []),
%% collect all hashes and compute the first name without hash collision to %% collect all hashes and compute the first name without hash collision to
SymbolHashes = maps:keys(aeb_fate_code:symbols(FateCode)), SymbolHashes = maps:keys(aeb_fate_code:symbols(FateCode)),
CallName = first_none_match(?CALL_NAME, SymbolHashes, CallName = first_none_match(?CALL_NAME, SymbolHashes,

View File

@ -125,7 +125,9 @@ function_to_scode(ChildContracts, ContractName, Functions, Name, Attrs0, Args, B
{ArgTypes, ResType1} = typesig_to_scode(Args, ResType), {ArgTypes, ResType1} = typesig_to_scode(Args, ResType),
Attrs = Attrs0 -- [stateful], %% Only track private and payable from here. Attrs = Attrs0 -- [stateful], %% Only track private and payable from here.
Env = init_env(ChildContracts, ContractName, Functions, Name, Args, SavedFreshNames, Options), Env = init_env(ChildContracts, ContractName, Functions, Name, Args, SavedFreshNames, Options),
[ add_variables_register(Env, Arg, Register) || {Arg, Register} <- Env#env.vars ], [ add_variables_register(Env, Arg, Register) ||
proplists:get_value(debug_info, Options, false),
{Arg, Register} <- Env#env.vars ],
SCode = to_scode(Env, Body), SCode = to_scode(Env, Body),
{Attrs, {ArgTypes, ResType1}, SCode}. {Attrs, {ArgTypes, ResType1}, SCode}.
@ -205,7 +207,7 @@ next_var(#env{ vars = Vars }) ->
1 + lists:max([-1 | [J || {_, {var, J}} <- Vars]]). 1 + lists:max([-1 | [J || {_, {var, J}} <- Vars]]).
bind_var(Name, Var, Env = #env{ vars = Vars }) -> bind_var(Name, Var, Env = #env{ vars = Vars }) ->
add_variables_register(Env, Name, Var), proplists:get_value(debug_info, Env#env.options, false) andalso add_variables_register(Env, Name, Var),
Env#env{ vars = [{Name, Var} | Vars] }. Env#env{ vars = [{Name, Var} | Vars] }.
bind_local(Name, Env) -> bind_local(Name, Env) ->