Debug mode turns off hermetization

Added tests and fixed bugs
This commit is contained in:
radrow 2020-10-08 17:09:24 +02:00
parent 25fa365c29
commit 1a5017ce2b
6 changed files with 68 additions and 17 deletions

View File

@ -69,7 +69,7 @@ do_contract_interface(Type, ContractString, Options) ->
try try
Ast = aeso_compiler:parse(ContractString, Options), Ast = aeso_compiler:parse(ContractString, Options),
%% io:format("~p\n", [Ast]), %% io:format("~p\n", [Ast]),
{TypedAst, _} = aeso_ast_infer_types:infer(Ast, [dont_unfold]), {TypedAst, _} = aeso_ast_infer_types:infer(Ast, [dont_unfold | Options]),
%% io:format("~p\n", [TypedAst]), %% io:format("~p\n", [TypedAst]),
from_typed_ast(Type, TypedAst) from_typed_ast(Type, TypedAst)
catch catch

View File

@ -557,7 +557,7 @@ map_t(As, K, V) -> {app_t, As, {id, As, "map"}, [K, V]}.
infer(Contracts) -> infer(Contracts) ->
infer(Contracts, []). infer(Contracts, []).
-type option() :: return_env | dont_unfold | no_code | term(). -type option() :: return_env | dont_unfold | no_code | debug_mode | term().
-spec init_env(list(option())) -> env(). -spec init_env(list(option())) -> env().
init_env(_Options) -> global_env(). init_env(_Options) -> global_env().
@ -622,16 +622,20 @@ check_scope_name_clash(Env, Kind, Name) ->
-spec infer_contract_top(env(), main_contract | contract | namespace, [aeso_syntax:decl()], list(option())) -> -spec infer_contract_top(env(), main_contract | contract | namespace, [aeso_syntax:decl()], list(option())) ->
{env(), [aeso_syntax:decl()]}. {env(), [aeso_syntax:decl()]}.
infer_contract_top(Env, Kind, Defs0, _Options) -> infer_contract_top(Env, Kind, Defs0, Options) ->
Defs = desugar(Defs0), Defs = desugar(Defs0),
infer_contract(Env, Kind, Defs). infer_contract(Env, Kind, Defs, Options).
%% infer_contract takes a proplist mapping global names to types, and %% infer_contract takes a proplist mapping global names to types, and
%% a list of definitions. %% a list of definitions.
-spec infer_contract(env(), main_contract | contract | namespace, [aeso_syntax:decl()]) -> {env(), [aeso_syntax:decl()]}. -spec infer_contract(env(), main_contract | contract | namespace, [aeso_syntax:decl()], list(option())) -> {env(), [aeso_syntax:decl()]}.
infer_contract(Env0, What, Defs0) -> infer_contract(Env0, What, Defs0, Options) ->
create_type_errors(), create_type_errors(),
Defs = process_blocks(Defs0), Defs01 = process_blocks(Defs0),
Defs = case lists:member(debug_mode, Options) of
true -> expose_internals(Defs01, What);
false -> Defs01
end,
destroy_and_report_type_errors(Env0), destroy_and_report_type_errors(Env0),
Env = Env0#env{ what = What }, Env = Env0#env{ what = What },
Kind = fun({type_def, _, _, _, _}) -> type; Kind = fun({type_def, _, _, _, _}) -> type;
@ -679,7 +683,7 @@ process_blocks(Decls) ->
-spec process_block(aeso_syntax:ann(), [aeso_syntax:decl()]) -> [aeso_syntax:decl()]. -spec process_block(aeso_syntax:ann(), [aeso_syntax:decl()]) -> [aeso_syntax:decl()].
process_block(_, []) -> []; process_block(_, []) -> [];
process_block(_, [Decl]) -> [Decl]; process_block(_, [Decl]) -> [Decl];
process_block(Ann, [Decl | Decls]) -> process_block(_Ann, [Decl | Decls]) ->
IsThis = fun(Name) -> fun({letfun, _, {id, _, Name1}, _, _, _}) -> Name == Name1; IsThis = fun(Name) -> fun({letfun, _, {id, _, Name1}, _, _, _}) -> Name == Name1;
(_) -> false end end, (_) -> false end end,
case Decl of case Decl of
@ -693,6 +697,20 @@ process_block(Ann, [Decl | Decls]) ->
[{fun_clauses, Ann1, Id, {id, [{origin, system} | Ann1], "_"}, Clauses}] [{fun_clauses, Ann1, Id, {id, [{origin, system} | Ann1], "_"}, Clauses}]
end. end.
%% Turns private stuff into public stuff
expose_internals(Defs, What) ->
[ begin
Ann = element(2, Def),
NewAnn = case What of
namespace -> [A ||A <- Ann, A /= {private, true}, A /= private];
main_contract -> [{entrypoint, true}|Ann]; % minor duplication
contract -> Ann
end,
setelement(2, Def, NewAnn)
end
|| Def <- Defs
].
-spec check_typedefs(env(), [aeso_syntax:decl()]) -> {env(), [aeso_syntax:decl()]}. -spec check_typedefs(env(), [aeso_syntax:decl()]) -> {env(), [aeso_syntax:decl()]}.
check_typedefs(Env = #env{ namespace = Ns }, Defs) -> check_typedefs(Env = #env{ namespace = Ns }, Defs) ->
create_type_errors(), create_type_errors(),

View File

@ -39,6 +39,7 @@
| pp_bytecode | pp_bytecode
| no_code | no_code
| keep_included | keep_included
| debug_mode
| {backend, aevm | fate} | {backend, aevm | fate}
| {include, {file_system, [string()]} | | {include, {file_system, [string()]} |
{explicit_files, #{string() => binary()}}} {explicit_files, #{string() => binary()}}}

View File

@ -97,7 +97,10 @@ all_contracts() -> aeso_compiler_tests:compilable_contracts().
aci_test_contract(Name) -> aci_test_contract(Name) ->
String = aeso_test_utils:read_contract(Name), String = aeso_test_utils:read_contract(Name),
Opts = [{include, {file_system, [aeso_test_utils:contract_path()]}}], Opts = case lists:member(Name, aeso_compiler_tests:debug_mode_contracts()) of
true -> [debug_mode];
false -> []
end ++ [{include, {file_system, [aeso_test_utils:contract_path()]}}],
{ok, JSON} = aeso_aci:contract_interface(json, String, Opts), {ok, JSON} = aeso_aci:contract_interface(json, String, Opts),
{ok, #{aci := JSON1}} = aeso_compiler:from_string(String, [{aci, json}, {backend, fate} | Opts]), {ok, #{aci := JSON1}} = aeso_compiler:from_string(String, [{aci, json}, {backend, fate} | Opts]),
?assertEqual(JSON, JSON1), ?assertEqual(JSON, JSON1),

View File

@ -110,7 +110,15 @@ compile(Backend, Name) ->
compile(Backend, Name, Options) -> compile(Backend, Name, Options) ->
String = aeso_test_utils:read_contract(Name), String = aeso_test_utils:read_contract(Name),
case aeso_compiler:from_string(String, [{src_file, Name ++ ".aes"}, {backend, Backend} | Options]) of Options1 =
case lists:member(Name, debug_mode_contracts()) of
true -> [debug_mode];
false -> []
end ++
[ {src_file, Name ++ ".aes"}, {backend, Backend}
, {include, {file_system, [aeso_test_utils:contract_path()]}}
] ++ Options,
case aeso_compiler:from_string(String, Options1) of
{ok, Map} -> Map; {ok, Map} -> Map;
{error, ErrorString} when is_binary(ErrorString) -> ErrorString; {error, ErrorString} when is_binary(ErrorString) -> ErrorString;
{error, Errors} -> Errors {error, Errors} -> Errors
@ -165,15 +173,20 @@ compilable_contracts() ->
"underscore_number_literals", "underscore_number_literals",
"qualified_constructor", "qualified_constructor",
"let_patterns", "let_patterns",
"lhs_matching" "lhs_matching",
"hermetization_turnoff"
]. ].
not_compilable_on(fate) -> []; not_compilable_on(fate) -> [];
not_compilable_on(aevm) -> not_compilable_on(aevm) ->
["stdlib_include", ["stdlib_include",
"manual_stdlib_include" "manual_stdlib_include",
"hermetization_turnoff"
]. ].
debug_mode_contracts() ->
["hermetization_turnoff"].
%% Contracts that should produce type errors %% Contracts that should produce type errors
-define(Pos(Kind, File, Line, Col), (list_to_binary(Kind))/binary, " error in '", -define(Pos(Kind, File, Line, Col), (list_to_binary(Kind))/binary, " error in '",
@ -853,6 +866,11 @@ validate(Contract1, Contract2) ->
ByteCode = #{ fate_code := FCode } = compile(fate, Contract1), ByteCode = #{ fate_code := FCode } = compile(fate, Contract1),
FCode1 = aeb_fate_code:serialize(aeb_fate_code:strip_init_function(FCode)), FCode1 = aeb_fate_code:serialize(aeb_fate_code:strip_init_function(FCode)),
Source = aeso_test_utils:read_contract(Contract2), Source = aeso_test_utils:read_contract(Contract2),
aeso_compiler:validate_byte_code(ByteCode#{ byte_code := FCode1 }, Source, aeso_compiler:validate_byte_code(
ByteCode#{ byte_code := FCode1 }, Source,
case lists:member(Contract2, debug_mode_contracts()) of
true -> [debug_mode];
false -> []
end ++
[{backend, fate}, {include, {file_system, [aeso_test_utils:contract_path()]}}]). [{backend, fate}, {include, {file_system, [aeso_test_utils:contract_path()]}}]).

View File

@ -0,0 +1,11 @@
namespace M =
function mf() = mg()
function mg() = mf()
namespace N =
function nf() = ng() + M.mf() + M.mg()
private function ng() = nf() + M.mf() + M.mg()
contract C =
entrypoint f() = N.ng() + N.nf() + g()
function g() = N.ng() + N.nf() + f()