diff options
author | Björn Gustavsson <[email protected]> | 2011-03-22 05:23:09 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2011-08-16 08:58:48 +0200 |
commit | f2e0e976382eddd3d120110c87882a2185e868aa (patch) | |
tree | b257e405877983d48fb428c9ac2797b5ba7f28c5 /lib/debugger/src/dbg_ieval.erl | |
parent | 19713d214462b863def874385844521f00a2bac5 (diff) | |
download | otp-f2e0e976382eddd3d120110c87882a2185e868aa.tar.gz otp-f2e0e976382eddd3d120110c87882a2185e868aa.tar.bz2 otp-f2e0e976382eddd3d120110c87882a2185e868aa.zip |
Fix binary matching in the debugger
'eval_bits' is a common utility module used for evaluting binary
construction and matching. The functions that do matching
(match_bits/{6,7} and bin_gen/6) are supposed to treat the bindings as
an abstract data type, but they assume that the bindings have the same
representation as in the erl_eval module. That may cause binary
matching to fail in the debugger, because the debugger represents the
bindings as an unordered list of two-tuples, while the erl_eval
modules uses an ordered list of two-tuple (an ordset).
One way to fix the problem would be to let the debugger to use ordered
lists to represent the bindings. Unfortunately, that would also change
how the bindings are presented in the user interface. Currently, the
variable have most been recently assigned is shown first, which is
convenient.
Fix the matching problem by mending the leaky abstraction in
eval_bits. The matching functions needs to be passed two additional
operations: one for looking up a variable in the bindings and one for
adding a binding. Those operations could be passed as two more funs
(in addition to the evaluation and match fun already passed), but the
functions already have too many arguments. Therefore, change the
meaning of the match fun, so that the first argument is the operation
to perform ('match', 'binding', or 'add_binding') and second argument
is a tuple with arguments for the operation.
Diffstat (limited to 'lib/debugger/src/dbg_ieval.erl')
-rw-r--r-- | lib/debugger/src/dbg_ieval.erl | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl index 9b6919074f..b0792b05f0 100644 --- a/lib/debugger/src/dbg_ieval.erl +++ b/lib/debugger/src/dbg_ieval.erl @@ -1023,7 +1023,7 @@ eval_generate(Term, _P, Bs, _CompFun, Ieval) -> exception(error, {bad_generator,Term}, Bs, Ieval). eval_b_generate(<<_/bitstring>>=Bin, P, Bs0, CompFun, Ieval) -> - Mfun = fun(L, R, Bs) -> match1(L, R, Bs, Bs0) end, + Mfun = match_fun(Bs0), Efun = fun(Exp, Bs) -> expr(Exp, Bs, #ieval{}) end, case eval_bits:bin_gen(P, Bin, erl_eval:new_bindings(), Bs0, Mfun, Efun) of {match,Rest,Bs1} -> @@ -1392,11 +1392,9 @@ match1({cons,_,H,T}, [H1|T1], Bs0, BBs) -> match1({tuple,_,Elts}, Tuple, Bs, BBs) when length(Elts) =:= tuple_size(Tuple) -> match_tuple(Elts, Tuple, 1, Bs, BBs); -match1({bin,_,Fs}, B, Bs0, BBs0) when is_bitstring(B) -> - Bs1 = lists:sort(Bs0), %Kludge. - BBs = lists:sort(BBs0), - try eval_bits:match_bits(Fs, B, Bs1, BBs, - fun(L, R, Bs) -> match1(L, R, Bs, BBs) end, +match1({bin,_,Fs}, B, Bs0, BBs) when is_bitstring(B) -> + try eval_bits:match_bits(Fs, B, Bs0, BBs, + match_fun(BBs), fun(E, Bs) -> expr(E, Bs, #ieval{}) end, false) catch @@ -1405,6 +1403,12 @@ match1({bin,_,Fs}, B, Bs0, BBs0) when is_bitstring(B) -> match1(_,_,_,_) -> throw(nomatch). +match_fun(BBs) -> + fun(match, {L,R,Bs}) -> match1(L, R, Bs, BBs); + (binding, {Name,Bs}) -> binding(Name, Bs); + (add_binding, {Name,Val,Bs}) -> add_binding(Name, Val, Bs) + end. + match_tuple([E|Es], Tuple, I, Bs0, BBs) -> {match,Bs} = match1(E, element(I, Tuple), Bs0, BBs), match_tuple(Es, Tuple, I+1, Bs, BBs); |