Merge pull request #284 from aeternity/hermetization-turnoff

Debug mode to turn off hermetization
This commit is contained in:
Radosław Rowicki 2020-10-12 13:17:40 +02:00 committed by GitHub
commit 0b83422189
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 17 deletions

View File

@ -69,7 +69,7 @@ do_contract_interface(Type, ContractString, Options) ->
try
Ast = aeso_compiler:parse(ContractString, Options),
%% 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]),
from_typed_ast(Type, TypedAst)
catch

View File

@ -557,7 +557,7 @@ map_t(As, K, V) -> {app_t, As, {id, As, "map"}, [K, V]}.
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().
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())) ->
{env(), [aeso_syntax:decl()]}.
infer_contract_top(Env, Kind, Defs0, _Options) ->
infer_contract_top(Env, Kind, Defs0, Options) ->
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
%% a list of definitions.
-spec infer_contract(env(), main_contract | contract | namespace, [aeso_syntax:decl()]) -> {env(), [aeso_syntax:decl()]}.
infer_contract(Env0, What, Defs0) ->
-spec infer_contract(env(), main_contract | contract | namespace, [aeso_syntax:decl()], list(option())) -> {env(), [aeso_syntax:decl()]}.
infer_contract(Env0, What, Defs0, Options) ->
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),
Env = Env0#env{ what = What },
Kind = fun({type_def, _, _, _, _}) -> type;
@ -679,7 +683,7 @@ process_blocks(Decls) ->
-spec process_block(aeso_syntax:ann(), [aeso_syntax:decl()]) -> [aeso_syntax:decl()].
process_block(_, []) -> [];
process_block(_, [Decl]) -> [Decl];
process_block(Ann, [Decl | Decls]) ->
process_block(_Ann, [Decl | Decls]) ->
IsThis = fun(Name) -> fun({letfun, _, {id, _, Name1}, _, _, _}) -> Name == Name1;
(_) -> false end end,
case Decl of
@ -693,6 +697,20 @@ process_block(Ann, [Decl | Decls]) ->
[{fun_clauses, Ann1, Id, {id, [{origin, system} | Ann1], "_"}, Clauses}]
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()]}.
check_typedefs(Env = #env{ namespace = Ns }, Defs) ->
create_type_errors(),

View File

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

View File

@ -97,7 +97,10 @@ all_contracts() -> aeso_compiler_tests:compilable_contracts().
aci_test_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, #{aci := JSON1}} = aeso_compiler:from_string(String, [{aci, json}, {backend, fate} | Opts]),
?assertEqual(JSON, JSON1),

View File

@ -110,7 +110,15 @@ compile(Backend, Name) ->
compile(Backend, Name, Options) ->
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;
{error, ErrorString} when is_binary(ErrorString) -> ErrorString;
{error, Errors} -> Errors
@ -165,15 +173,20 @@ compilable_contracts() ->
"underscore_number_literals",
"qualified_constructor",
"let_patterns",
"lhs_matching"
"lhs_matching",
"hermetization_turnoff"
].
not_compilable_on(fate) -> [];
not_compilable_on(aevm) ->
["stdlib_include",
"manual_stdlib_include"
"manual_stdlib_include",
"hermetization_turnoff"
].
debug_mode_contracts() ->
["hermetization_turnoff"].
%% Contracts that should produce type errors
-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),
FCode1 = aeb_fate_code:serialize(aeb_fate_code:strip_init_function(FCode)),
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()]}}]).

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()