From bea524635b997447b1d3f8de6960f0cc9b6a3995 Mon Sep 17 00:00:00 2001 From: Ulf Norell Date: Tue, 28 May 2019 16:40:54 +0200 Subject: [PATCH] Add backend argument (aevm | fate) to aeso_compiler options and test fate backend on (most) compilable contracts --- src/aeso_compiler.erl | 43 ++++++++++++++++++++++-------------- test/aeso_compiler_tests.erl | 40 ++++++++++++++++++++++----------- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/aeso_compiler.erl b/src/aeso_compiler.erl index 2fb5763..513dac6 100644 --- a/src/aeso_compiler.erl +++ b/src/aeso_compiler.erl @@ -75,23 +75,14 @@ file(File, Options) -> end. -spec from_string(binary() | string(), options()) -> {ok, map()} | {error, binary()}. -from_string(ContractBin, Options) when is_binary(ContractBin) -> - from_string(binary_to_list(ContractBin), Options); -from_string(ContractString, Options) -> +from_string(Contract, Options) -> + from_string(proplists:get_value(backend, Options, aevm), Contract, Options). + +from_string(Backend, ContractBin, Options) when is_binary(ContractBin) -> + from_string(Backend, binary_to_list(ContractBin), Options); +from_string(Backend, ContractString, Options) -> try - #{icode := Icode} = string_to_icode(ContractString, Options), - TypeInfo = extract_type_info(Icode), - Assembler = assemble(Icode, Options), - pp_assembler(Assembler, Options), - ByteCodeList = to_bytecode(Assembler, Options), - ByteCode = << << B:8 >> || B <- ByteCodeList >>, - pp_bytecode(ByteCode, Options), - {ok, Version} = version(), - {ok, #{byte_code => ByteCode, - compiler_version => Version, - contract_source => ContractString, - type_info => TypeInfo - }} + from_string1(Backend, ContractString, Options) catch %% The compiler errors. error:{parse_errors, Errors} -> @@ -104,6 +95,26 @@ from_string(ContractString, Options) -> %% General programming errors in the compiler just signal error. end. +from_string1(aevm, ContractString, Options) -> + #{icode := Icode} = string_to_icode(ContractString, Options), + TypeInfo = extract_type_info(Icode), + Assembler = assemble(Icode, Options), + pp_assembler(Assembler, Options), + ByteCodeList = to_bytecode(Assembler, Options), + ByteCode = << << B:8 >> || B <- ByteCodeList >>, + pp_bytecode(ByteCode, Options), + {ok, Version} = version(), + {ok, #{byte_code => ByteCode, + compiler_version => Version, + contract_source => ContractString, + type_info => TypeInfo + }}; +from_string1(fate, ContractString, Options) -> + Ast = parse(ContractString, Options), + TypedAst = aeso_ast_infer_types:infer(Ast, Options), + FCode = aeso_ast_to_fcode:ast_to_fcode(TypedAst, Options), + {ok, aeso_fcode_to_fate:compile(FCode, Options)}. + -spec string_to_icode(string(), [option()]) -> map(). string_to_icode(ContractString, Options) -> Ast = parse(ContractString, Options), diff --git a/test/aeso_compiler_tests.erl b/test/aeso_compiler_tests.erl index 2a6ac0e..b704e21 100644 --- a/test/aeso_compiler_tests.erl +++ b/test/aeso_compiler_tests.erl @@ -16,20 +16,24 @@ %% are made on the output, just that it is a binary which indicates %% that the compilation worked. simple_compile_test_() -> - [ {"Testing the " ++ ContractName ++ " contract", + [ {"Testing the " ++ ContractName ++ " contract with the " ++ atom_to_list(Backend) ++ " backend", fun() -> - case compile(ContractName) of + case compile(Backend, ContractName) of #{byte_code := ByteCode, contract_source := _, - type_info := _} -> ?assertMatch(Code when is_binary(Code), ByteCode); + type_info := _} when Backend == aevm -> + ?assertMatch(Code when is_binary(Code), ByteCode); + Code when Backend == fate, is_tuple(Code) -> + ?assertMatch(#{}, aeb_fate_code:functions(Code)); ErrBin -> io:format("\n~s", [ErrBin]), error(ErrBin) end - end} || ContractName <- compilable_contracts() ] ++ + end} || ContractName <- compilable_contracts(), Backend <- [aevm, fate], + not lists:member(ContractName, not_yet_compilable(Backend))] ++ [ {"Testing error messages of " ++ ContractName, fun() -> - case compile(ContractName) of + case compile(aevm, ContractName) of <<"Type errors\n", ErrorString/binary>> -> check_errors(lists:sort(ExpectedErrors), ErrorString); <<"Parse errors\n", ErrorString/binary>> -> @@ -44,14 +48,14 @@ simple_compile_test_() -> {ok, Bin} = file:read_file(filename:join([aeso_test_utils:contract_path(), File])), {File, Bin} end || File <- ["included.aes", "../contracts/included2.aes"] ]), - #{byte_code := Code1} = compile("include", [{include, {explicit_files, FileSystem}}]), - #{byte_code := Code2} = compile("include"), + #{byte_code := Code1} = compile(aevm, "include", [{include, {explicit_files, FileSystem}}]), + #{byte_code := Code2} = compile(aevm, "include"), ?assertMatch(true, Code1 == Code2) end} ] ++ [ {"Testing deadcode elimination", fun() -> - #{ byte_code := NoDeadCode } = compile("nodeadcode"), - #{ byte_code := DeadCode } = compile("deadcode"), + #{ byte_code := NoDeadCode } = compile(aevm, "nodeadcode"), + #{ byte_code := DeadCode } = compile(aevm, "deadcode"), SizeNoDeadCode = byte_size(NoDeadCode), SizeDeadCode = byte_size(DeadCode), ?assertMatch({_, _, true}, {SizeDeadCode, SizeNoDeadCode, SizeDeadCode + 40 < SizeNoDeadCode}), @@ -67,12 +71,12 @@ check_errors(Expect, ErrorString) -> {Missing, Extra} -> ?assertEqual(Missing, Extra) end. -compile(Name) -> - compile(Name, [{include, {file_system, [aeso_test_utils:contract_path()]}}]). +compile(Backend, Name) -> + compile(Backend, Name, [{include, {file_system, [aeso_test_utils:contract_path()]}}]). -compile(Name, Options) -> +compile(Backend, Name, Options) -> String = aeso_test_utils:read_contract(Name), - case aeso_compiler:from_string(String, [{src_file, Name} | Options]) of + case aeso_compiler:from_string(String, [{src_file, Name}, {backend, Backend} | Options]) of {ok, Map} -> Map; {error, ErrorString} -> ErrorString end. @@ -112,6 +116,16 @@ compilable_contracts() -> "address_chain" ]. +not_yet_compilable(fate) -> + ["oracles", %% Oracle.register + "events", %% events + "basic_auth", %% auth_tx_hash instruction + "bitcoin_auth", %% auth_tx_hash instruction + "address_literals", %% oracle_query_id literals + "address_chain" %% Oracle.check_query + ]; +not_yet_compilable(aevm) -> []. + %% Contracts that should produce type errors failing_contracts() ->