views:

28

answers:

2

Hi All,

Was using this solution to convert anonymous types to dictionaries using reflection.emit. Was working fine until I changed to .Net 4.0 from 3.5.

Now, I'm getting the "System.Security.VerificationException: Operation could destabilize the runtime." error.

Converted the anonymously loaded dynamic method to one hosted in a dynamic assembly, saved it, then ran peverify.exe on it to find out what was wrong.

Got: [IL]: Error: [DynamicAssemblyExample.dll : MyDynamicType::MyMethod][offs et 0x0000000D][found ref ('this' ptr) 'MyDynamicType'][expected ref '<>f__AnonymousType1`3[System.String,System.Int32,System.Byte]'] Unexpected type on the stac k. [IL]: Error: [DynamicAssemblyExample.dll : MyDynamicType::MyMethod][offs et 0x0000000D] Method is not visible. 2 Error(s) Verifying DynamicAssemblyExample.dll

The code:

    foreach (PropertyInfo property in itemType.GetProperties(attributes).Where(info => info.CanRead))
    {
        // load Dictionary (prepare for call later)
        methIL.Emit(OpCodes.Ldloc_0);

        // load key, i.e. name of the property
        methIL.Emit(OpCodes.Ldstr, property.Name);

        // load value of property to stack
        methIL.Emit(OpCodes.Ldarg_0);
        methIL.EmitCall(OpCodes.Callvirt, property.GetGetMethod(), null);

        // perform boxing if necessary
        if (property.PropertyType.IsValueType)
        {
            methIL.Emit(OpCodes.Box, property.PropertyType);
        }

        // stack at this point
        // 1. string or null (value)
        // 2. string (key)
        // 3. dictionary

        // ready to call dict.Add(key, value)
        methIL.EmitCall(OpCodes.Callvirt, addMethod, null);

    }

Is there a way to derefence the pointer to the actual property? Or do I have to cast it somehow? Any pointers?

Regards!

A: 

Sorry guys, made a mistake, since the actual dynamic method creates a delegate type that acts on the instance of the anonymous (or non-anonymous) type, the Ldarg_0 code is looking for a something that is not there in this debug implementation.

So I, changed it to OpCodes.Ldnull.

           var attributes = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy;
        foreach (PropertyInfo property in itemType.GetProperties(attributes).Where(info => info.CanRead))
        {
            // load Dictionary (prepare for call later)
            methIL.Emit(OpCodes.Ldloc_0);

            // load key, i.e. name of the property
            methIL.Emit(OpCodes.Ldstr, property.Name);

            // load value of property to stack
            methIL.Emit(OpCodes.Ldnull);

            //methIL.Emit(OpCodes.Castclass, itemType);
            methIL.EmitCall(OpCodes.Callvirt, property.GetGetMethod(), null);

            // perform boxing if necessary
            if (property.PropertyType.IsValueType)
            {
                methIL.Emit(OpCodes.Box, property.PropertyType);
            }

            // stack at this point
            // 1. string or null (value)
            // 2. string (key)
            // 3. dictionary

            // ready to call dict.Add(key, value)
            methIL.EmitCall(OpCodes.Callvirt, addMethod, null);

        }

But I still get a method not visible error after peverifying it. Is it that get methods for properties of anonymous types are not visible via reflection?

A: 

Just a suggestion, have you tried to rewrite the code that emits IL to actually write to the dictionary - i.e. no Reflection.Emit ? My bet is that the generated IL is not proper in some way, not the code that accesses the anonymous type.

Igor Zevaka
Yes, i did a test where i did it without reflection, it looked pretty much the same except for a castclass opcode... which gives me an idea.
Yaay, problem solved. I just had to cast the argument, and it works. .Net 3.5 runtime verifier has some holes, obviously. Thanks for the reply.