aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/beam_type.erl44
-rw-r--r--lib/compiler/src/compile.erl8
-rw-r--r--lib/compiler/src/core_scan.erl8
-rw-r--r--lib/compiler/test/compile_SUITE.erl69
4 files changed, 109 insertions, 20 deletions
diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl
index 2b5d558ee4..7e9a243ada 100644
--- a/lib/compiler/src/beam_type.erl
+++ b/lib/compiler/src/beam_type.erl
@@ -26,6 +26,8 @@
-import(lists, [filter/2,foldl/3,keyfind/3,member/2,
reverse/1,reverse/2,sort/1]).
+-define(UNICODE_INT, {integer,{0,16#10FFFF}}).
+
-spec module(beam_utils:module_code(), [compile:option()]) ->
{'ok',beam_utils:module_code()}.
@@ -494,6 +496,10 @@ update({test,test_arity,_Fail,[Src,Arity]}, Ts0) ->
tdb_update([{Src,{tuple,Arity,[]}}], Ts0);
update({test,is_map,_Fail,[Src]}, Ts0) ->
tdb_update([{Src,map}], Ts0);
+update({get_map_elements,_,Src,{list,Elems0}}, Ts0) ->
+ {_Ss,Ds} = beam_utils:split_even(Elems0),
+ Elems = [{Dst,kill} || Dst <- Ds],
+ tdb_update([{Src,map}|Elems], Ts0);
update({test,is_nonempty_list,_Fail,[Src]}, Ts0) ->
tdb_update([{Src,nonempty_list}], Ts0);
update({test,is_eq_exact,_,[Reg,{atom,_}=Atom]}, Ts) ->
@@ -507,10 +513,39 @@ update({test,is_eq_exact,_,[Reg,{atom,_}=Atom]}, Ts) ->
end;
update({test,is_record,_Fail,[Src,Tag,{integer,Arity}]}, Ts) ->
tdb_update([{Src,{tuple,Arity,[Tag]}}], Ts);
-update({test,_Test,_Fail,_Other}, Ts) ->
- Ts;
+
+%% Binary matching
+
update({test,bs_get_integer2,_,_,Args,Dst}, Ts) ->
tdb_update([{Dst,get_bs_integer_type(Args)}], Ts);
+update({test,bs_get_utf8,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,?UNICODE_INT}], Ts);
+update({test,bs_get_utf16,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,?UNICODE_INT}], Ts);
+update({test,bs_get_utf32,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,?UNICODE_INT}], Ts);
+update({bs_init,_,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,kill}], Ts);
+update({bs_put,_,_,_}, Ts) ->
+ Ts;
+update({bs_save2,_,_}, Ts) ->
+ Ts;
+update({bs_restore2,_,_}, Ts) ->
+ Ts;
+update({bs_context_to_binary,Dst}, Ts) ->
+ tdb_update([{Dst,kill}], Ts);
+update({test,bs_start_match2,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,kill}], Ts);
+update({test,bs_get_binary2,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,kill}], Ts);
+update({test,bs_get_float2,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,float}], Ts);
+
+update({test,_Test,_Fail,_Other}, Ts) ->
+ Ts;
+
+%% Calls
+
update({call_ext,Ar,{extfunc,math,Math,Ar}}, Ts) ->
case is_math_bif(Math, Ar) of
true -> tdb_update([{{x,0},float}], Ts);
@@ -537,9 +572,10 @@ update({call_ext,3,{extfunc,erlang,setelement,3}}, Ts0) ->
update({call,_Arity,_Func}, Ts) -> tdb_kill_xregs(Ts);
update({call_ext,_Arity,_Func}, Ts) -> tdb_kill_xregs(Ts);
update({make_fun2,_,_,_,_}, Ts) -> tdb_kill_xregs(Ts);
+update({call_fun, _}, Ts) -> tdb_kill_xregs(Ts);
+update({apply, _}, Ts) -> tdb_kill_xregs(Ts);
+
update({line,_}, Ts) -> Ts;
-update({bs_save2,_,_}, Ts) -> Ts;
-update({bs_restore2,_,_}, Ts) -> Ts;
%% The instruction is unknown. Kill all information.
update(_I, _Ts) -> tdb_new().
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index 03b52932d1..019d8ba864 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -213,14 +213,6 @@ expand_opt(report, Os) ->
[report_errors,report_warnings|Os];
expand_opt(return, Os) ->
[return_errors,return_warnings|Os];
-expand_opt(r12, Os) ->
- [no_recv_opt,no_line_info,no_utf8_atoms|Os];
-expand_opt(r13, Os) ->
- [no_record_opt,no_recv_opt,no_line_info,no_utf8_atoms|Os];
-expand_opt(r14, Os) ->
- [no_record_opt,no_line_info,no_utf8_atoms|Os];
-expand_opt(r15, Os) ->
- [no_record_opt,no_utf8_atoms|Os];
expand_opt(r16, Os) ->
[no_record_opt,no_utf8_atoms|Os];
expand_opt(r17, Os) ->
diff --git a/lib/compiler/src/core_scan.erl b/lib/compiler/src/core_scan.erl
index 15bfc78c8b..d7d5f900de 100644
--- a/lib/compiler/src/core_scan.erl
+++ b/lib/compiler/src/core_scan.erl
@@ -283,10 +283,12 @@ scan1([$$|Cs0], Toks, Pos) -> %Character constant
scan1(Cs, [{char,Pos,C}|Toks], Pos1);
scan1([$'|Cs0], Toks, Pos) -> %Atom (always quoted)
{S,Cs1,Pos1} = scan_string(Cs0, $', Pos),
- case catch list_to_atom(S) of
+ try binary_to_atom(list_to_binary(S), utf8) of
A when is_atom(A) ->
- scan1(Cs1, [{atom,Pos,A}|Toks], Pos1);
- _Error -> scan_error({illegal,atom}, Pos)
+ scan1(Cs1, [{atom,Pos,A}|Toks], Pos1)
+ catch
+ error:_ ->
+ scan_error({illegal,atom}, Pos)
end;
scan1([$"|Cs0], Toks, Pos) -> %String
{S,Cs1,Pos1} = scan_string(Cs0, $", Pos),
diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl
index 10740ac2b0..474c3e2ca0 100644
--- a/lib/compiler/test/compile_SUITE.erl
+++ b/lib/compiler/test/compile_SUITE.erl
@@ -865,9 +865,7 @@ do_core_roundtrip_2(M, Core0, Outdir) ->
case cmp_core(Core0, Core, M) of
true -> ok;
false -> error
- end,
-
- ok.
+ end.
undo_var_translation(Tree) ->
F = fun(Node) ->
@@ -920,11 +918,72 @@ diff(E, E) ->
diff([H1|T1], [H2|T2]) ->
[diff(H1, H2)|diff(T1, T2)];
diff(T1, T2) when tuple_size(T1) =:= tuple_size(T2) ->
- L = diff(tuple_to_list(T1), tuple_to_list(T2)),
- list_to_tuple(L);
+ case cerl:is_c_var(T1) andalso cerl:is_c_var(T2) of
+ true ->
+ diff_var(T1, T2);
+ false ->
+ case cerl:is_c_map(T1) andalso cerl:is_c_map(T2) of
+ true ->
+ diff_map(T1, T2);
+ false ->
+ diff_tuple(T1, T2)
+ end
+ end;
diff(E1, E2) ->
{'DIFF',E1,E2}.
+diff_var(V1, V2) ->
+ case {cerl:var_name(V1),cerl:var_name(V2)} of
+ {Same,Same} ->
+ V1;
+ {Name1,Name2} ->
+ %% The inliner uses integers as variable names. Such integers
+ %% are read back as atoms.
+ case is_integer(Name1) andalso
+ list_to_atom(integer_to_list(Name1)) =:= Name2 of
+ true ->
+ V1;
+ _ ->
+ cerl:update_c_var(V1, {'DIFF',Name1,Name2})
+ end
+ end.
+
+%% Annotations for maps are not preserved exactly, but that is not
+%% a real problem. Workaround by not comparing all annotations when
+%% comparing maps.
+
+diff_map(M, M) ->
+ M;
+diff_map(M1, M2) ->
+ case cerl:get_ann(M1) =:= cerl:get_ann(M2) of
+ false ->
+ diff_tuple(M1, M2);
+ true ->
+ case remove_compiler_gen(M1) =:= remove_compiler_gen(M2) of
+ true ->
+ M1;
+ false ->
+ diff_tuple(M1, M2)
+ end
+ end.
+
+diff_tuple(T1, T2) ->
+ L = diff(tuple_to_list(T1), tuple_to_list(T2)),
+ list_to_tuple(L).
+
+remove_compiler_gen(M) ->
+ Arg0 = cerl:map_arg(M),
+ Arg = cerl:set_ann(Arg0, []),
+ Es0 = cerl:map_es(M),
+ Es = [remove_compiler_gen_1(Pair) || Pair <- Es0],
+ cerl:update_c_map(M, Arg, Es).
+
+remove_compiler_gen_1(Pair) ->
+ Op0 = cerl:map_pair_op(Pair),
+ Op = cerl:set_ann(Op0, []),
+ K = cerl:map_pair_key(Pair),
+ V = cerl:map_pair_val(Pair),
+ cerl:update_c_map_pair(Pair, Op, K, V).
%% Compile to Beam assembly language (.S) and then try to
%% run .S through the compiler again.