43
43
%% them when/if they get used in other files.)
44
44
%%-----------------------------------------------------------------------
46
%% -spec(function__name/1 :: (#function{}) -> atom()).
46
%% -spec function__name(#function{}) -> atom().
47
47
%% function__name(#function{name=N}) -> N.
48
%% -spec(function__arity/1 :: (#function{}) -> byte()).
48
%% -spec function__arity(#function{}) -> byte().
49
49
%% function__arity(#function{arity=A}) -> A.
50
50
%% function__entry(#function{entry=E}) -> E.
52
-spec(function__code/1 :: (#function{}) -> [beam_instr()]).
52
-spec function__code(#function{}) -> [beam_instr()].
53
53
function__code(#function{code=Code}) -> Code.
55
-spec(function__code_update/2 :: (#function{}, [beam_instr()]) -> #function{}).
55
-spec function__code_update(#function{}, [beam_instr()]) -> #function{}.
56
56
function__code_update(Function, NewCode) ->
57
57
Function#function{code = NewCode}.
59
59
%%-----------------------------------------------------------------------
60
60
%% Error information
62
-spec(format_error/1 :: ({'internal',_} | {'error',atom(),_}) -> string()).
62
-spec format_error({'internal',_} | {'error',atom(),_}) -> string().
64
64
format_error({internal,Error}) ->
65
65
io_lib:format("~p: disassembly failed with reason ~P.",
340
340
%%-----------------------------------------------------------------------
342
342
disasm_instr(B, Bs, Atoms, Literals) ->
343
{SymOp,Arity} = beam_opcodes:opname(B),
343
{SymOp, Arity} = beam_opcodes:opname(B),
346
346
disasm_select_inst(select_val, Bs, Atoms, Literals);
347
347
select_tuple_arity ->
348
348
disasm_select_inst(select_tuple_arity, Bs, Atoms, Literals);
350
case catch decode_n_args(Arity, Bs, Atoms, Literals) of
352
?NO_DEBUG("decode_n_args(~p,~p) failed~n",[Arity,Bs]),
353
{{'EXIT',{SymOp,Arity,Rsn}},[]};
355
?NO_DEBUG("instr ~p~n",[{SymOp,Args}]),
356
{{SymOp,Args}, RestBs}
350
try decode_n_args(Arity, Bs, Atoms, Literals) of
352
?NO_DEBUG("instr ~p~n", [{SymOp, Args}]),
353
{{SymOp, Args}, RestBs}
356
?NO_DEBUG("decode_n_args(~p,~p) failed~n", [Arity, Bs]),
357
?exit({cannot_disasm_instr, {SymOp, Arity, Rsn}})
497
497
decode_z_tagged(_,B,_,_) ->
498
498
?exit({decode_z_tagged,{weird_value,B}}).
500
-spec(decode_float/1 :: ([byte(),...]) -> {{'float',float()}, [byte()]}).
500
-spec decode_float([byte(),...]) -> {{'float',float()}, [byte()]}.
501
501
decode_float(Bs) ->
502
502
{FL,RestBs} = take_bytes(8,Bs),
503
503
<<Float:64/float>> = list_to_binary(FL),
504
504
{{float,Float},RestBs}.
506
-spec(decode_fr/1 :: ([byte(),...]) -> {{'fr',non_neg_integer()}, [byte()]}).
506
-spec decode_fr([byte(),...]) -> {{'fr',non_neg_integer()}, [byte()]}.
508
508
{{u,Fr},RestBs} = decode_arg(Bs),
509
509
{{fr,Fr},RestBs}.
1045
1045
{bs_init_bits,Lbl,A2,W,R,decode_field_flags(F),A6};
1050
resolve_inst({bs_get_utf8=I,[Lbl,Arg2,Arg3,{u,U},Arg4]},_,_,_) ->
1051
[A2,A3,A4] = resolve_args([Arg2,Arg3,Arg4]),
1052
{test,I,Lbl,[A2,A3,decode_field_flags(U),A4]};
1053
resolve_inst({bs_skip_utf8=I,[Lbl,Arg2,Arg3,{u,U}]},_,_,_) ->
1054
[A2,A3] = resolve_args([Arg2,Arg3]),
1055
{test,I,Lbl,[A2,A3,decode_field_flags(U)]};
1056
resolve_inst({bs_get_utf16=I,[Lbl,Arg2,Arg3,{u,U},Arg4]},_,_,_) ->
1057
[A2,A3,A4] = resolve_args([Arg2,Arg3,Arg4]),
1058
{test,I,Lbl,[A2,A3,decode_field_flags(U),A4]};
1059
resolve_inst({bs_skip_utf16=I,[Lbl,Arg2,Arg3,{u,U}]},_,_,_) ->
1060
[A2,A3] = resolve_args([Arg2,Arg3]),
1061
{test,I,Lbl,[A2,A3,decode_field_flags(U)]};
1062
resolve_inst({bs_get_utf32=I,[Lbl,Arg2,Arg3,{u,U},Arg4]},_,_,_) ->
1063
[A2,A3,A4] = resolve_args([Arg2,Arg3,Arg4]),
1064
{test,I,Lbl,[A2,A3,decode_field_flags(U),A4]};
1065
resolve_inst({bs_skip_utf32=I,[Lbl,Arg2,Arg3,{u,U}]},_,_,_) ->
1066
[A2,A3] = resolve_args([Arg2,Arg3]),
1067
{test,I,Lbl,[A2,A3,decode_field_flags(U)]};
1068
resolve_inst({bs_utf8_size=I,[Lbl,Arg2,Arg3]},_,_,_) ->
1069
[A2,A3] = resolve_args([Arg2,Arg3]),
1071
resolve_inst({bs_put_utf8=I,[Lbl,{u,U},Arg3]},_,_,_) ->
1072
[A3] = resolve_args([Arg3]),
1073
{I,Lbl,decode_field_flags(U),A3};
1074
resolve_inst({bs_utf16_size=I,[Lbl,Arg2,Arg3]},_,_,_) ->
1075
[A2,A3] = resolve_args([Arg2,Arg3]),
1077
resolve_inst({bs_put_utf16=I,[Lbl,{u,U},Arg3]},_,_,_) ->
1078
[A3] = resolve_args([Arg3]),
1079
{I,Lbl,decode_field_flags(U),A3};
1080
resolve_inst({bs_put_utf32=I,[Lbl,{u,U},Arg3]},_,_,_) ->
1081
[A3] = resolve_args([Arg3]),
1082
{I,Lbl,decode_field_flags(U),A3};
1048
1085
%% Catches instructions that are not yet handled.
1050
1087
resolve_inst(X,_,_,_) -> ?exit({resolve_inst,X}).