[Mono-dev] TypeForwardedFrom

Neale Ferguson NealeFerguson at verizon.net
Fri Apr 12 14:46:37 UTC 2013


In both the MONO_REFLECTION_SERIALIZER=yes & no cases we die in
GetAssemblyId when called from WriteTypeSpec:

case TypeTag.GenericType:
      writer.Write (type.FullName);
      writer.Write ((int)GetAssemblyId (type.Assembly));
      break;

I put a couple of WriteLines in the ObjectWriter version before each call
and prior to the break and saw:

type.FullName = TypeTag.GenericType:
System.Collections.ObjectModel.ObservableCollection`1[[System.String,
mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089]]

Type.Assembly = Getting assembly id System, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089

I'm not sure why commenting out the EmitLoadType/EmitCall to
WriteTypeAssembly and using the previous EmitLoadAssemblyType/EmitCall to
WriteAssembly causes things not to fail.


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

> This looks good. Maybe the error is somewhere else, so try to
> disable the IL serializer with
> 
> MONO_REFLECTION_SERIALIZER=yes mono yourtest.exe
> 
> If it still breaks, the bug is in WriteTypeAssembly.
> 
> Robert
> 
> On 11.04.2013 20:58, Neale Ferguson wrote:
>> 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