aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1/src
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2013-10-29 14:40:47 +0100
committerBjörn Gustavsson <[email protected]>2014-01-20 12:22:42 +0100
commitdeae68b06e58027efe0b203bb2c30d3addb24f96 (patch)
tree95530e5b9b5c1a93965ea9c7b5e58dd14c483a14 /lib/asn1/src
parent1331c80ed6ca5a196fe184cce11eb257a46be728 (diff)
downloadotp-deae68b06e58027efe0b203bb2c30d3addb24f96.tar.gz
otp-deae68b06e58027efe0b203bb2c30d3addb24f96.tar.bz2
otp-deae68b06e58027efe0b203bb2c30d3addb24f96.zip
asn1ct_imm: Add a field for intermediate code for call_gen
It will greatly facilitate further optimizations if we include the intermediate code (if available) in the call_gen tuple.
Diffstat (limited to 'lib/asn1/src')
-rw-r--r--lib/asn1/src/asn1ct_constructed_per.erl34
-rw-r--r--lib/asn1/src/asn1ct_imm.erl20
2 files changed, 32 insertions, 22 deletions
diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index 4672f7edd3..709f6596b0 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -1014,13 +1014,16 @@ enc_var_type_call(Erule, Name, RestFieldNames,
{_,Key,Code} <- ObjSet1],
ObjSet = lists:sort([P || {_,B}=P <- ObjSet2, B =/= none]),
Key = erlang:md5(term_to_binary({encode,ObjSet,RestFieldNames,Extensible})),
+ Imm = enc_objset_imm(Erule, Name, ObjSet, RestFieldNames, Extensible),
+ Lambda = {lambda,[{var,"Val"},{var,"Id"}],Imm},
Gen = fun(_Fd, N) ->
- enc_objset(Erule, Name, N, ObjSet,
- RestFieldNames, Extensible)
+ Aligned = is_aligned(Erule),
+ emit([{asis,N},"(Val, Id) ->",nl]),
+ asn1ct_imm:enc_cg(Imm, Aligned),
+ emit([".",nl])
end,
Prefix = lists:concat(["enc_os_",Name]),
- F = asn1ct_func:call_gen(Prefix, Key, Gen),
- [{apply,F,[{var,atom_to_list(Val)},{var,Fun}]}].
+ [{call_gen,Prefix,Key,Gen,Lambda,[{var,atom_to_list(Val)},{var,Fun}]}].
fix_object_code(Name, [{Name,B}|_], _ClassFields) ->
B;
@@ -1042,9 +1045,7 @@ fix_object_code(Name, [], ClassFields) ->
end
end.
-
-enc_objset(Erule, Component, Name, ObjSet, RestFieldNames, Extensible) ->
- asn1ct_name:start(),
+enc_objset_imm(Erule, Component, ObjSet, RestFieldNames, Extensible) ->
Aligned = is_aligned(Erule),
E = {error,
fun() ->
@@ -1053,17 +1054,14 @@ enc_objset(Erule, Component, Name, ObjSet, RestFieldNames, Extensible) ->
"{value,Val},"
"{unique_name_and_value,'_'}})",nl])
end},
- Imm = [{'cond',
- [[{eq,{var,"Id"},Key}|
- enc_obj(Erule, Obj, RestFieldNames, Aligned)] ||
- {Key,Obj} <- ObjSet] ++
- [['_',case Extensible of
- false -> E;
- true -> {put_bits,{var,"Val"},binary,[1]}
- end]]}],
- emit([{asis,Name},"(Val, Id) ->",nl]),
- asn1ct_imm:enc_cg(Imm, Aligned),
- emit([".",nl]).
+ [{'cond',
+ [[{eq,{var,"Id"},Key}|
+ enc_obj(Erule, Obj, RestFieldNames, Aligned)] ||
+ {Key,Obj} <- ObjSet] ++
+ [['_',case Extensible of
+ false -> E;
+ true -> {put_bits,{var,"Val"},binary,[1]}
+ end]]}].
enc_obj(Erule, Obj, RestFieldNames0, Aligned) ->
case Obj of
diff --git a/lib/asn1/src/asn1ct_imm.erl b/lib/asn1/src/asn1ct_imm.erl
index a7b2e8a23b..26923b425e 100644
--- a/lib/asn1/src/asn1ct_imm.erl
+++ b/lib/asn1/src/asn1ct_imm.erl
@@ -975,6 +975,7 @@ split_off_nonbuilding(Imm) ->
is_nonbuilding({apply,_,_,_}) -> true;
is_nonbuilding({assign,_,_}) -> true;
is_nonbuilding({call,_,_,_,_}) -> true;
+is_nonbuilding({call_gen,_,_,_,_,_,_}) -> true;
is_nonbuilding({'cond',_,_}) -> true;
is_nonbuilding({lc,_,_,_,_}) -> true;
is_nonbuilding({sub,_,_,_}) -> true;
@@ -1404,6 +1405,9 @@ per_enc_open_type_output([{apply,F,A}], Acc) ->
per_enc_open_type_output([{call,M,F,A}], Acc) ->
Dst = output_var(),
{Dst,lists:reverse(Acc, [{call,M,F,A,{var,atom_to_list(Dst)}}])};
+per_enc_open_type_output([{call_gen,P,K,G,I,As}], Acc) ->
+ Dst = output_var(),
+ {Dst,lists:reverse(Acc, [{call_gen,P,K,G,I,As,{var,atom_to_list(Dst)}}])};
per_enc_open_type_output([{'cond',Cs}], Acc) ->
Dst = output_var(),
{Dst,lists:reverse(Acc, [{'cond',Cs,{var,atom_to_list(Dst)}}])};
@@ -1644,7 +1648,9 @@ enc_pre_cg_2({block,Bl0}, StL, StB) ->
enc_pre_cg_1(Bl0, StL, StB);
enc_pre_cg_2({call,_,_,_}=Imm, _, _) ->
Imm;
-enc_pre_cg_2({call_gen,_,_,_,_}=Imm, _, _) ->
+enc_pre_cg_2({call_gen,_,_,_,_,_}=Imm, _, _) ->
+ Imm;
+enc_pre_cg_2({call_gen,_,_,_,_,_,_}=Imm, _, _) ->
Imm;
enc_pre_cg_2({'cond',Cs0}, StL, _StB) ->
Cs = [{C,enc_pre_cg_1(Act, StL, outside_seq)} || [C|Act] <- Cs0],
@@ -1739,8 +1745,12 @@ enc_cg({call,M,F,As0,Dst}) ->
As = [mk_val(A) || A <- As0],
emit([mk_val(Dst)," = "]),
asn1ct_func:call(M, F, As);
-enc_cg({call_gen,Prefix,Key,Gen,As0}) ->
+enc_cg({call_gen,Prefix,Key,Gen,_,As0}) ->
+ As = [mk_val(A) || A <- As0],
+ asn1ct_func:call_gen(Prefix, Key, Gen, As);
+enc_cg({call_gen,Prefix,Key,Gen,_,As0,Dst}) ->
As = [mk_val(A) || A <- As0],
+ emit([mk_val(Dst)," = "]),
asn1ct_func:call_gen(Prefix, Key, Gen, As);
enc_cg({'cond',Cs}) ->
enc_cg_cond(Cs);
@@ -1860,7 +1870,7 @@ mk_val(Other) -> {asis,Other}.
bit_string_name2pos_fun(NNL, Src) ->
{call_gen,"bit_string_name2pos_",NNL,
- fun(Fd, Name) -> gen_name2pos(Fd, Name, NNL) end,[Src]}.
+ fun(Fd, Name) -> gen_name2pos(Fd, Name, NNL) end,[],[Src]}.
gen_name2pos(Fd, Name, Names) ->
Cs0 = gen_name2pos_cs(Names, Name),
@@ -2124,7 +2134,9 @@ per_fixup([{call,_,_,_}=H|T]) ->
[H|per_fixup(T)];
per_fixup([{call,_,_,_,_}=H|T]) ->
[H|per_fixup(T)];
-per_fixup([{call_gen,_,_,_,_}=H|T]) ->
+per_fixup([{call_gen,_,_,_,_,_}=H|T]) ->
+ [H|per_fixup(T)];
+per_fixup([{call_gen,_,_,_,_,_,_}=H|T]) ->
[H|per_fixup(T)];
per_fixup([{error,_}=H|T]) ->
[H|per_fixup(T)];