diff options
author | Sverker Eriksson <[email protected]> | 2017-05-10 11:47:25 +0200 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2017-05-10 11:47:25 +0200 |
commit | 42d240e9144bd6219c9fd3b59ef9bc4f29bcf5f5 (patch) | |
tree | 4229ac7f656110a30c45d492b86a67991359488d /erts/emulator/beam | |
parent | 381a47d5219407f9c734cf0b081776129e7c180f (diff) | |
parent | 6c3265b86582d4848e1c77efee3a649a137694d6 (diff) | |
download | otp-42d240e9144bd6219c9fd3b59ef9bc4f29bcf5f5.tar.gz otp-42d240e9144bd6219c9fd3b59ef9bc4f29bcf5f5.tar.bz2 otp-42d240e9144bd6219c9fd3b59ef9bc4f29bcf5f5.zip |
Merge branch 'sverker/ets-select-replace-const'
* sverker/ets-select-replace-const:
stdlib: Add examples for ets:select_replace docs
erts: Fix ets:select_replace with {const, NewTuple}
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r-- | erts/emulator/beam/erl_db_util.c | 41 |
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)) { |