[Mono-dev] Reflection Emit issues

Ayende Rahien ayende at ayende.com
Wed Mar 14 17:53:49 EDT 2007


After a lot of trail and error, here is a small sample that duplicate this
issue, it works flawlessly on CLR, but fails on Mono.
Note that I put an assert before the call to Emit(OpCode, method), but it
still thing that it is null.

Unhandled Exception: System.ArgumentNullException: Argument cannot be null.
Parameter name: method
  at System.Reflection.Emit.ILGenerator.Emit (OpCode opcode,
System.Reflection.MethodInfo method) [0
x00099] in C:\cygwin\tmp\scratch\mono- 1.2.3.1\mcs\class\corlib
\System.Reflection.Emit\ILGenerator.cs
:720
  at Mono.Emit.Program.Main (System.String[] args) [0x00000]

class Program
{
    static void Main(string[] args)
    {
        AssemblyName assemblyName = new AssemblyName("Blag");
        AssemblyBuilder assemblyBuilder =
AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,
AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder =
assemblyBuilder.DefineDynamicModule("Module","
test.dll");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("Child",
TypeAttributes.Class, typeof(Parent));
        MethodBuilder methodBuilder = typeBuilder.DefineMethod("Method",
MethodAttributes.Virtual|MethodAttributes.Public);
        ILGenerator ilGenerator = methodBuilder. GetILGenerator();
        LocalBuilder localBuilder = ilGenerator.DeclareLocal(typeof
(MethodInfo));
        ilGenerator.Emit (OpCodes.Ldtoken,
typeof(Parent).GetMethod("Method"));
        ilGenerator.Emit(OpCodes.Ldtoken, typeof(Parent));
        MethodInfo methodInfo = typeof(MethodBase).GetMethod(
            "GetMethodFromHandle", BindingFlags.Static | BindingFlags.Public,
null,
            new Type[] { typeof(RuntimeMethodHandle),
typeof(RuntimeTypeHandle) }, null);
        Debug.Assert(methodInfo != null, "GetMethodFromHandle must exists");

        ilGenerator.Emit(OpCodes.Call, methodInfo);
        ilGenerator.Emit(OpCodes.Castclass, typeof(MethodInfo));
        ilGenerator.Emit(OpCodes.Stloc,localBuilder);
        ilGenerator.EmitWriteLine(localBuilder);
        ilGenerator.Emit(OpCodes.Ret);
        Type type = typeBuilder.CreateType();
        Parent parent = (Parent) Activator.CreateInstance(type);
        assemblyBuilder.Save("test.dll");
        parent.Method();
    }
}

public class Parent
{
    public virtual void Method()
    {

    }

    public virtual void Print(object obj)
    {
        Console.WriteLine(obj);
    }
}


On 3/12/07, Gert Driesen <gert.driesen at telenet.be> wrote:
>
>  Hi Ayende,
>
>
>
> I tried the tests myself (with SVN head), and did not even succeed in
> running the complete test suite:
>
>
>
> "no implementation for interface method
> Rhino.Mocks.Interfaces.IMockedObject::g
>
> _ProxyHash() in class .genericClass`1Proxy79e618bfe6044bb9bb680503b32a2e36
>
>
>
> This application has requested the Runtime to terminate it in an unusual
> way.
>
> Please contact the application's support team for more information."
>
>
>
> It would be great if you could create smaller test cases, and submit a bug
> reports for these issues.
>
>
>
> A good place to start would be running the unit tests of Castle on Mono,
> and once these pass move on to the Rhino tests.
>
>
>
> Gert
>
>
>
> *From:* mono-devel-list-bounces at lists.ximian.com [mailto:
> mono-devel-list-bounces at lists.ximian.com] *On Behalf Of *Ayende Rahien
> *Sent:* maandag 12 maart 2007 7:13
> *To:* mono-devel-list at lists.ximian.com
> *Subject:* [Mono-dev] Reflection Emit issues
>
>
>
> Hi guys,
> I have just attempted to run the Rhino Mocks test suite on Mono (Win32).
> The result is about 300 failing tests. The root cause seems to be
> differences in Reflection.Emit behavior.
> Rhino Mocks is using Castle Dynamic Proxy 2 to generate proxies, and all
> those tests are running on the Microsoft .NET implementation successfully.
>
> How to reproduce:
> 1/ Get the source from
> https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools
> 2/ Build rhino-mocks (xbuild default.build )
> 3/ rhino-tools\rhino-mocks\Rhino.Mocks.Tests\bin\debug>"c:\Program
> Files\Mono-1.2.3.1\bin\mono" MbUnit.GUI.exe
>
> The result of one of the failing tests:
>
> 1)
> Rhino.Mocks.Tests.FieldsProblem.PresenterBaseTestFixture.SetUp.TestEventInitialization.TearDown:
> Argument cannot be null.
> Parameter name: method
>   at System.Reflection.Emit.ILGenerator.Emit (OpCode opcode,
> System.Reflection.MethodInfo method) [0x00000]
>   at
> Castle.DynamicProxy.Generators.Emitters.SimpleAST.MethodTokenExpression.Emit(IMemberEmitter member,
> System.Reflection.Emit.ILGenerator gen) [0x00000]
>   at
> Castle.DynamicProxy.Generators.Emitters.SimpleAST.AssignStatement.Emit(IMemberEmitter member,
> System.Reflection.Emit.ILGenerator gen) [0x00000]
>   at
> Castle.DynamicProxy.Generators.Emitters.CodeBuilders.AbstractCodeBuilder.Generate(IMemberEmitter member,
> System.Reflection.Emit.ILGenerator il) [0x00000]
>   at Castle.DynamicProxy.Generators.Emitters.ConstructorEmitter.Generate() [0x00000]
>   at
> Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.EnsureBuildersAreInAValidState() [0x00000]
>   at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType() [0x00000]
>   at
> Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(
> System.Type proxyTargetType, System.Type[] interfaces,
> Castle.DynamicProxy.ProxyGenerationOptions options) [0x00000]
>   at
> Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(
> System.Type theInterface, System.Type[] interfaces,
> Castle.DynamicProxy.ProxyGenerationOptions options) [0x00000]
>   at
> Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithoutTarget (
> System.Type theInterface, System.Type[] interfaces,
> Castle.DynamicProxy.ProxyGenerationOptions options) [0x00000]
>   at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(
> System.Type theInterface, System.Type[] interfaces,
> Castle.DynamicProxy.ProxyGenerationOptions options,
> Castle.Core.Interceptor.IInterceptor[] interceptors) [0x00000]
>   at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(
> System.Type theInterface, System.Type[] interfaces,
> Castle.Core.Interceptor.IInterceptor [] interceptors) [0x00000]
>   at Rhino.Mocks.MockRepository.MockInterface (Rhino.Mocks.CreateMockStatemockStateFactory,
> System.Type type, System.Type[] extras) [0x00000]
>   at Rhino.Mocks.MockRepository.CreateMockObject (System.Type type,
> Rhino.Mocks.CreateMockState factory, System.Type[] extras, System.Object[]
> argumentsForConstructor) [0x00000]
>   at Rhino.Mocks.MockRepository.DynamicMultiMock (System.Type mainType,
> System.Type[] extraTypes, System.Object[] argumentsForConstructor)
> [0x00000]
>   at Rhino.Mocks.MockRepository.DynamicMock (System.Type type,
> System.Object[] argumentsForConstructor) [0x00000]
>   at Rhino.Mocks.Tests.FieldsProblem.PresenterBaseTestFixture.SetUp ()
> [0x00000]
>   at &lt;0x00000&gt; &lt;unknown method&gt;
>   at (wrapper managed-to-native)
> System.Reflection.MonoMethod:InternalInvoke (object,object[])
>   at System.Reflection.MonoMethod.Invoke ( System.Object obj, BindingFlags
> invokeAttr, System.Reflection.Binder binder, System.Object[] parameters,
> System.Globalization.CultureInfo culture) [0x00000]
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20070314/8d4b11b6/attachment.html 


More information about the Mono-devel-list mailing list