diff options
-rw-r--r-- | erts/emulator/beam/erl_debug.c | 3 | ||||
-rw-r--r-- | erts/emulator/beam/erl_printf_term.c | 9 | ||||
-rw-r--r-- | erts/emulator/beam/erl_term.c | 1 | ||||
-rw-r--r-- | erts/emulator/beam/erl_term.h | 3 | ||||
-rw-r--r-- | erts/emulator/beam/utils.c | 9 | ||||
-rw-r--r-- | erts/emulator/test/match_spec_SUITE.erl | 60 |
6 files changed, 54 insertions, 31 deletions
diff --git a/erts/emulator/beam/erl_debug.c b/erts/emulator/beam/erl_debug.c index 50bdc79506..b6c131a43e 100644 --- a/erts/emulator/beam/erl_debug.c +++ b/erts/emulator/beam/erl_debug.c @@ -188,6 +188,9 @@ pdisplay1(int to, void *to_arg, Process* p, Eterm obj) case BINARY_DEF: erts_print(to, to_arg, "#Bin"); break; + case MATCHSTATE_DEF: + erts_print(to, to_arg, "#Matchstate"); + break; default: erts_print(to, to_arg, "unknown object %x", obj); } diff --git a/erts/emulator/beam/erl_printf_term.c b/erts/emulator/beam/erl_printf_term.c index d18760dc43..ba9a174fdf 100644 --- a/erts/emulator/beam/erl_printf_term.c +++ b/erts/emulator/beam/erl_printf_term.c @@ -441,11 +441,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount, PRINT_DOUBLE(res, fn, arg, 'e', 6, 0, ff.fd); } break; - case BINARY_DEF: - if (header_is_bin_matchstate(*boxed_val(wobj))) { - PRINT_STRING(res, fn, arg, "#MatchState"); - } - else { + case BINARY_DEF: { ProcBin* pb = (ProcBin *) binary_val(wobj); if (pb->size == 1) PRINT_STRING(res, fn, arg, "<<1 byte>>"); @@ -519,6 +515,9 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount, } } break; + case MATCHSTATE_DEF: + PRINT_STRING(res, fn, arg, "#MatchState"); + break; default: PRINT_STRING(res, fn, arg, "<unknown:"); PRINT_POINTER(res, fn, arg, wobj); diff --git a/erts/emulator/beam/erl_term.c b/erts/emulator/beam/erl_term.c index 28cbe7004f..07818472ec 100644 --- a/erts/emulator/beam/erl_term.c +++ b/erts/emulator/beam/erl_term.c @@ -90,6 +90,7 @@ unsigned tag_val_def(Wterm x) case (_TAG_HEADER_HEAP_BIN >> _TAG_PRIMARY_SIZE): return BINARY_DEF; case (_TAG_HEADER_SUB_BIN >> _TAG_PRIMARY_SIZE): return BINARY_DEF; case (_TAG_HEADER_MAP >> _TAG_PRIMARY_SIZE): return MAP_DEF; + case (_TAG_HEADER_BIN_MATCHSTATE >> _TAG_PRIMARY_SIZE): return MATCHSTATE_DEF; } break; } diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h index 37014ccf94..1b6bb27395 100644 --- a/erts/emulator/beam/erl_term.h +++ b/erts/emulator/beam/erl_term.h @@ -1095,6 +1095,9 @@ _ET_DECLARE_CHECKED(Uint,y_reg_index,Uint) #define FLOAT_DEF 0xe #define BIG_DEF 0xf #define SMALL_DEF 0x10 +#define MATCHSTATE_DEF 0x11 /* not a "real" term */ + +#define FIRST_VACANT_TAG_DEF 0x12 #if ET_DEBUG extern unsigned tag_val_def_debug(Wterm, const char*, unsigned); diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index f810fca9a4..a8bbdb9354 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -788,11 +788,10 @@ Uint32 make_hash(Eterm term_arg) Eterm hash = 0; unsigned op; - /* Must not collide with the real tag_val_def's: */ -#define MAKE_HASH_TUPLE_OP 0x11 -#define MAKE_HASH_TERM_ARRAY_OP 0x12 -#define MAKE_HASH_CDR_PRE_OP 0x13 -#define MAKE_HASH_CDR_POST_OP 0x14 +#define MAKE_HASH_TUPLE_OP (FIRST_VACANT_TAG_DEF) +#define MAKE_HASH_TERM_ARRAY_OP (FIRST_VACANT_TAG_DEF+1) +#define MAKE_HASH_CDR_PRE_OP (FIRST_VACANT_TAG_DEF+2) +#define MAKE_HASH_CDR_POST_OP (FIRST_VACANT_TAG_DEF+3) /* ** Convenience macro for calculating a bytewise hash on an unsigned 32 bit diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl index fdce157abc..bfa09c625f 100644 --- a/erts/emulator/test/match_spec_SUITE.erl +++ b/erts/emulator/test/match_spec_SUITE.erl @@ -167,12 +167,11 @@ test_1(Config) when is_list(Config) -> [{['$1','$1'],[{is_atom, '$1'}],[kakalorum]}], [{call, {?MODULE, f2, [a, a]}}]), -% case tr0(fun() -> ?MODULE:f2(a, a) end, -% {?MODULE, f2, 2}, -% [{['$1','$1'],[{is_atom, '$1'}],[{message, {process_dump}}]}]) of -% [{trace, _, call, {?MODULE, f2, [a, a]}, Bin}] -> -% erlang:display(binary_to_list(Bin)) -% end, + %% Verify that 'process_dump' can handle a matchstate on the stack. + tr(fun() -> fbinmatch(<<0>>, 0) end, + {?MODULE, f1, 1}, + [{['_'],[],[{message, {process_dump}}]}], + [fun({trace, _, call, {?MODULE, f1, [0]}, _Bin}) -> true end]), % Error cases ?line errchk([{['$1','$1'],[{is_atom, '$1'}],[{banka, kanin}]}]), @@ -928,14 +927,14 @@ tr(Fun, MFA, TraceFlags, Pat, PatFlags, Expected0) -> erlang:trace(P, true, TraceFlags), erlang:trace_pattern(MFA, Pat, PatFlags), lists:map( - fun(X) -> - list_to_tuple([trace, P | tuple_to_list(X)]) + fun(X) when is_function(X,1) -> X; + (X) -> list_to_tuple([trace, P | tuple_to_list(X)]) end, Expected0) end). tr(RunFun, ControlFun) -> - P = spawn(?MODULE, runner, [self(), RunFun]), + P = spawn_link(?MODULE, runner, [self(), RunFun]), collect(P, ControlFun(P)). collect(P, TMs) -> @@ -954,18 +953,33 @@ collect([]) -> collect([TM | TMs]) -> ?t:format( "Expecting: ~p~n", [TM]), receive - M -> - case if element(1, M) == trace_ts -> - list_to_tuple(lists:reverse( - tl(lists:reverse(tuple_to_list(M))))); - true -> M - end of - TM -> - ?t:format("Got: ~p~n", [M]), - collect(TMs); - _ -> - ?t:format("Got unexpected: ~p~n", [M]), - flush({got_unexpected,M}) + M0 -> + M = case element(1, M0) of + trace_ts -> + list_to_tuple(lists:reverse( + tl(lists:reverse(tuple_to_list(M0))))); + _ -> M0 + end, + case is_function(TM,1) of + true -> + case (catch TM(M)) of + true -> + ?t:format("Got: ~p~n", [M]), + collect(TMs); + _ -> + ?t:format("Got unexpected: ~p~n", [M]), + flush({got_unexpected,M}) + end; + + false -> + case M of + TM -> + ?t:format("Got: ~p~n", [M]), + collect(TMs); + _ -> + ?t:format("Got unexpected: ~p~n", [M]), + flush({got_unexpected,M}) + end end end. @@ -1045,6 +1059,10 @@ fn(X, Y) -> fn(X, Y, Z) -> [X, Y, Z]. +fbinmatch(<<Int, Rest/binary>>, Acc) -> + fbinmatch(Rest, [?MODULE:f1(Int) | Acc]); +fbinmatch(<<>>, Acc) -> Acc. + id(X) -> X. |