Add backend argument (aevm | fate) to aeso_compiler options
and test fate backend on (most) compilable contracts
This commit is contained in:
parent
e44a890292
commit
bea524635b
@ -75,23 +75,14 @@ file(File, Options) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
-spec from_string(binary() | string(), options()) -> {ok, map()} | {error, binary()}.
|
-spec from_string(binary() | string(), options()) -> {ok, map()} | {error, binary()}.
|
||||||
from_string(ContractBin, Options) when is_binary(ContractBin) ->
|
from_string(Contract, Options) ->
|
||||||
from_string(binary_to_list(ContractBin), Options);
|
from_string(proplists:get_value(backend, Options, aevm), Contract, Options).
|
||||||
from_string(ContractString, Options) ->
|
|
||||||
|
from_string(Backend, ContractBin, Options) when is_binary(ContractBin) ->
|
||||||
|
from_string(Backend, binary_to_list(ContractBin), Options);
|
||||||
|
from_string(Backend, ContractString, Options) ->
|
||||||
try
|
try
|
||||||
#{icode := Icode} = string_to_icode(ContractString, Options),
|
from_string1(Backend, 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
|
|
||||||
}}
|
|
||||||
catch
|
catch
|
||||||
%% The compiler errors.
|
%% The compiler errors.
|
||||||
error:{parse_errors, Errors} ->
|
error:{parse_errors, Errors} ->
|
||||||
@ -104,6 +95,26 @@ from_string(ContractString, Options) ->
|
|||||||
%% General programming errors in the compiler just signal error.
|
%% General programming errors in the compiler just signal error.
|
||||||
end.
|
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().
|
-spec string_to_icode(string(), [option()]) -> map().
|
||||||
string_to_icode(ContractString, Options) ->
|
string_to_icode(ContractString, Options) ->
|
||||||
Ast = parse(ContractString, Options),
|
Ast = parse(ContractString, Options),
|
||||||
|
@ -16,20 +16,24 @@
|
|||||||
%% are made on the output, just that it is a binary which indicates
|
%% are made on the output, just that it is a binary which indicates
|
||||||
%% that the compilation worked.
|
%% that the compilation worked.
|
||||||
simple_compile_test_() ->
|
simple_compile_test_() ->
|
||||||
[ {"Testing the " ++ ContractName ++ " contract",
|
[ {"Testing the " ++ ContractName ++ " contract with the " ++ atom_to_list(Backend) ++ " backend",
|
||||||
fun() ->
|
fun() ->
|
||||||
case compile(ContractName) of
|
case compile(Backend, ContractName) of
|
||||||
#{byte_code := ByteCode,
|
#{byte_code := ByteCode,
|
||||||
contract_source := _,
|
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 ->
|
ErrBin ->
|
||||||
io:format("\n~s", [ErrBin]),
|
io:format("\n~s", [ErrBin]),
|
||||||
error(ErrBin)
|
error(ErrBin)
|
||||||
end
|
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,
|
[ {"Testing error messages of " ++ ContractName,
|
||||||
fun() ->
|
fun() ->
|
||||||
case compile(ContractName) of
|
case compile(aevm, ContractName) of
|
||||||
<<"Type errors\n", ErrorString/binary>> ->
|
<<"Type errors\n", ErrorString/binary>> ->
|
||||||
check_errors(lists:sort(ExpectedErrors), ErrorString);
|
check_errors(lists:sort(ExpectedErrors), ErrorString);
|
||||||
<<"Parse errors\n", ErrorString/binary>> ->
|
<<"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])),
|
{ok, Bin} = file:read_file(filename:join([aeso_test_utils:contract_path(), File])),
|
||||||
{File, Bin}
|
{File, Bin}
|
||||||
end || File <- ["included.aes", "../contracts/included2.aes"] ]),
|
end || File <- ["included.aes", "../contracts/included2.aes"] ]),
|
||||||
#{byte_code := Code1} = compile("include", [{include, {explicit_files, FileSystem}}]),
|
#{byte_code := Code1} = compile(aevm, "include", [{include, {explicit_files, FileSystem}}]),
|
||||||
#{byte_code := Code2} = compile("include"),
|
#{byte_code := Code2} = compile(aevm, "include"),
|
||||||
?assertMatch(true, Code1 == Code2)
|
?assertMatch(true, Code1 == Code2)
|
||||||
end} ] ++
|
end} ] ++
|
||||||
[ {"Testing deadcode elimination",
|
[ {"Testing deadcode elimination",
|
||||||
fun() ->
|
fun() ->
|
||||||
#{ byte_code := NoDeadCode } = compile("nodeadcode"),
|
#{ byte_code := NoDeadCode } = compile(aevm, "nodeadcode"),
|
||||||
#{ byte_code := DeadCode } = compile("deadcode"),
|
#{ byte_code := DeadCode } = compile(aevm, "deadcode"),
|
||||||
SizeNoDeadCode = byte_size(NoDeadCode),
|
SizeNoDeadCode = byte_size(NoDeadCode),
|
||||||
SizeDeadCode = byte_size(DeadCode),
|
SizeDeadCode = byte_size(DeadCode),
|
||||||
?assertMatch({_, _, true}, {SizeDeadCode, SizeNoDeadCode, SizeDeadCode + 40 < SizeNoDeadCode}),
|
?assertMatch({_, _, true}, {SizeDeadCode, SizeNoDeadCode, SizeDeadCode + 40 < SizeNoDeadCode}),
|
||||||
@ -67,12 +71,12 @@ check_errors(Expect, ErrorString) ->
|
|||||||
{Missing, Extra} -> ?assertEqual(Missing, Extra)
|
{Missing, Extra} -> ?assertEqual(Missing, Extra)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
compile(Name) ->
|
compile(Backend, Name) ->
|
||||||
compile(Name, [{include, {file_system, [aeso_test_utils:contract_path()]}}]).
|
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),
|
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;
|
{ok, Map} -> Map;
|
||||||
{error, ErrorString} -> ErrorString
|
{error, ErrorString} -> ErrorString
|
||||||
end.
|
end.
|
||||||
@ -112,6 +116,16 @@ compilable_contracts() ->
|
|||||||
"address_chain"
|
"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
|
%% Contracts that should produce type errors
|
||||||
|
|
||||||
failing_contracts() ->
|
failing_contracts() ->
|
||||||
|
Loading…
x
Reference in New Issue
Block a user