aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFredrik Gustafsson <[email protected]>2013-09-25 12:39:47 +0200
committerFredrik Gustafsson <[email protected]>2013-09-25 12:39:47 +0200
commit1d9845de7904710119160ebdc4d3c9fcf551e260 (patch)
treef812c0e37b4074d64e8d913e3a23a15b4f6808a3
parentf038ae74fc66730e054453afaaf143dc3bf54567 (diff)
parent26940a8c0c37248af03f60dad26133420a01c6d5 (diff)
downloadotp-1d9845de7904710119160ebdc4d3c9fcf551e260.tar.gz
otp-1d9845de7904710119160ebdc4d3c9fcf551e260.tar.bz2
otp-1d9845de7904710119160ebdc4d3c9fcf551e260.zip
Merge branch 'nox/lift-after/OTP-11267'
* nox/lift-after/OTP-11267: Lift 'after' blocks to zeroary functions
-rw-r--r--lib/compiler/src/v3_core.erl42
1 files changed, 15 insertions, 27 deletions
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 6dc4f3f300..89319af502 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);
@@ -2041,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, []).