aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_utils.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2016-09-26 15:01:19 +0200
committerBjörn Gustavsson <[email protected]>2016-10-05 13:00:45 +0200
commit0c599bcad1e7f5f66dd2342ab27791048145e892 (patch)
tree2f9702b3f3c829d6862df0cc193d5abc394251b4 /lib/compiler/src/beam_utils.erl
parent3f3f25b23379b1afb15cc97462cf5d385690f5a0 (diff)
downloadotp-0c599bcad1e7f5f66dd2342ab27791048145e892.tar.gz
otp-0c599bcad1e7f5f66dd2342ab27791048145e892.tar.bz2
otp-0c599bcad1e7f5f66dd2342ab27791048145e892.zip
beam_block: Avoid unsafe inclusion of get_map_elements in blocks
c2035ebb8b restricted the get_map_elements instruction so that it could only occur at the beginning of a block. It turns out that including it anywhere in a block is unsafe. Therefore, never put get_map_elements instruction in blocks. (Also remove the beam_utils:join_even/2 function since it is no longer used.) ERL-266
Diffstat (limited to 'lib/compiler/src/beam_utils.erl')
-rw-r--r--lib/compiler/src/beam_utils.erl12
1 files changed, 6 insertions, 6 deletions
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index a15ecf633e..249d9395ca 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -26,7 +26,7 @@
empty_label_index/0,index_label/3,index_labels/1,
code_at/2,bif_to_test/3,is_pure_test/1,
live_opt/1,delete_live_annos/1,combine_heap_needs/2,
- join_even/2,split_even/1]).
+ split_even/1]).
-import(lists, [member/2,sort/1,reverse/1,splitwith/2]).
@@ -233,11 +233,6 @@ combine_heap_needs(H1, H2) when is_integer(H1), is_integer(H2) ->
split_even(Rs) -> split_even(Rs, [], []).
-%% join_even/1
-%% {[1,3,5],[2,4,6]} -> [1,2,3,4,5,6]
-
-join_even([], []) -> [];
-join_even([S|Ss], [D|Ds]) -> [S,D|join_even(Ss, Ds)].
%%%
%%% Local functions.
@@ -753,6 +748,11 @@ live_opt([timeout=I|Is], _, D, Acc) ->
live_opt(Is, 0, D, [I|Acc]);
live_opt([{wait,_}=I|Is], _, D, Acc) ->
live_opt(Is, 0, D, [I|Acc]);
+live_opt([{get_map_elements,Fail,Src,{list,List}}=I|Is], Regs0, D, Acc) ->
+ {Ss,Ds} = split_even(List),
+ Regs1 = x_live([Src|Ss], x_dead(Ds, Regs0)),
+ Regs = live_join_label(Fail, D, Regs1),
+ live_opt(Is, Regs, D, [I|Acc]);
%% Transparent instructions - they neither use nor modify x registers.
live_opt([{deallocate,_}=I|Is], Regs, D, Acc) ->