aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/beam_dict.erl18
-rw-r--r--lib/compiler/src/v3_kernel.erl31
2 files changed, 19 insertions, 30 deletions
diff --git a/lib/compiler/src/beam_dict.erl b/lib/compiler/src/beam_dict.erl
index ff6c7c11dc..531968b3c8 100644
--- a/lib/compiler/src/beam_dict.erl
+++ b/lib/compiler/src/beam_dict.erl
@@ -138,17 +138,7 @@ string(Str, Dict) when is_list(Str) ->
-spec lambda(label(), non_neg_integer(), bdict()) ->
{non_neg_integer(), bdict()}.
-lambda(Lbl, 0, #asm{lambdas=Lambdas0}=Dict) ->
- case lists:keyfind(Lbl, 1, Lambdas0) of
- {Lbl,{OldIndex,_,_,_,_}} ->
- {OldIndex,Dict};
- false ->
- new_lambda(Lbl, 0, Dict)
- end;
-lambda(Lbl, NumFree, Dict) ->
- new_lambda(Lbl, NumFree, Dict).
-
-new_lambda(Lbl, NumFree, #asm{lambdas=Lambdas0}=Dict) ->
+lambda(Lbl, NumFree, #asm{lambdas=Lambdas0}=Dict) ->
OldIndex = length(Lambdas0),
%% Set Index the same as OldIndex.
Index = OldIndex,
@@ -245,12 +235,10 @@ string_table(#asm{strings=Strings,string_offset=Size}) ->
-spec lambda_table(bdict()) -> {non_neg_integer(), [<<_:192>>]}.
-lambda_table(#asm{exports=Ext0,locals=Loc0,lambdas=Lambdas0}) ->
+lambda_table(#asm{locals=Loc0,lambdas=Lambdas0}) ->
Lambdas1 = sofs:relation(Lambdas0),
Loc = sofs:relation([{Lbl,{F,A}} || {F,A,Lbl} <- Loc0]),
- Ext = sofs:relation([{Lbl,{F,A}} || {F,A,Lbl} <- Ext0]),
- All = sofs:union(Loc, Ext),
- Lambdas2 = sofs:relative_product1(Lambdas1, All),
+ Lambdas2 = sofs:relative_product1(Lambdas1, Loc),
Lambdas = [<<F:32,A:32,Lbl:32,Index:32,NumFree:32,OldUniq:32>> ||
{{_,Lbl,Index,NumFree,OldUniq},{F,A}} <- sofs:to_external(Lambdas2)],
{length(Lambdas),Lambdas}.
diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl
index b1bff47f69..8ef71e1346 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -235,8 +235,16 @@ gexpr_test_add(Ke, St0) ->
%% expr(Cexpr, Sub, State) -> {Kexpr,[PreKexpr],State}.
%% Convert a Core expression, flattening it at the same time.
-expr(#c_var{anno=A,name={Name,Arity}}, Sub, St) ->
- {#k_local{anno=A,name=get_fsub(Name, Arity, Sub),arity=Arity},[],St};
+expr(#c_var{anno=A,name={_Name,Arity}}=Fname, Sub, St) ->
+ %% A local in an expression.
+ %% For now, these are wrapped into a fun by reverse
+ %% etha-conversion, but really, there should be exactly one
+ %% such "lambda function" for each escaping local name,
+ %% instead of one for each occurrence as done now.
+ Vs = [#c_var{name=list_to_atom("V" ++ integer_to_list(V))} ||
+ V <- integers(1, Arity)],
+ Fun = #c_fun{anno=A,vars=Vs,body=#c_apply{anno=A,op=Fname,args=Vs}},
+ expr(Fun, Sub, St);
expr(#c_var{anno=A,name=V}, Sub, St) ->
{#k_var{anno=A,name=get_vsub(V, Sub)},[],St};
expr(#c_literal{anno=A,val=V}, _Sub, St) ->
@@ -1655,19 +1663,6 @@ uexpr(#ifun{anno=A,vars=Vs,body=B0}, {break,Rs}, St0) ->
#k_int{val=Index},#k_int{val=Uniq}|Fvs],
ret=Rs},
Free,add_local_function(Fun, St)};
-uexpr(#k_local{anno=A,name=Name,arity=Arity}, {break,Rs}, St) ->
- Fs = get_free(Name, Arity, St),
- FsCount = length(Fs),
- Free = lit_list_vars(Fs),
- %% Set dummy values for Index and Uniq -- the real values will
- %% be assigned by beam_asm.
- Index = Uniq = 0,
- Bif = #k_bif{anno=#k{us=Free,ns=lit_list_vars(Rs),a=A},
- op=#k_internal{name=make_fun,arity=FsCount+3},
- args=[#k_atom{val=Name},#k_int{val=FsCount+Arity},
- #k_int{val=Index},#k_int{val=Uniq}|Fs],
- ret=Rs},
- {Bif,Free,St};
uexpr(Lit, {break,Rs0}, St0) ->
%% Transform literals to puts here.
%%ok = io:fwrite("uexpr ~w:~p~n", [?LINE,Lit]),
@@ -1848,6 +1843,12 @@ make_list(Es) ->
#c_cons{hd=E,tl=Acc}
end, #c_literal{val=[]}, Es).
+%% List of integers in interval [N,M]. Empty list if N > M.
+
+integers(N, M) when N =< M ->
+ [N|integers(N + 1, M)];
+integers(_, _) -> [].
+
%% is_in_guard(State) -> true|false.
is_in_guard(#kern{guard_refc=Refc}) ->