diff --git a/include/aeso_heap.hrl b/include/aeso_heap.hrl deleted file mode 100644 index a37d97a..0000000 --- a/include/aeso_heap.hrl +++ /dev/null @@ -1,15 +0,0 @@ - --record(pmap, {key_t :: aeso_sophia:type(), - val_t :: aeso_sophia:type(), - parent :: none | non_neg_integer(), - size = 0 :: non_neg_integer(), - data :: #{aeso_heap:binary_value() => aeso_heap:binary_value() | tombstone} - | stored}). - --record(maps, { maps = #{} :: #{ non_neg_integer() => #pmap{} } - , next_id = 0 :: non_neg_integer() }). - --record(heap, { maps :: #maps{}, - offset :: aeso_heap:offset(), - heap :: binary() | #{non_neg_integer() => non_neg_integer()} }). - diff --git a/src/aeso_abi.erl b/src/aeso_abi.erl deleted file mode 100644 index da507ab..0000000 --- a/src/aeso_abi.erl +++ /dev/null @@ -1,209 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @copyright (C) 2017, Aeternity Anstalt -%%% @doc -%%% Encode and decode data and function calls according to -%%% Sophia-AEVM-ABI. -%%% @end -%%% Created : 25 Jan 2018 -%%% -%%%------------------------------------------------------------------- --module(aeso_abi). --define(HASH_SIZE, 32). - --export([ old_create_calldata/3 - , create_calldata/4 - , check_calldata/2 - , function_type_info/3 - , function_type_hash/3 - , arg_typerep_from_function/2 - , type_hash_from_function_name/2 - , typereps_from_type_hash/2 - , function_name_from_type_hash/2 - , get_function_hash_from_calldata/1 - ]). - --type hash() :: <<_:256>>. %% 256 = ?HASH_SIZE * 8. --type function_name() :: binary(). %% String --type typerep() :: aeso_sophia:type(). --type function_type_info() :: { FunctionHash :: hash() - , FunctionName :: function_name() - , ArgType :: binary() %% binary typerep - , OutType :: binary() %% binary typerep - }. --type type_info() :: [function_type_info()]. - -%%%=================================================================== -%%% API -%%%=================================================================== - -%%%=================================================================== -%%% Handle calldata - -create_calldata(FunName, Args, ArgTypes0, RetType) -> - ArgTypes = {tuple, ArgTypes0}, - <> = - function_type_hash(list_to_binary(FunName), ArgTypes, RetType), - Data = aeso_heap:to_binary({TypeHashInt, list_to_tuple(Args)}), - {ok, Data, {tuple, [word, ArgTypes]}, RetType}. - -get_type_info_and_hash(#{type_info := TypeInfo}, FunName) -> - FunBin = list_to_binary(FunName), - case type_hash_from_function_name(FunBin, TypeInfo) of - {ok, <>} -> {ok, TypeInfo, TypeHashInt}; - {ok, _} -> {error, bad_type_hash}; - {error, _} = Err -> Err - end. - --spec check_calldata(binary(), type_info()) -> - {'ok', typerep(), typerep()} | {'error', atom()}. -check_calldata(CallData, TypeInfo) -> - %% The first element of the CallData should be the function name - case get_function_hash_from_calldata(CallData) of - {ok, Hash} -> - case typereps_from_type_hash(Hash, TypeInfo) of - {ok, ArgType, OutType} -> - try aeso_heap:from_binary({tuple, [word, ArgType]}, CallData) of - {ok, _Something} -> - {ok, {tuple, [word, ArgType]}, OutType}; - {error, _} -> - {error, bad_call_data} - catch - _T:_E -> - {error, bad_call_data} - end; - {error, _} -> - {error, unknown_function} - end; - {error, _What} -> - {error, bad_call_data} - end. - --spec get_function_hash_from_calldata(CallData::binary()) -> - {ok, binary()} | {error, term()}. -get_function_hash_from_calldata(CallData) -> - case aeso_heap:from_binary({tuple, [word]}, CallData) of - {ok, {HashInt}} -> {ok, <>}; - {error, _} = Error -> Error - end. - -%%%=================================================================== -%%% Handle type info from contract meta data - --spec function_type_info(function_name(), [typerep()], typerep()) -> - function_type_info(). -function_type_info(Name, ArgTypes, OutType) -> - ArgType = {tuple, ArgTypes}, - { function_type_hash(Name, ArgType, OutType) - , Name - , aeso_heap:to_binary(ArgType) - , aeso_heap:to_binary(OutType) - }. - --spec function_type_hash(function_name(), typerep(), typerep()) -> hash(). -function_type_hash(Name, ArgType, OutType) when is_binary(Name) -> - Bin = iolist_to_binary([ Name - , aeso_heap:to_binary(ArgType) - , aeso_heap:to_binary(OutType) - ]), - %% Calculate a 256 bit digest BLAKE2b hash value of a binary - {ok, Hash} = eblake2:blake2b(?HASH_SIZE, Bin), - Hash. - --spec arg_typerep_from_function(function_name(), type_info()) -> - {'ok', typerep()} | {'error', 'bad_type_data' | 'unknown_function'}. -arg_typerep_from_function(Function, TypeInfo) -> - case lists:keyfind(Function, 2, TypeInfo) of - {_TypeHash, Function, ArgTypeBin,_OutTypeBin} -> - case aeso_heap:from_binary(typerep, ArgTypeBin) of - {ok, ArgType} -> {ok, ArgType}; - {error,_} -> {error, bad_type_data} - end; - false -> - {error, unknown_function} - end. - --spec typereps_from_type_hash(hash(), type_info()) -> - {'ok', typerep(), typerep()} | {'error', 'bad_type_data' | 'unknown_function'}. -typereps_from_type_hash(TypeHash, TypeInfo) -> - case lists:keyfind(TypeHash, 1, TypeInfo) of - {TypeHash,_Function, ArgTypeBin, OutTypeBin} -> - case {aeso_heap:from_binary(typerep, ArgTypeBin), - aeso_heap:from_binary(typerep, OutTypeBin)} of - {{ok, ArgType}, {ok, OutType}} -> {ok, ArgType, OutType}; - {_, _} -> {error, bad_type_data} - end; - false -> - {error, unknown_function} - end. - --spec function_name_from_type_hash(hash(), type_info()) -> - {'ok', function_name()} - | {'error', 'unknown_function'}. -function_name_from_type_hash(TypeHash, TypeInfo) -> - case lists:keyfind(TypeHash, 1, TypeInfo) of - {TypeHash, Function,_ArgTypeBin,_OutTypeBin} -> - {ok, Function}; - false -> - {error, unknown_function} - end. - --spec type_hash_from_function_name(function_name(), type_info()) -> - {'ok', hash()} - | {'error', 'unknown_function'}. -type_hash_from_function_name(Name, TypeInfo) -> - case lists:keyfind(Name, 2, TypeInfo) of - {TypeHash, Name,_ArgTypeBin,_OutTypeBin} -> - {ok, TypeHash}; - false -> - {error, unknown_function} - end. - -%% -- Old calldata creation. Kept for backwards compatibility. --------------- - -old_create_calldata(Contract, Function, Argument) when is_map(Contract) -> - case aeso_constants:string(Argument) of - {ok, {tuple, _, _} = Tuple} -> - old_encode_call(Contract, Function, Tuple); - {ok, {unit, _} = Tuple} -> - old_encode_call(Contract, Function, Tuple); - {ok, ParsedArgument} -> - %% The Sophia compiler does not parse a singleton tuple (42) as a tuple, - %% Wrap it in a tuple. - old_encode_call(Contract, Function, {tuple, [], [ParsedArgument]}); - {error, _} -> - {error, argument_syntax_error} - end. - -%% Call takes one arument. -%% Use a tuple to pass multiple arguments. -old_encode_call(Contract, Function, ArgumentAst) -> - Argument = old_ast_to_erlang(ArgumentAst), - case get_type_info_and_hash(Contract, Function) of - {ok, TypeInfo, TypeHashInt} -> - Data = aeso_heap:to_binary({TypeHashInt, Argument}), - case check_calldata(Data, TypeInfo) of - {ok, CallDataType, OutType} -> - {ok, Data, CallDataType, OutType}; - {error, _} = Err -> - Err - end; - {error, _} = Err -> Err - end. - -old_ast_to_erlang({int, _, N}) -> N; -old_ast_to_erlang({hash, _, <>}) -> N; -old_ast_to_erlang({hash, _, <>}) -> {Hi, Lo}; %% signature -old_ast_to_erlang({bool, _, true}) -> 1; -old_ast_to_erlang({bool, _, false}) -> 0; -old_ast_to_erlang({string, _, Bin}) -> Bin; -old_ast_to_erlang({unit, _}) -> {}; -old_ast_to_erlang({con, _, "None"}) -> none; -old_ast_to_erlang({app, _, {con, _, "Some"}, [A]}) -> {some, old_ast_to_erlang(A)}; -old_ast_to_erlang({tuple, _, Elems}) -> - list_to_tuple(lists:map(fun old_ast_to_erlang/1, Elems)); -old_ast_to_erlang({list, _, Elems}) -> - lists:map(fun old_ast_to_erlang/1, Elems); -old_ast_to_erlang({map, _, Elems}) -> - maps:from_list([ {old_ast_to_erlang(element(1, Elem)), old_ast_to_erlang(element(2, Elem))} - || Elem <- Elems ]). - diff --git a/src/aeso_ast_to_icode.erl b/src/aeso_ast_to_icode.erl index a7fbbb3..06f80a4 100644 --- a/src/aeso_ast_to_icode.erl +++ b/src/aeso_ast_to_icode.erl @@ -420,7 +420,7 @@ ast_body({hash, _, Hash}, _Icode) -> #integer{value = Lo}]} end; ast_body({string,_,Bin}, _Icode) -> - Cpts = [size(Bin) | aeso_memory:binary_to_words(Bin)], + Cpts = [size(Bin) | aeb_memory:binary_to_words(Bin)], #tuple{cpts = [#integer{value=X} || X <- Cpts]}; ast_body({tuple,_,Args}, Icode) -> #tuple{cpts = [ast_body(A, Icode) || A <- Args]}; @@ -444,7 +444,7 @@ ast_body({app, _, {typed, _, {proj, _, {typed, _, Addr, {con, _, Contract}}, {id Gas = proplists:get_value("gas", ArgOpts ++ Defaults), Value = proplists:get_value("value", ArgOpts ++ Defaults), OutType = ast_typerep(OutT, Icode), - <> = aeso_abi:function_type_hash(list_to_binary(FunName), ArgType, OutType), + <> = aeb_abi:function_type_hash(list_to_binary(FunName), ArgType, OutType), %% The function is represented by its type hash (which includes the name) Fun = #integer{value = TypeHash}, #prim_call_contract{ @@ -645,7 +645,7 @@ prim_call(Prim, Amount, Args, ArgTypes, OutType) -> true -> PrimBin = binary:encode_unsigned(Prim), ArgType = {tuple, ArgTypes}, - <> = aeso_abi:function_type_hash(PrimBin, ArgType, OutType), + <> = aeb_abi:function_type_hash(PrimBin, ArgType, OutType), TH; false -> 0 @@ -674,7 +674,7 @@ make_type_def(Args, Def, Icode = #{ type_vars := TypeEnv }) -> ast_typerep(Def, Icode#{ type_vars := maps:merge(TypeEnv, TypeEnv1) }) end. --spec ast_typerep(aeso_syntax:type()) -> aeso_sophia:type(). +-spec ast_typerep(aeso_syntax:type()) -> aeb_aevm_data:type(). ast_typerep(Type) -> ast_typerep(Type, aeso_icode:new([])). ast_typerep({id, _, Name}, Icode) -> diff --git a/src/aeso_builtins.erl b/src/aeso_builtins.erl index dfb2258..b94cb79 100644 --- a/src/aeso_builtins.erl +++ b/src/aeso_builtins.erl @@ -94,7 +94,7 @@ operand(T) -> T. str_to_icode(String) when is_list(String) -> str_to_icode(list_to_binary(String)); str_to_icode(BinStr) -> - Cpts = [size(BinStr) | aeso_memory:binary_to_words(BinStr)], + Cpts = [size(BinStr) | aeb_memory:binary_to_words(BinStr)], #tuple{ cpts = [ #integer{value = X} || X <- Cpts ] }. check_event_type(Icode) -> diff --git a/src/aeso_compiler.erl b/src/aeso_compiler.erl index 5a243ef..f8b2d1d 100644 --- a/src/aeso_compiler.erl +++ b/src/aeso_compiler.erl @@ -208,7 +208,7 @@ last_contract_indent(Decls) -> _ -> 0 end. --spec to_sophia_value(string(), string(), ok | error | revert, aeso_sophia:data()) -> +-spec to_sophia_value(string(), string(), ok | error | revert, aeb_aevm_data:data()) -> {ok, aeso_syntax:expr()} | {error, term()}. to_sophia_value(ContractString, Fun, ResType, Data) -> to_sophia_value(ContractString, Fun, ResType, Data, []). @@ -218,7 +218,7 @@ to_sophia_value(ContractString, Fun, ResType, Data) -> to_sophia_value(_, _, error, Err, _Options) -> {ok, {app, [], {id, [], "error"}, [{string, [], Err}]}}; to_sophia_value(_, _, revert, Data, _Options) -> - case aeso_heap:from_binary(string, Data) of + case aeb_heap:from_binary(string, Data) of {ok, Err} -> {ok, {app, [], {id, [], "abort"}, [{string, [], Err}]}}; {error, _} = Err -> Err end; @@ -230,7 +230,7 @@ to_sophia_value(ContractString, FunName, ok, Data, Options) -> {ok, _, Type0} = get_decode_type(FunName, TypedAst), Type = aeso_ast_infer_types:unfold_types_in_type(TypeEnv, Type0, [unfold_record_types, unfold_variant_types]), VmType = aeso_ast_to_icode:ast_typerep(Type, Icode), - case aeso_heap:from_binary(VmType, Data) of + case aeb_heap:from_binary(VmType, Data) of {ok, VmValue} -> try {ok, translate_vm_value(VmType, Type, VmValue)} @@ -260,7 +260,7 @@ to_sophia_value(ContractString, FunName, ok, Data, Options) -> address_literal(N) -> {hash, [], <>}. % TODO %% TODO: somewhere else --spec translate_vm_value(aeso_sophia:type(), aeso_syntax:type(), aeso_sophia:data()) -> aeso_syntax:expr(). +-spec translate_vm_value(aeb_aevm_data:type(), aeso_syntax:type(), aeb_aevm_data:data()) -> aeso_syntax:expr(). translate_vm_value(word, {id, _, "address"}, N) -> address_literal(N); translate_vm_value(word, {app_t, _, {id, _, "oracle"}, _}, N) -> address_literal(N); translate_vm_value(word, {app_t, _, {id, _, "oracle_query"}, _}, N) -> address_literal(N); @@ -313,12 +313,12 @@ translate_vm_value(_VmType, _Type, _Data) -> throw(cannot_translate_to_sophia). -spec create_calldata(string(), string(), [string()]) -> - {ok, binary(), aeso_sophia:type(), aeso_sophia:type()} + {ok, binary(), aeb_aevm_data:type(), aeb_aevm_data:type()} | {error, term()}. create_calldata(Code, Fun, Args) -> case check_call(Code, Fun, Args, []) of {ok, FunName, {ArgTypes, RetType}, VMArgs} -> - aeso_abi:create_calldata(FunName, VMArgs, ArgTypes, RetType); + aeb_abi:create_calldata(FunName, VMArgs, ArgTypes, RetType); {error, _} = Err -> Err end. @@ -336,7 +336,7 @@ decode_calldata(ContractString, FunName, Calldata) -> Type0 = {tuple_t, [], ArgTypes}, Type = aeso_ast_infer_types:unfold_types_in_type(TypeEnv, Type0, [unfold_record_types, unfold_variant_types]), VmType = aeso_ast_to_icode:ast_typerep(Type, Icode), - case aeso_heap:from_binary({tuple, [word, VmType]}, Calldata) of + case aeb_heap:from_binary({tuple, [word, VmType]}, Calldata) of {ok, {_, VmValue}} -> try {tuple, [], Values} = translate_vm_value(VmType, Type, VmValue), @@ -397,7 +397,7 @@ get_decode_type(FunName, [_ | Contracts]) -> get_decode_type(FunName, Contracts). %% Translate an icode value (error if not value) to an Erlang term that can be -%% consumed by aeso_heap:to_binary(). +%% consumed by aeb_heap:to_binary(). icode_to_term(word, {integer, N}) -> N; icode_to_term(string, {tuple, [{integer, Len} | Words]}) -> <> = << <> || {integer, W} <- Words >>, @@ -445,7 +445,7 @@ to_bytecode([], _) -> []. extract_type_info(#{functions := Functions} =_Icode) -> ArgTypesOnly = fun(As) -> [ T || {_, T} <- As ] end, - TypeInfo = [aeso_abi:function_type_info(list_to_binary(lists:last(Name)), + TypeInfo = [aeb_abi:function_type_info(list_to_binary(lists:last(Name)), ArgTypesOnly(Args), TypeRep) || {Name, Attrs, Args,_Body, TypeRep} <- Functions, not is_tuple(Name), diff --git a/src/aeso_heap.erl b/src/aeso_heap.erl deleted file mode 100644 index b437a68..0000000 --- a/src/aeso_heap.erl +++ /dev/null @@ -1,301 +0,0 @@ --module(aeso_heap). - --export([ to_binary/1 - , to_binary/2 - , from_heap/3 - , from_binary/2 - , from_binary/3 - , maps_with_next_id/1 - , set_next_id/2 - , heap_fragment/3 - , heap_value/3 - , heap_value/4 - , heap_value_pointer/1 - , heap_value_maps/1 - , heap_value_offset/1 - , heap_value_heap/1 - , heap_fragment_maps/1 - , heap_fragment_offset/1 - , heap_fragment_heap/1 - ]). - --export_type([binary_value/0, heap_value/0, offset/0, heap_fragment/0]). - --include("aeso_icode.hrl"). --include_lib("aesophia/include/aeso_heap.hrl"). - --type word() :: non_neg_integer(). --type pointer() :: word(). --opaque heap_fragment() :: #heap{}. --type offset() :: non_neg_integer(). --type binary_value() :: binary(). --type heap_value() :: {pointer(), heap_fragment()}. - - --spec maps_with_next_id(heap_fragment()) -> #maps{}. -%% Create just a maps value, don't keep rest of Heap -maps_with_next_id(#heap{maps = #maps{next_id = N}}) -> - #maps{ next_id = N }. - --spec set_next_id(heap_fragment(), non_neg_integer()) -> heap_fragment(). -set_next_id(Heap, N) -> - Heap#heap{ maps = Heap#heap.maps#maps{ next_id = N } }. - -%% -- data type heap_fragment - --spec heap_fragment(binary() | #{non_neg_integer() => non_neg_integer()}) -> heap_fragment(). -heap_fragment(Heap) -> - heap_fragment(#maps{ next_id = 0 }, 0, Heap). - --spec heap_fragment(#maps{}, offset(), - binary() | #{non_neg_integer() => non_neg_integer()}) -> heap_fragment(). -heap_fragment(Maps, Offset, Heap) -> - #heap{maps = Maps, offset = Offset, heap = Heap}. - --spec heap_fragment_maps(heap_fragment()) -> #maps{}. -heap_fragment_maps(#heap{maps = Maps}) -> - Maps. - --spec heap_fragment_offset(heap_fragment()) -> offset(). -heap_fragment_offset(#heap{offset = Offs}) -> - Offs. - --spec heap_fragment_heap(heap_fragment()) -> binary() | #{non_neg_integer() => non_neg_integer()}. -heap_fragment_heap(#heap{heap = Heap}) -> - Heap. - - -%% -- data type heap_value - --spec heap_value(#maps{}, pointer(), - binary() | #{non_neg_integer() => non_neg_integer()}) -> heap_value(). -heap_value(Maps, Ptr, Heap) -> - heap_value(Maps, Ptr, Heap, 0). - --spec heap_value(#maps{}, pointer(), - binary() | #{non_neg_integer() => non_neg_integer()}, offset()) -> heap_value(). -heap_value(Maps, Ptr, Heap, Offs) -> - {Ptr, heap_fragment(Maps, Offs, Heap)}. - --spec heap_value_pointer(heap_value()) -> pointer(). -heap_value_pointer({Ptr, _}) -> Ptr. - --spec heap_value_maps(heap_value()) -> #maps{}. -heap_value_maps({_, Heap}) -> Heap#heap.maps. - --spec heap_value_offset(heap_value()) -> offset(). -heap_value_offset({_, Heap}) -> Heap#heap.offset. - --spec heap_value_heap(heap_value()) -> - binary() | #{non_neg_integer() => non_neg_integer()}. -heap_value_heap({_, Heap}) -> Heap#heap.heap. - -%% -- Value to binary -------------------------------------------------------- - --spec to_binary(aeso_sophia:data()) -> aeso_sophia:heap(). -%% Encode the data as a heap where the first word is the value (for unboxed -%% types) or a pointer to the value (for boxed types). -to_binary(Data) -> - to_binary(Data, 0). - -to_binary(Data, BaseAddress) -> - {Address, Memory} = to_binary1(Data, BaseAddress + 32), - R = <>, - R. - - -%% Allocate the data in memory, from the given address. Return a pair -%% of memory contents from that address and the value representing the -%% data. -to_binary1(Data,_Address) when is_integer(Data) -> - {Data,<<>>}; -to_binary1(Data, Address) when is_binary(Data) -> - %% a string - Words = aeso_memory:binary_to_words(Data), - {Address,<<(size(Data)):256, << <> || W <- Words>>/binary>>}; -to_binary1(none, Address) -> to_binary1({variant, 0, []}, Address); -to_binary1({some, Value}, Address) -> to_binary1({variant, 1, [Value]}, Address); -to_binary1(word, Address) -> to_binary1({?TYPEREP_WORD_TAG}, Address); -to_binary1(string, Address) -> to_binary1({?TYPEREP_STRING_TAG}, Address); -to_binary1(typerep, Address) -> to_binary1({?TYPEREP_TYPEREP_TAG}, Address); -to_binary1(function, Address) -> to_binary1({?TYPEREP_FUN_TAG}, Address); -to_binary1({list, T}, Address) -> to_binary1({?TYPEREP_LIST_TAG, T}, Address); -to_binary1({option, T}, Address) -> to_binary1({variant, [[], [T]]}, Address); -to_binary1({tuple, Ts}, Address) -> to_binary1({?TYPEREP_TUPLE_TAG, Ts}, Address); -to_binary1({variant, Cons}, Address) -> to_binary1({?TYPEREP_VARIANT_TAG, Cons}, Address); -to_binary1({map, K, V}, Address) -> to_binary1({?TYPEREP_MAP_TAG, K, V}, Address); -to_binary1({variant, Tag, Args}, Address) -> - to_binary1(list_to_tuple([Tag | Args]), Address); -to_binary1(Map, Address) when is_map(Map) -> - Size = maps:size(Map), - %% Sort according to binary ordering - KVs = lists:sort([ {to_binary(K), to_binary(V)} || {K, V} <- maps:to_list(Map) ]), - {Address, <> || {K, V} <- KVs >>/binary >>}; -to_binary1({}, _Address) -> - {0, <<>>}; -to_binary1(Data, Address) when is_tuple(Data) -> - {Elems,Memory} = to_binaries(tuple_to_list(Data),Address+32*size(Data)), - ElemsBin = << <> || W <- Elems>>, - {Address,<< ElemsBin/binary, Memory/binary >>}; -to_binary1([],_Address) -> - <> = <<(-1):256>>, - {Nil,<<>>}; -to_binary1([H|T],Address) -> - to_binary1({H,T},Address). - - -to_binaries([],_Address) -> - {[],<<>>}; -to_binaries([H|T],Address) -> - {HRep,HMem} = to_binary1(H,Address), - {TRep,TMem} = to_binaries(T,Address+size(HMem)), - {[HRep|TRep],<>}. - -%% Interpret a return value (a binary) using a type rep. - --spec from_heap(Type :: ?Type(), Heap :: binary(), Ptr :: integer()) -> - {ok, term()} | {error, term()}. -from_heap(Type, Heap, Ptr) -> - try {ok, from_binary(#{}, Type, Heap, Ptr)} - catch _:Err -> - %% io:format("** Error: from_heap failed with ~p\n ~p\n", [Err, erlang:get_stacktrace()]), - {error, Err} - end. - -%% Base address is the address of the first word of the given heap. --spec from_binary(T :: ?Type(), - Heap :: binary(), - BaseAddr :: non_neg_integer()) -> - {ok, term()} | {error, term()}. -from_binary(T, Heap = <>, BaseAddr) -> - from_heap(T, <<0:BaseAddr/unit:8, Heap/binary>>, V); -from_binary(_, Bin, _BaseAddr) -> - {error, {binary_too_short, Bin}}. - --spec from_binary(?Type(), binary()) -> {ok, term()} | {error, term()}. -from_binary(T, Heap) -> - from_binary(T, Heap, 0). - -from_binary(_, word, _, V) -> - V; -from_binary(_, signed_word, _, V) -> - <> = <>, - N; -from_binary(_, bool, _, V) -> - case V of - 0 -> false; - 1 -> true - end; -from_binary(_, string, Heap, V) -> - StringSize = heap_word(Heap,V), - BitAddr = 8*(V+32), - <<_:BitAddr,Bytes:StringSize/binary,_/binary>> = Heap, - Bytes; -from_binary(_, {tuple, []}, _, _) -> - {}; -from_binary(Visited, {tuple,Cpts}, Heap, V) -> - check_circular_refs(Visited, V), - NewVisited = Visited#{V => true}, - ElementNums = lists:seq(0, length(Cpts)-1), - TypesAndPointers = lists:zip(Cpts, ElementNums), - ElementAddress = fun(Index) -> V + 32 * Index end, - Element = fun(Index) -> - heap_word(Heap, ElementAddress(Index)) - end, - Convert = fun(Type, Index) -> - from_binary(NewVisited, Type, Heap, Element(Index)) - end, - Elements = [Convert(T, I) || {T,I} <- TypesAndPointers], - list_to_tuple(Elements); -from_binary(Visited, {list, Elem}, Heap, V) -> - <> = <<(-1):256>>, - if V==Nil -> - []; - true -> - {H,T} = from_binary(Visited, {tuple,[Elem,{list,Elem}]},Heap,V), - [H|T] - end; -from_binary(Visited, {option, A}, Heap, V) -> - from_binary(Visited, {variant_t, [{none, []}, {some, [A]}]}, Heap, V); -from_binary(Visited, {variant, Cons}, Heap, V) -> - Tag = heap_word(Heap, V), - Args = lists:nth(Tag + 1, Cons), - Visited1 = Visited#{V => true}, - {variant, Tag, tuple_to_list(from_binary(Visited1, {tuple, Args}, Heap, V + 32))}; -from_binary(Visited, {variant_t, TCons}, Heap, V) -> %% Tagged variants - {Tags, Cons} = lists:unzip(TCons), - {variant, I, Args} = from_binary(Visited, {variant, Cons}, Heap, V), - Tag = lists:nth(I + 1, Tags), - case Args of - [] -> Tag; - _ -> list_to_tuple([Tag | Args]) - end; -from_binary(_Visited, {map, A, B}, Heap, Ptr) -> - %% FORMAT: [Size] [KeySize] Key [ValSize] Val .. [KeySize] Key [ValSize] Val - Size = heap_word(Heap, Ptr), - map_binary_to_value(A, B, Size, Heap, Ptr + 32); -from_binary(Visited, typerep, Heap, V) -> - check_circular_refs(Visited, V), - Tag = heap_word(Heap, V), - Arg1 = fun(T, I) -> from_binary(Visited#{V => true}, T, Heap, heap_word(Heap, V + 32 * I)) end, - Arg = fun(T) -> Arg1(T, 1) end, - case Tag of - ?TYPEREP_WORD_TAG -> word; - ?TYPEREP_STRING_TAG -> string; - ?TYPEREP_TYPEREP_TAG -> typerep; - ?TYPEREP_LIST_TAG -> {list, Arg(typerep)}; - ?TYPEREP_TUPLE_TAG -> {tuple, Arg({list, typerep})}; - ?TYPEREP_VARIANT_TAG -> {variant, Arg({list, {list, typerep}})}; - ?TYPEREP_MAP_TAG -> {map, Arg(typerep), Arg1(typerep, 2)}; - ?TYPEREP_FUN_TAG -> function - end. - -map_binary_to_value(KeyType, ValType, N, Bin, Ptr) -> - %% Avoid looping on bogus sizes - MaxN = byte_size(Bin) div 64, - Heap = heap_fragment(Bin), - map_from_binary({value, KeyType, ValType}, min(N, MaxN), Heap, Ptr, #{}). - -map_from_binary(_, 0, _, _, Map) -> Map; -map_from_binary({value, KeyType, ValType} = Output, I, Heap, Ptr, Map) -> - KeySize = get_word(Heap, Ptr), - KeyPtr = Ptr + 32, - KeyBin = get_chunk(Heap, KeyPtr, KeySize), - ValSize = get_word(Heap, KeyPtr + KeySize), - ValPtr = KeyPtr + KeySize + 32, - ValBin = get_chunk(Heap, ValPtr, ValSize), - %% Keys and values are self contained binaries - {ok, Key} = from_binary(KeyType, KeyBin), - {ok, Val} = from_binary(ValType, ValBin), - map_from_binary(Output, I - 1, Heap, ValPtr + ValSize, Map#{Key => Val}). - -check_circular_refs(Visited, V) -> - case maps:is_key(V, Visited) of - true -> exit(circular_references); - false -> ok - end. - -heap_word(Heap, Addr) when is_binary(Heap) -> - BitSize = 8*Addr, - <<_:BitSize,W:256,_/binary>> = Heap, - W; -heap_word(Heap, Addr) when is_map(Heap) -> - 0 = Addr rem 32, %% Check that it's word aligned. - maps:get(Addr, Heap, 0). - -get_word(#heap{offset = Offs, heap = Mem}, Addr) when Addr >= Offs -> - get_word(Mem, Addr - Offs); -get_word(Mem, Addr) when is_binary(Mem) -> - <<_:Addr/unit:8, Word:256, _/binary>> = Mem, - Word. - -get_chunk(#heap{offset = Offs, heap = Mem}, Addr, Bytes) when Addr >= Offs -> - get_chunk(Mem, Addr - Offs, Bytes); -get_chunk(Mem, Addr, Bytes) when is_binary(Mem) -> - <<_:Addr/unit:8, Chunk:Bytes/binary, _/binary>> = Mem, - Chunk. - - - - diff --git a/src/aeso_icode.erl b/src/aeso_icode.erl index 16953da..c589152 100644 --- a/src/aeso_icode.erl +++ b/src/aeso_icode.erl @@ -25,14 +25,14 @@ -include("aeso_icode.hrl"). --type type_def() :: fun(([aeso_sophia:type()]) -> aeso_sophia:type()). +-type type_def() :: fun(([aeb_aevm_data:type()]) -> aeb_aevm_data:type()). -type bindings() :: any(). -type fun_dec() :: { string() , [modifier()] , arg_list() , expr() - , aeso_sophia:type()}. + , aeb_aevm_data:type()}. -type modifier() :: private | stateful. @@ -42,10 +42,10 @@ , functions => [fun_dec()] , namespace => aeso_syntax:con() | aeso_syntax:qcon() , env => [bindings()] - , state_type => aeso_sophia:type() - , event_type => aeso_sophia:type() + , state_type => aeb_aevm_data:type() + , event_type => aeb_aevm_data:type() , types => #{ type_name() => type_def() } - , type_vars => #{ string() => aeso_sophia:type() } + , type_vars => #{ string() => aeb_aevm_data:type() } , constructors => #{ [string()] => integer() } %% name to tag , options => [any()] }. diff --git a/src/aeso_icode.hrl b/src/aeso_icode.hrl index 56da80a..d41fe02 100644 --- a/src/aeso_icode.hrl +++ b/src/aeso_icode.hrl @@ -1,14 +1,5 @@ --define(Type(), aeso_sophia:type()). - --define(TYPEREP_WORD_TAG, 0). --define(TYPEREP_STRING_TAG, 1). --define(TYPEREP_LIST_TAG, 2). --define(TYPEREP_TUPLE_TAG, 3). --define(TYPEREP_VARIANT_TAG, 4). --define(TYPEREP_TYPEREP_TAG, 5). --define(TYPEREP_MAP_TAG, 6). --define(TYPEREP_FUN_TAG, 7). +-include_lib("aebytecode/include/aeb_typerep_def.hrl"). -record(arg, {name::string(), type::?Type()}). diff --git a/src/aeso_icode_to_asm.erl b/src/aeso_icode_to_asm.erl index aa99e2e..7da8010 100644 --- a/src/aeso_icode_to_asm.erl +++ b/src/aeso_icode_to_asm.erl @@ -105,7 +105,7 @@ make_args(Args) -> fun_hash({FName, _, Args, _, TypeRep}) -> ArgType = {tuple, [T || {_, T} <- Args]}, - <> = aeso_abi:function_type_hash(list_to_binary(lists:last(FName)), ArgType, TypeRep), + <> = aeb_abi:function_type_hash(list_to_binary(lists:last(FName)), ArgType, TypeRep), {integer, Hash}. %% Expects two return addresses below N elements on the stack. Picks the top diff --git a/src/aeso_memory.erl b/src/aeso_memory.erl deleted file mode 100644 index 6d6c203..0000000 --- a/src/aeso_memory.erl +++ /dev/null @@ -1,19 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @copyright (C) 2018, Aeternity Anstalt -%%% @doc -%%% Memory speifics that compiler and VM need to agree upon -%%% @end -%%% Created : 19 Dec 2018 -%%%------------------------------------------------------------------- - --module(aeso_memory). - --export([binary_to_words/1]). - -binary_to_words(<<>>) -> - []; -binary_to_words(<>) -> - [N|binary_to_words(Bin)]; -binary_to_words(Bin) -> - binary_to_words(<>). - diff --git a/src/aeso_sophia.erl b/src/aeso_sophia.erl deleted file mode 100644 index 96d6700..0000000 --- a/src/aeso_sophia.erl +++ /dev/null @@ -1,30 +0,0 @@ --module(aeso_sophia). - --export_type([data/0, - type/0, - heap/0]). - --type type() :: word | signed_word | string | typerep | function - | {list, type()} - | {option, type()} - | {tuple, [type()]} - | {variant, [[type()]]}. - - --type data() :: none - | {some, data()} - | {option, data()} - | word - | string - | {list, data()} - | {tuple, [data()]} - | {variant, integer(), [data()]} - | integer() - | binary() - | [data()] - | {} - | {data()} - | {data(), data()}. - --type heap() :: binary(). - diff --git a/test/aeso_abi_tests.erl b/test/aeso_abi_tests.erl index 4ebe946..4f2f256 100644 --- a/test/aeso_abi_tests.erl +++ b/test/aeso_abi_tests.erl @@ -19,8 +19,8 @@ sandbox(Code) -> malicious_from_binary_test() -> CircularList = from_words([32, 1, 32]), %% Xs = 1 :: Xs - {ok, {error, circular_references}} = ?SANDBOX(aeso_heap:from_binary({list, word}, CircularList)), - {ok, {error, {binary_too_short, _}}} = ?SANDBOX(aeso_heap:from_binary(word, <<1, 2, 3, 4>>)), + {ok, {error, circular_references}} = ?SANDBOX(aeb_heap:from_binary({list, word}, CircularList)), + {ok, {error, {binary_too_short, _}}} = ?SANDBOX(aeb_heap:from_binary(word, <<1, 2, 3, 4>>)), ok. from_words(Ws) -> @@ -161,7 +161,7 @@ encode_decode_calldata(FunName, Types, Args, RetType) -> encode_decode_calldata_(Code, FunName, Args, RetVMType) -> {ok, Calldata, CalldataType, RetVMType1} = aeso_compiler:create_calldata(Code, FunName, Args), ?assertEqual(RetVMType1, RetVMType), - {ok, {_Hash, ArgTuple}} = aeso_heap:from_binary(CalldataType, Calldata), + {ok, {_Hash, ArgTuple}} = aeb_heap:from_binary(CalldataType, Calldata), case FunName of "init" -> ok; @@ -177,8 +177,8 @@ encode_decode(T, D) -> D. encode(D) -> - aeso_heap:to_binary(D). + aeb_heap:to_binary(D). decode(T,B) -> - {ok, D} = aeso_heap:from_binary(T, B), + {ok, D} = aeb_heap:from_binary(T, B), D.