Exemplo n.º 1
0
            public static bool isMethodDeprecated(object method)
            {
                MethodWrapper mw = MethodWrapper.FromMethodOrConstructor(method);
                MethodBase    mb = mw.GetMethod();

                return(mb != null && mb.IsDefined(typeof(ObsoleteAttribute), false));
            }
Exemplo n.º 2
0
        public static Delegate DynamicCreateDelegate(object obj, Type delegateType, string name, string sig)
        {
            TypeWrapper   tw = TypeWrapper.FromClass(ikvm.runtime.Util.getClassFromObject(obj));
            MethodWrapper mw = tw.GetMethodWrapper(name, sig, true);

            if (mw == null || mw.IsStatic || !mw.IsPublic)
            {
                MethodInfo      invoke         = delegateType.GetMethod("Invoke");
                ParameterInfo[] parameters     = invoke.GetParameters();
                Type[]          parameterTypes = new Type[parameters.Length + 1];
                parameterTypes[0] = typeof(object);
                for (int i = 0; i < parameters.Length; i++)
                {
                    parameterTypes[i + 1] = parameters[i].ParameterType;
                }
                System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("Invoke", invoke.ReturnType, parameterTypes);
                CodeEmitter ilgen = CodeEmitter.Create(dm);
                ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, tw.Name + ".Invoke" + sig);
                ClassLoaderWrapper.GetBootstrapClassLoader()
                .LoadClassByDottedName(mw == null || mw.IsStatic ? "java.lang.AbstractMethodError" : "java.lang.IllegalAccessError")
                .GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false)
                .EmitNewobj(ilgen);
                ilgen.Emit(System.Reflection.Emit.OpCodes.Throw);
                ilgen.DoEmit();
                return(dm.CreateDelegate(delegateType, obj));
            }
            else
            {
                mw.ResolveMethod();
                return(Delegate.CreateDelegate(delegateType, obj, (MethodInfo)mw.GetMethod()));
            }
        }
Exemplo n.º 3
0
        public static Delegate DynamicCreateDelegate(object obj, Type delegateType, string name, string sig)
        {
#if !WINRT
#if FIRST_PASS
            return(null);
#else
            TypeWrapper   tw = TypeWrapper.FromClass(ikvm.runtime.Util.getClassFromObject(obj));
            MethodWrapper mw = tw.GetMethodWrapper(name, sig, true);
            if (mw == null || mw.IsStatic || !mw.IsPublic)
            {
#if NO_REF_EMIT
                java.lang.invoke.MethodType methodType = MethodHandleUtil.GetDelegateMethodType(delegateType);
                if (methodType.parameterCount() > MethodHandleUtil.MaxArity)
                {
                    throw new NotImplementedException();
                }
                java.lang.invoke.MethodHandle exception = java.lang.invoke.MethodHandles.publicLookup()
                                                          .findConstructor(mw == null || mw.IsStatic ? typeof(java.lang.AbstractMethodError) : typeof(java.lang.IllegalAccessError),
                                                                           java.lang.invoke.MethodType.methodType(typeof(void), typeof(string)))
                                                          .bindTo(tw.Name + ".Invoke" + sig);
                return(Delegate.CreateDelegate(delegateType,
                                               java.lang.invoke.MethodHandles.dropArguments(
                                                   java.lang.invoke.MethodHandles.foldArguments(java.lang.invoke.MethodHandles.throwException(methodType.returnType(), exception.type().returnType()), exception),
                                                   0, methodType.parameterArray()).vmtarget, "Invoke"));
#else
                MethodInfo      invoke         = delegateType.GetMethod("Invoke");
                ParameterInfo[] parameters     = invoke.GetParameters();
                Type[]          parameterTypes = new Type[parameters.Length + 1];
                parameterTypes[0] = typeof(object);
                for (int i = 0; i < parameters.Length; i++)
                {
                    parameterTypes[i + 1] = parameters[i].ParameterType;
                }
                System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("Invoke", invoke.ReturnType, parameterTypes);
                CodeEmitter ilgen = CodeEmitter.Create(dm);
                ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, tw.Name + ".Invoke" + sig);
                ClassLoaderWrapper.GetBootstrapClassLoader()
                .LoadClassByDottedName(mw == null || mw.IsStatic ? "java.lang.AbstractMethodError" : "java.lang.IllegalAccessError")
                .GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false)
                .EmitNewobj(ilgen);
                ilgen.Emit(System.Reflection.Emit.OpCodes.Throw);
                ilgen.DoEmit();
                return(dm.CreateDelegate(delegateType, obj));
#endif
            }
            else
            {
                mw.ResolveMethod();
                return(Delegate.CreateDelegate(delegateType, obj, (MethodInfo)mw.GetMethod()));
            }
#endif
#else
            throw new NotImplementedException();
#endif
        }
Exemplo n.º 4
0
    // TODO consider caching this delegate in MethodWrapper
    private static Delegate CreateMemberNameDelegate(MethodWrapper mw, java.lang.Class caller, bool doDispatch, MethodType type)
    {
#if FIRST_PASS
        return(null);
#else
        if (mw.IsDynamicOnly)
        {
            return(MethodHandleUtil.DynamicMethodBuilder.CreateDynamicOnly(mw, type));
        }
        // HACK this code is duplicated in compiler.cs
        if (mw.IsProtected && (mw.DeclaringType == CoreClasses.java.lang.Object.Wrapper || mw.DeclaringType == CoreClasses.java.lang.Throwable.Wrapper))
        {
            TypeWrapper thisType             = TypeWrapper.FromClass(caller);
            TypeWrapper cli_System_Object    = ClassLoaderWrapper.LoadClassCritical("cli.System.Object");
            TypeWrapper cli_System_Exception = ClassLoaderWrapper.LoadClassCritical("cli.System.Exception");
            // HACK we may need to redirect finalize or clone from java.lang.Object/Throwable
            // to a more specific base type.
            if (thisType.IsAssignableTo(cli_System_Object))
            {
                mw = cli_System_Object.GetMethodWrapper(mw.Name, mw.Signature, true);
            }
            else if (thisType.IsAssignableTo(cli_System_Exception))
            {
                mw = cli_System_Exception.GetMethodWrapper(mw.Name, mw.Signature, true);
            }
            else if (thisType.IsAssignableTo(CoreClasses.java.lang.Throwable.Wrapper))
            {
                mw = CoreClasses.java.lang.Throwable.Wrapper.GetMethodWrapper(mw.Name, mw.Signature, true);
            }
        }
        TypeWrapper tw = mw.DeclaringType;
        tw.Finish();
        mw.Link();
        mw.ResolveMethod();
        MethodInfo mi = mw.GetMethod() as MethodInfo;
        if (mi != null &&
            !mw.HasCallerID &&
            mw.IsStatic &&
            MethodHandleUtil.HasOnlyBasicTypes(mw.GetParameters(), mw.ReturnType) &&
            type.parameterCount() <= MethodHandleUtil.MaxArity)
        {
            return(Delegate.CreateDelegate(MethodHandleUtil.CreateMemberWrapperDelegateType(mw.GetParameters(), mw.ReturnType), mi));
        }
        else
        {
            // slow path where we emit a DynamicMethod
            return(MethodHandleUtil.DynamicMethodBuilder.CreateMemberName(mw, type, doDispatch));
        }
#endif
    }
Exemplo n.º 5
0
 private MemberInfo Resolve(CodeGenContext context)
 {
     if (type != null)
     {
         if (Class != null || Method != null || Field != null || Sig != null)
         {
             throw new NotImplementedException();
         }
         return(StaticCompiler.GetTypeForMapXml(context.ClassLoader, type));
     }
     else if (Class != null)
     {
         TypeWrapper tw = context.ClassLoader.LoadClassByDottedNameFast(Class);
         if (tw == null)
         {
             return(null);
         }
         else if (Method != null)
         {
             MethodWrapper mw = tw.GetMethodWrapper(Method, Sig, false);
             if (mw == null)
             {
                 return(null);
             }
             return(mw.GetMethod());
         }
         else if (Field != null)
         {
             FieldWrapper fw = tw.GetFieldWrapper(Field, Sig);
             if (fw == null)
             {
                 return(null);
             }
             return(fw.GetField());
         }
         else
         {
             return(tw.TypeAsBaseType);
         }
     }
     else
     {
         return(null);
     }
 }
Exemplo n.º 6
0
 internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen)
 {
     Debug.Assert(Name != null);
     if (Name == ".ctor")
     {
         Debug.Assert(Class == null && type != null);
         Type[]          argTypes = context.ClassLoader.ArgTypeListFromSig(Sig);
         ConstructorInfo ci       = StaticCompiler.GetTypeForMapXml(context.ClassLoader, type).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, argTypes, null);
         if (ci == null)
         {
             throw new InvalidOperationException("Missing .ctor: " + type + "..ctor" + Sig);
         }
         ilgen.Emit(opcode, ci);
     }
     else
     {
         Debug.Assert(Class == null ^ type == null);
         if (Class != null)
         {
             Debug.Assert(Sig != null);
             MethodWrapper method = context.ClassLoader.LoadClassByDottedName(Class).GetMethodWrapper(Name, Sig, false);
             if (method == null)
             {
                 throw new InvalidOperationException("method not found: " + Class + "." + Name + Sig);
             }
             method.Link();
             // TODO this code is part of what Compiler.CastInterfaceArgs (in compiler.cs) does,
             // it would be nice if we could avoid this duplication...
             TypeWrapper[] argTypeWrappers = method.GetParameters();
             for (int i = 0; i < argTypeWrappers.Length; i++)
             {
                 if (argTypeWrappers[i].IsGhost)
                 {
                     CodeEmitterLocal[] temps = new CodeEmitterLocal[argTypeWrappers.Length + (method.IsStatic ? 0 : 1)];
                     for (int j = temps.Length - 1; j >= 0; j--)
                     {
                         TypeWrapper tw;
                         if (method.IsStatic)
                         {
                             tw = argTypeWrappers[j];
                         }
                         else
                         {
                             if (j == 0)
                             {
                                 tw = method.DeclaringType;
                             }
                             else
                             {
                                 tw = argTypeWrappers[j - 1];
                             }
                         }
                         if (tw.IsGhost)
                         {
                             tw.EmitConvStackTypeToSignatureType(ilgen, null);
                         }
                         temps[j] = ilgen.DeclareLocal(tw.TypeAsSignatureType);
                         ilgen.Emit(OpCodes.Stloc, temps[j]);
                     }
                     for (int j = 0; j < temps.Length; j++)
                     {
                         ilgen.Emit(OpCodes.Ldloc, temps[j]);
                     }
                     break;
                 }
             }
             if (opcode.Value == OpCodes.Call.Value)
             {
                 method.EmitCall(ilgen);
             }
             else if (opcode.Value == OpCodes.Callvirt.Value)
             {
                 method.EmitCallvirt(ilgen);
             }
             else if (opcode.Value == OpCodes.Newobj.Value)
             {
                 method.EmitNewobj(ilgen);
             }
             else
             {
                 // ldftn or ldvirtftn
                 ilgen.Emit(opcode, (MethodInfo)method.GetMethod());
             }
         }
         else
         {
             Type[] argTypes;
             if (Sig.StartsWith("("))
             {
                 argTypes = context.ClassLoader.ArgTypeListFromSig(Sig);
             }
             else if (Sig == "")
             {
                 argTypes = Type.EmptyTypes;
             }
             else
             {
                 string[] types = Sig.Split(';');
                 argTypes = new Type[types.Length];
                 for (int i = 0; i < types.Length; i++)
                 {
                     argTypes[i] = StaticCompiler.GetTypeForMapXml(context.ClassLoader, types[i]);
                 }
             }
             MethodInfo mi = StaticCompiler.GetTypeForMapXml(context.ClassLoader, type).GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null, argTypes, null);
             if (mi == null)
             {
                 throw new InvalidOperationException("Missing method: " + type + "." + Name + Sig);
             }
             ilgen.Emit(opcode, mi);
         }
     }
 }
        private static void EmitDispatch(DynamicTypeWrapper.FinishContext context, TypeWrapper[] args, TypeBuilder tb, MethodWrapper interfaceMethod, TypeWrapper[] implParameters,
                                         ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, FieldBuilder[] capturedFields)
        {
            MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final);

            if (interfaceMethod.Name != interfaceMethod.RealName)
            {
                tb.DefineMethodOverride(mb, (MethodInfo)interfaceMethod.GetMethod());
            }
            CodeEmitter ilgen = CodeEmitter.Create(mb);

            for (int i = 0; i < capturedFields.Length; i++)
            {
                ilgen.EmitLdarg(0);
                OpCode opc = OpCodes.Ldfld;
                if (i == 0 && args[0].IsGhost)
                {
                    switch (implMethod.Kind)
                    {
                    case ClassFile.RefKind.invokeInterface:
                    case ClassFile.RefKind.invokeVirtual:
                    case ClassFile.RefKind.invokeSpecial:
                        opc = OpCodes.Ldflda;
                        break;
                    }
                }
                ilgen.Emit(opc, capturedFields[i]);
            }
            for (int i = 0, count = interfaceMethod.GetParameters().Length, k = capturedFields.Length; i < count; i++)
            {
                ilgen.EmitLdarg(i + 1);
                TypeWrapper Ui = interfaceMethod.GetParameters()[i];
                TypeWrapper Ti = instantiatedMethodType.GetArgTypes()[i];
                TypeWrapper Aj = implParameters[i + k];
                if (Ui == PrimitiveTypeWrapper.BYTE)
                {
                    ilgen.Emit(OpCodes.Conv_I1);
                }
                if (Ti != Ui)
                {
                    if (Ti.IsGhost)
                    {
                        Ti.EmitConvStackTypeToSignatureType(ilgen, Ui);
                    }
                    else if (Ui.IsGhost)
                    {
                        Ui.EmitConvSignatureTypeToStackType(ilgen);
                    }
                    else
                    {
                        Ti.EmitCheckcast(ilgen);
                    }
                }
                if (Ti != Aj)
                {
                    if (Ti.IsPrimitive && !Aj.IsPrimitive)
                    {
                        Boxer.EmitBox(ilgen, Ti);
                    }
                    else if (!Ti.IsPrimitive && Aj.IsPrimitive)
                    {
                        TypeWrapper primitive = GetPrimitiveFromWrapper(Ti);
                        Boxer.EmitUnbox(ilgen, primitive, false);
                        if (primitive == PrimitiveTypeWrapper.BYTE)
                        {
                            ilgen.Emit(OpCodes.Conv_I1);
                        }
                    }
                    else if (Aj == PrimitiveTypeWrapper.LONG)
                    {
                        ilgen.Emit(OpCodes.Conv_I8);
                    }
                    else if (Aj == PrimitiveTypeWrapper.FLOAT)
                    {
                        ilgen.Emit(OpCodes.Conv_R4);
                    }
                    else if (Aj == PrimitiveTypeWrapper.DOUBLE)
                    {
                        ilgen.Emit(OpCodes.Conv_R8);
                    }
                }
            }
            switch (implMethod.Kind)
            {
            case ClassFile.RefKind.invokeVirtual:
            case ClassFile.RefKind.invokeInterface:
                ((MethodWrapper)implMethod.Member).EmitCallvirt(ilgen);
                break;

            case ClassFile.RefKind.newInvokeSpecial:
                ((MethodWrapper)implMethod.Member).EmitNewobj(ilgen);
                break;

            case ClassFile.RefKind.invokeStatic:
            case ClassFile.RefKind.invokeSpecial:
                ((MethodWrapper)implMethod.Member).EmitCall(ilgen);
                break;

            default:
                throw new InvalidOperationException();
            }
            TypeWrapper Ru = interfaceMethod.ReturnType;
            TypeWrapper Ra = GetImplReturnType(implMethod);
            TypeWrapper Rt = instantiatedMethodType.GetRetType();

            if (Ra == PrimitiveTypeWrapper.BYTE)
            {
                ilgen.Emit(OpCodes.Conv_I1);
            }
            if (Ra != Ru)
            {
                if (Ru == PrimitiveTypeWrapper.VOID)
                {
                    ilgen.Emit(OpCodes.Pop);
                }
                else if (Ra.IsGhost)
                {
                    Ra.EmitConvSignatureTypeToStackType(ilgen);
                }
                else if (Ru.IsGhost)
                {
                    Ru.EmitConvStackTypeToSignatureType(ilgen, Ra);
                }
            }
            if (Ra != Rt)
            {
                if (Rt.IsPrimitive)
                {
                    if (Rt == PrimitiveTypeWrapper.VOID)
                    {
                        // already popped
                    }
                    else if (!Ra.IsPrimitive)
                    {
                        TypeWrapper primitive = GetPrimitiveFromWrapper(Ra);
                        if (primitive != null)
                        {
                            Boxer.EmitUnbox(ilgen, primitive, false);
                        }
                        else
                        {
                            // If Q is not a primitive wrapper, cast Q to the base Wrapper(S); for example Number for numeric types
                            EmitConvertingUnbox(ilgen, Rt);
                        }
                    }
                    else if (Rt == PrimitiveTypeWrapper.LONG)
                    {
                        ilgen.Emit(OpCodes.Conv_I8);
                    }
                    else if (Rt == PrimitiveTypeWrapper.FLOAT)
                    {
                        ilgen.Emit(OpCodes.Conv_R4);
                    }
                    else if (Rt == PrimitiveTypeWrapper.DOUBLE)
                    {
                        ilgen.Emit(OpCodes.Conv_R8);
                    }
                }
                else if (Ra.IsPrimitive)
                {
                    Boxer.EmitBox(ilgen, GetPrimitiveFromWrapper(Rt));
                }
                else
                {
                    Rt.EmitCheckcast(ilgen);
                }
            }
            ilgen.EmitTailCallPrevention();
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
        }
Exemplo n.º 8
0
    public static object createDelegate(MethodType type, MemberName m, bool doDispatch, jlClass lookupClass)
    {
#if FIRST_PASS
        return(null);
#else
        int index = m.getVMIndex();
        if (index == Int32.MaxValue)
        {
            bool invokeExact        = m.getName() == "invokeExact";
            Type targetDelegateType = MethodHandleUtil.CreateDelegateType(invokeExact ? type.dropParameterTypes(0, 1) : type);
            MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("DirectMethodHandle." + m.getName(), type, typeof(IKVM.Runtime.InvokeCache <>).MakeGenericType(targetDelegateType));
            dm.Ldarg(0);
            if (invokeExact)
            {
                dm.Call(ByteCodeHelperMethods.GetDelegateForInvokeExact.MakeGenericMethod(targetDelegateType));
            }
            else
            {
                dm.LoadValueAddress();
                dm.Call(ByteCodeHelperMethods.GetDelegateForInvoke.MakeGenericMethod(targetDelegateType));
                dm.Ldarg(0);
            }
            for (int i = 1, count = type.parameterCount(); i < count; i++)
            {
                dm.Ldarg(i);
            }
            dm.CallDelegate(targetDelegateType);
            dm.Ret();
            return(dm.CreateDelegate());
        }
        else
        {
            TypeWrapper tw = (TypeWrapper)typeof(MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(m);
            tw.Finish();
            MethodWrapper mw = tw.GetMethods()[index];
            if (mw.IsDynamicOnly)
            {
                MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("CustomInvoke:" + mw.Name, type, (ICustomInvoke)mw);
                if (mw.IsStatic)
                {
                    dm.LoadNull();
                    dm.BoxArgs(0);
                }
                else
                {
                    dm.Ldarg(0);
                    dm.BoxArgs(1);
                }
                dm.Callvirt(typeof(ICustomInvoke).GetMethod("Invoke"));
                dm.Convert(typeof(object), type.returnType(), 0);
                dm.Ret();
                return(dm.CreateDelegate());
            }
            // HACK this code is duplicated in compiler.cs
            if (mw.IsProtected && (mw.DeclaringType == CoreClasses.java.lang.Object.Wrapper || mw.DeclaringType == CoreClasses.java.lang.Throwable.Wrapper))
            {
                TypeWrapper thisType             = TypeWrapper.FromClass(lookupClass);
                TypeWrapper cli_System_Object    = ClassLoaderWrapper.LoadClassCritical("cli.System.Object");
                TypeWrapper cli_System_Exception = ClassLoaderWrapper.LoadClassCritical("cli.System.Exception");
                // HACK we may need to redirect finalize or clone from java.lang.Object/Throwable
                // to a more specific base type.
                if (thisType.IsAssignableTo(cli_System_Object))
                {
                    mw = cli_System_Object.GetMethodWrapper(mw.Name, mw.Signature, true);
                }
                else if (thisType.IsAssignableTo(cli_System_Exception))
                {
                    mw = cli_System_Exception.GetMethodWrapper(mw.Name, mw.Signature, true);
                }
                else if (thisType.IsAssignableTo(CoreClasses.java.lang.Throwable.Wrapper))
                {
                    mw = CoreClasses.java.lang.Throwable.Wrapper.GetMethodWrapper(mw.Name, mw.Signature, true);
                }
            }
            mw.ResolveMethod();
            MethodInfo mi = mw.GetMethod() as MethodInfo;
            if (mi != null &&
                !tw.IsRemapped &&
                !tw.IsGhost &&
                !tw.IsNonPrimitiveValueType &&
                type.parameterCount() <= MethodHandleUtil.MaxArity
                // FXBUG we should be able to use a normal (unbound) delegate for virtual methods
                // (when doDispatch is set), but the x64 CLR crashes when doing a virtual method dispatch on
                // a null reference
                && (!mi.IsVirtual || (doDispatch && IntPtr.Size == 4)) &&
                (doDispatch || !mi.IsVirtual))
            {
                return(Delegate.CreateDelegate(MethodHandleUtil.CreateDelegateType(tw, mw), mi));
            }
            else
            {
                // slow path where we emit a DynamicMethod
                MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder(mw.DeclaringType.TypeAsBaseType, "DirectMethodHandle:" + mw.Name, type);
                for (int i = 0, count = type.parameterCount(); i < count; i++)
                {
                    if (i == 0 && !mw.IsStatic && (tw.IsGhost || tw.IsNonPrimitiveValueType))
                    {
                        dm.LoadFirstArgAddress();
                    }
                    else
                    {
                        dm.Ldarg(i);
                    }
                }
                if (doDispatch && !mw.IsStatic)
                {
                    dm.Callvirt(mw);
                }
                else
                {
                    dm.Call(mw);
                }
                dm.Ret();
                return(dm.CreateDelegate());
            }
        }
#endif
    }
Exemplo n.º 9
0
    // TODO what is lookupClass for?
    public static object createDelegate(MethodType type, MemberName m, bool doDispatch, jlClass lookupClass)
    {
#if FIRST_PASS
        return(null);
#else
        int index = m.getVMIndex();
        if (index == Int32.MaxValue)
        {
            bool invokeExact        = m.getName() == "invokeExact";
            Type targetDelegateType = MethodHandleUtil.CreateDelegateType(invokeExact ? type.dropParameterTypes(0, 1) : type);
            MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("DirectMethodHandle." + m.getName(), type, typeof(IKVM.Runtime.InvokeCache <>).MakeGenericType(targetDelegateType));
            dm.Ldarg(0);
            if (invokeExact)
            {
                dm.Call(ByteCodeHelperMethods.GetDelegateForInvokeExact.MakeGenericMethod(targetDelegateType));
            }
            else
            {
                dm.LoadValueAddress();
                dm.Call(ByteCodeHelperMethods.GetDelegateForInvoke.MakeGenericMethod(targetDelegateType));
                dm.Ldarg(0);
            }
            for (int i = 1, count = type.parameterCount(); i < count; i++)
            {
                dm.Ldarg(i);
            }
            dm.CallDelegate(targetDelegateType);
            dm.Ret();
            return(dm.CreateDelegate());
        }
        else
        {
            TypeWrapper tw = (TypeWrapper)typeof(MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(m);
            tw.Finish();
            MethodWrapper mw = tw.GetMethods()[index];
            mw.ResolveMethod();
            MethodInfo mi = mw.GetMethod() as MethodInfo;
            if (mi != null &&
                !tw.IsRemapped &&
                !tw.IsGhost &&
                !tw.IsNonPrimitiveValueType &&
                type.parameterCount() <= MethodHandleUtil.MaxArity
                // FXBUG we should be able to use a normal (unbound) delegate for virtual methods
                // (when doDispatch is set), but the x64 CLR crashes when doing a virtual method dispatch on
                // a null reference
                && (!mi.IsVirtual || (doDispatch && IntPtr.Size == 4)) &&
                (doDispatch || !mi.IsVirtual))
            {
                return(Delegate.CreateDelegate(MethodHandleUtil.CreateDelegateType(tw, mw), mi));
            }
            else
            {
                // slow path where we emit a DynamicMethod
                MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder(mw.DeclaringType.TypeAsBaseType, "DirectMethodHandle:" + mw.Name, type);
                for (int i = 0, count = type.parameterCount(); i < count; i++)
                {
                    if (i == 0 && !mw.IsStatic && (tw.IsGhost || tw.IsNonPrimitiveValueType))
                    {
                        dm.LoadFirstArgAddress();
                    }
                    else
                    {
                        dm.Ldarg(i);
                    }
                }
                if (doDispatch && !mw.IsStatic)
                {
                    dm.Callvirt(mw);
                }
                else
                {
                    dm.Call(mw);
                }
                dm.Ret();
                return(dm.CreateDelegate());
            }
        }
#endif
    }