[Mono-dev] TypeForwardedFrom

Neale Ferguson NealeFerguson at verizon.net
Thu Apr 11 18:58:14 UTC 2013


This, in my naivety, looks like what I want. However, it's not and leads to
a NULL reference exception. What I am attempting to do is change the
generated code from calling ow.WriteAssembly(writer, memberType.Assembly) to
ow.WriteTypeAssembly(writer, memberType)

--- 
a/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenera
tor.cs
+++ 
b/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenera
tor.cs
@@ -115,8 +115,10 @@ namespace
System.Runtime.Serialization.Formatters.Binary
-                                       // EMIT ow.WriteAssembly (writer,
memberType.Assembly);
+                                       // EMIT ow.WriteTypeAssembly
(writer, memberType);

                                        gen.Emit (OpCodes.Ldarg_1);
                                        gen.Emit (OpCodes.Ldarg_2);
-                                       EmitLoadTypeAssembly (gen,
memberType, field.Name);
-                                       gen.EmitCall (OpCodes.Callvirt,
typeof(ObjectWriter).GetMethod("WriteAssembly"), null);
+//                                     EmitLoadTypeAssembly (gen,
memberType, field.Name);
+//                                     gen.EmitCall (OpCodes.Callvirt,
typeof(ObjectWriter).GetMethod("WriteAssembly"), null);
+                                       EmitLoadType (gen, memberType);
+                                       gen.EmitCall (OpCodes.Callvirt,
typeof(ObjectWriter).GetMethod("WriteTypeAssembly"), null);
                                        gen.Emit (OpCodes.Pop);
                                }
                        }
@@ -318,6 +320,12 @@ namespace
System.Runtime.Serialization.Formatters.Binary
                        gen.EmitCall (OpCodes.Callvirt,
typeof(Type).GetProperty("Assembly").GetGetMethod(), null);
                }
                
+               static void EmitLoadType (ILGenerator gen, Type type)
+               {
+                       gen.Emit (OpCodes.Ldtoken, type);
+                       gen.EmitCall (OpCodes.Call,
typeof(Type).GetMethod("GetTypeFromHandle"), null);
+               }
+               
                static void EmitWrite (ILGenerator gen, Type type)
                {
                        gen.EmitCall (OpCodes.Callvirt,
typeof(BinaryWriter).GetMethod("Write", new Type[] { type }), null);



On 4/11/13 1:21 PM, "Robert Jordan" <robertj at gmx.net> wrote:

> Neale,
> 
> Rename & Modify WriteAssembly to take a Type argument:
> 
> public int WriteTypeAssembly (BinaryWriter writer, Type type)
> {
> return WriteAssemblyName (writer, type.GetAssemblyName ());
> }
> 
> (GetAssemblyName () is the extension from my first post)
> 
> Then change all call sites such that they pass the type directly
> instead type.Assembly to WriteTypeAssembly. Don't forget
> CodeGenerator.cs, where things get nastier due to IL code
> generation ;)
> 
> Robert
> 
> 
> On 11.04.2013 17:48, Neale Ferguson wrote:
>> Thanks again and apologies for peppering you with questions. In
>> WriteAssemblyName() it retrieves the AssemblyFullName so I'm not sure how I
>> can get the forwarded name without the associated Type value.
>> 
>> Neale
>> 
>> On 4/11/13 10:04 AM, "Robert Jordan" <robertj at gmx.net> wrote:
>> 
>>> Neale,
>>> 
>>> The icall's declaration:
>>> 
>>> mono/metadata/icall-def.h:ICALL(ASSEM_23, "get_fullname",
>>> ves_icall_System_Reflection_Assembly_get_fullName)
>>> 
>>> The function:
>>> 
>>> mono/metadata/icall.c:ves_icall_System_Reflection_Assembly_get_fullName
>>> (MonoReflectionAssembly *assembly)
>>> 
>>> 
>>> I won't add this overhead to the Assembly class because it's a Type
>>> feature after all. You can handle this locally in ObjectWriter,
>>> as this is the only place where TypeForwardedFrom is used at all.
>> 
>> 
> 




More information about the Mono-devel-list mailing list