diff options
author | John Högberg <[email protected]> | 2018-07-12 21:55:00 +0200 |
---|---|---|
committer | John Högberg <[email protected]> | 2018-07-13 09:57:51 +0200 |
commit | 32d674c58ba0cfddb2d5e2e83a8bf3b9a70cce4d (patch) | |
tree | 7ce0cdd94a53b611f3e038893c0cad43490b5331 | |
parent | 1f55b15c5e3f6ff79c855963876c501e9f782406 (diff) | |
download | otp-32d674c58ba0cfddb2d5e2e83a8bf3b9a70cce4d.tar.gz otp-32d674c58ba0cfddb2d5e2e83a8bf3b9a70cce4d.tar.bz2 otp-32d674c58ba0cfddb2d5e2e83a8bf3b9a70cce4d.zip |
Fix a rare crash when matching on literal maps
When matching on a literal map, the map is placed into the general
scratch register first. This is fine in isolation, but when the
key to be matched was in a Y register it would also be placed in
the scratch register, overwriting the map and crashing the
emulator.
-rw-r--r-- | erts/emulator/beam/ops.tab | 5 | ||||
-rw-r--r-- | erts/emulator/test/map_SUITE.erl | 11 |
2 files changed, 12 insertions, 4 deletions
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab index 88ede3bb60..c51e4ef784 100644 --- a/erts/emulator/beam/ops.tab +++ b/erts/emulator/beam/ops.tab @@ -1421,16 +1421,13 @@ get_map_elements Fail Src Size Rest=* | map_key_sort(Size, Rest) => \ i_get_map_elements f? s I -i_get_map_element Fail Src=xy Key=y Dst => \ - move Key x | i_get_map_element Fail Src x Dst - i_get_map_element_hash Fail Src=c Key Hash Dst => \ move Src x | i_get_map_element_hash Fail x Key Hash Dst i_get_map_element_hash f? xy c I xy i_get_map_element Fail Src=c Key Dst => \ move Src x | i_get_map_element Fail x Key Dst -i_get_map_element f? xy x xy +i_get_map_element f? xy xy xy # # Convert the plus operations to a generic plus instruction. diff --git a/erts/emulator/test/map_SUITE.erl b/erts/emulator/test/map_SUITE.erl index f93c637650..d0a6763fe5 100644 --- a/erts/emulator/test/map_SUITE.erl +++ b/erts/emulator/test/map_SUITE.erl @@ -3080,8 +3080,19 @@ y_regs(Config) when is_list(Config) -> true = is_map(Map2) andalso is_map(Map4), + gurka = y_regs_literal(0), + gaffel = y_regs_literal(1), + ok. +y_regs_literal(Key) when is_integer(Key) -> + %% Forces the key to be placed in a Y register. + lists:seq(1, 2), + case is_map_key(Key, #{ 0 => 0 }) of + true -> gurka; + false -> gaffel + end. + y_regs_update(Map0, Val0) -> Val1 = {t,Val0}, K1 = id({key,1}), |