Exemplo n.º 1
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());
        }