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

View File

@ -112,9 +112,11 @@ from_string(ContractString, Options) ->
from_string1(ContractString, Options) ->
#{ fcode := FCode
, fcode_env := #{child_con_env := ChildContracts, saved_fresh_names := SavedFreshNames}
, fcode_env := FCodeEnv
, folded_typed_ast := FoldedTypedAst
, 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),
pp_assembler(FateCode, Options),
ByteCode = aeb_fate_code:serialize(FateCode, []),
@ -126,10 +128,15 @@ from_string1(ContractString, Options) ->
fate_code => FateCode,
abi_version => aeb_fate_abi:abi_version(),
payable => maps:get(payable, FCode),
variables_registers => VarsRegs,
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) ->
case proplists:get_value(aci, Options) of
@ -184,9 +191,9 @@ check_call1(ContractString0, FunName, Args, Options) ->
try
%% First check the contract without the __call function
#{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),
{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
SymbolHashes = maps:keys(aeb_fate_code:symbols(FateCode)),
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),
Attrs = Attrs0 -- [stateful], %% Only track private and payable from here.
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),
{Attrs, {ArgTypes, ResType1}, SCode}.
@ -205,7 +207,7 @@ next_var(#env{ vars = Vars }) ->
1 + lists:max([-1 | [J || {_, {var, J}} <- 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] }.
bind_local(Name, Env) ->