示例#1
0
        internal static Delegate CreateMethodHandleInvoke(MemberName mn)
        {
            MethodType           type = mn.getMethodType().insertParameterTypes(0, mn.getDeclaringClass());
            Type                 targetDelegateType = MethodHandleUtil.GetMemberWrapperDelegateType(type);
            DynamicMethodBuilder dm = new DynamicMethodBuilder("DirectMethodHandle." + mn.getName() + type, type,
                                                               typeof(Container <,>).MakeGenericType(typeof(object), typeof(IKVM.Runtime.InvokeCache <>).MakeGenericType(targetDelegateType)), null, null, null, true);

            dm.Ldarg(0);
            dm.EmitCheckcast(CoreClasses.java.lang.invoke.MethodHandle.Wrapper);
            switch (mn.getName())
            {
            case "invokeExact":
                dm.Call(ByteCodeHelperMethods.GetDelegateForInvokeExact.MakeGenericMethod(targetDelegateType));
                break;

            case "invoke":
                dm.LoadValueAddress();
                dm.Call(ByteCodeHelperMethods.GetDelegateForInvoke.MakeGenericMethod(targetDelegateType));
                break;

            case "invokeBasic":
                dm.Call(ByteCodeHelperMethods.GetDelegateForInvokeBasic.MakeGenericMethod(targetDelegateType));
                break;

            default:
                throw new InvalidOperationException();
            }
            dm.Ldarg(0);
            for (int i = 1, count = type.parameterCount(); i < count; i++)
            {
                dm.Ldarg(i);
            }
            dm.CallDelegate(targetDelegateType);
            dm.Ret();
            return(dm.CreateDelegate());
        }
示例#2
0
        internal static Delegate CreateMemberName(MethodWrapper mw, MethodType type, bool doDispatch)
        {
            FinishTypes(type);
            TypeWrapper tw    = mw.DeclaringType;
            Type        owner = tw.TypeAsBaseType;

#if NET_4_0
            if (!doDispatch && !mw.IsStatic)
            {
                // on .NET 4 we can only do a non-virtual invocation of a virtual method if we skip verification,
                // and to skip verification we need to inject the dynamic method in a critical assembly

                // TODO instead of injecting in mscorlib, we should use DynamicMethodUtils.Create()
                owner = typeof(object);
            }
#endif
            DynamicMethodBuilder dm = new DynamicMethodBuilder("MemberName:" + mw.DeclaringType.Name + "::" + mw.Name + mw.Signature, type, null,
                                                               mw.HasCallerID ? DynamicCallerIDProvider.Instance : null, null, owner, true);
            for (int i = 0, count = type.parameterCount(); i < count; i++)
            {
                if (i == 0 && !mw.IsStatic && (tw.IsGhost || tw.IsNonPrimitiveValueType || tw.IsRemapped) && (!mw.IsConstructor || tw != CoreClasses.java.lang.String.Wrapper))
                {
                    if (tw.IsGhost || tw.IsNonPrimitiveValueType)
                    {
                        dm.LoadFirstArgAddress(tw);
                    }
                    else
                    {
                        Debug.Assert(tw.IsRemapped);
                        // TODO this must be checked
                        dm.Ldarg(0);
                        if (mw.IsConstructor)
                        {
                            dm.EmitCastclass(tw.TypeAsBaseType);
                        }
                        else if (tw != CoreClasses.cli.System.Object.Wrapper)
                        {
                            dm.EmitCheckcast(tw);
                        }
                    }
                }
                else
                {
                    dm.Ldarg(i);
                    TypeWrapper argType = TypeWrapper.FromClass(type.parameterType(i));
                    if (!argType.IsPrimitive)
                    {
                        if (argType.IsUnloadable)
                        {
                        }
                        else if (argType.IsNonPrimitiveValueType)
                        {
                            dm.Unbox(argType);
                        }
                        else if (argType.IsGhost)
                        {
                            dm.UnboxGhost(argType);
                        }
                        else
                        {
                            dm.EmitCheckcast(argType);
                        }
                    }
                }
            }
            if (mw.HasCallerID)
            {
                dm.LoadCallerID();
            }
            // special case for Object.clone() and Object.finalize()
            if (mw.IsFinalizeOrClone)
            {
                if (doDispatch)
                {
                    mw.EmitCallvirtReflect(dm.ilgen);
                }
                else
                {
                    // we can re-use the implementations from cli.System.Object (even though the object may not in-fact extend cli.System.Object)
                    CoreClasses.cli.System.Object.Wrapper.GetMethodWrapper(mw.Name, mw.Signature, false).EmitCall(dm.ilgen);
                }
            }
            else if (doDispatch && !mw.IsStatic)
            {
                dm.Callvirt(mw);
            }
            else
            {
                dm.Call(mw);
            }
            TypeWrapper retType = TypeWrapper.FromClass(type.returnType());
            if (retType.IsUnloadable)
            {
            }
            else if (retType.IsNonPrimitiveValueType)
            {
                dm.Box(retType);
            }
            else if (retType.IsGhost)
            {
                dm.BoxGhost(retType);
            }
            else if (retType == PrimitiveTypeWrapper.BYTE)
            {
                dm.CastByte();
            }
            dm.Ret();
            return(dm.CreateDelegate());
        }