More compact implementation of serialization/deserialization
Changed argument specification order
This commit is contained in:
parent
f3c30b059a
commit
6640414b38
@ -158,161 +158,41 @@ serialize_op(Opcode) ->
|
|||||||
%% xx xx xx xx
|
%% xx xx xx xx
|
||||||
%% Arg3 Arg2 Arg1 Arg0
|
%% Arg3 Arg2 Arg1 Arg0
|
||||||
%% For 5-8 args another Argument Spec Byte is used
|
%% For 5-8 args another Argument Spec Byte is used
|
||||||
|
%% bitpos: 6 4 2 0 | 6 4 2 0
|
||||||
|
%% xx xx xx xx | xx xx xx xx
|
||||||
|
%% Arg7 Arg6 Arg5 Arg4 | Arg3 Arg2 Arg1 Arg0
|
||||||
%% Bit pattern
|
%% Bit pattern
|
||||||
%% 00 : stack/unused (depending on instruction)
|
%% 00 : stack/unused (depending on instruction)
|
||||||
%% 01 : argN
|
%% 01 : argN
|
||||||
%% 10 : varN
|
%% 10 : varN
|
||||||
%% 11 : immediate
|
%% 11 : immediate
|
||||||
serialize_code([ {Arg0Type, Arg0}
|
|
||||||
, {Arg1Type, Arg1}
|
|
||||||
, {Arg2Type, Arg2}
|
|
||||||
, {Arg3Type, Arg3}
|
|
||||||
, {Arg4Type, Arg4}
|
|
||||||
, {Arg5Type, Arg5}
|
|
||||||
, {Arg6Type, Arg6}
|
|
||||||
, {Arg7Type, Arg7}
|
|
||||||
| Rest]) ->
|
|
||||||
ArgSpec1 =
|
|
||||||
modifier_bits(Arg0Type) bor
|
|
||||||
(modifier_bits(Arg1Type) bsl 2) bor
|
|
||||||
(modifier_bits(Arg2Type) bsl 4) bor
|
|
||||||
(modifier_bits(Arg3Type) bsl 6),
|
|
||||||
ArgSpec2 =
|
|
||||||
modifier_bits(Arg4Type) bor
|
|
||||||
(modifier_bits(Arg5Type) bsl 2) bor
|
|
||||||
(modifier_bits(Arg6Type) bsl 4) bor
|
|
||||||
(modifier_bits(Arg7Type) bsl 6),
|
|
||||||
[ ArgSpec1
|
|
||||||
, ArgSpec2
|
|
||||||
, serialize_data(Arg0Type, Arg0)
|
|
||||||
, serialize_data(Arg1Type, Arg1)
|
|
||||||
, serialize_data(Arg2Type, Arg2)
|
|
||||||
, serialize_data(Arg3Type, Arg3)
|
|
||||||
, serialize_data(Arg4Type, Arg4)
|
|
||||||
, serialize_data(Arg5Type, Arg5)
|
|
||||||
, serialize_data(Arg6Type, Arg6)
|
|
||||||
, serialize_data(Arg7Type, Arg7)
|
|
||||||
| serialize_code(Rest)];
|
|
||||||
serialize_code([ {Arg0Type, Arg0}
|
|
||||||
, {Arg1Type, Arg1}
|
|
||||||
, {Arg2Type, Arg2}
|
|
||||||
, {Arg3Type, Arg3}
|
|
||||||
, {Arg4Type, Arg4}
|
|
||||||
, {Arg5Type, Arg5}
|
|
||||||
, {Arg6Type, Arg6}
|
|
||||||
| Rest]) ->
|
|
||||||
ArgSpec1 =
|
|
||||||
modifier_bits(Arg0Type) bor
|
|
||||||
(modifier_bits(Arg1Type) bsl 2) bor
|
|
||||||
(modifier_bits(Arg2Type) bsl 4) bor
|
|
||||||
(modifier_bits(Arg3Type) bsl 6),
|
|
||||||
ArgSpec2 =
|
|
||||||
modifier_bits(Arg4Type) bor
|
|
||||||
(modifier_bits(Arg5Type) bsl 2) bor
|
|
||||||
(modifier_bits(Arg6Type) bsl 4),
|
|
||||||
[ ArgSpec1
|
|
||||||
, ArgSpec2
|
|
||||||
, serialize_data(Arg0Type, Arg0)
|
|
||||||
, serialize_data(Arg1Type, Arg1)
|
|
||||||
, serialize_data(Arg2Type, Arg2)
|
|
||||||
, serialize_data(Arg3Type, Arg3)
|
|
||||||
, serialize_data(Arg4Type, Arg4)
|
|
||||||
, serialize_data(Arg5Type, Arg5)
|
|
||||||
, serialize_data(Arg6Type, Arg6)
|
|
||||||
| serialize_code(Rest)];
|
|
||||||
serialize_code([ {Arg0Type, Arg0}
|
|
||||||
, {Arg1Type, Arg1}
|
|
||||||
, {Arg2Type, Arg2}
|
|
||||||
, {Arg3Type, Arg3}
|
|
||||||
, {Arg4Type, Arg4}
|
|
||||||
, {Arg5Type, Arg5}
|
|
||||||
| Rest]) ->
|
|
||||||
ArgSpec1 =
|
|
||||||
modifier_bits(Arg0Type) bor
|
|
||||||
(modifier_bits(Arg1Type) bsl 2) bor
|
|
||||||
(modifier_bits(Arg2Type) bsl 4) bor
|
|
||||||
(modifier_bits(Arg3Type) bsl 6),
|
|
||||||
ArgSpec2 =
|
|
||||||
modifier_bits(Arg4Type) bor
|
|
||||||
(modifier_bits(Arg5Type) bsl 2),
|
|
||||||
[ ArgSpec1
|
|
||||||
, ArgSpec2
|
|
||||||
, serialize_data(Arg0Type, Arg0)
|
|
||||||
, serialize_data(Arg1Type, Arg1)
|
|
||||||
, serialize_data(Arg2Type, Arg2)
|
|
||||||
, serialize_data(Arg3Type, Arg3)
|
|
||||||
, serialize_data(Arg4Type, Arg4)
|
|
||||||
, serialize_data(Arg5Type, Arg5)
|
|
||||||
| serialize_code(Rest)];
|
|
||||||
serialize_code([ {Arg0Type, Arg0}
|
|
||||||
, {Arg1Type, Arg1}
|
|
||||||
, {Arg2Type, Arg2}
|
|
||||||
, {Arg3Type, Arg3}
|
|
||||||
, {Arg4Type, Arg4}
|
|
||||||
| Rest]) ->
|
|
||||||
ArgSpec1 =
|
|
||||||
modifier_bits(Arg0Type) bor
|
|
||||||
(modifier_bits(Arg1Type) bsl 2) bor
|
|
||||||
(modifier_bits(Arg2Type) bsl 4) bor
|
|
||||||
(modifier_bits(Arg3Type) bsl 6),
|
|
||||||
ArgSpec2 =
|
|
||||||
modifier_bits(Arg4Type),
|
|
||||||
[ ArgSpec1
|
|
||||||
, ArgSpec2
|
|
||||||
, serialize_data(Arg0Type, Arg0)
|
|
||||||
, serialize_data(Arg1Type, Arg1)
|
|
||||||
, serialize_data(Arg2Type, Arg2)
|
|
||||||
, serialize_data(Arg3Type, Arg3)
|
|
||||||
, serialize_data(Arg4Type, Arg4)
|
|
||||||
| serialize_code(Rest)];
|
|
||||||
|
|
||||||
serialize_code([ {Arg0Type, Arg0}
|
serialize_code([{_,_}|_] = List ) ->
|
||||||
, {Arg1Type, Arg1}
|
%% Take out the full argument list.
|
||||||
, {Arg2Type, Arg2}
|
{Args, Rest} = lists:splitwith(fun({_, _}) -> true; (_) -> false end, List),
|
||||||
, {Arg3Type, Arg3}| Rest]) ->
|
%% Create the appropriate number of modifier bytes.
|
||||||
ArgSpec =
|
Mods = << <<(modifier_bits(Type)):2>> || {Type, _} <- pad_args(lists:reverse(Args)) >>,
|
||||||
modifier_bits(Arg0Type) bor
|
case Mods of
|
||||||
(modifier_bits(Arg1Type) bsl 2) bor
|
<<M1:8, M2:8>> ->
|
||||||
(modifier_bits(Arg2Type) bsl 4) bor
|
[M1, M2 | [serialize_data(Type, Arg) || {Type, Arg} <- Args]] ++
|
||||||
(modifier_bits(Arg3Type) bsl 6),
|
serialize_code(Rest);
|
||||||
[ ArgSpec
|
<<M1:8>> ->
|
||||||
, serialize_data(Arg0Type, Arg0)
|
[M1 | [serialize_data(Type, Arg) || {Type, Arg} <- Args]] ++
|
||||||
, serialize_data(Arg1Type, Arg1)
|
serialize_code(Rest)
|
||||||
, serialize_data(Arg2Type, Arg2)
|
end;
|
||||||
, serialize_data(Arg3Type, Arg3)
|
serialize_code([Op|Rest]) ->
|
||||||
| serialize_code(Rest)];
|
[Op|serialize_code(Rest)];
|
||||||
serialize_code([ {Arg0Type, Arg0}
|
serialize_code([]) ->
|
||||||
, {Arg1Type, Arg1}
|
[].
|
||||||
, {Arg2Type, Arg2}
|
|
||||||
| Rest]) ->
|
pad_args(List) ->
|
||||||
ArgSpec =
|
case length(List) of
|
||||||
modifier_bits(Arg0Type) bor
|
0 -> List;
|
||||||
(modifier_bits(Arg1Type) bsl 2) bor
|
N when N =< 4 ->
|
||||||
(modifier_bits(Arg2Type) bsl 4),
|
lists:duplicate(4 - N, {stack, 0}) ++ List;
|
||||||
[ArgSpec
|
N when N =< 8 ->
|
||||||
, serialize_data(Arg0Type, Arg0)
|
lists:duplicate(8 - N, {stack, 0}) ++ List
|
||||||
, serialize_data(Arg1Type, Arg1)
|
end.
|
||||||
, serialize_data(Arg2Type, Arg2)
|
|
||||||
| serialize_code(Rest)];
|
|
||||||
serialize_code([ {Arg0Type, Arg0}
|
|
||||||
, {Arg1Type, Arg1}
|
|
||||||
| Rest]) ->
|
|
||||||
ArgSpec =
|
|
||||||
modifier_bits(Arg0Type) bor
|
|
||||||
(modifier_bits(Arg1Type) bsl 2),
|
|
||||||
[ArgSpec
|
|
||||||
, serialize_data(Arg0Type, Arg0)
|
|
||||||
, serialize_data(Arg1Type, Arg1)
|
|
||||||
| serialize_code(Rest)];
|
|
||||||
serialize_code([ {Arg0Type, Arg0} | Rest]) ->
|
|
||||||
ArgSpec =
|
|
||||||
modifier_bits(Arg0Type),
|
|
||||||
[ArgSpec
|
|
||||||
, serialize_data(Arg0Type, Arg0)
|
|
||||||
| serialize_code(Rest)];
|
|
||||||
serialize_code([B|Rest]) ->
|
|
||||||
[B | serialize_code(Rest)];
|
|
||||||
serialize_code([]) -> [].
|
|
||||||
|
|
||||||
serialize_data(_, Data) ->
|
serialize_data(_, Data) ->
|
||||||
aeb_fate_encoding:serialize(Data).
|
aeb_fate_encoding:serialize(Data).
|
||||||
@ -414,150 +294,26 @@ deserialize_functions(<<>>, #{ function := {F, Sig}
|
|||||||
deserialize_op(Op, Rest, Code) ->
|
deserialize_op(Op, Rest, Code) ->
|
||||||
OpName = aeb_fate_opcodes:mnemonic(Op),
|
OpName = aeb_fate_opcodes:mnemonic(Op),
|
||||||
case aeb_fate_opcodes:args(Op) of
|
case aeb_fate_opcodes:args(Op) of
|
||||||
0 -> {Rest, [OpName | Code]};
|
0 ->
|
||||||
1 ->
|
{Rest, [OpName | Code]};
|
||||||
<<ArgType:8, Rest2/binary>> = Rest,
|
N ->
|
||||||
{Arg, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
{Args, Rest1} = deserialize_n_args(N, Rest),
|
||||||
Modifier = bits_to_modifier(ArgType),
|
{Rest1, [list_to_tuple([OpName|Args])|Code]}
|
||||||
{Rest3, [{OpName, {Modifier, Arg}} | Code]};
|
|
||||||
2 ->
|
|
||||||
<<ArgType:8, Rest2/binary>> = Rest,
|
|
||||||
{Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
|
||||||
{Arg1, Rest4} = aeb_fate_encoding:deserialize_one(Rest3),
|
|
||||||
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
|
||||||
Modifier1 = bits_to_modifier((ArgType bsr 2) band 2#11),
|
|
||||||
{Rest4, [{OpName, {Modifier0, Arg0},
|
|
||||||
{Modifier1, Arg1}} | Code]};
|
|
||||||
3 ->
|
|
||||||
<<ArgType:8, Rest2/binary>> = Rest,
|
|
||||||
{Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
|
||||||
{Arg1, Rest4} = aeb_fate_encoding:deserialize_one(Rest3),
|
|
||||||
{Arg2, Rest5} = aeb_fate_encoding:deserialize_one(Rest4),
|
|
||||||
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
|
||||||
Modifier1 = bits_to_modifier((ArgType bsr 2) band 2#11),
|
|
||||||
Modifier2 = bits_to_modifier((ArgType bsr 4) band 2#11),
|
|
||||||
{Rest5, [{ OpName
|
|
||||||
, {Modifier0, Arg0}
|
|
||||||
, {Modifier1, Arg1}
|
|
||||||
, {Modifier2, Arg2}}
|
|
||||||
| Code]};
|
|
||||||
4 ->
|
|
||||||
<<ArgType:8, Rest2/binary>> = Rest,
|
|
||||||
{Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
|
||||||
{Arg1, Rest4} = aeb_fate_encoding:deserialize_one(Rest3),
|
|
||||||
{Arg2, Rest5} = aeb_fate_encoding:deserialize_one(Rest4),
|
|
||||||
{Arg3, Rest6} = aeb_fate_encoding:deserialize_one(Rest5),
|
|
||||||
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
|
||||||
Modifier1 = bits_to_modifier((ArgType bsr 2) band 2#11),
|
|
||||||
Modifier2 = bits_to_modifier((ArgType bsr 4) band 2#11),
|
|
||||||
Modifier3 = bits_to_modifier((ArgType bsr 6) band 2#11),
|
|
||||||
{Rest6, [{ OpName
|
|
||||||
, {Modifier0, Arg0}
|
|
||||||
, {Modifier1, Arg1}
|
|
||||||
, {Modifier2, Arg2}
|
|
||||||
, {Modifier3, Arg3}}
|
|
||||||
| Code]};
|
|
||||||
5 ->
|
|
||||||
<<ArgType:8, ArgType2:8, Rest2/binary>> = Rest,
|
|
||||||
{Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
|
||||||
{Arg1, Rest4} = aeb_fate_encoding:deserialize_one(Rest3),
|
|
||||||
{Arg2, Rest5} = aeb_fate_encoding:deserialize_one(Rest4),
|
|
||||||
{Arg3, Rest6} = aeb_fate_encoding:deserialize_one(Rest5),
|
|
||||||
{Arg4, Rest7} = aeb_fate_encoding:deserialize_one(Rest6),
|
|
||||||
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
|
||||||
Modifier1 = bits_to_modifier((ArgType bsr 2) band 2#11),
|
|
||||||
Modifier2 = bits_to_modifier((ArgType bsr 4) band 2#11),
|
|
||||||
Modifier3 = bits_to_modifier((ArgType bsr 6) band 2#11),
|
|
||||||
Modifier4 = bits_to_modifier(ArgType2 band 2#11),
|
|
||||||
{Rest7, [{ OpName
|
|
||||||
, {Modifier0, Arg0}
|
|
||||||
, {Modifier1, Arg1}
|
|
||||||
, {Modifier2, Arg2}
|
|
||||||
, {Modifier3, Arg3}
|
|
||||||
, {Modifier4, Arg4}
|
|
||||||
}
|
|
||||||
| Code]};
|
|
||||||
6 ->
|
|
||||||
<<ArgType:8, ArgType2:8, Rest2/binary>> = Rest,
|
|
||||||
{Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
|
||||||
{Arg1, Rest4} = aeb_fate_encoding:deserialize_one(Rest3),
|
|
||||||
{Arg2, Rest5} = aeb_fate_encoding:deserialize_one(Rest4),
|
|
||||||
{Arg3, Rest6} = aeb_fate_encoding:deserialize_one(Rest5),
|
|
||||||
{Arg4, Rest7} = aeb_fate_encoding:deserialize_one(Rest6),
|
|
||||||
{Arg5, Rest8} = aeb_fate_encoding:deserialize_one(Rest7),
|
|
||||||
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
|
||||||
Modifier1 = bits_to_modifier((ArgType bsr 2) band 2#11),
|
|
||||||
Modifier2 = bits_to_modifier((ArgType bsr 4) band 2#11),
|
|
||||||
Modifier3 = bits_to_modifier((ArgType bsr 6) band 2#11),
|
|
||||||
Modifier4 = bits_to_modifier(ArgType2 band 2#11),
|
|
||||||
Modifier5 = bits_to_modifier((ArgType2 bsr 2) band 2#11),
|
|
||||||
{Rest8, [{ OpName
|
|
||||||
, {Modifier0, Arg0}
|
|
||||||
, {Modifier1, Arg1}
|
|
||||||
, {Modifier2, Arg2}
|
|
||||||
, {Modifier3, Arg3}
|
|
||||||
, {Modifier4, Arg4}
|
|
||||||
, {Modifier5, Arg5}
|
|
||||||
}
|
|
||||||
| Code]};
|
|
||||||
7 ->
|
|
||||||
<<ArgType:8, ArgType2:8, Rest2/binary>> = Rest,
|
|
||||||
{Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
|
||||||
{Arg1, Rest4} = aeb_fate_encoding:deserialize_one(Rest3),
|
|
||||||
{Arg2, Rest5} = aeb_fate_encoding:deserialize_one(Rest4),
|
|
||||||
{Arg3, Rest6} = aeb_fate_encoding:deserialize_one(Rest5),
|
|
||||||
{Arg4, Rest7} = aeb_fate_encoding:deserialize_one(Rest6),
|
|
||||||
{Arg5, Rest8} = aeb_fate_encoding:deserialize_one(Rest7),
|
|
||||||
{Arg6, Rest9} = aeb_fate_encoding:deserialize_one(Rest8),
|
|
||||||
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
|
||||||
Modifier1 = bits_to_modifier((ArgType bsr 2) band 2#11),
|
|
||||||
Modifier2 = bits_to_modifier((ArgType bsr 4) band 2#11),
|
|
||||||
Modifier3 = bits_to_modifier((ArgType bsr 6) band 2#11),
|
|
||||||
Modifier4 = bits_to_modifier(ArgType2 band 2#11),
|
|
||||||
Modifier5 = bits_to_modifier((ArgType2 bsr 2) band 2#11),
|
|
||||||
Modifier6 = bits_to_modifier((ArgType2 bsr 4) band 2#11),
|
|
||||||
{Rest9, [{ OpName
|
|
||||||
, {Modifier0, Arg0}
|
|
||||||
, {Modifier1, Arg1}
|
|
||||||
, {Modifier2, Arg2}
|
|
||||||
, {Modifier3, Arg3}
|
|
||||||
, {Modifier4, Arg4}
|
|
||||||
, {Modifier5, Arg5}
|
|
||||||
, {Modifier6, Arg6}
|
|
||||||
}
|
|
||||||
| Code]};
|
|
||||||
8 ->
|
|
||||||
<<ArgType:8, ArgType2:8, Rest2/binary>> = Rest,
|
|
||||||
{Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
|
||||||
{Arg1, Rest4} = aeb_fate_encoding:deserialize_one(Rest3),
|
|
||||||
{Arg2, Rest5} = aeb_fate_encoding:deserialize_one(Rest4),
|
|
||||||
{Arg3, Rest6} = aeb_fate_encoding:deserialize_one(Rest5),
|
|
||||||
{Arg4, Rest7} = aeb_fate_encoding:deserialize_one(Rest6),
|
|
||||||
{Arg5, Rest8} = aeb_fate_encoding:deserialize_one(Rest7),
|
|
||||||
{Arg6, Rest9} = aeb_fate_encoding:deserialize_one(Rest8),
|
|
||||||
{Arg7, Rest10} = aeb_fate_encoding:deserialize_one(Rest9),
|
|
||||||
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
|
||||||
Modifier1 = bits_to_modifier((ArgType bsr 2) band 2#11),
|
|
||||||
Modifier2 = bits_to_modifier((ArgType bsr 4) band 2#11),
|
|
||||||
Modifier3 = bits_to_modifier((ArgType bsr 6) band 2#11),
|
|
||||||
Modifier4 = bits_to_modifier(ArgType2 band 2#11),
|
|
||||||
Modifier5 = bits_to_modifier((ArgType2 bsr 2) band 2#11),
|
|
||||||
Modifier6 = bits_to_modifier((ArgType2 bsr 4) band 2#11),
|
|
||||||
Modifier7 = bits_to_modifier((ArgType2 bsr 6) band 2#11),
|
|
||||||
{Rest10, [{ OpName
|
|
||||||
, {Modifier0, Arg0}
|
|
||||||
, {Modifier1, Arg1}
|
|
||||||
, {Modifier2, Arg2}
|
|
||||||
, {Modifier3, Arg3}
|
|
||||||
, {Modifier4, Arg4}
|
|
||||||
, {Modifier5, Arg5}
|
|
||||||
, {Modifier6, Arg6}
|
|
||||||
, {Modifier7, Arg7}
|
|
||||||
}
|
|
||||||
| Code]}
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
deserialize_n_args(N, <<M3:2, M2:2, M1:2, M0:2, Rest/binary>>) when N =< 4 ->
|
||||||
|
ArgMods = lists:sublist([M0, M1, M2, M3], N),
|
||||||
|
lists:mapfoldl(fun(M, Acc) ->
|
||||||
|
{Arg, Acc2} = aeb_fate_encoding:deserialize_one(Acc),
|
||||||
|
{{bits_to_modifier(M), Arg}, Acc2}
|
||||||
|
end, Rest, ArgMods);
|
||||||
|
deserialize_n_args(N, <<M7:2, M6:2, M5:2, M4:2, M3:2, M2:2, M1:2, M0:2,
|
||||||
|
Rest/binary>>) when N =< 8 ->
|
||||||
|
ArgMods = lists:sublist([M0, M1, M2, M3, M4, M5, M6, M7], N),
|
||||||
|
lists:mapfoldl(fun(M, Acc) ->
|
||||||
|
{Arg, Acc2} = aeb_fate_encoding:deserialize_one(Acc),
|
||||||
|
{{bits_to_modifier(M), Arg}, Acc2}
|
||||||
|
end, Rest, ArgMods).
|
||||||
|
|
||||||
deserialize_signature(Binary) ->
|
deserialize_signature(Binary) ->
|
||||||
{{tuple, Args}, Rest} = aeb_fate_encoding:deserialize_type(Binary),
|
{{tuple, Args}, Rest} = aeb_fate_encoding:deserialize_type(Binary),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user