aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/erl_db_util.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index 91ac53ad0b..eaed15b14b 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -1125,12 +1125,11 @@ error:
* Returns true if 'b' is guaranteed to always construct
* the same term as 'a' has matched.
*/
-static int db_match_eq_body(Eterm a, Eterm b)
+static int db_match_eq_body(Eterm a, Eterm b, int const_mode)
{
DECLARE_ESTACK(s);
Uint arity;
Eterm *ap, *bp;
- int const_mode = 0;
const Eterm CONST_MODE_OFF = THE_NON_VALUE;
while (1) {
@@ -1224,6 +1223,7 @@ int db_match_keeps_key(int keypos, Eterm match, Eterm guard, Eterm body)
Eterm single_body_subterm;
Eterm single_body_subterm_key;
Eterm* single_body_subterm_key_tpl;
+ int const_mode;
if (!is_list(body)) {
return 0;
@@ -1244,42 +1244,53 @@ int db_match_keeps_key(int keypos, Eterm match, Eterm guard, Eterm body)
return 0;
}
- single_body_term_tpl = tuple_val(single_body_term);
- if (arityval(*single_body_term_tpl) != 1) {
- // not the 1-element tuple we're expecting
- return 0;
- }
-
match_key = db_getkey(keypos, match);
if (!is_value(match_key)) {
// can't get key out of match
return 0;
}
- single_body_subterm = single_body_term_tpl[1];
+ single_body_term_tpl = tuple_val(single_body_term);
+ if (single_body_term_tpl[0] == make_arityval(2) &&
+ single_body_term_tpl[1] == am_const) {
+ /* {const, {"ets-tuple constant"}} */
+ single_body_subterm = single_body_term_tpl[2];
+ const_mode = 1;
+ }
+ else if (*single_body_term_tpl == make_arityval(1)) {
+ /* {{"ets-tuple construction"}} */
+ single_body_subterm = single_body_term_tpl[1];
+ const_mode = 0;
+ }
+ else {
+ /* not a tuple construction */
+ return 0;
+ }
+
single_body_subterm_key = db_getkey(keypos, single_body_subterm);
if (!is_value(single_body_subterm_key)) {
// can't get key out of single body subterm
return 0;
}
- if (db_match_eq_body(match_key, single_body_subterm_key)) {
+ if (db_match_eq_body(match_key, single_body_subterm_key, const_mode)) {
/* tuple with same key is returned */
return 1;
}
- if (!is_tuple(single_body_subterm_key)) {
- /* can't possibly be an element instruction */
+ if (const_mode) {
+ /* constant key did not match */
return 0;
}
- single_body_subterm_key_tpl = tuple_val(single_body_subterm_key);
- if (arityval(*single_body_subterm_key_tpl) != 3) {
+ if (!is_tuple(single_body_subterm_key)) {
/* can't possibly be an element instruction */
return 0;
}
- if (single_body_subterm_key_tpl[1] == am_element &&
+ single_body_subterm_key_tpl = tuple_val(single_body_subterm_key);
+ if (single_body_subterm_key_tpl[0] == make_arityval(3) &&
+ single_body_subterm_key_tpl[1] == am_element &&
single_body_subterm_key_tpl[3] == am_DollarUnderscore &&
single_body_subterm_key_tpl[2] == make_small(keypos))
{