aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/beam/utils.c26
-rw-r--r--erts/emulator/test/map_SUITE.erl4
2 files changed, 26 insertions, 4 deletions
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index 471bce8940..908116c64c 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -2686,8 +2686,22 @@ tailrecur_ne:
}
aa += 2;
bb += 2;
- i += 1; /* increment for tuple-keys */
- goto term_array;
+ if (exact) {
+ i += 1; /* increment for tuple-keys */
+ goto term_array;
+ }
+ else {
+ /* Value array */
+ WSTACK_PUSH3(stack, i, (UWord)(bb+1), (UWord)(aa+1) | TAG_PRIMARY_HEADER);
+ /* Marker to switch back from 'exact' compare */
+ WSTACK_PUSH(stack, (UWord)NULL | TAG_PRIMARY_HEADER);
+ /* Now do 'exact' compare of key tuples */
+ a = *aa;
+ b = *bb;
+ exact = 1;
+ goto tailrecur;
+ }
+
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
if (!is_float_rel(b,b_base)) {
a_tag = FLOAT_DEF;
@@ -3061,7 +3075,13 @@ pop_next:
if (!WSTACK_ISEMPTY(stack)) {
UWord something = WSTACK_POP(stack);
if (primary_tag((Eterm) something) == TAG_PRIMARY_HEADER) { /* a term_array */
- aa = (Eterm*) something;
+ if (something == ((UWord)NULL | TAG_PRIMARY_HEADER)) {
+ /* Done with exact compare of map keys, switch back */
+ ASSERT(exact);
+ exact = 0;
+ goto pop_next;
+ }
+ aa = (Eterm *)something;
bb = (Eterm*) WSTACK_POP(stack);
i = WSTACK_POP(stack);
goto term_array;
diff --git a/erts/emulator/test/map_SUITE.erl b/erts/emulator/test/map_SUITE.erl
index 888ed8e272..1e989fbc4d 100644
--- a/erts/emulator/test/map_SUITE.erl
+++ b/erts/emulator/test/map_SUITE.erl
@@ -432,7 +432,7 @@ t_map_sort_literals(Config) when is_list(Config) ->
true = #{ c => 1, b => 1, a => 1 } < id(#{ b => 1, c => 1, d => 1}),
true = #{ "a" => 1 } < id(#{ <<"a">> => 1}),
false = #{ <<"a">> => 1 } < id(#{ "a" => 1}),
- false = #{ 1 => 1 } < id(#{ 1.0 => 1}),
+ true = #{ 1 => 1 } < id(#{ 1.0 => 1}),
false = #{ 1.0 => 1 } < id(#{ 1 => 1}),
%% value order
@@ -440,6 +440,8 @@ t_map_sort_literals(Config) when is_list(Config) ->
false = #{ a => 2 } < id(#{ a => 1}),
false = #{ a => 2, b => 1 } < id(#{ a => 1, b => 3}),
true = #{ a => 1, b => 1 } < id(#{ a => 1, b => 3}),
+ false = #{ a => 1 } < id(#{ a => 1.0}),
+ false = #{ a => 1.0 } < id(#{ a => 1}),
true = #{ "a" => "hi", b => 134 } == id(#{ b => 134,"a" => "hi"}),