diff options
Diffstat (limited to 'lib/compiler/src')
-rw-r--r-- | lib/compiler/src/Makefile | 69 | ||||
-rw-r--r-- | lib/compiler/src/beam_asm.erl | 2 | ||||
-rw-r--r-- | lib/compiler/src/beam_bool.erl | 27 | ||||
-rw-r--r-- | lib/compiler/src/beam_validator.erl | 16 | ||||
-rw-r--r-- | lib/compiler/src/compile.erl | 113 | ||||
-rw-r--r-- | lib/compiler/src/sys_expand_pmod.erl | 30 | ||||
-rw-r--r-- | lib/compiler/src/sys_pre_expand.erl | 60 | ||||
-rw-r--r-- | lib/compiler/src/v3_core.erl | 14 |
8 files changed, 187 insertions, 144 deletions
diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile index fde2b1a655..70ddd54145 100644 --- a/lib/compiler/src/Makefile +++ b/lib/compiler/src/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 1996-2009. All Rights Reserved. -# +# +# Copyright Ericsson AB 1996-2010. All Rights Reserved. +# # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in # compliance with the License. You should have received a copy of the # Erlang Public License along with this software. If not, it can be # retrieved online at http://www.erlang.org/. -# +# # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See # the License for the specific language governing rights and limitations # under the License. -# +# # %CopyrightEnd% # @@ -45,46 +45,46 @@ RELSYSDIR = $(RELEASE_PATH)/lib/compiler-$(VSN) # Target Specs # ---------------------------------------------------- MODULES = \ - compile \ - sys_pre_attributes \ - sys_pre_expand \ - sys_expand_pmod \ - v3_core \ - sys_core_fold \ - sys_core_inline \ - sys_core_dsetel \ - core_lib \ - core_scan \ - core_parse \ - core_lint \ - core_pp \ - v3_kernel \ - v3_kernel_pp \ - v3_life \ - v3_codegen \ + beam_asm \ beam_block \ beam_bool \ - beam_dead \ - beam_jump \ - beam_type \ - beam_clean \ - beam_peep \ beam_bsm \ - beam_trim \ + beam_clean \ + beam_dead \ + beam_dict \ + beam_disasm \ beam_flatten \ + beam_jump \ beam_listing \ - beam_asm \ - beam_dict \ beam_opcodes \ - beam_disasm \ + beam_peep \ + beam_trim \ + beam_type \ beam_utils \ beam_validator \ - erl_bifs \ cerl \ cerl_clauses \ cerl_inline \ cerl_trees \ - rec_env + compile \ + core_lib \ + core_lint \ + core_parse \ + core_pp \ + core_scan \ + erl_bifs \ + rec_env \ + sys_core_dsetel \ + sys_core_fold \ + sys_core_inline \ + sys_expand_pmod \ + sys_pre_attributes \ + sys_pre_expand \ + v3_codegen \ + v3_core \ + v3_kernel \ + v3_kernel_pp \ + v3_life BEAM_H = $(wildcard ../priv/beam_h/*.h) @@ -114,6 +114,9 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE) # FLAGS # ---------------------------------------------------- +ifeq ($(NATIVE_LIBS_ENABLED),yes) +ERL_COMPILE_FLAGS += +native +endif ERL_COMPILE_FLAGS += +inline +warn_unused_import -I../../stdlib/include -I$(EGEN) -W # ---------------------------------------------------- diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl index 90d25d87b2..497c4fa07b 100644 --- a/lib/compiler/src/beam_asm.erl +++ b/lib/compiler/src/beam_asm.erl @@ -150,7 +150,7 @@ build_file(Code, Attr, Dict, NumLabels, NumFuncs, Abst, SourceFile, Opts) -> %% Create IFF chunk. Chunks = case member(slim, Opts) of - true -> [Essentials,AttrChunk,CompileChunk,AbstChunk]; + true -> [Essentials,AttrChunk,AbstChunk]; false -> [Essentials,LocChunk,AttrChunk,CompileChunk,AbstChunk] end, build_form(<<"BEAM">>, Chunks). diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl index d8c201a194..dcc6ad4c7c 100644 --- a/lib/compiler/src/beam_bool.erl +++ b/lib/compiler/src/beam_bool.erl @@ -123,6 +123,12 @@ bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) -> throw:mixed -> failed; + %% There was a reference to a boolean expression + %% from inside a protected block (try/catch), to + %% a boolean expression outside. + throw:protected_barrier -> + failed; + %% The 'xor' operator was used. We currently don't %% find it worthwile to translate 'xor' operators %% (the code would be clumsy). @@ -167,7 +173,7 @@ bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) -> %% whether the optimized code is guaranteed to work in the same %% way as the original code. %% -%% Throws an exception if the optmization is not safe. +%% Throw an exception if the optimization is not safe. %% ensure_opt_safe(Bl, NewCode, OldIs, Fail, PreceedingCode, St) -> %% Here are the conditions that must be true for the @@ -184,10 +190,10 @@ ensure_opt_safe(Bl, NewCode, OldIs, Fail, PreceedingCode, St) -> %% by the code that follows. %% %% 3. Any register that is assigned a value in the optimized - %% code must be UNUSED or KILLED in the following code. - %% (Possible future improvement: Registers that are known - %% to be assigned the SAME value in the original and optimized - %% code don't need to be unused in the following code.) + %% code must be UNUSED or KILLED in the following code + %% (because the register might be assigned the wrong value, + %% and even if the value is right it might no longer be + %% assigned on *all* paths leading to its use). InitInPreceeding = initialized_regs(PreceedingCode), @@ -304,6 +310,8 @@ dst_regs([{set,[D],_,{bif,_,{f,_}}}|Is], Acc) -> dst_regs(Is, [D|Acc]); dst_regs([{set,[D],_,{alloc,_,{gc_bif,_,{f,_}}}}|Is], Acc) -> dst_regs(Is, [D|Acc]); +dst_regs([{set,[D],_,move}|Is], Acc) -> + dst_regs(Is, [D|Acc]); dst_regs([_|Is], Acc) -> dst_regs(Is, Acc); dst_regs([], Acc) -> ordsets:from_list(Acc). @@ -414,11 +422,10 @@ bopt_good_args([A|As], Regs) -> bopt_good_args([], _) -> ok. bopt_good_arg({Tag,_}=X, Regs) when Tag =:= x; Tag =:= tmp -> - case gb_trees:get(X, Regs) of - any -> ok; - _Other -> - %%io:format("not any: ~p: ~p\n", [X,_Other]), - throw(mixed) + case gb_trees:lookup(X, Regs) of + {value,any} -> ok; + {value,_} -> throw(mixed); + none -> throw(protected_barrier) end; bopt_good_arg(_, _) -> ok. diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 08ba9c3ee4..1fd61831e0 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% -module(beam_validator). @@ -604,9 +604,9 @@ valfun_4({gc_bif,Op,{f,Fail},Live,Src,Dst}, #vst{current=St0}=Vst0) -> St = kill_heap_allocation(St0), Vst1 = Vst0#vst{current=St}, verify_live(Live, Vst1), - Vst2 = prune_x_regs(Live, Vst1), - validate_src(Src, Vst2), - Vst = branch_state(Fail, Vst2), + Vst2 = branch_state(Fail, Vst1), + Vst = prune_x_regs(Live, Vst2), + validate_src(Src, Vst), Type = bif_type(Op, Src, Vst), set_type_reg(Type, Dst, Vst); valfun_4(return, #vst{current=#st{numy=none}}=Vst) -> diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl index e725083a9f..b853800d73 100644 --- a/lib/compiler/src/compile.erl +++ b/lib/compiler/src/compile.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% Purpose: Run the Erlang compiler. @@ -187,9 +187,9 @@ format_error(no_crypto_key) -> format_error({native, E}) -> io_lib:fwrite("native-code compilation failed with reason: ~P.", [E, 25]); -format_error({native_crash, E}) -> - io_lib:fwrite("native-code compilation crashed with reason: ~P.", - [E, 25]); +format_error({native_crash,E,Stk}) -> + io_lib:fwrite("native-code compilation crashed with reason: ~P.\n~P\n", + [E,25,Stk,25]); format_error({open,E}) -> io_lib:format("open error '~s'", [file:format_error(E)]); format_error({epp,E}) -> @@ -302,7 +302,7 @@ os_process_size() -> list_to_integer(lib:nonl(Size)); _ -> 0 - end. + end. run_tc({Name,Fun}, St) -> Before0 = statistics(runtime), @@ -318,17 +318,30 @@ run_tc({Name,Fun}, St) -> Val. comp_ret_ok(#compile{code=Code,warnings=Warn0,module=Mod,options=Opts}=St) -> - Warn = messages_per_file(Warn0), - report_warnings(St#compile{warnings = Warn}), - Ret1 = case member(binary, Opts) andalso not member(no_code_generation, Opts) of - true -> [Code]; - false -> [] - end, - Ret2 = case member(return_warnings, Opts) of - true -> Ret1 ++ [Warn]; - false -> Ret1 - end, - list_to_tuple([ok,Mod|Ret2]). + case member(warnings_as_errors, Opts) andalso length(Warn0) > 0 of + true -> + case member(report_warnings, Opts) of + true -> + io:format("~p: warnings being treated as errors\n", + [?MODULE]); + false -> + ok + end, + comp_ret_err(St); + false -> + Warn = messages_per_file(Warn0), + report_warnings(St#compile{warnings = Warn}), + Ret1 = case member(binary, Opts) andalso + not member(no_code_generation, Opts) of + true -> [Code]; + false -> [] + end, + Ret2 = case member(return_warnings, Opts) of + true -> Ret1 ++ [Warn]; + false -> Ret1 + end, + list_to_tuple([ok,Mod|Ret2]) + end. comp_ret_err(#compile{warnings=Warn0,errors=Err0,options=Opts}=St) -> Warn = messages_per_file(Warn0), @@ -344,18 +357,18 @@ comp_ret_err(#compile{warnings=Warn0,errors=Err0,options=Opts}=St) -> messages_per_file(Ms) -> T = lists:sort([{File,M} || {File,Messages} <- Ms, M <- Messages]), PrioMs = [erl_scan, epp, erl_parse], - {Prio0, Rest} = + {Prio0, Rest} = lists:mapfoldl(fun(M, A) -> lists:partition(fun({_,{_,Mod,_}}) -> Mod =:= M; (_) -> false end, A) end, T, PrioMs), - Prio = lists:sort(fun({_,{L1,_,_}}, {_,{L2,_,_}}) -> L1 =< L2 end, + Prio = lists:sort(fun({_,{L1,_,_}}, {_,{L2,_,_}}) -> L1 =< L2 end, lists:append(Prio0)), flatmap(fun mpf/1, [Prio, Rest]). mpf(Ms) -> - [{File,[M || {F,M} <- Ms, F =:= File]} || + [{File,[M || {F,M} <- Ms, F =:= File]} || File <- lists:usort([F || {F,_} <- Ms])]. %% passes(form|file, [Option]) -> [{Name,PassFun}] @@ -495,14 +508,14 @@ select_passes([List|Ps], Opts) when is_list(List) -> select_cond(Flag, ShouldBe, Pass, Ps, Opts) -> ShouldNotBe = not ShouldBe, - case member(Flag, Opts) of + case member(Flag, Opts) of ShouldBe -> select_passes([Pass|Ps], Opts); ShouldNotBe -> select_passes(Ps, Opts) end. %% select_list_passes([Pass], Opts) -> {done,[Pass]} | {not_done,[Pass]} %% Evaluate all conditions having to do with listings in the list of -%% passes. +%% passes. select_list_passes(Ps, Opts) -> select_list_passes_1(Ps, Opts, []). @@ -704,7 +717,7 @@ read_beam_file(St) -> case file:read_file(St#compile.ifile) of {ok,Beam} -> Infile = St#compile.ifile, - case is_too_old(Infile) of + case no_native_compilation(Infile, St) of true -> {ok,St#compile{module=none,code=none}}; false -> @@ -717,12 +730,15 @@ read_beam_file(St) -> {error,St#compile{errors=St#compile.errors ++ Es}} end. -is_too_old(BeamFile) -> +no_native_compilation(BeamFile, #compile{options=Opts0}) -> case beam_lib:chunks(BeamFile, ["CInf"]) of {ok,{_,[{"CInf",Term0}]}} -> Term = binary_to_term(Term0), - Opts = proplists:get_value(options, Term, []), - lists:member(no_new_funs, Opts); + + %% Compiler options in the beam file will override + %% options passed to the compiler. + Opts = proplists:get_value(options, Term, []) ++ Opts0, + member(no_new_funs, Opts) orelse not is_native_enabled(Opts); _ -> false end. @@ -782,7 +798,7 @@ clean_parse_transforms_1([F|Fs], Acc) -> clean_parse_transforms_1(Fs, [F|Acc]); clean_parse_transforms_1([], Acc) -> reverse(Acc). -transforms(Os) -> [ M || {parse_transform,M} <- Os ]. +transforms(Os) -> [ M || {parse_transform,M} <- Os ]. transform_module(#compile{options=Opt,code=Code0}=St0) -> %% Extract compile options from code into options field. @@ -815,7 +831,7 @@ foldl_transform(St, [T|Ts]) -> end; foldl_transform(St, []) -> {ok,St}. -get_core_transforms(Opts) -> [M || {core_transform,M} <- Opts]. +get_core_transforms(Opts) -> [M || {core_transform,M} <- Opts]. core_transforms(St) -> %% The options field holds the complete list of options at this @@ -1033,7 +1049,14 @@ beam_asm(#compile{ifile=File,code=Code0,abstract_code=Abst,options=Opts0}=St) -> test_native(#compile{options=Opts}) -> %% This test is done late, in case some other option has turned off native. - member(native, Opts). + %% 'native' given on the command line can be overridden by + %% 'no_native' in the module itself. + is_native_enabled(Opts). + +is_native_enabled([native|_]) -> true; +is_native_enabled([no_native|_]) -> false; +is_native_enabled([_|Opts]) -> is_native_enabled(Opts); +is_native_enabled([]) -> false. native_compile(#compile{code=none}=St) -> {ok,St}; native_compile(St) -> @@ -1057,25 +1080,27 @@ native_compile_1(St) -> St#compile.core_code, St#compile.code, Opts) of - {ok, {_Type,Bin} = T} when is_binary(Bin) -> - {ok, embed_native_code(St, T)}; - {error, R} -> + {ok,{_Type,Bin}=T} when is_binary(Bin) -> + {ok,embed_native_code(St, T)}; + {error,R} -> case IgnoreErrors of true -> - Ws = [{St#compile.ifile,[{none,?MODULE,{native,R}}]}], - {ok, St#compile{warnings=St#compile.warnings ++ Ws}}; + Ws = [{St#compile.ifile,[{?MODULE,{native,R}}]}], + {ok,St#compile{warnings=St#compile.warnings ++ Ws}}; false -> - Es = [{St#compile.ifile,[{none,?MODULE,{native,R}}]}], - {error, St#compile{errors=St#compile.errors ++ Es}} + Es = [{St#compile.ifile,[{?MODULE,{native,R}}]}], + {error,St#compile{errors=St#compile.errors ++ Es}} end catch - error:R -> + Class:R -> + Stk = erlang:get_stacktrace(), case IgnoreErrors of true -> - Ws = [{St#compile.ifile,[{none,?MODULE,{native_crash,R}}]}], - {ok, St#compile{warnings=St#compile.warnings ++ Ws}}; + Ws = [{St#compile.ifile, + [{?MODULE,{native_crash,R,Stk}}]}], + {ok,St#compile{warnings=St#compile.warnings ++ Ws}}; false -> - exit(R) + erlang:raise(Class, R, Stk) end end. @@ -1264,7 +1289,7 @@ listing(Ext, St) -> listing(LFun, Ext, St) -> Lfile = outfile(St#compile.base, Ext, St#compile.options), case file:open(Lfile, [write,delayed_write]) of - {ok,Lf} -> + {ok,Lf} -> Code = restore_expanded_types(Ext, St#compile.code), LFun(Lf, Code), ok = file:close(Lf), diff --git a/lib/compiler/src/sys_expand_pmod.erl b/lib/compiler/src/sys_expand_pmod.erl index dbd5c1ec2f..4fee26f2a6 100644 --- a/lib/compiler/src/sys_expand_pmod.erl +++ b/lib/compiler/src/sys_expand_pmod.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(sys_expand_pmod). @@ -283,9 +283,13 @@ expr({cons,Line,H0,T0},St) -> T1 = expr(T0,St), {cons,Line,H1,T1}; expr({lc,Line,E0,Qs0},St) -> - Qs1 = lc_quals(Qs0,St), + Qs1 = lc_bc_quals(Qs0,St), E1 = expr(E0,St), {lc,Line,E1,Qs1}; +expr({bc,Line,E0,Qs0},St) -> + Qs1 = lc_bc_quals(Qs0,St), + E1 = expr(E0,St), + {bc,Line,E1,Qs1}; expr({tuple,Line,Es0},St) -> Es1 = expr_list(Es0,St), {tuple,Line,Es1}; @@ -391,14 +395,18 @@ icr_clauses([C0|Cs],St) -> [C1|icr_clauses(Cs,St)]; icr_clauses([],_St) -> []. -lc_quals([{generate,Line,P0,E0}|Qs],St) -> +lc_bc_quals([{generate,Line,P0,E0}|Qs],St) -> + E1 = expr(E0,St), + P1 = pattern(P0,St), + [{generate,Line,P1,E1}|lc_bc_quals(Qs,St)]; +lc_bc_quals([{b_generate,Line,P0,E0}|Qs],St) -> E1 = expr(E0,St), P1 = pattern(P0,St), - [{generate,Line,P1,E1}|lc_quals(Qs,St)]; -lc_quals([E0|Qs],St) -> + [{b_generate,Line,P1,E1}|lc_bc_quals(Qs,St)]; +lc_bc_quals([E0|Qs],St) -> E1 = expr(E0,St), - [E1|lc_quals(Qs,St)]; -lc_quals([],_St) -> []. + [E1|lc_bc_quals(Qs,St)]; +lc_bc_quals([],_St) -> []. fun_clauses([C0|Cs],St) -> C1 = clause(C0,St), diff --git a/lib/compiler/src/sys_pre_expand.erl b/lib/compiler/src/sys_pre_expand.erl index 78dd73e0a2..f80d03dfac 100644 --- a/lib/compiler/src/sys_pre_expand.erl +++ b/lib/compiler/src/sys_pre_expand.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% Purpose : Expand some source Erlang constructions. This is part of the @@ -114,7 +114,7 @@ expand_pmod(Fs0, St0) -> St1 = St0#expand{exports=Xs, defined=Ds}, {Fs2,St2} = add_instance(Ps, Fs1, St1), {Fs3,St3} = ensure_new(Base, Ps0, Fs2, St2), - {Fs3,St3#expand{attributes = [{abstract, [true]} + {Fs3,St3#expand{attributes = [{abstract, 0, [true]} | St3#expand.attributes]}} end. @@ -173,7 +173,7 @@ define_functions(Forms, #expand{defined=Predef}=St) -> St#expand{defined=ordsets:from_list(Fs)}. module_attrs(St) -> - {[{attribute,0,Name,Val} || {Name,Val} <- St#expand.attributes],St}. + {[{attribute,Line,Name,Val} || {Name,Line,Val} <- St#expand.attributes],St}. module_predef_funcs(St) -> PreDef = [{module_info,0},{module_info,1}], @@ -197,8 +197,8 @@ module_predef_funcs(St) -> forms([{attribute,_,file,_File}=F|Fs0], St0) -> {Fs,St1} = forms(Fs0, St0), {[F|Fs],St1}; -forms([{attribute,_,Name,Val}|Fs0], St0) -> - St1 = attribute(Name, Val, St0), +forms([{attribute,Line,Name,Val}|Fs0], St0) -> + St1 = attribute(Name, Val, Line, St0), forms(Fs0, St1); forms([{function,L,N,A,Cs}|Fs0], St0) -> {Ff,St1} = function(L, N, A, Cs, St0), @@ -207,30 +207,30 @@ forms([{function,L,N,A,Cs}|Fs0], St0) -> forms([_|Fs], St) -> forms(Fs, St); forms([], St) -> {[],St}. -%% attribute(Attribute, Value, State) -> State'. +%% attribute(Attribute, Value, Line, State) -> State'. %% Process an attribute, this just affects the state. -attribute(module, {Module, As}, St) -> +attribute(module, {Module, As}, _L, St) -> M = package_to_string(Module), St#expand{module=list_to_atom(M), - package = packages:strip_last(M), + package=packages:strip_last(M), parameters=As}; -attribute(module, Module, St) -> +attribute(module, Module, _L, St) -> M = package_to_string(Module), St#expand{module=list_to_atom(M), - package = packages:strip_last(M)}; -attribute(export, Es, St) -> + package=packages:strip_last(M)}; +attribute(export, Es, _L, St) -> St#expand{exports=union(from_list(Es), St#expand.exports)}; -attribute(import, Is, St) -> +attribute(import, Is, _L, St) -> import(Is, St); -attribute(compile, C, St) when is_list(C) -> +attribute(compile, C, _L, St) when is_list(C) -> St#expand{compile=St#expand.compile ++ C}; -attribute(compile, C, St) -> +attribute(compile, C, _L, St) -> St#expand{compile=St#expand.compile ++ [C]}; -attribute(Name, Val, St) when is_list(Val) -> - St#expand{attributes=St#expand.attributes ++ [{Name,Val}]}; -attribute(Name, Val, St) -> - St#expand{attributes=St#expand.attributes ++ [{Name,[Val]}]}. +attribute(Name, Val, Line, St) when is_list(Val) -> + St#expand{attributes=St#expand.attributes ++ [{Name,Line,Val}]}; +attribute(Name, Val, Line, St) -> + St#expand{attributes=St#expand.attributes ++ [{Name,Line,[Val]}]}. function(L, N, A, Cs0, St0) -> {Cs,St} = clauses(Cs0, St0#expand{func=N,arity=A,fcount=0}), @@ -299,10 +299,10 @@ pattern({match,Line,Pat1, Pat2}, St0) -> {TT,St2} = pattern(Pat1, St1), {{match,Line,TT,TH},St2}; %% Compile-time pattern expressions, including unary operators. -pattern({op,Line,Op,A}, St) -> - {erl_eval:partial_eval({op,Line,Op,A}),St}; -pattern({op,Line,Op,L,R}, St) -> - {erl_eval:partial_eval({op,Line,Op,L,R}),St}. +pattern({op,_Line,_Op,_A}=Op, St) -> + {erl_eval:partial_eval(Op),St}; +pattern({op,_Line,_Op,_L,_R}=Op, St) -> + {erl_eval:partial_eval(Op),St}. pattern_list([P0|Ps0], St0) -> {P,St1} = pattern(P0, St0), @@ -400,18 +400,18 @@ expr({'receive',Line,Cs0,To0,ToEs0}, St0) -> {{'receive',Line,Cs,To,ToEs},St3}; expr({'fun',Line,Body}, St) -> fun_tq(Line, Body, St); -expr({call,Line,{atom,La,N},As0}, St0) -> +expr({call,Line,{atom,La,N}=Atom,As0}, St0) -> {As,St1} = expr_list(As0, St0), Ar = length(As), case erl_internal:bif(N, Ar) of true -> - {{call,Line,{remote,La,{atom,La,erlang},{atom,La,N}},As},St1}; + {{call,Line,{remote,La,{atom,La,erlang},Atom},As},St1}; false -> case imported(N, Ar, St1) of {yes,Mod} -> - {{call,Line,{remote,La,{atom,La,Mod},{atom,La,N}},As},St1}; + {{call,Line,{remote,La,{atom,La,Mod},Atom},As},St1}; no -> - {{call,Line,{atom,La,N},As},St1} + {{call,Line,Atom,As},St1} end end; expr({call,Line,{record_field,_,_,_}=M,As0}, St0) -> diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index a39a3c538f..dfe15de4ff 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% Purpose : Transform normal Erlang to Core Erlang @@ -164,8 +164,8 @@ form({attribute,_,file,{File,_Line}}, {Fs,As,Es,Ws,_}, _Opts) -> form({attribute,_,_,_}=F, {Fs,As,Es,Ws,File}, _Opts) -> {Fs,[attribute(F)|As],Es,Ws,File}. -attribute({attribute,_,Name,Val}) -> - {#c_literal{val=Name},#c_literal{val=Val}}. +attribute({attribute,Line,Name,Val}) -> + {#c_literal{val=Name, anno=[Line]}, #c_literal{val=Val, anno=[Line]}}. function({function,_,Name,Arity,Cs0}, Es0, Ws0, File, Opts) -> %%ok = io:fwrite("~p - ", [{Name,Arity}]), |