aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/beam/erl_debug.c3
-rw-r--r--erts/emulator/beam/erl_printf_term.c9
-rw-r--r--erts/emulator/beam/erl_term.c1
-rw-r--r--erts/emulator/beam/erl_term.h3
-rw-r--r--erts/emulator/beam/utils.c9
-rw-r--r--erts/emulator/test/match_spec_SUITE.erl60
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.