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()); }