diff options
author | Björn-Egil Dahlberg <[email protected]> | 2014-02-24 14:28:22 +0100 |
---|---|---|
committer | Björn-Egil Dahlberg <[email protected]> | 2014-02-24 14:28:22 +0100 |
commit | 4acee7b02b53d785c444e886c39ed82ab76b52fe (patch) | |
tree | 2d5110c59ad0022d43f97e76681b13e5dec58ea7 /lib/compiler | |
parent | ce614726e9fb19b462ed41a2f020b68ef98cd532 (diff) | |
parent | 771fa6d1f96684b61ed5f6033db51f5b0a55ec19 (diff) | |
download | otp-4acee7b02b53d785c444e886c39ed82ab76b52fe.tar.gz otp-4acee7b02b53d785c444e886c39ed82ab76b52fe.tar.bz2 otp-4acee7b02b53d785c444e886c39ed82ab76b52fe.zip |
Merge branch 'egil/maps/fix-cerl-inlining'
* egil/maps/fix-cerl-inlining:
compiler: Update map_SUITE to handle inlining
erts: Maps src instructions can't be literals
compiler: Fix map inlining
compiler: Add variable coverage of map in cerl
Diffstat (limited to 'lib/compiler')
-rw-r--r-- | lib/compiler/src/cerl.erl | 17 | ||||
-rw-r--r-- | lib/compiler/src/cerl_inline.erl | 26 | ||||
-rw-r--r-- | lib/compiler/src/cerl_trees.erl | 20 | ||||
-rw-r--r-- | lib/compiler/test/Makefile | 1 | ||||
-rw-r--r-- | lib/compiler/test/map_SUITE.erl | 24 |
5 files changed, 55 insertions, 33 deletions
diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl index 60a8559950..3c121f3b04 100644 --- a/lib/compiler/src/cerl.erl +++ b/lib/compiler/src/cerl.erl @@ -124,8 +124,9 @@ %% keep map exports here for now map_es/1, - update_c_map/2, - ann_c_map/2, + map_val/1, + update_c_map/3, + ann_c_map/3, map_pair_op/1,map_pair_key/1,map_pair_val/1, update_c_map_pair/4, ann_c_map_pair/4 @@ -1579,11 +1580,15 @@ ann_make_list(_, [], Node) -> map_es(#c_map{es = Es}) -> Es. -ann_c_map(As, Es) -> - #c_map{es = Es, anno = As }. +-spec map_val(c_map()) -> cerl(). +map_val(#c_map{var = M}) -> + M. -update_c_map(Old, Es) -> - #c_map{es = Es, anno = get_ann(Old)}. +ann_c_map(As,M,Es) -> + #c_map{var=M,es = Es, anno = As }. + +update_c_map(Old,M,Es) -> + #c_map{var=M, es = Es, anno = get_ann(Old)}. map_pair_key(#c_map_pair{key=K}) -> K. map_pair_val(#c_map_pair{val=V}) -> V. diff --git a/lib/compiler/src/cerl_inline.erl b/lib/compiler/src/cerl_inline.erl index 3837b57750..44293bb8ce 100644 --- a/lib/compiler/src/cerl_inline.erl +++ b/lib/compiler/src/cerl_inline.erl @@ -64,7 +64,7 @@ seq_body/1, set_ann/2, try_arg/1, try_body/1, try_vars/1, try_evars/1, try_handler/1, tuple_es/1, tuple_arity/1, type/1, values_es/1, var_name/1, - map_es/1, update_c_map/2, + map_val/1, map_es/1, update_c_map/3, update_c_map_pair/4, map_pair_op/1, map_pair_key/1, map_pair_val/1 ]). @@ -1334,12 +1334,12 @@ i_bitstr(E, Ren, Env, S) -> i_map(E, Ctx, Ren, Env, S) -> %% Visit the segments for value. - {Es, S1} = mapfoldl(fun (E, S) -> - i_map_pair(E, Ctx, Ren, Env, S) - end, - S, map_es(E)), - S2 = count_size(weight(map), S1), - {update_c_map(E, Es), S2}. + {M1, S1} = i(map_val(E), value, Ren, Env, S), + {Es, S2} = mapfoldl(fun (E, S) -> + i_map_pair(E, Ctx, Ren, Env, S) + end, S1, map_es(E)), + S3 = count_size(weight(map), S2), + {update_c_map(E, M1,Es), S3}. i_map_pair(E, Ctx, Ren, Env, S) -> %% It is not necessary to visit the Op and Key fields, @@ -1411,13 +1411,15 @@ i_pattern(E, Ren, Env, Ren0, Env0, S) -> S2 = count_size(weight(binary), S1), {update_c_binary(E, Es), S2}; map -> + %% map patterns should not have vals + M = map_val(E), + {Es, S1} = mapfoldl(fun (E, S) -> - i_map_pair_pattern(E, Ren, Env, - Ren0, Env0, S) - end, - S, map_es(E)), + i_map_pair_pattern(E, Ren, Env, Ren0, Env0, S) + end, + S, map_es(E)), S2 = count_size(weight(map), S1), - {update_c_map(E, Es), S2}; + {update_c_map(E, M, Es), S2}; _ -> case is_literal(E) of true -> diff --git a/lib/compiler/src/cerl_trees.erl b/lib/compiler/src/cerl_trees.erl index 2542841eef..2ebeab243f 100644 --- a/lib/compiler/src/cerl_trees.erl +++ b/lib/compiler/src/cerl_trees.erl @@ -57,9 +57,9 @@ update_c_try/6, update_c_tuple/2, update_c_tuple_skel/2, update_c_values/2, values_es/1, var_name/1, - map_es/1, - ann_c_map/2, - update_c_map/2, + map_val/1, map_es/1, + ann_c_map/3, + update_c_map/3, map_pair_key/1,map_pair_val/1,map_pair_op/1, ann_c_map_pair/4, update_c_map_pair/4 @@ -138,7 +138,7 @@ map_1(F, T) -> tuple -> update_c_tuple_skel(T, map_list(F, tuple_es(T))); map -> - update_c_map(T, map_list(F, map_es(T))); + update_c_map(T, map(F,map_val(T)), map_list(F, map_es(T))); map_pair -> update_c_map_pair(T, map(F, map_pair_op(T)), map(F, map_pair_key(T)), @@ -372,8 +372,9 @@ mapfold(F, S0, T) -> {Ts, S1} = mapfold_list(F, S0, tuple_es(T)), F(update_c_tuple_skel(T, Ts), S1); map -> - {Ts, S1} = mapfold_list(F, S0, map_es(T)), - F(update_c_map(T, Ts), S1); + {M , S1} = mapfold(F, S0, map_val(T)), + {Ts, S2} = mapfold_list(F, S1, map_es(T)), + F(update_c_map(T, M, Ts), S2); map_pair -> {Op, S1} = mapfold(F, S0, map_pair_op(T)), {Key, S2} = mapfold(F, S1, map_pair_key(T)), @@ -723,9 +724,10 @@ label(T, N, Env) -> {As, N2} = label_ann(T, N1), {ann_c_tuple_skel(As, Ts), N2}; map -> - {Ts, N1} = label_list(map_es(T), N, Env), - {As, N2} = label_ann(T, N1), - {ann_c_map(As, Ts), N2}; + {M, N1} = label(map_val(T), N, Env), + {Ts, N2} = label_list(map_es(T), N1, Env), + {As, N3} = label_ann(T, N2), + {ann_c_map(As, M, Ts), N3}; map_pair -> {Op, N1} = label(map_pair_op(T), N, Env), {Val, N2} = label(map_pair_key(T), N1, Env), diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile index 39c9fea5d9..0b56a49cd6 100644 --- a/lib/compiler/test/Makefile +++ b/lib/compiler/test/Makefile @@ -69,6 +69,7 @@ INLINE= \ fun \ guard \ lc \ + map \ match \ misc \ num_bif \ diff --git a/lib/compiler/test/map_SUITE.erl b/lib/compiler/test/map_SUITE.erl index 7d35ffc8d5..b4baef461b 100644 --- a/lib/compiler/test/map_SUITE.erl +++ b/lib/compiler/test/map_SUITE.erl @@ -418,8 +418,12 @@ t_guard_fun(Config) when is_list(Config) -> {l,V} = F2(#{s=>l,v=>[V,V]}), %% error case - {'EXIT', {function_clause,[{?MODULE,_,[#{s:=none,v:=none}],_}|_]}} = (catch F1(#{s=>none,v=>none})), - ok. + case (catch F1(#{s=>none,v=>none})) of + {'EXIT', {function_clause,[{?MODULE,_,[#{s:=none,v:=none}],_}|_]}} -> ok; + {'EXIT', {{case_clause,_},_}} -> {comment,inlined}; + Other -> + test_server:fail({no_match, Other}) + end. t_map_sort_literals(Config) when is_list(Config) -> @@ -500,8 +504,12 @@ t_build_and_match_empty_val(Config) when is_list(Config) -> ok = F(id(#{"hi"=>ok,{1,2}=>ok,1337=>ok})), %% error case - {'EXIT',{function_clause,_}} = (catch (F(id(#{"hi"=>ok})))), - ok. + case (catch (F(id(#{"hi"=>ok})))) of + {'EXIT',{function_clause,_}} -> ok; + {'EXIT', {{case_clause,_},_}} -> {comment,inlined}; + Other -> + test_server:fail({no_match, Other}) + end. t_build_and_match_val(Config) when is_list(Config) -> F = fun @@ -514,8 +522,12 @@ t_build_and_match_val(Config) when is_list(Config) -> {2,"second"} = F(id(#{"hi"=>second,v=>"second"})), %% error case - {'EXIT',{function_clause,_}} = (catch (F(id(#{"hi"=>ok})))), - ok. + case (catch (F(id(#{"hi"=>ok})))) of + {'EXIT',{function_clause,_}} -> ok; + {'EXIT', {{case_clause,_},_}} -> {comment,inlined}; + Other -> + test_server:fail({no_match, Other}) + end. %% Use this function to avoid compile-time evaluation of an expression. |