From a12301def60aa2c20f25eaad1299089de3375063 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Sun, 16 Dec 2012 10:05:08 +0100
Subject: Always inline decoding of open types

---
 lib/asn1/src/asn1ct_constructed_per.erl | 55 +++++++++++++++++----------------
 lib/asn1/src/asn1ct_gen_per.erl         | 54 ++++++++++++++------------------
 lib/asn1/src/asn1ct_gen_per_rt2ct.erl   | 21 ++-----------
 3 files changed, 53 insertions(+), 77 deletions(-)

(limited to 'lib/asn1')

diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index 4ec34da019..2f711413bf 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -1362,7 +1362,7 @@ gen_dec_line_open_type(_, _, _) ->
 		   fun() -> St end}
 	  end}.
 
-gen_dec_line_special(_, {typefield,_}, _TopType, Comp,
+gen_dec_line_special(Erule, {typefield,_}, _TopType, Comp,
 		     DecInfObj, Ext) ->
     #'ComponentType'{name=Cname,typespec=Type,prop=Prop} = Comp,
     fun({_BytesVar,PrevSt}) ->
@@ -1371,13 +1371,14 @@ gen_dec_line_special(_, {typefield,_}, _TopType, Comp,
 		    {Name,RestFieldNames} =
 			(Type#type.def)#'ObjectClassFieldType'.fieldname,
 
-		    asn1ct_name:new(tmpterm),
 		    asn1ct_name:new(reason),
-		    emit([indent(2),"{",{curr,tmpterm},", ",{next,bytes},
-			  "} = ?RT_PER:decode_open_type(",{curr,bytes},
-			  ", []),",nl]),
-		    emit([indent(2),"case (catch ObjFun(",
-			  {asis,Name},",",{curr,tmpterm},",telltype,",
+		    Imm = asn1ct_imm:per_dec_open_type(is_aligned(Erule)),
+		    BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)),
+		    {TmpTerm,TempBuf} = asn1ct_imm:dec_slim_cg(Imm, BytesVar),
+		    emit([com,nl,
+			  {next,bytes}," = ",TempBuf,com,nl,
+			  indent(2),"case (catch ObjFun(",
+			  {asis,Name},",",TmpTerm,",telltype,",
 			  {asis,RestFieldNames},")) of", nl]),
 		    emit([indent(4),"{'EXIT',",{curr,reason},"} ->",nl]),
 		    emit([indent(6),"exit({'Type not ",
@@ -1403,8 +1404,10 @@ gen_dec_line_special(_, {typefield,_}, _TopType, Comp,
 		    end,
 		    {Name,RestFieldNames} =
 			(Type#type.def)#'ObjectClassFieldType'.fieldname,
-		    emit(["?RT_PER:decode_open_type(",{curr,bytes},
-			  ", []),",nl]),
+		    Imm = asn1ct_imm:per_dec_open_type(is_aligned(Erule)),
+		    BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)),
+		    asn1ct_imm:dec_code_gen(Imm, BytesVar),
+		    emit([com,nl]),
 		    if
 			Ext == noext andalso Prop == mandatory ->
 			    emit([{curr,term}," =",nl,"      "]);
@@ -1430,8 +1433,9 @@ gen_dec_line_special(_, {typefield,_}, _TopType, Comp,
 		    end,
 		    {[],PrevSt};
 		_ ->
-		    emit(["?RT_PER:decode_open_type(",{curr,bytes},
-			  ", [])"]),
+		    Imm = asn1ct_imm:per_dec_open_type(is_aligned(Erule)),
+		    BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)),
+		    asn1ct_imm:dec_code_gen(Imm, BytesVar),
 		    RefedFieldName =
 			(Type#type.def)#'ObjectClassFieldType'.fieldname,
 
@@ -1441,10 +1445,12 @@ gen_dec_line_special(_, {typefield,_}, _TopType, Comp,
 		       Prop}],PrevSt}
 	    end
     end;
-gen_dec_line_special(_, {objectfield,PrimFieldName1,PFNList}, _TopType,
+gen_dec_line_special(Erule, {objectfield,PrimFieldName1,PFNList}, _TopType,
 		     Comp, _DecInfObj, _Ext) ->
     fun({_BytesVar,PrevSt}) ->
-	    emit(["?RT_PER:decode_open_type(",{curr,bytes},", [])"]),
+	    Imm = asn1ct_imm:per_dec_open_type(is_aligned(Erule)),
+	    BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)),
+	    asn1ct_imm:dec_code_gen(Imm, BytesVar),
 	    #'ComponentType'{name=Cname,prop=Prop} = Comp,
 	    SaveBytes = [{Cname,{PrimFieldName1,PFNList},
 			  asn1ct_gen:mk_var(asn1ct_name:curr(term)),
@@ -1667,20 +1673,15 @@ gen_dec_choice1(Erule,TopType,CompList,{ext,ExtPos,ExtNum}) ->
 	  length(CompList)-ExtNum,",Ext ),",nl}),
     emit({"{Cname,{Val,NewBytes}} = case Choice + Ext*",ExtPos-1," of",nl}),
     gen_dec_choice2(Erule,TopType,CompList,{ext,ExtPos,ExtNum}),
-    case Erule of
-	per ->
-	    emit([";",nl,"_ -> {asn1_ExtAlt,",nl,
-		  "      fun() -> ",nl,
-		  "          {XTerm,XBytes} = ?RT_PER:decode_open_type(",
-		  {curr,bytes},",[]),",nl,
-		  "          {binary_to_list(XTerm),XBytes}",nl,
-		  "      end()}"]);
-	_ ->
-	    emit([";",nl,"_ -> {asn1_ExtAlt, ?RT_PER:decode_open_type(",
-		  {curr,bytes},",[])}"])
-    end,
-    emit({nl,"end,",nl}),
-    emit({nl,"{{Cname,Val},NewBytes}"}).
+    Imm = asn1ct_imm:per_dec_open_type(is_aligned(Erule)),
+    BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)),
+    emit([";",nl,
+	  "_ ->",nl]),
+    {TmpTerm,TmpBuf} = asn1ct_imm:dec_slim_cg(Imm, BytesVar),
+    emit([com,nl,
+	  "{asn1_ExtAlt,{",TmpTerm,com,TmpBuf,"}}",nl,
+	  "end,",nl,nl,
+	  "{{Cname,Val},NewBytes}"]).
 
 
 gen_dec_choice2(Erule,TopType,L,Ext) ->
diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl
index 43346832b9..af19edb908 100644
--- a/lib/asn1/src/asn1ct_gen_per.erl
+++ b/lib/asn1/src/asn1ct_gen_per.erl
@@ -931,7 +931,6 @@ gen_objset_dec(ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName,_ClFields,
 	      _NthObj) ->
     emit({"'getdec_",ObjSetName,"'(_, _) ->",nl}),
     emit({indent(3),"fun(Attr1, Bytes, _,_) ->",nl}),
-%%    emit({indent(6),"?RT_PER:decode_open_type(Bytes,[])",nl}),
     emit({indent(6),"{Bytes,Attr1}",nl}),
     emit({indent(3),"end.",nl,nl}),
     ok;
@@ -1101,6 +1100,10 @@ gen_dec_imm(Erule, #type{def=Name,constraint=C}) ->
 	      end,
     gen_dec_imm_1(Name, C, Aligned).
 
+gen_dec_imm_1('ASN1_OPEN_TYPE', Constraint, Aligned) ->
+    imm_decode_open_type(Constraint, Aligned);
+gen_dec_imm_1('ANY', _Constraint, Aligned) ->
+    imm_decode_open_type([], Aligned);
 gen_dec_imm_1('BOOLEAN', _Constr, _Aligned) ->
     asn1ct_imm:per_dec_boolean();
 gen_dec_imm_1({'ENUMERATED',{Base,Ext}}, _Constr, Aligned) ->
@@ -1193,36 +1196,6 @@ gen_dec_prim_1(Erule,
 		  ",",{asis,Constraint},")"});
 	'UTF8String' ->
 	    emit({"?RT_PER:decode_UTF8String(",BytesVar,")"});
-	'ANY' ->
-	    case Erule of
-		per ->
-		    emit(["fun() -> {XTerm,YTermXBytes} = ?RT_PER:decode_open_type(",BytesVar,",",{asis,Constraint}, "), {binary_to_list(XTerm),XBytes} end ()"]);
-		_ ->
-		    emit(["?RT_PER:decode_open_type(",BytesVar,",", 
-			  {asis,Constraint}, ")"])
-	    end;
-	'ASN1_OPEN_TYPE' ->
-	    case Constraint of
-		[#'Externaltypereference'{type=Tname}] ->
-		    emit(["fun(FBytes) ->",nl,
-			  "   {XTerm,XBytes} = "]),
-		    emit(["?RT_PER:decode_open_type(FBytes,[]),",nl]),
-		    emit(["   {YTerm,_} = dec_",Tname,"(XTerm,mandatory),",nl]),
-		    emit(["   {YTerm,XBytes} end(",BytesVar,")"]);
-		[#type{def=#'Externaltypereference'{type=Tname}}] ->
-		    emit(["fun(FBytes) ->",nl,
-			  "   {XTerm,XBytes} = "]),
-		    emit(["?RT_PER:decode_open_type(FBytes,[]),",nl]),
-		    emit(["   {YTerm,_} = dec_",Tname,"(XTerm,mandatory),",nl]),
-		    emit(["   {YTerm,XBytes} end(",BytesVar,")"]);
-		_ ->
-		    case Erule of
-			per ->
-			    emit(["fun() -> {XTerm,XBytes} = ?RT_PER:decode_open_type(",BytesVar,", []), {binary_to_list(XTerm),XBytes} end()"]);
-			_ ->
-			    emit(["?RT_PER:decode_open_type(",BytesVar,",[])"])
-		    end
-	    end;
 	#'ObjectClassFieldType'{} ->
 		case asn1ct_gen:get_inner(Typename) of
 		    {fixedtypevaluefield,_,InnerType} -> 
@@ -1288,3 +1261,22 @@ extaddgroup2sequence([C|T],ExtNum,Acc) ->
     extaddgroup2sequence(T,ExtNum,[C|Acc]);
 extaddgroup2sequence([],_,Acc) ->
     lists:reverse(Acc).
+
+imm_decode_open_type([#'Externaltypereference'{type=Tname}], Aligned) ->
+    imm_dec_open_type_1(Tname, Aligned);
+imm_decode_open_type([#type{def=#'Externaltypereference'{type=Tname}}],
+		     Aligned) ->
+    imm_dec_open_type_1(Tname, Aligned);
+imm_decode_open_type(_, Aligned) ->
+    asn1ct_imm:per_dec_open_type(Aligned).
+
+imm_dec_open_type_1(Type, Aligned) ->
+    D = fun(OpenType, Buf) ->
+		asn1ct_name:new(tmpval),
+		emit(["begin",nl,
+		      "{",{curr,tmpval},",_} = ",
+		      "dec_",Type,"(",OpenType,", mandatory),",nl,
+		      "{",{curr,tmpval},com,Buf,"}",nl,
+		      "end"])
+	end,
+    {call,D,asn1ct_imm:per_dec_open_type(Aligned)}.
diff --git a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
index 670f9076f4..4f4563833f 100644
--- a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
+++ b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
@@ -1291,7 +1291,6 @@ gen_objset_dec(ObjSetName,_,['EXTENSIONMARK'],_ClName,_ClFields,
 	       _NthObj) ->
     emit({"'getdec_",ObjSetName,"'(_, _) ->",nl}),
     emit({indent(3),"fun(Attr1, Bytes, _, _) ->",nl}),
-    %%    emit({indent(6),"?RT_PER:decode_open_type(Bytes,[])",nl}),
     emit({indent(6),"{Bytes,Attr1}",nl}),
     emit({indent(3),"end.",nl,nl}),
     ok;
@@ -1543,25 +1542,9 @@ gen_dec_prim(Erules,Att,BytesVar) ->
 	'UTF8String' ->
 	    emit({"?RT_PER:decode_UTF8String(",BytesVar,")"});
 	'ANY' ->
-	    emit(["?RT_PER:decode_open_type(",BytesVar,",", 
-		  {asis,Constraint}, ")"]); 
+	    asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar);
 	'ASN1_OPEN_TYPE' ->
-	    case Constraint of
-		[#'Externaltypereference'{type=Tname}] ->
-		    emit(["fun(FBytes) ->",nl,
-			  "   {XTerm,XBytes} = "]),
-		    emit(["?RT_PER:decode_open_type(FBytes,[]),",nl]),
-		    emit(["   {YTerm,_} = dec_",Tname,"(XTerm,mandatory),",nl]),
-		    emit(["   {YTerm,XBytes} end(",BytesVar,")"]);
-		[#type{def=#'Externaltypereference'{type=Tname}}] ->
-		    emit(["fun(FBytes) ->",nl,
-			  "   {XTerm,XBytes} = "]),
-		    emit(["?RT_PER:decode_open_type(FBytes,[]),",nl]),
-		    emit(["   {YTerm,_} = dec_",Tname,"(XTerm,mandatory),",nl]),
-		    emit(["   {YTerm,XBytes} end(",BytesVar,")"]);
-		_ ->
-		    emit(["?RT_PER:decode_open_type(",BytesVar,",[])"])
-	    end;
+	    asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar);
 	#'ObjectClassFieldType'{} ->
 		case asn1ct_gen:get_inner(Att#type.def) of
 		    {fixedtypevaluefield,_,InnerType} -> 
-- 
cgit v1.2.3