diff options
author | Fredrik Gustafsson <[email protected]> | 2013-09-25 12:39:47 +0200 |
---|---|---|
committer | Fredrik Gustafsson <[email protected]> | 2013-09-25 12:39:47 +0200 |
commit | 1d9845de7904710119160ebdc4d3c9fcf551e260 (patch) | |
tree | f812c0e37b4074d64e8d913e3a23a15b4f6808a3 | |
parent | f038ae74fc66730e054453afaaf143dc3bf54567 (diff) | |
parent | 26940a8c0c37248af03f60dad26133420a01c6d5 (diff) | |
download | otp-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.erl | 42 |
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, []). |