aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler/src')
-rw-r--r--lib/compiler/src/beam_clean.erl2
-rw-r--r--lib/compiler/src/beam_type.erl2
-rw-r--r--lib/compiler/src/beam_validator.erl2
-rw-r--r--lib/compiler/src/compile.erl4
-rw-r--r--lib/compiler/src/core_scan.erl7
-rw-r--r--lib/compiler/src/sys_core_fold.erl19
-rw-r--r--lib/compiler/src/v3_core.erl63
-rw-r--r--lib/compiler/src/v3_kernel.erl8
8 files changed, 49 insertions, 58 deletions
diff --git a/lib/compiler/src/beam_clean.erl b/lib/compiler/src/beam_clean.erl
index e208ffec1f..9d89e21a4e 100644
--- a/lib/compiler/src/beam_clean.erl
+++ b/lib/compiler/src/beam_clean.erl
@@ -86,7 +86,7 @@ add_to_work_list(F, {Fs,Used}=Sets) ->
false -> {[F|Fs],sets:add_element(F, Used)}
end.
-
+
%%%
%%% Coalesce adjacent labels. Renumber all labels to eliminate gaps.
%%% This cleanup will slightly reduce file size and slightly speed up loading.
diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl
index 3b51216a6c..3ec57a67da 100644
--- a/lib/compiler/src/beam_type.erl
+++ b/lib/compiler/src/beam_type.erl
@@ -600,7 +600,7 @@ checkerror_1([], OrigIs) -> OrigIs.
checkerror_2(OrigIs) -> [{set,[],[],fcheckerror}|OrigIs].
-
+
%%% Routines for maintaining a type database. The type database
%%% associates type information with registers.
%%%
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 70279ab658..48f5135aca 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -530,7 +530,7 @@ valfun_2(I, #vst{current=#st{ct=[[Fail]|_]}}=Vst) when is_integer(Fail) ->
%% Update branched state
valfun_3(I, branch_state(Fail, Vst));
valfun_2(_, _) ->
- error(ambigous_catch_try_state).
+ error(ambiguous_catch_try_state).
%% Handle the remaining floating point instructions here.
%% Floating point.
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index 802e3dfa2f..47d446273b 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -1556,7 +1556,7 @@ restore_expand_module([F|Fs]) ->
[F|restore_expand_module(Fs)];
restore_expand_module([]) -> [].
-
+
-spec options() -> 'ok'.
options() ->
@@ -1593,7 +1593,7 @@ help([_|T]) ->
help(_) ->
ok.
-
+
%% compile(AbsFileName, Outfilename, Options)
%% Compile entry point for erl_compile.
diff --git a/lib/compiler/src/core_scan.erl b/lib/compiler/src/core_scan.erl
index 0ca2f57dde..a4fe920258 100644
--- a/lib/compiler/src/core_scan.erl
+++ b/lib/compiler/src/core_scan.erl
@@ -1,8 +1,7 @@
-%% -*- coding: utf-8 -*-
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2013. 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
@@ -96,7 +95,7 @@ format_error(Other) -> io_lib:write(Other).
string_thing($') -> "atom"; %' stupid emacs
string_thing($") -> "string". %" stupid emacs
-
+
%% Re-entrant pre-scanner.
%%
%% If the input list of characters is insufficient to build a term the
@@ -214,7 +213,7 @@ pre_comment(eof, Sofar, Pos) ->
pre_error(E, Epos, Pos) ->
{error,{Epos,core_scan,E}, Pos}.
-
+
%% scan(CharList, StartPos)
%% This takes a list of characters and tries to tokenise them.
%%
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index cda3f7d81e..6b0ae87172 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -2342,6 +2342,25 @@ move_let_into_expr(#c_let{vars=Lvs0,body=Lbody0}=Let,
Case#c_case{arg=Cexpr,clauses=[Ca,Cb]};
{_,_,_} -> impossible
end;
+move_let_into_expr(#c_let{vars=Lvs0,body=Lbody0}=Let,
+ #c_seq{arg=Sarg0,body=Sbody0}=Seq, Sub0) ->
+ %%
+ %% let <Lvars> = do <Seq-arg>
+ %% <Seq-body>
+ %% in <Let-body>
+ %%
+ %% ==>
+ %%
+ %% do <Seq-arg>
+ %% let <Lvars> = <Seq-body>
+ %% in <Let-body>
+ %%
+ Sarg = body(Sarg0, Sub0),
+ Sbody1 = body(Sbody0, Sub0),
+ {Lvs,Sbody,Sub} = let_substs(Lvs0, Sbody1, Sub0),
+ Lbody = body(Lbody0, Sub),
+ Seq#c_seq{arg=Sarg,body=Let#c_let{vars=Lvs,arg=core_lib:make_values(Sbody),
+ body=Lbody}};
move_let_into_expr(_Let, _Expr, _Sub) -> impossible.
is_failing_clause(#c_clause{body=B}) ->
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 1195937d91..33f5015e0b 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -553,16 +553,22 @@ expr({'try',L,Es0,[],[],As0}, St0) ->
%% 'try ... after ... end'
{Es1,St1} = exprs(Es0, St0),
{As1,St2} = exprs(As0, St1),
- {Evs,Hs0,St3} = try_after(As1, St2),
- %% We must kill the id for any funs in the duplicated after body,
- %% to avoid getting two local functions having the same name.
- Hs = kill_id_anns(Hs0),
+ {Name,St3} = new_fun_name("after", St2),
{V,St4} = new_var(St3), % (must not exist in As1)
- %% TODO: this duplicates the 'after'-code; should lift to function.
- Lanno = lineno_anno(L, St4),
- {#itry{anno=#a{anno=Lanno},args=Es1,vars=[V],body=As1++[V],
- evars=Evs,handler=Hs},
- [],St4};
+ LA = lineno_anno(L, St4),
+ Lanno = #a{anno=LA},
+ Fc = function_clause([], LA, {Name,0}),
+ Fun = #ifun{anno=Lanno,id=[],vars=[],
+ clauses=[#iclause{anno=Lanno,pats=[],
+ guard=[#c_literal{val=true}],
+ body=As1}],
+ fc=Fc},
+ App = #iapply{anno=Lanno,op=#c_var{anno=LA,name={Name,0}},args=[]},
+ {Evs,Hs,St5} = try_after([App], St4),
+ Try = #itry{anno=Lanno,args=Es1,vars=[V],body=[App,V],evars=Evs,handler=Hs},
+ Letrec = #iletrec{anno=Lanno,defs=[{{Name,0},Fun}],
+ body=[Try]},
+ {Letrec,[],St5};
expr({'try',L,Es,Cs,Ecs,As}, St0) ->
%% 'try ... [of ...] [catch ...] after ... end'
expr({'try',L,[{'try',L,Es,Cs,Ecs,[]}],[],[],As}, St0);
@@ -1135,28 +1141,13 @@ bc_tq1(_, {bin,Bl,Elements}, [], AccVar, St0) ->
%%Anno = Anno0#a{anno=[compiler_generated|A]},
{set_anno(E, Anno),Pre,St}.
-append_tail_segment(Segs, St) ->
- app_tail_seg(Segs, St, []).
-
-app_tail_seg([#c_bitstr{val=Var0,size=#c_literal{val=all}}=Seg0]=L,
- St0, Acc) ->
- case Var0 of
- #c_var{name='_'} ->
- {Var,St} = new_var(St0),
- Seg = Seg0#c_bitstr{val=Var},
- {reverse(Acc, [Seg]),Var,St};
- #c_var{} ->
- {reverse(Acc, L),Var0,St0}
- end;
-app_tail_seg([H|T], St, Acc) ->
- app_tail_seg(T, St, [H|Acc]);
-app_tail_seg([], St0, Acc) ->
+append_tail_segment(Segs, St0) ->
{Var,St} = new_var(St0),
Tail = #c_bitstr{val=Var,size=#c_literal{val=all},
unit=#c_literal{val=1},
type=#c_literal{val=binary},
flags=#c_literal{val=[unsigned,big]}},
- {reverse(Acc, [Tail]),Var,St}.
+ {Segs++[Tail],Var,St}.
emasculate_segments(Segs, St) ->
emasculate_segments(Segs, St, []).
@@ -1912,7 +1903,7 @@ new_in_all([Le|Les]) ->
foldl(fun (L, Ns) -> intersection((get_anno(L))#a.ns, Ns) end,
(get_anno(Le))#a.ns, Les);
new_in_all([]) -> [].
-
+
%% The AfterVars are the variables which are used afterwards. We need
%% this to work out which variables are actually exported and used
%% from case/receive. In subblocks/clauses the AfterVars of the block
@@ -2056,24 +2047,6 @@ cexpr(Lit, _As, St) ->
%%Vs = lit_vars(Lit),
{set_anno(Lit, Anno#a.anno),[],Vs,St}.
-%% Kill the id annotations for any fun inside the expression.
-%% Necessary when duplicating code in try ... after.
-
-kill_id_anns(#ifun{clauses=Cs0}=Fun) ->
- Cs = kill_id_anns(Cs0),
- Fun#ifun{clauses=Cs,id=[]};
-kill_id_anns(#a{}=A) ->
- %% Optimization: Don't waste time searching for funs inside annotations.
- A;
-kill_id_anns([H|T]) ->
- [kill_id_anns(H)|kill_id_anns(T)];
-kill_id_anns([]) -> [];
-kill_id_anns(Tuple) when is_tuple(Tuple) ->
- L0 = tuple_to_list(Tuple),
- L = kill_id_anns(L0),
- list_to_tuple(L);
-kill_id_anns(Other) -> Other.
-
%% lit_vars(Literal) -> [Var].
lit_vars(Lit) -> lit_vars(Lit, []).
diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl
index 2b2b8bf550..65f1251099 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -160,8 +160,8 @@ function({#c_var{name={F,Arity}=FA},Body}, St0) ->
io:fwrite("Function: ~w/~w\n", [F,Arity]),
erlang:raise(Class, Error, Stack)
end.
-
-
+
+
%% body(Cexpr, Sub, State) -> {Kexpr,[PreKepxr],State}.
%% Do the main sequence of a body. A body ends in an atomic value or
%% values. Must check if vector first so do expr.
@@ -834,7 +834,7 @@ last([_|T]) -> last(T).
first([_]) -> [];
first([H|T]) -> [H|first(T)].
-
+
%% This code implements the algorithm for an optimizing compiler for
%% pattern matching given "The Implementation of Functional
%% Programming Languages" by Simon Peyton Jones. The code is much
@@ -1428,7 +1428,7 @@ arg_val(Arg, C) ->
{set_kanno(S, []),U,T,Fs}
end
end.
-
+
%% ubody_used_vars(Expr, State) -> [UsedVar]
%% Return all used variables for the body sequence. Much more
%% efficient than using ubody/3 if the body contains nested letrecs.