Record real names
This commit is contained in:
parent
49200a6c55
commit
f8f67ced47
@ -122,12 +122,13 @@
|
|||||||
return := ftype(),
|
return := ftype(),
|
||||||
body := fexpr() }.
|
body := fexpr() }.
|
||||||
|
|
||||||
-type fcode() :: #{ contract_name := string(),
|
-type fcode() :: #{ contract_name := string(),
|
||||||
state_type := ftype(),
|
state_type := ftype(),
|
||||||
state_layout := state_layout(),
|
state_layout := state_layout(),
|
||||||
event_type := ftype() | none,
|
event_type := ftype() | none,
|
||||||
functions := #{ fun_name() => fun_def() },
|
functions := #{ fun_name() => fun_def() },
|
||||||
payable := boolean() }.
|
payable := boolean(),
|
||||||
|
saved_fresh_names := #{ var_name() => var_name() } }.
|
||||||
|
|
||||||
-type type_def() :: fun(([ftype()]) -> ftype()).
|
-type type_def() :: fun(([ftype()]) -> ftype()).
|
||||||
|
|
||||||
@ -171,6 +172,7 @@
|
|||||||
-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(),
|
||||||
|
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 :=
|
||||||
@ -178,8 +180,10 @@ 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)
|
||||||
)},
|
)},
|
||||||
|
FCode3 = FCode2#{saved_fresh_names => get(saved_fresh_names)},
|
||||||
clear_fresh_names(),
|
clear_fresh_names(),
|
||||||
{Env2, FCode2}.
|
clear_saved_fresh_names(),
|
||||||
|
{Env2, FCode3}.
|
||||||
|
|
||||||
optimize(FCode1, Options) ->
|
optimize(FCode1, Options) ->
|
||||||
Verbose = lists:member(pp_fcode, Options),
|
Verbose = lists:member(pp_fcode, Options),
|
||||||
@ -1734,6 +1738,19 @@ init_fresh_names() ->
|
|||||||
clear_fresh_names() ->
|
clear_fresh_names() ->
|
||||||
erase('%fresh').
|
erase('%fresh').
|
||||||
|
|
||||||
|
init_saved_fresh_names() ->
|
||||||
|
put(saved_fresh_names, #{}).
|
||||||
|
|
||||||
|
clear_saved_fresh_names() ->
|
||||||
|
erase(saved_fresh_names).
|
||||||
|
|
||||||
|
-spec fresh_name_save(string()) -> var_name().
|
||||||
|
fresh_name_save(Name) ->
|
||||||
|
Fresh = fresh_name(),
|
||||||
|
Old = get(saved_fresh_names),
|
||||||
|
New = put(saved_fresh_names, Old#{Fresh => Name}),
|
||||||
|
Fresh.
|
||||||
|
|
||||||
-spec fresh_name() -> var_name().
|
-spec fresh_name() -> var_name().
|
||||||
fresh_name() -> fresh_name("%").
|
fresh_name() -> fresh_name("%").
|
||||||
|
|
||||||
@ -1862,7 +1879,7 @@ bottom_up(F, Env, Expr) ->
|
|||||||
(_) -> true end,
|
(_) -> true end,
|
||||||
case ShouldFreshen(X) of
|
case ShouldFreshen(X) of
|
||||||
true ->
|
true ->
|
||||||
Z = fresh_name(),
|
Z = fresh_name_save(X),
|
||||||
Env1 = Env#{ Z => E1 },
|
Env1 = Env#{ Z => E1 },
|
||||||
{'let', Z, E1, bottom_up(F, Env1, rename([{X, Z}], Body))};
|
{'let', Z, E1, bottom_up(F, Env1, rename([{X, Z}], Body))};
|
||||||
false ->
|
false ->
|
||||||
|
@ -45,7 +45,14 @@
|
|||||||
-define(s(N), {store, N}).
|
-define(s(N), {store, N}).
|
||||||
-define(void, {var, 9999}).
|
-define(void, {var, 9999}).
|
||||||
|
|
||||||
-record(env, { contract, vars = [], locals = [], current_function, tailpos = true, child_contracts = #{}, options = []}).
|
-record(env, { contract,
|
||||||
|
vars = [],
|
||||||
|
locals = [],
|
||||||
|
current_function,
|
||||||
|
tailpos = true,
|
||||||
|
child_contracts = #{},
|
||||||
|
saved_fresh_names = #{},
|
||||||
|
options = [] }).
|
||||||
|
|
||||||
%% -- Debugging --------------------------------------------------------------
|
%% -- Debugging --------------------------------------------------------------
|
||||||
|
|
||||||
@ -74,10 +81,11 @@ code_error(Err) ->
|
|||||||
compile(FCode, Options) ->
|
compile(FCode, Options) ->
|
||||||
compile(#{}, FCode, Options).
|
compile(#{}, FCode, Options).
|
||||||
compile(ChildContracts, FCode, Options) ->
|
compile(ChildContracts, FCode, Options) ->
|
||||||
#{ contract_name := ContractName,
|
#{ contract_name := ContractName,
|
||||||
functions := Functions } = FCode,
|
functions := Functions,
|
||||||
|
saved_fresh_names := SavedFreshNames } = FCode,
|
||||||
try
|
try
|
||||||
SFuns = functions_to_scode(ChildContracts, ContractName, Functions, Options),
|
SFuns = functions_to_scode(ChildContracts, ContractName, Functions, SavedFreshNames, Options),
|
||||||
SFuns1 = optimize_scode(SFuns, Options),
|
SFuns1 = optimize_scode(SFuns, Options),
|
||||||
FateCode = to_basic_blocks(SFuns1),
|
FateCode = to_basic_blocks(SFuns1),
|
||||||
?debug(compile, Options, "~s\n", [aeb_fate_asm:pp(FateCode)]),
|
?debug(compile, Options, "~s\n", [aeb_fate_asm:pp(FateCode)]),
|
||||||
@ -102,33 +110,34 @@ add_child_symbols(ChildContracts, FateCode) ->
|
|||||||
Symbols = maps:from_list([ {make_function_id(FName), make_function_name(FName)} || FName <- Funs ]),
|
Symbols = maps:from_list([ {make_function_id(FName), make_function_name(FName)} || FName <- Funs ]),
|
||||||
aeb_fate_code:update_symbols(FateCode, Symbols).
|
aeb_fate_code:update_symbols(FateCode, Symbols).
|
||||||
|
|
||||||
functions_to_scode(ChildContracts, ContractName, Functions, Options) ->
|
functions_to_scode(ChildContracts, ContractName, Functions, SavedFreshNames, Options) ->
|
||||||
FunNames = maps:keys(Functions),
|
FunNames = maps:keys(Functions),
|
||||||
maps:from_list(
|
maps:from_list(
|
||||||
[ {make_function_name(Name), function_to_scode(ChildContracts, ContractName, FunNames, Name, Attrs, Args, Body, Type, Options)}
|
[ {make_function_name(Name), function_to_scode(ChildContracts, ContractName, FunNames, Name, Attrs, Args, Body, Type, SavedFreshNames, Options)}
|
||||||
|| {Name, #{args := Args,
|
|| {Name, #{args := Args,
|
||||||
body := Body,
|
body := Body,
|
||||||
attrs := Attrs,
|
attrs := Attrs,
|
||||||
return := Type}} <- maps:to_list(Functions)]).
|
return := Type}} <- maps:to_list(Functions)]).
|
||||||
|
|
||||||
function_to_scode(ChildContracts, ContractName, Functions, Name, Attrs0, Args, Body, ResType, Options) ->
|
function_to_scode(ChildContracts, ContractName, Functions, Name, Attrs0, Args, Body, ResType, SavedFreshNames, Options) ->
|
||||||
{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, 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) || {Arg, Register} <- Env#env.vars ],
|
||||||
SCode = to_scode(Env, Body),
|
SCode = to_scode(Env, Body),
|
||||||
{Attrs, {ArgTypes, ResType1}, SCode}.
|
{Attrs, {ArgTypes, ResType1}, SCode}.
|
||||||
|
|
||||||
get_variables_registers() ->
|
get_variables_registers() ->
|
||||||
case get(variables_registers) of
|
case get(variables_registers) of
|
||||||
undefined -> [];
|
undefined -> #{};
|
||||||
Vs -> Vs
|
Vs -> Vs
|
||||||
end.
|
end.
|
||||||
|
|
||||||
add_variables_register(Env, Name, Register) ->
|
add_variables_register(Env = #env{saved_fresh_names = SavedFreshNames}, Name, Register) ->
|
||||||
Olds = get_variables_registers(),
|
Olds = get_variables_registers(),
|
||||||
New = {Env#env.contract, Env#env.current_function, Name, Register},
|
RealName = maps:get(Name, SavedFreshNames, Name),
|
||||||
put(variables_registers, [New | Olds]).
|
New = {Env#env.contract, Env#env.current_function, RealName},
|
||||||
|
put(variables_registers, Olds#{New => Register}).
|
||||||
|
|
||||||
-define(tvars, '$tvars').
|
-define(tvars, '$tvars').
|
||||||
|
|
||||||
@ -174,14 +183,15 @@ types_to_scode(Ts) -> lists:map(fun type_to_scode/1, Ts).
|
|||||||
|
|
||||||
%% -- Environment functions --
|
%% -- Environment functions --
|
||||||
|
|
||||||
init_env(ChildContracts, ContractName, FunNames, Name, Args, Options) ->
|
init_env(ChildContracts, ContractName, FunNames, Name, Args, SavedFreshNames, Options) ->
|
||||||
#env{ vars = [ {X, {arg, I}} || {I, {X, _}} <- with_ixs(Args) ],
|
#env{ vars = [ {X, {arg, I}} || {I, {X, _}} <- with_ixs(Args) ],
|
||||||
contract = ContractName,
|
contract = ContractName,
|
||||||
child_contracts = ChildContracts,
|
child_contracts = ChildContracts,
|
||||||
locals = FunNames,
|
locals = FunNames,
|
||||||
current_function = Name,
|
current_function = Name,
|
||||||
options = Options,
|
options = Options,
|
||||||
tailpos = true }.
|
tailpos = true,
|
||||||
|
saved_fresh_names = SavedFreshNames }.
|
||||||
|
|
||||||
next_var(#env{ vars = Vars }) ->
|
next_var(#env{ vars = Vars }) ->
|
||||||
1 + lists:max([-1 | [J || {_, {var, J}} <- Vars]]).
|
1 + lists:max([-1 | [J || {_, {var, J}} <- Vars]]).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user