From 523d6b03a9f4779f4c15ff153a2563c1d0a3b068 Mon Sep 17 00:00:00 2001 From: Ulf Norell Date: Tue, 25 Jun 2019 16:26:50 +0200 Subject: [PATCH] Allow bytes(N) as indices if N =< 32 and payload if N > 32 --- src/aeso_ast_infer_types.erl | 4 ++-- src/aeso_builtins.erl | 27 +++++++++++++++++---------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/aeso_ast_infer_types.erl b/src/aeso_ast_infer_types.erl index 8df2359..b1caf16 100644 --- a/src/aeso_ast_infer_types.erl +++ b/src/aeso_ast_infer_types.erl @@ -772,13 +772,13 @@ is_word_type({id, _, Name}) -> lists:member(Name, ["int", "address", "hash", "bits", "bool"]); is_word_type({app_t, _, {id, _, Name}, [_, _]}) -> lists:member(Name, ["oracle", "oracle_query"]); -is_word_type({bytes_t, _, [N]}) -> N =< 32; +is_word_type({bytes_t, _, N}) -> N =< 32; is_word_type({con, _, _}) -> true; is_word_type({qcon, _, _}) -> true; is_word_type(_) -> false. is_string_type({id, _, "string"}) -> true; -is_string_type({bytes_t, _, _}) -> true; +is_string_type({bytes_t, _, N}) -> N > 32; is_string_type(_) -> false. -spec check_constructor_overlap(env(), aeso_syntax:con(), type()) -> ok | no_return(). diff --git a/src/aeso_builtins.erl b/src/aeso_builtins.erl index 4736e2f..daf638f 100644 --- a/src/aeso_builtins.erl +++ b/src/aeso_builtins.erl @@ -119,11 +119,12 @@ check_event_type(EvtName, Ix, Type, Icode) -> catch _:_ -> error({EvtName, could_not_resolve_type, Type}) end, - case {Ix, VMType} of - {indexed, word} -> ok; - {notindexed, string} -> ok; - {indexed, _} -> error({EvtName, indexed_field_should_be_word, is, VMType}); - {notindexed, _} -> error({EvtName, payload_should_be_string, is, VMType}) + case {Ix, VMType, Type} of + {indexed, word, _} -> ok; + {notindexed, string, _} -> ok; + {notindexed, _, {bytes_t, _, N}} when N > 32 -> ok; + {indexed, _, _} -> error({EvtName, indexed_field_should_be_word, is, VMType}); + {notindexed, _, _} -> error({EvtName, payload_should_be_string, is, VMType}) end. bfun(B, {IArgs, IExpr, IRet}) -> @@ -177,16 +178,22 @@ builtin_event(EventT) -> VIx = fun(Ix) -> v(lists:concat(["v", Ix])) end, ArgPats = fun(Ts) -> [ VIx(Ix) || Ix <- lists:seq(0, length(Ts) - 1) ] end, Payload = %% Should put data ptr, length on stack. - fun([]) -> {inline_asm, [A(?PUSH1), 0, A(?PUSH1), 0]}; - ([V]) -> {seq, [V, {inline_asm, [A(?DUP1), A(?MLOAD), %% length, ptr - A(?SWAP1), A(?PUSH1), 32, A(?ADD)]}]} %% ptr+32, length + fun([]) -> {inline_asm, [A(?PUSH1), 0, A(?PUSH1), 0]}; + ([{{id, _, "string"}, V}]) -> + {seq, [V, {inline_asm, [A(?DUP1), A(?MLOAD), %% length, ptr + A(?SWAP1), A(?PUSH1), 32, A(?ADD)]}]}; %% ptr+32, length + ([{{bytes_t, _, N}, V}]) -> {seq, [V, {integer, N}, {inline_asm, A(?SWAP1)}]} end, + Ix = + fun({bytes_t, _, N}, V) when N < 32 -> ?BSR(V, 32 - N); + (_, V) -> V end, Clause = fun(_Tag, {con, _, Con}, IxTypes) -> Types = [ T || {_Ix, T} <- IxTypes ], - Indexed = [ Var || {Var, {indexed, _Type}} <- lists:zip(ArgPats(Types), IxTypes) ], + Indexed = [ Ix(Type, Var) || {Var, {indexed, Type}} <- lists:zip(ArgPats(Types), IxTypes) ], + Data = [ {Type, Var} || {Var, {notindexed, Type}} <- lists:zip(ArgPats(Types), IxTypes) ], EvtIndex = {unop, 'sha3', str_to_icode(Con)}, - {event, lists:reverse(Indexed) ++ [EvtIndex], Payload(ArgPats(Types) -- Indexed)} + {event, lists:reverse(Indexed) ++ [EvtIndex], Payload(Data)} end, Pat = fun(Tag, Types) -> {tuple, [{integer, Tag} | ArgPats(Types)]} end,