diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs index 6e89f50a1ea29..fad67c99946a9 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs @@ -539,7 +539,7 @@ private static bool AreTypesEquivalent(MethodTable* pMTa, MethodTable* pMTb) [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool IsNullableForType(MethodTable* typeMT, MethodTable* boxedMT) + internal static bool IsNullableForType(MethodTable* typeMT, MethodTable* boxedMT) { if (!typeMT->IsNullable) { diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index 3bb984f14e7d6..994cb70b5079b 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -1098,28 +1098,64 @@ public static TypeHandle TypeHandleOf() public static bool AreSameType(TypeHandle left, TypeHandle right) => left.m_asTAddr == right.m_asTAddr; + public int GetCorElementType() => GetCorElementType(m_asTAddr); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool CanCastTo(TypeHandle destTH) { - if (m_asTAddr == destTH.m_asTAddr) - return true; + return TryCanCastTo(this, destTH) switch + { + CastResult.CanCast => true, + CastResult.CannotCast => false, - if (!IsTypeDesc && destTH.IsTypeDesc) - return false; + // Regular casting does not allow T to be cast to Nullable. + // See TypeHandle::CanCastTo() + _ => CanCastToWorker(this, destTH, nullableCast: false) + }; + } - CastResult result = CastCache.TryGet(CastHelpers.s_table!, (nuint)m_asTAddr, (nuint)destTH.m_asTAddr); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool CanCastToForReflection(TypeHandle srcTH, TypeHandle destTH) + { + return TryCanCastTo(srcTH, destTH) switch + { + CastResult.CanCast => true, + CastResult.CannotCast => false, - if (result != CastResult.MaybeCast) - return result == CastResult.CanCast; + // Reflection allows T to be cast to Nullable. + // See ObjIsInstanceOfCore() + _ => CanCastToWorker(srcTH, destTH, nullableCast: true) + }; + } - return CanCastTo_NoCacheLookup(m_asTAddr, destTH.m_asTAddr); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static CastResult TryCanCastTo(TypeHandle srcTH, TypeHandle destTH) + { + // See TypeHandle::CanCastToCached() for duplicate quick checks. + if (srcTH.m_asTAddr == destTH.m_asTAddr) + return CastResult.CanCast; + + if (!srcTH.IsTypeDesc && destTH.IsTypeDesc) + return CastResult.CannotCast; + + return CastCache.TryGet(CastHelpers.s_table!, (nuint)srcTH.m_asTAddr, (nuint)destTH.m_asTAddr); } - public int GetCorElementType() => GetCorElementType(m_asTAddr); + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool CanCastToWorker(TypeHandle srcTH, TypeHandle destTH, bool nullableCast) + { + if (!srcTH.IsTypeDesc + && !destTH.IsTypeDesc + && CastHelpers.IsNullableForType(destTH.AsMethodTable(), srcTH.AsMethodTable())) + { + return nullableCast; + } + + return CanCastTo_NoCacheLookup(srcTH.m_asTAddr, destTH.m_asTAddr) != Interop.BOOL.FALSE; + } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "TypeHandle_CanCastTo_NoCacheLookup")] - [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool CanCastTo_NoCacheLookup(void* fromTypeHnd, void* toTypeHnd); + private static partial Interop.BOOL CanCastTo_NoCacheLookup(void* fromTypeHnd, void* toTypeHnd); [SuppressGCTransition] [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "TypeHandle_GetCorElementType")] diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index a1907fd90df76..3246c90a35f47 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -659,8 +659,13 @@ internal static unsafe MdUtf8String GetUtf8Name(RuntimeType type) return new MdUtf8String(name); } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern bool CanCastTo(RuntimeType type, RuntimeType target); + internal static bool CanCastTo(RuntimeType type, RuntimeType target) + { + bool ret = TypeHandle.CanCastToForReflection(type.GetNativeTypeHandle(), target.GetNativeTypeHandle()); + GC.KeepAlive(type); + GC.KeepAlive(target); + return ret; + } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable")] private static partial IntPtr GetDeclaringTypeHandleForGenericVariable(IntPtr typeHandle); @@ -695,8 +700,17 @@ internal static unsafe MdUtf8String GetUtf8Name(RuntimeType type) return result; } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern IRuntimeMethodInfo GetDeclaringMethod(RuntimeType type); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetDeclaringMethodForGenericParameter")] + private static partial void GetDeclaringMethodForGenericParameter(QCallTypeHandle typeHandle, ObjectHandleOnStack result); + + internal static IRuntimeMethodInfo? GetDeclaringMethodForGenericParameter(RuntimeType type) + { + Debug.Assert(IsGenericVariable(type)); + + IRuntimeMethodInfo? method = null; + GetDeclaringMethodForGenericParameter(new QCallTypeHandle(ref type), ObjectHandleOnStack.Create(ref method)); + return method; + } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetInstantiation")] internal static partial void GetInstantiation(QCallTypeHandle type, ObjectHandleOnStack types, Interop.BOOL fAsRuntimeTypeArray); @@ -819,23 +833,15 @@ internal bool ContainsGenericVariables() return ContainsGenericVariables(GetRuntimeTypeChecked()); } - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern bool SatisfiesConstraints(RuntimeType paramType, IntPtr* pTypeContext, int typeContextLength, IntPtr* pMethodContext, int methodContextLength, RuntimeType toType); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_SatisfiesConstraints")] + private static partial Interop.BOOL SatisfiesConstraints(QCallTypeHandle paramType, QCallTypeHandle pTypeContext, RuntimeMethodHandleInternal pMethodContext, QCallTypeHandle toType); - internal static bool SatisfiesConstraints(RuntimeType paramType, RuntimeType[]? typeContext, RuntimeType[]? methodContext, RuntimeType toType) + internal static bool SatisfiesConstraints(RuntimeType paramType, RuntimeType? typeContext, RuntimeMethodInfo? methodContext, RuntimeType toType) { - IntPtr[]? typeContextHandles = CopyRuntimeTypeHandles(typeContext, out int typeContextLength); - IntPtr[]? methodContextHandles = CopyRuntimeTypeHandles(methodContext, out int methodContextLength); - - fixed (IntPtr* pTypeContextHandles = typeContextHandles, pMethodContextHandles = methodContextHandles) - { - bool result = SatisfiesConstraints(paramType, pTypeContextHandles, typeContextLength, pMethodContextHandles, methodContextLength, toType); - - GC.KeepAlive(typeContext); - GC.KeepAlive(methodContext); - - return result; - } + RuntimeMethodHandleInternal methodContextRaw = ((IRuntimeMethodInfo?)methodContext)?.Value ?? RuntimeMethodHandleInternal.EmptyHandle; + bool result = SatisfiesConstraints(new QCallTypeHandle(ref paramType), new QCallTypeHandle(ref typeContext!), methodContextRaw, new QCallTypeHandle(ref toType)) != Interop.BOOL.FALSE; + GC.KeepAlive(methodContext); + return result; } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_RegisterCollectibleTypeDependency")] @@ -1087,7 +1093,16 @@ internal static int GetSlot(IRuntimeMethodInfo method) } [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern int GetMethodDef(IRuntimeMethodInfo method); + private static extern int GetMethodDef(RuntimeMethodHandleInternal method); + + internal static int GetMethodDef(IRuntimeMethodInfo method) + { + Debug.Assert(method != null); + + int token = GetMethodDef(method.Value); + GC.KeepAlive(method); + return token; + } internal static string GetName(RuntimeMethodHandleInternal method) => GetUtf8Name(method).ToString(); @@ -1208,7 +1223,26 @@ internal static bool HasMethodInstantiation(IRuntimeMethodInfo method) } [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern RuntimeMethodHandleInternal GetStubIfNeeded(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[]? methodInstantiation); + private static extern RuntimeMethodHandleInternal GetStubIfNeededInternal(RuntimeMethodHandleInternal method, RuntimeType declaringType); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetStubIfNeededSlow")] + private static partial RuntimeMethodHandleInternal GetStubIfNeededSlow(RuntimeMethodHandleInternal method, QCallTypeHandle declaringTypeHandle, ObjectHandleOnStack methodInstantiation); + + internal static RuntimeMethodHandleInternal GetStubIfNeeded(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[]? methodInstantiation) + { + if (methodInstantiation is null) + { + RuntimeMethodHandleInternal handle = GetStubIfNeededInternal(method, declaringType); + if (!handle.IsNullHandle()) + return handle; + } + + return GetStubIfNeededWorker(method, declaringType, methodInstantiation); + + [MethodImpl(MethodImplOptions.NoInlining)] + static RuntimeMethodHandleInternal GetStubIfNeededWorker(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[]? methodInstantiation) + => GetStubIfNeededSlow(method, new QCallTypeHandle(ref declaringType), ObjectHandleOnStack.Create(ref methodInstantiation)); + } [MethodImpl(MethodImplOptions.InternalCall)] internal static extern RuntimeMethodHandleInternal GetMethodFromCanonical(RuntimeMethodHandleInternal method, RuntimeType declaringType); @@ -1267,8 +1301,16 @@ internal static IRuntimeMethodInfo StripMethodInstantiation(IRuntimeMethodInfo m [MethodImpl(MethodImplOptions.InternalCall)] internal static extern Resolver GetResolver(RuntimeMethodHandleInternal method); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern RuntimeMethodBody? GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetMethodBody")] + private static partial void GetMethodBody(RuntimeMethodHandleInternal method, QCallTypeHandle declaringType, ObjectHandleOnStack result); + + internal static RuntimeMethodBody? GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType) + { + RuntimeMethodBody? result = null; + GetMethodBody(method.Value, new QCallTypeHandle(ref declaringType), ObjectHandleOnStack.Create(ref result)); + GC.KeepAlive(method); + return result; + } [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool IsConstructor(RuntimeMethodHandleInternal method); @@ -1895,68 +1937,97 @@ internal static int GetMDStreamVersion(RuntimeModule module) internal sealed unsafe partial class Signature { - #region FCalls - [MemberNotNull(nameof(m_arguments))] - [MemberNotNull(nameof(m_declaringType))] - [MemberNotNull(nameof(m_returnTypeORfieldType))] - [MethodImpl(MethodImplOptions.InternalCall)] - private extern void GetSignature( - void* pCorSig, int cCorSig, - RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo? methodHandle, RuntimeType? declaringType); - #endregion - #region Private Data Members // // Keep the layout in sync with SignatureNative in the VM // - internal RuntimeType[] m_arguments; - internal RuntimeType m_declaringType; - internal RuntimeType m_returnTypeORfieldType; - internal object? m_keepalive; - internal void* m_sig; - internal int m_managedCallingConventionAndArgIteratorFlags; // lowest byte is CallingConvention, upper 3 bytes are ArgIterator flags - internal int m_nSizeOfArgStack; - internal int m_csig; - internal RuntimeMethodHandleInternal m_pMethod; + private RuntimeType[]? _arguments; + private RuntimeType _declaringType; + private RuntimeType _returnTypeORfieldType; +#pragma warning disable CA1823, 169 + private object? _keepAlive; +#pragma warning restore CA1823, 169 + private void* _sig; + private int _csig; + private int _managedCallingConventionAndArgIteratorFlags; // lowest byte is CallingConvention, upper 3 bytes are ArgIterator flags +#pragma warning disable CA1823, 169 + private int _nSizeOfArgStack; +#pragma warning restore CA1823, 169 + private RuntimeMethodHandleInternal _pMethod; #endregion + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Signature_Init")] + private static partial void Init( + ObjectHandleOnStack _this, + void* pCorSig, int cCorSig, + RuntimeFieldHandleInternal fieldHandle, + RuntimeMethodHandleInternal methodHandle); + + [MemberNotNull(nameof(_returnTypeORfieldType))] + private void Init( + void* pCorSig, int cCorSig, + RuntimeFieldHandleInternal fieldHandle, + RuntimeMethodHandleInternal methodHandle) + { + Signature _this = this; + Init(ObjectHandleOnStack.Create(ref _this), + pCorSig, cCorSig, + fieldHandle, + methodHandle); + Debug.Assert(_returnTypeORfieldType != null); + } + #region Constructors public Signature( - IRuntimeMethodInfo method, + IRuntimeMethodInfo methodHandle, RuntimeType[] arguments, RuntimeType returnType, CallingConventions callingConvention) { - m_pMethod = method.Value; - m_arguments = arguments; - m_returnTypeORfieldType = returnType; - m_managedCallingConventionAndArgIteratorFlags = (byte)callingConvention; + _arguments = arguments; + _returnTypeORfieldType = returnType; + _managedCallingConventionAndArgIteratorFlags = (int)callingConvention; + Debug.Assert((_managedCallingConventionAndArgIteratorFlags & 0xffffff00) == 0); + _pMethod = methodHandle.Value; - GetSignature(null, 0, default, method, null); + _declaringType = RuntimeMethodHandle.GetDeclaringType(_pMethod); + Init(null, 0, default, _pMethod); + GC.KeepAlive(methodHandle); } public Signature(IRuntimeMethodInfo methodHandle, RuntimeType declaringType) { - GetSignature(null, 0, default, methodHandle, declaringType); + _declaringType = declaringType; + Init(null, 0, default, methodHandle.Value); + GC.KeepAlive(methodHandle); } public Signature(IRuntimeFieldInfo fieldHandle, RuntimeType declaringType) { - GetSignature(null, 0, fieldHandle.Value, null, declaringType); + _declaringType = declaringType; + Init(null, 0, fieldHandle.Value, default); GC.KeepAlive(fieldHandle); } public Signature(void* pCorSig, int cCorSig, RuntimeType declaringType) { - GetSignature(pCorSig, cCorSig, default, null, declaringType); + _declaringType = declaringType; + Init(pCorSig, cCorSig, default, default); } #endregion #region Internal Members - internal CallingConventions CallingConvention => (CallingConventions)(byte)m_managedCallingConventionAndArgIteratorFlags; - internal RuntimeType[] Arguments => m_arguments; - internal RuntimeType ReturnType => m_returnTypeORfieldType; - internal RuntimeType FieldType => m_returnTypeORfieldType; + internal CallingConventions CallingConvention => (CallingConventions)(_managedCallingConventionAndArgIteratorFlags & 0xff); + internal RuntimeType[] Arguments + { + get + { + Debug.Assert(_arguments != null); + return _arguments; + } + } + internal RuntimeType ReturnType => _returnTypeORfieldType; + internal RuntimeType FieldType => _returnTypeORfieldType; [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Signature_AreEqual")] private static partial Interop.BOOL AreEqual( @@ -1966,19 +2037,16 @@ private static partial Interop.BOOL AreEqual( internal static bool AreEqual(Signature sig1, Signature sig2) { return AreEqual( - sig1.m_sig, sig1.m_csig, new QCallTypeHandle(ref sig1.m_declaringType), - sig2.m_sig, sig2.m_csig, new QCallTypeHandle(ref sig2.m_declaringType)) != Interop.BOOL.FALSE; + sig1._sig, sig1._csig, new QCallTypeHandle(ref sig1._declaringType), + sig2._sig, sig2._csig, new QCallTypeHandle(ref sig2._declaringType)) != Interop.BOOL.FALSE; } - internal Type[] GetCustomModifiers(int parameterIndex, bool required) => - GetCustomModifiersAtOffset(GetParameterOffset(parameterIndex), required); - [MethodImpl(MethodImplOptions.InternalCall)] private static extern unsafe int GetParameterOffsetInternal(void* sig, int csig, int parameterIndex); internal int GetParameterOffset(int parameterIndex) { - int offsetMaybe = GetParameterOffsetInternal(m_sig, m_csig, parameterIndex); + int offsetMaybe = GetParameterOffsetInternal(_sig, _csig, parameterIndex); // If the result is negative, it is an error code. if (offsetMaybe < 0) Marshal.ThrowExceptionForHR(offsetMaybe, new IntPtr(-1)); @@ -1986,13 +2054,62 @@ internal int GetParameterOffset(int parameterIndex) } [MethodImpl(MethodImplOptions.InternalCall)] - internal extern int GetTypeParameterOffset(int offset, int index); + private static extern unsafe int GetTypeParameterOffsetInternal(void* sig, int csig, int offset, int index); - [MethodImpl(MethodImplOptions.InternalCall)] - internal extern SignatureCallingConvention GetCallingConventionFromFunctionPointerAtOffset(int offset); + internal int GetTypeParameterOffset(int offset, int index) + { + if (offset < 0) + { + Debug.Assert(offset == -1); + return offset; + } + + int offsetMaybe = GetTypeParameterOffsetInternal(_sig, _csig, offset, index); + // If the result is negative and not -1, it is an error code. + if (offsetMaybe < 0 && offsetMaybe != -1) + Marshal.ThrowExceptionForHR(offsetMaybe, new IntPtr(-1)); + return offsetMaybe; + } [MethodImpl(MethodImplOptions.InternalCall)] - internal extern Type[] GetCustomModifiersAtOffset(int offset, bool required); + private static extern unsafe int GetCallingConventionFromFunctionPointerAtOffsetInternal(void* sig, int csig, int offset); + + internal SignatureCallingConvention GetCallingConventionFromFunctionPointerAtOffset(int offset) + { + if (offset < 0) + { + Debug.Assert(offset == -1); + return SignatureCallingConvention.Default; + } + + int callConvMaybe = GetCallingConventionFromFunctionPointerAtOffsetInternal(_sig, _csig, offset); + // If the result is negative, it is an error code. + if (callConvMaybe < 0) + Marshal.ThrowExceptionForHR(callConvMaybe, new IntPtr(-1)); + return (SignatureCallingConvention)callConvMaybe; + } + + internal Type[] GetCustomModifiers(int parameterIndex, bool required) => + GetCustomModifiersAtOffset(GetParameterOffset(parameterIndex), required); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Signature_GetCustomModifiersAtOffset")] + private static partial void GetCustomModifiersAtOffset( + ObjectHandleOnStack sigObj, + int offset, + Interop.BOOL required, + ObjectHandleOnStack result); + + internal Type[] GetCustomModifiersAtOffset(int offset, bool required) + { + Signature _this = this; + Type[]? result = null; + GetCustomModifiersAtOffset( + ObjectHandleOnStack.Create(ref _this), + offset, + required ? Interop.BOOL.TRUE : Interop.BOOL.FALSE, + ObjectHandleOnStack.Create(ref result)); + return result!; + } #endregion } diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index d1591d88036b2..ea88559efeceb 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -2011,29 +2011,23 @@ private static RuntimePropertyInfo GetPropertyInfo(RuntimeType reflectedType, in internal static void ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception? e) { - RuntimeType[]? typeContext = null; - RuntimeType[]? methodContext = null; + RuntimeType? typeContext; + RuntimeMethodInfo? methodContext = null; RuntimeType[] genericParameters; if (definition is Type) { - RuntimeType genericTypeDefinition = (RuntimeType)definition; - genericParameters = genericTypeDefinition.GetGenericArgumentsInternal(); - typeContext = genericArguments; + typeContext = (RuntimeType)definition; + genericParameters = typeContext.GetGenericArgumentsInternal(); } else { - RuntimeMethodInfo genericMethodDefinition = (RuntimeMethodInfo)definition; - genericParameters = genericMethodDefinition.GetGenericArgumentsInternal(); - methodContext = genericArguments; - - RuntimeType? declaringType = (RuntimeType?)genericMethodDefinition.DeclaringType; - if (declaringType != null) - { - typeContext = declaringType.TypeHandle.GetInstantiationInternal(); - } + methodContext = (RuntimeMethodInfo)definition; + typeContext = (RuntimeType?)methodContext.DeclaringType; + genericParameters = methodContext.GetGenericArgumentsInternal(); } + Debug.Assert(genericArguments.Length == genericParameters.Length); for (int i = 0; i < genericArguments.Length; i++) { Type genericArgument = genericArguments[i]; @@ -3276,8 +3270,7 @@ public override MethodBase? DeclaringMethod if (!IsGenericParameter) throw new InvalidOperationException(SR.Arg_NotGenericParameter); - IRuntimeMethodInfo declaringMethod = RuntimeTypeHandle.GetDeclaringMethod(this); - + IRuntimeMethodInfo? declaringMethod = RuntimeTypeHandle.GetDeclaringMethodForGenericParameter(this); if (declaringMethod == null) return null; diff --git a/src/coreclr/vm/assemblynative.cpp b/src/coreclr/vm/assemblynative.cpp index 3ca0783d65349..c2d9d8706f25e 100644 --- a/src/coreclr/vm/assemblynative.cpp +++ b/src/coreclr/vm/assemblynative.cpp @@ -1089,7 +1089,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetEntryPoint(QCall::AssemblyHandle pAs if (pMeth != NULL) { GCX_COOP(); - retMethod.Set(pMeth->GetStubMethodInfo()); + retMethod.Set(pMeth->AllocateStubMethodInfo()); } END_QCALL; diff --git a/src/coreclr/vm/comdelegate.cpp b/src/coreclr/vm/comdelegate.cpp index f13e28fc3cd14..18fb1f1e10328 100644 --- a/src/coreclr/vm/comdelegate.cpp +++ b/src/coreclr/vm/comdelegate.cpp @@ -2127,7 +2127,7 @@ extern "C" void QCALLTYPE Delegate_FindMethodHandle(QCall::ObjectHandleOnStack d MethodDesc* pMD = COMDelegate::GetMethodDesc(d.Get()); pMD = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMD, TypeHandle(pMD->GetMethodTable()), pMD->GetMethodInstantiation()); - retMethodInfo.Set(pMD->GetStubMethodInfo()); + retMethodInfo.Set(pMD->AllocateStubMethodInfo()); END_QCALL; } diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index 123bf906aef7a..fff8e59962db2 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -445,7 +445,7 @@ extern "C" void QCALLTYPE ExceptionNative_GetMethodFromStackTrace(QCall::ObjectH // The managed stack trace classes always return typical method definition, // so we don't need to bother providing exact instantiation. MethodDesc* pMDTypical = pMD->LoadTypicalMethodDefinition(); - retMethodInfo.Set(pMDTypical->GetStubMethodInfo()); + retMethodInfo.Set(pMDTypical->AllocateStubMethodInfo()); _ASSERTE(pMDTypical->IsRuntimeMethodHandle()); END_QCALL; @@ -1861,11 +1861,6 @@ extern "C" BOOL QCALLTYPE TypeHandle_CanCastTo_NoCacheLookup(void* fromTypeHnd, { ret = fromTH.AsTypeDesc()->CanCastTo(toTH, NULL); } - else if (Nullable::IsNullableForType(toTH, fromTH.AsMethodTable())) - { - // do not allow type T to be cast to Nullable - ret = FALSE; - } else { ret = fromTH.AsMethodTable()->CanCastTo(toTH.AsMethodTable(), NULL); diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 7a5fe8d99743b..41b8b07733548 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -137,6 +137,7 @@ DEFINE_METHOD(ASSEMBLY, CTOR, .ctor, DEFINE_CLASS(ASYNCCALLBACK, System, AsyncCallback) DEFINE_CLASS(ATTRIBUTE, System, Attribute) +DEFINE_CLASS_U(System, Signature, SignatureNative) DEFINE_CLASS(BINDER, Reflection, Binder) @@ -182,7 +183,7 @@ DEFINE_METHOD(COM_OBJECT, RELEASE_ALL_DATA, ReleaseAllData, DEFINE_METHOD(COM_OBJECT, GET_EVENT_PROVIDER, GetEventProvider, IM_Class_RetObj) #ifdef FOR_ILLINK DEFINE_METHOD(COM_OBJECT, CTOR, .ctor, IM_RetVoid) -#endif +#endif // FOR_ILLINK DEFINE_CLASS(LICENSE_INTEROP_PROXY, InternalInteropServices, LicenseInteropProxy) DEFINE_METHOD(LICENSE_INTEROP_PROXY, CREATE, Create, SM_RetObj) @@ -358,9 +359,9 @@ DEFINE_FIELD(RT_FIELD_INFO, HANDLE, m_fieldHandle) DEFINE_CLASS_U(System, RuntimeFieldInfoStub, ReflectFieldObject) DEFINE_FIELD_U(m_fieldHandle, ReflectFieldObject, m_pFD) DEFINE_CLASS(STUBFIELDINFO, System, RuntimeFieldInfoStub) -#if FOR_ILLINK +#ifdef FOR_ILLINK DEFINE_METHOD(STUBFIELDINFO, CTOR, .ctor, IM_RetVoid) -#endif +#endif // FOR_ILLINK DEFINE_CLASS(FIELD, Reflection, RuntimeFieldInfo) @@ -497,18 +498,18 @@ DEFINE_FIELD_U(_handlerLength, RuntimeExceptionHandlingClause, _h DEFINE_FIELD_U(_catchMetadataToken, RuntimeExceptionHandlingClause, _catchToken) DEFINE_FIELD_U(_filterOffset, RuntimeExceptionHandlingClause, _filterOffset) DEFINE_CLASS(RUNTIME_EH_CLAUSE, Reflection, RuntimeExceptionHandlingClause) -#if FOR_ILLINK +#ifdef FOR_ILLINK DEFINE_METHOD(RUNTIME_EH_CLAUSE, CTOR, .ctor, IM_RetVoid) -#endif +#endif // FOR_ILLINK DEFINE_CLASS_U(Reflection, RuntimeLocalVariableInfo, RuntimeLocalVariableInfo) DEFINE_FIELD_U(_type, RuntimeLocalVariableInfo, _type) DEFINE_FIELD_U(_localIndex, RuntimeLocalVariableInfo, _localIndex) DEFINE_FIELD_U(_isPinned, RuntimeLocalVariableInfo, _isPinned) DEFINE_CLASS(RUNTIME_LOCAL_VARIABLE_INFO, Reflection, RuntimeLocalVariableInfo) -#if FOR_ILLINK +#ifdef FOR_ILLINK DEFINE_METHOD(RUNTIME_LOCAL_VARIABLE_INFO, CTOR, .ctor, IM_RetVoid) -#endif +#endif // FOR_ILLINK DEFINE_CLASS_U(Reflection, RuntimeMethodBody, RuntimeMethodBody) DEFINE_FIELD_U(_IL, RuntimeMethodBody, _IL) @@ -518,7 +519,11 @@ DEFINE_FIELD_U(_methodBase, RuntimeMethodBody, _methodBase DEFINE_FIELD_U(_localSignatureMetadataToken, RuntimeMethodBody, _localVarSigToken) DEFINE_FIELD_U(_maxStackSize, RuntimeMethodBody, _maxStackSize) DEFINE_FIELD_U(_initLocals, RuntimeMethodBody, _initLocals) -DEFINE_CLASS(RUNTIME_METHOD_BODY, Reflection, RuntimeMethodBody) + +DEFINE_CLASS(RUNTIME_METHOD_BODY, Reflection, RuntimeMethodBody) +#ifdef FOR_ILLINK +DEFINE_METHOD(RUNTIME_METHOD_BODY, CTOR, .ctor, IM_RetVoid) +#endif // FOR_ILLINK DEFINE_CLASS(METHOD_INFO, Reflection, MethodInfo) diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 7535c717c3955..a782ae05d2d41 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -82,7 +82,6 @@ FCFuncStart(gExceptionFuncs) FCFuncEnd() FCFuncStart(gCOMTypeHandleFuncs) - FCFuncElement("GetDeclaringMethod", RuntimeTypeHandle::GetDeclaringMethod) FCFuncElement("GetFirstIntroducedMethod", RuntimeTypeHandle::GetFirstIntroducedMethod) FCFuncElement("GetNextIntroducedMethod", RuntimeTypeHandle::GetNextIntroducedMethod) FCFuncElement("GetAssemblyIfExists", RuntimeTypeHandle::GetAssemblyIfExists) @@ -93,11 +92,9 @@ FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("GetUtf8NameInternal", RuntimeTypeHandle::GetUtf8Name) FCFuncElement("GetAttributes", RuntimeTypeHandle::GetAttributes) FCFuncElement("GetNumVirtuals", RuntimeTypeHandle::GetNumVirtuals) - FCFuncElement("CanCastTo", RuntimeTypeHandle::CanCastTo) FCFuncElement("GetGenericVariableIndex", RuntimeTypeHandle::GetGenericVariableIndex) FCFuncElement("IsGenericVariable", RuntimeTypeHandle::IsGenericVariable) FCFuncElement("ContainsGenericVariables", RuntimeTypeHandle::ContainsGenericVariables) - FCFuncElement("SatisfiesConstraints", RuntimeTypeHandle::SatisfiesConstraints) FCFuncElement("IsUnmanagedFunctionPointer", RuntimeTypeHandle::IsUnmanagedFunctionPointer) FCFuncElement("CompareCanonicalHandles", RuntimeTypeHandle::CompareCanonicalHandles) FCFuncElement("GetRuntimeTypeFromHandleIfExists", RuntimeTypeHandle::GetRuntimeTypeFromHandleIfExists) @@ -132,11 +129,9 @@ FCFuncStart(gMetaDataImport) FCFuncEnd() FCFuncStart(gSignatureNative) - FCFuncElement("GetSignature", SignatureNative::GetSignature) FCFuncElement("GetParameterOffsetInternal", SignatureNative::GetParameterOffsetInternal) - FCFuncElement("GetTypeParameterOffset", SignatureNative::GetTypeParameterOffset) - FCFuncElement("GetCustomModifiersAtOffset", SignatureNative::GetCustomModifiersAtOffset) - FCFuncElement("GetCallingConventionFromFunctionPointerAtOffset", SignatureNative::GetCallingConventionFromFunctionPointerAtOffset) + FCFuncElement("GetTypeParameterOffsetInternal", SignatureNative::GetTypeParameterOffsetInternal) + FCFuncElement("GetCallingConventionFromFunctionPointerAtOffsetInternal", SignatureNative::GetCallingConventionFromFunctionPointerAtOffsetInternal) FCFuncEnd() FCFuncStart(gRuntimeMethodHandle) @@ -150,10 +145,9 @@ FCFuncStart(gRuntimeMethodHandle) FCFuncElement("IsGenericMethodDefinition", RuntimeMethodHandle::IsGenericMethodDefinition) FCFuncElement("GetGenericParameterCount", RuntimeMethodHandle::GetGenericParameterCount) FCFuncElement("IsTypicalMethodDefinition", RuntimeMethodHandle::IsTypicalMethodDefinition) - FCFuncElement("GetStubIfNeeded", RuntimeMethodHandle::GetStubIfNeeded) + FCFuncElement("GetStubIfNeededInternal", RuntimeMethodHandle::GetStubIfNeededInternal) FCFuncElement("GetMethodFromCanonical", RuntimeMethodHandle::GetMethodFromCanonical) FCFuncElement("IsDynamicMethod", RuntimeMethodHandle::IsDynamicMethod) - FCFuncElement("GetMethodBody", RuntimeMethodHandle::GetMethodBody) FCFuncElement("IsConstructor", RuntimeMethodHandle::IsConstructor) FCFuncElement("GetResolver", RuntimeMethodHandle::GetResolver) FCFuncElement("GetLoaderAllocatorInternal", RuntimeMethodHandle::GetLoaderAllocatorInternal) diff --git a/src/coreclr/vm/interoplibinterface_objc.cpp b/src/coreclr/vm/interoplibinterface_objc.cpp index a59d56a423c55..76daddfa51d41 100644 --- a/src/coreclr/vm/interoplibinterface_objc.cpp +++ b/src/coreclr/vm/interoplibinterface_objc.cpp @@ -336,7 +336,7 @@ void* ObjCMarshalNative::GetPropagatingExceptionCallback( if (CallAvailableUnhandledExceptionPropagation()) { gc.throwableRef = ObjectFromHandle(throwable); - gc.methodRef = method->GetStubMethodInfo(); + gc.methodRef = method->AllocateStubMethodInfo(); callback = CallInvokeUnhandledExceptionPropagation( &gc.throwableRef, diff --git a/src/coreclr/vm/interpreter.cpp b/src/coreclr/vm/interpreter.cpp index 80a058b3494d9..9ab7906b22bec 100644 --- a/src/coreclr/vm/interpreter.cpp +++ b/src/coreclr/vm/interpreter.cpp @@ -6536,7 +6536,7 @@ void Interpreter::LdToken() if (tok.hMethod != NULL) { MethodDesc* pMethod = (MethodDesc*)tok.hMethod; - Object* objPtr = OBJECTREFToObject((OBJECTREF)pMethod->GetStubMethodInfo()); + Object* objPtr = OBJECTREFToObject((OBJECTREF)pMethod->AllocateStubMethodInfo()); OpStackSet(m_curStackHt, objPtr); } else if (tok.hField != NULL) diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index e116ff3b26994..3d582b87e78f6 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -701,7 +701,7 @@ HCIMPLEND_RAW // //======================================================================== -BOOL ObjIsInstanceOfCore(Object *pObject, TypeHandle toTypeHnd, BOOL throwCastException) +static BOOL ObjIsInstanceOfCore(Object *pObject, TypeHandle toTypeHnd, BOOL throwCastException) { CONTRACTL { THROWS; @@ -1625,7 +1625,7 @@ HCIMPL1(Object*, JIT_GetRuntimeMethodStub, CORINFO_METHOD_HANDLE method) HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame MethodDesc *pMethod = (MethodDesc *)method; - stubRuntimeMethod = (OBJECTREF)pMethod->GetStubMethodInfo(); + stubRuntimeMethod = (OBJECTREF)pMethod->AllocateStubMethodInfo(); HELPER_METHOD_FRAME_END(); @@ -4049,7 +4049,7 @@ bool IndirectionAllowedForJitHelper(CorInfoHelpFunc ftnNum) { return false; } - + return true; } diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 71012b72649d1..ecbd3adc76652 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -1045,7 +1045,6 @@ FCDECL2(Object*, JIT_Box, CORINFO_CLASS_HANDLE type, void* data); FCDECL0(VOID, JIT_PollGC); BOOL ObjIsInstanceOf(Object *pObject, TypeHandle toTypeHnd, BOOL throwCastException = FALSE); -BOOL ObjIsInstanceOfCore(Object* pObject, TypeHandle toTypeHnd, BOOL throwCastException = FALSE); #ifdef HOST_64BIT class InlinedCallFrame; diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 98af92ef04879..d042dc8a8f96b 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -3724,7 +3724,7 @@ PTR_LoaderAllocator MethodDesc::GetLoaderAllocator() } #if !defined(DACCESS_COMPILE) -REFLECTMETHODREF MethodDesc::GetStubMethodInfo() +REFLECTMETHODREF MethodDesc::AllocateStubMethodInfo() { CONTRACTL { diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index 44d03a2ffd3c1..5d541b84fbb49 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -1861,8 +1861,8 @@ class MethodDesc public: MethodDesc *GetInterfaceMD(); -// StubMethodInfo for use in creating RuntimeMethodHandles - REFLECTMETHODREF GetStubMethodInfo(); + // StubMethodInfo for use in creating RuntimeMethodHandles + REFLECTMETHODREF AllocateStubMethodInfo(); PrecodeType GetPrecodeType(); diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index a359ecde8aa68..b257af27bcfde 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -127,11 +127,13 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeTypeHandle_GetFields) DllImportEntry(RuntimeTypeHandle_VerifyInterfaceIsImplemented) DllImportEntry(RuntimeTypeHandle_GetInterfaceMethodImplementation) + DllImportEntry(RuntimeTypeHandle_GetDeclaringMethodForGenericParameter) DllImportEntry(RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable) DllImportEntry(RuntimeTypeHandle_GetDeclaringTypeHandle) DllImportEntry(RuntimeTypeHandle_IsVisible) DllImportEntry(RuntimeTypeHandle_ConstructName) DllImportEntry(RuntimeTypeHandle_GetInterfaces) + DllImportEntry(RuntimeTypeHandle_SatisfiesConstraints) DllImportEntry(RuntimeTypeHandle_GetInstantiation) DllImportEntry(RuntimeTypeHandle_Instantiate) DllImportEntry(RuntimeTypeHandle_GetGenericTypeDefinition) @@ -158,6 +160,8 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeMethodHandle_StripMethodInstantiation) DllImportEntry(RuntimeMethodHandle_IsCAVisibleFromDecoratedType) DllImportEntry(RuntimeMethodHandle_Destroy) + DllImportEntry(RuntimeMethodHandle_GetStubIfNeededSlow) + DllImportEntry(RuntimeMethodHandle_GetMethodBody) DllImportEntry(RuntimeModule_GetScopeName) DllImportEntry(RuntimeModule_GetFullyQualifiedName) DllImportEntry(RuntimeModule_GetTypes) @@ -187,7 +191,9 @@ static const Entry s_QCall[] = DllImportEntry(ModuleHandle_GetPEKind) DllImportEntry(ModuleHandle_GetDynamicMethod) DllImportEntry(AssemblyHandle_GetManifestModuleSlow) + DllImportEntry(Signature_Init) DllImportEntry(Signature_AreEqual) + DllImportEntry(Signature_GetCustomModifiersAtOffset) DllImportEntry(TypeBuilder_DefineGenericParam) DllImportEntry(TypeBuilder_DefineType) DllImportEntry(TypeBuilder_SetParentType) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 42f1772e37d8c..b016f70ba60dc 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -895,37 +895,27 @@ extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetInterfaceMethodImplementat return pResult; } -FCIMPL1(ReflectMethodObject*, RuntimeTypeHandle::GetDeclaringMethod, ReflectClassBaseObject *pTypeUNSAFE) { - CONTRACTL { - FCALL_CHECK; - } - CONTRACTL_END; - - REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); - - if (refType == NULL) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); +extern "C" void QCALLTYPE RuntimeTypeHandle_GetDeclaringMethodForGenericParameter(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack result) +{ + QCALL_CONTRACT; - TypeHandle typeHandle = refType->GetType();; + BEGIN_QCALL; - if (!typeHandle.IsTypeDesc()) - return NULL; + TypeHandle typeHandle = pTypeHandle.AsTypeHandle(); + _ASSERTE(typeHandle.IsGenericVariable()); TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable(); mdToken defToken = pGenericVariable->GetTypeOrMethodDef(); - if (TypeFromToken(defToken) != mdtMethodDef) - return NULL; - - REFLECTMETHODREF pRet = NULL; - HELPER_METHOD_FRAME_BEGIN_RET_0(); - MethodDesc * pMD = pGenericVariable->LoadOwnerMethod(); - pMD->CheckRestore(); - pRet = pMD->GetStubMethodInfo(); - HELPER_METHOD_FRAME_END(); + if (TypeFromToken(defToken) == mdtMethodDef) + { + GCX_COOP(); + MethodDesc* pMD = pGenericVariable->LoadOwnerMethod(); + pMD->CheckRestore(); + result.Set(pMD->AllocateStubMethodInfo()); + } - return (ReflectMethodObject*)OBJECTREFToObject(pRet); + END_QCALL; } -FCIMPLEND extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable(EnregisteredTypeHandle pTypeHandle) { @@ -1006,101 +996,38 @@ extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHa return (EnregisteredTypeHandle)retTypeHandle.AsTAddr(); } -FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CanCastTo, ReflectClassBaseObject *pTypeUNSAFE, ReflectClassBaseObject *pTargetUNSAFE) { - CONTRACTL { - FCALL_CHECK; - } - CONTRACTL_END; - - - REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); - REFLECTCLASSBASEREF refTarget = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTargetUNSAFE); - - if ((refType == NULL) || (refTarget == NULL)) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - - TypeHandle fromHandle = refType->GetType(); - TypeHandle toHandle = refTarget->GetType(); - - TypeHandle::CastResult r = fromHandle.CanCastToCached(toHandle); - if (r != TypeHandle::MaybeCast) - { - FC_RETURN_BOOL((BOOL)r); - } - - BOOL iRetVal = FALSE; - HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget); - { - // We allow T to be cast to Nullable - if (!fromHandle.IsTypeDesc() && Nullable::IsNullableForType(toHandle, fromHandle.AsMethodTable())) - { - // do not put this in the cache (see TypeHandle::CanCastTo and ObjIsInstanceOfCore). - iRetVal = TRUE; - } - else - { - if (fromHandle.IsTypeDesc()) - { - iRetVal = fromHandle.AsTypeDesc()->CanCastTo(toHandle, /* pVisited */ NULL); - } - else if (toHandle.IsTypeDesc()) - { - iRetVal = FALSE; - CastCache::TryAddToCache(fromHandle, toHandle, FALSE); - } - else - { - iRetVal = fromHandle.AsMethodTable()->CanCastTo(toHandle.AsMethodTable(), /* pVisited */ NULL); - } - } - } - HELPER_METHOD_FRAME_END(); - - FC_RETURN_BOOL(iRetVal); -} -FCIMPLEND - -FCIMPL6(FC_BOOL_RET, RuntimeTypeHandle::SatisfiesConstraints, PTR_ReflectClassBaseObject pParamTypeUNSAFE, TypeHandle *typeContextArgs, INT32 typeContextCount, TypeHandle *methodContextArgs, INT32 methodContextCount, PTR_ReflectClassBaseObject pArgumentTypeUNSAFE); +extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, QCall::TypeHandle typeContext, MethodDesc* methodContext, QCall::TypeHandle toType) { - CONTRACTL { - FCALL_CHECK; - PRECONDITION(CheckPointer(typeContextArgs, NULL_OK)); - PRECONDITION(CheckPointer(methodContextArgs, NULL_OK)); + CONTRACTL + { + QCALL_CHECK; + PRECONDITION(CheckPointer(methodContext, NULL_OK)); } CONTRACTL_END; - REFLECTCLASSBASEREF refParamType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pParamTypeUNSAFE); - REFLECTCLASSBASEREF refArgumentType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pArgumentTypeUNSAFE); - - TypeHandle thGenericParameter = refParamType->GetType(); - TypeHandle thGenericArgument = refArgumentType->GetType(); BOOL bResult = FALSE; - SigTypeContext typeContext; - - Instantiation classInst; - Instantiation methodInst; - if (typeContextArgs != NULL) - { - classInst = Instantiation(typeContextArgs, typeContextCount); - } + BEGIN_QCALL; - if (methodContextArgs != NULL) - { - methodInst = Instantiation(methodContextArgs, methodContextCount); - } + TypeHandle typeHandle = typeContext.AsTypeHandle(); + Instantiation classInst = !typeHandle.IsNull() + ? typeHandle.GetMethodTable()->GetInstantiation() + : Instantiation{}; + Instantiation methodInst = methodContext != NULL + ? methodContext->GetMethodInstantiation() + : Instantiation{}; + SigTypeContext typeContext; SigTypeContext::InitTypeContext(classInst, methodInst, &typeContext); - HELPER_METHOD_FRAME_BEGIN_RET_2(refParamType, refArgumentType); - { - bResult = thGenericParameter.AsGenericVariable()->SatisfiesConstraints(&typeContext, thGenericArgument); - } - HELPER_METHOD_FRAME_END(); + TypeHandle thGenericParameter = paramType.AsTypeHandle(); + TypeHandle thGenericArgument = toType.AsTypeHandle(); + bResult = thGenericParameter.AsGenericVariable()->SatisfiesConstraints(&typeContext, thGenericArgument); + + END_QCALL; - FC_RETURN_BOOL(bResult); + return bResult; } -FCIMPLEND extern "C" void QCALLTYPE RuntimeTypeHandle_GetInstantiation(QCall::TypeHandle pType, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray) { @@ -1471,325 +1398,260 @@ FCIMPL3(INT32, SignatureNative::GetParameterOffsetInternal, PCCOR_SIGNATURE sig, } FCIMPLEND -FCIMPL3(INT32, SignatureNative::GetTypeParameterOffset, SignatureNative* pSignatureUNSAFE, INT32 offset, INT32 index) +FCIMPL4(INT32, SignatureNative::GetTypeParameterOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 offset, INT32 index) { FCALL_CONTRACT; + _ASSERTE(offset >= 0); - struct - { - SIGNATURENATIVEREF pSig; - } gc; - - if (offset < 0) - { - _ASSERTE(offset == -1); - return offset; - } - - gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE; - - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); - { - SigPointer sp(gc.pSig->GetCorSig() + offset, gc.pSig->GetCorSigSize() - offset); - - CorElementType etype; - IfFailThrow(sp.GetElemType(&etype)); - - uint32_t argCnt; - - switch (etype) - { - case ELEMENT_TYPE_FNPTR: - IfFailThrow(sp.SkipMethodHeaderSignature(&argCnt, /* skipReturnType */ false)); - _ASSERTE((uint32_t)index <= argCnt); - break; - case ELEMENT_TYPE_GENERICINST: - IfFailThrow(sp.SkipExactlyOne()); - - IfFailThrow(sp.GetData(&argCnt)); - _ASSERTE((uint32_t)index < argCnt); - break; - case ELEMENT_TYPE_ARRAY: - case ELEMENT_TYPE_SZARRAY: - case ELEMENT_TYPE_BYREF: - case ELEMENT_TYPE_PTR: - _ASSERTE(index == 0); - break; - case ELEMENT_TYPE_VAR: - case ELEMENT_TYPE_MVAR: - offset = -1; // Use offset -1 to signal method substituted method variable. We do not have full signature for those. - goto Done; - default: - _ASSERTE(false); // Unexpected element type - offset = -1; - goto Done; - } - - for (int i = 0; i < index; i++) - IfFailThrow(sp.SkipExactlyOne()); - - offset = (INT32)(sp.GetPtr() - gc.pSig->GetCorSig()); - Done: ; - } - HELPER_METHOD_FRAME_END(); - + HRESULT hr; + SigPointer sp(sig + offset, csig - offset); + + CorElementType etype; + IfFailRet(sp.GetElemType(&etype)); + + uint32_t argCnt; + switch (etype) + { + case ELEMENT_TYPE_FNPTR: + IfFailRet(sp.SkipMethodHeaderSignature(&argCnt, /* skipReturnType */ false)); + _ASSERTE((uint32_t)index <= argCnt); + break; + case ELEMENT_TYPE_GENERICINST: + IfFailRet(sp.SkipExactlyOne()); + + IfFailRet(sp.GetData(&argCnt)); + _ASSERTE((uint32_t)index < argCnt); + break; + case ELEMENT_TYPE_ARRAY: + case ELEMENT_TYPE_SZARRAY: + case ELEMENT_TYPE_BYREF: + case ELEMENT_TYPE_PTR: + _ASSERTE(index == 0); + break; + case ELEMENT_TYPE_VAR: + case ELEMENT_TYPE_MVAR: + return -1; // Use offset -1 to signal method substituted method variable. We do not have full signature for those. + default: + _ASSERTE(false); // Unexpected element type + return -1; + } + + for (int i = 0; i < index; i++) + IfFailRet(sp.SkipExactlyOne()); + + offset = (INT32)(sp.GetPtr() - sig); return offset; } FCIMPLEND -FCIMPL2(FC_INT8_RET, SignatureNative::GetCallingConventionFromFunctionPointerAtOffset, SignatureNative* pSignatureUNSAFE, INT32 offset) +FCIMPL3(INT32, SignatureNative::GetCallingConventionFromFunctionPointerAtOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 offset) { FCALL_CONTRACT; + _ASSERTE(offset >= 0); - struct - { - SIGNATURENATIVEREF pSig; - } gc; - - if (offset < 0) - { - _ASSERTE(offset == -1); - return 0; - } - - gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE; - + HRESULT hr; uint32_t callConv = 0; + SigPointer sp(sig + offset, csig - offset); - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); - { - SigPointer sp(gc.pSig->GetCorSig() + offset, gc.pSig->GetCorSigSize() - offset); + CorElementType etype; + IfFailRet(sp.GetElemType(&etype)); + _ASSERTE(etype == ELEMENT_TYPE_FNPTR); - CorElementType etype; - IfFailThrow(sp.GetElemType(&etype)); - _ASSERTE(etype == ELEMENT_TYPE_FNPTR); + IfFailRet(sp.GetCallingConv(&callConv)); - IfFailThrow(sp.GetCallingConv(&callConv)); - } - HELPER_METHOD_FRAME_END(); - - return (FC_INT8_RET)(callConv); + return (INT32)callConv; } FCIMPLEND -FCIMPL3(Object *, SignatureNative::GetCustomModifiersAtOffset, - SignatureNative* pSignatureUNSAFE, +extern "C" void QCALLTYPE Signature_GetCustomModifiersAtOffset( + QCall::ObjectHandleOnStack sigObj, INT32 offset, - FC_BOOL_ARG fRequired) + BOOL fRequired, + QCall::ObjectHandleOnStack result) { - FCALL_CONTRACT; + QCALL_CONTRACT; + + BEGIN_QCALL; + + GCX_COOP(); struct { SIGNATURENATIVEREF pSig; PTRARRAYREF retVal; } gc; - - gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE; + gc.pSig = (SIGNATURENATIVEREF)sigObj.Get(); gc.retVal = NULL; + GCPROTECT_BEGIN(gc); + SigTypeContext typeContext; + gc.pSig->GetTypeContext(&typeContext); - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); - { - SigTypeContext typeContext; - gc.pSig->GetTypeContext(&typeContext); + SigPointer argument(gc.pSig->GetCorSig() + offset, gc.pSig->GetCorSigSize() - offset); - SigPointer argument(gc.pSig->GetCorSig() + offset, gc.pSig->GetCorSigSize() - offset); + SigPointer sp = argument; + Module* pModule = gc.pSig->GetModule(); + INT32 cMods = 0; + CorElementType cmodType; - SigPointer sp = argument; - Module* pModule = gc.pSig->GetModule(); - INT32 cMods = 0; - CorElementType cmodType; + CorElementType cmodTypeExpected = fRequired ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT; - CorElementType cmodTypeExpected = FC_ACCESS_BOOL(fRequired) ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT; + // Discover the number of required and optional custom modifiers. + while (TRUE) + { + BYTE data; + IfFailThrow(sp.GetByte(&data)); + cmodType = (CorElementType)data; - // Discover the number of required and optional custom modifiers. - while(TRUE) + if (cmodType == ELEMENT_TYPE_CMOD_REQD || cmodType == ELEMENT_TYPE_CMOD_OPT) { - BYTE data; - IfFailThrow(sp.GetByte(&data)); - cmodType = (CorElementType)data; - - if (cmodType == ELEMENT_TYPE_CMOD_REQD || cmodType == ELEMENT_TYPE_CMOD_OPT) + if (cmodType == cmodTypeExpected) { - if (cmodType == cmodTypeExpected) - { - cMods ++; - } - - IfFailThrow(sp.GetToken(NULL)); + cMods++; } - else if (cmodType == ELEMENT_TYPE_CMOD_INTERNAL) - { - BYTE required; - IfFailThrow(sp.GetByte(&required)); - if (fRequired == (required != 0)) - { - cMods ++; - } - IfFailThrow(sp.GetPointer(NULL)); - } - else if (cmodType != ELEMENT_TYPE_SENTINEL) + IfFailThrow(sp.GetToken(NULL)); + } + else if (cmodType == ELEMENT_TYPE_CMOD_INTERNAL) + { + BYTE required; + IfFailThrow(sp.GetByte(&required)); + if (fRequired == (required != 0)) { - break; + cMods++; } + + IfFailThrow(sp.GetPointer(NULL)); } + else if (cmodType != ELEMENT_TYPE_SENTINEL) + { + break; + } + } - // Reset sp and populate the arrays for the required and optional custom - // modifiers now that we know how long they should be. - sp = argument; + // Reset sp and populate the arrays for the required and optional custom + // modifiers now that we know how long they should be. + sp = argument; - MethodTable *pMT = CoreLibBinder::GetClass(CLASS__TYPE); - TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY); + MethodTable *pMT = CoreLibBinder::GetClass(CLASS__TYPE); + TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY); - gc.retVal = (PTRARRAYREF) AllocateSzArray(arrayHandle, cMods); + gc.retVal = (PTRARRAYREF) AllocateSzArray(arrayHandle, cMods); - while(cMods != 0) - { - BYTE data; - IfFailThrow(sp.GetByte(&data)); - cmodType = (CorElementType)data; + while (cMods != 0) + { + BYTE data; + IfFailThrow(sp.GetByte(&data)); + cmodType = (CorElementType)data; - if (cmodType == ELEMENT_TYPE_CMOD_INTERNAL) - { - BYTE required; - IfFailThrow(sp.GetByte(&required)); + if (cmodType == ELEMENT_TYPE_CMOD_INTERNAL) + { + BYTE required; + IfFailThrow(sp.GetByte(&required)); - TypeHandle th; - IfFailThrow(sp.GetPointer((void**)&th)); + TypeHandle th; + IfFailThrow(sp.GetPointer((void**)&th)); - if (fRequired == (required != 0)) - { - OBJECTREF refType = th.GetManagedClassObject(); - gc.retVal->SetAt(--cMods, refType); - } - } - else + if (fRequired == (required != 0)) { - mdToken token; - IfFailThrow(sp.GetToken(&token)); - - if (cmodType == cmodTypeExpected) - { - TypeHandle th = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, token, - &typeContext, - ClassLoader::ThrowIfNotFound, - ClassLoader::FailIfUninstDefOrRef); - - OBJECTREF refType = th.GetManagedClassObject(); - gc.retVal->SetAt(--cMods, refType); - } + OBJECTREF refType = th.GetManagedClassObject(); + gc.retVal->SetAt(--cMods, refType); } } - } - HELPER_METHOD_FRAME_END(); - - return OBJECTREFToObject(gc.retVal); -} -FCIMPLEND - -FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, ReflectMethodObject *pMethodUNSAFE) { - CONTRACTL { - FCALL_CHECK; - } - CONTRACTL_END; - - if (!pMethodUNSAFE) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); + else + { + mdToken token; + IfFailThrow(sp.GetToken(&token)); - MethodDesc* pMethod = pMethodUNSAFE->GetMethod(); + if (cmodType == cmodTypeExpected) + { + TypeHandle th = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, token, + &typeContext, + ClassLoader::ThrowIfNotFound, + ClassLoader::FailIfUninstDefOrRef); - if (pMethod->HasMethodInstantiation()) - { - HELPER_METHOD_FRAME_BEGIN_RET_1(pMethodUNSAFE); - { - pMethod = pMethod->StripMethodInstantiation(); + OBJECTREF refType = th.GetManagedClassObject(); + gc.retVal->SetAt(--cMods, refType); + } } - HELPER_METHOD_FRAME_END(); } + result.Set(gc.retVal); + GCPROTECT_END(); + END_QCALL; +} - INT32 tkMethodDef = (INT32)pMethod->GetMemberDef(); - _ASSERTE(TypeFromToken(tkMethodDef) == mdtMethodDef); - - if (IsNilToken(tkMethodDef) || TypeFromToken(tkMethodDef) != mdtMethodDef) - return mdMethodDefNil; - - return tkMethodDef; +FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, MethodDesc* pMethod) +{ + FCALL_CONTRACT; + _ASSERTE(pMethod != NULL); + return (INT32)pMethod->GetMemberDef(); } FCIMPLEND -FCIMPL6(void, SignatureNative::GetSignature, - SignatureNative* pSignatureNativeUNSAFE, +extern "C" void QCALLTYPE Signature_Init( + QCall::ObjectHandleOnStack sigObj, PCCOR_SIGNATURE pCorSig, DWORD cCorSig, - FieldDesc *pFieldDesc, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE) { - CONTRACTL { - FCALL_CHECK; - PRECONDITION(pDeclaringTypeUNSAFE || pMethodUNSAFE->GetMethod()->IsDynamicMethod()); - PRECONDITION(CheckPointer(pCorSig, NULL_OK)); - PRECONDITION(CheckPointer(pMethodUNSAFE, NULL_OK)); - PRECONDITION(CheckPointer(pFieldDesc, NULL_OK)); - } - CONTRACTL_END; + FieldDesc* pFieldDesc, + MethodDesc* pMethodDesc) +{ + QCALL_CONTRACT; + + BEGIN_QCALL; + + GCX_COOP(); struct { - REFLECTCLASSBASEREF refDeclaringType; - REFLECTMETHODREF refMethod; SIGNATURENATIVEREF pSig; } gc; + gc.pSig = (SIGNATURENATIVEREF)sigObj.Get(); + GCPROTECT_BEGIN(gc); - gc.refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE); - gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE); - gc.pSig = (SIGNATURENATIVEREF)pSignatureNativeUNSAFE; - - MethodDesc *pMethod; - TypeHandle declType; + TypeHandle declType = gc.pSig->GetDeclaringType(); + _ASSERTE(!declType.IsNull()); - if (gc.refDeclaringType == NULL) + if (pMethodDesc != NULL) { - // for dynamic method, see precondition - pMethod = gc.refMethod->GetMethod(); - declType = pMethod->GetMethodTable(); + pMethodDesc->GetSig(&pCorSig, &cCorSig); + if (pMethodDesc->GetClassification() == mcInstantiated) + { + LoaderAllocator *pLoaderAllocator = pMethodDesc->GetLoaderAllocator(); + if (pLoaderAllocator->IsCollectible()) + gc.pSig->SetKeepAlive(pLoaderAllocator->GetExposedObject()); + } } - else + else if (pFieldDesc != NULL) { - pMethod = gc.refMethod != NULL ? gc.refMethod->GetMethod() : NULL; - declType = gc.refDeclaringType->GetType(); + pFieldDesc->GetSig(&pCorSig, &cCorSig); } + _ASSERTE(pCorSig != NULL && cCorSig > 0); - HELPER_METHOD_FRAME_BEGIN_PROTECT(gc); - { - Module* pModule = declType.GetModule(); - - if (pMethod) - { - pMethod->GetSig(&pCorSig, &cCorSig); - if (pMethod->GetClassification() == mcInstantiated) - { - LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator(); - if (pLoaderAllocator->IsCollectible()) - gc.pSig->SetKeepAlive(pLoaderAllocator->GetExposedObject()); - } - } - else if (pFieldDesc) - pFieldDesc->GetSig(&pCorSig, &cCorSig); - - gc.pSig->m_sig = pCorSig; - gc.pSig->m_cSig = cCorSig; - gc.pSig->m_pMethod = pMethod; + gc.pSig->_sig = pCorSig; + gc.pSig->_csig = cCorSig; + gc.pSig->_pMethod = pMethodDesc; - REFLECTCLASSBASEREF refDeclType = (REFLECTCLASSBASEREF)declType.GetManagedClassObject(); - gc.pSig->SetDeclaringType(refDeclType); + // Initialize _returnTypeORfieldType and _arguments if they were not initialized yet + if (gc.pSig->_returnTypeORfieldType != NULL) + { + _ASSERTE(gc.pSig->_arguments != NULL); + } + else + { + uint32_t callConv; + if (FAILED(CorSigUncompressCallingConv(pCorSig, cCorSig, &callConv))) + COMPlusThrow(kBadImageFormatException); - PREFIX_ASSUME(pCorSig!= NULL); - BYTE callConv = *(BYTE*)pCorSig; SigTypeContext typeContext; - if (pMethod) + if (pMethodDesc != NULL) + { SigTypeContext::InitTypeContext( - pMethod, declType.GetClassOrArrayInstantiation(), pMethod->LoadMethodInstantiation(), &typeContext); + pMethodDesc, declType.GetClassOrArrayInstantiation(), pMethodDesc->LoadMethodInstantiation(), &typeContext); + } else + { SigTypeContext::InitTypeContext(declType, &typeContext); + } + Module* pModule = declType.GetModule(); MetaSig msig(pCorSig, cCorSig, pModule, &typeContext, (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember); @@ -1820,13 +1682,13 @@ FCIMPL6(void, SignatureNative::GetSignature, OBJECTREF refArgType = msig.GetLastTypeHandleThrowing().GetManagedClassObject(); gc.pSig->SetArgument(i, refArgType); } - - _ASSERTE(gc.pSig->m_returnType != NULL); } } - HELPER_METHOD_FRAME_END(); + + _ASSERTE(gc.pSig->_returnTypeORfieldType != NULL); + GCPROTECT_END(); + END_QCALL; } -FCIMPLEND extern "C" BOOL QCALLTYPE Signature_AreEqual( PCCOR_SIGNATURE sig1, INT32 cSig1, QCall::TypeHandle handle1, @@ -1952,7 +1814,7 @@ FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsTypicalMethodDefinition, ReflectMeth FCIMPLEND extern "C" void QCALLTYPE RuntimeMethodHandle_GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod) - { +{ QCALL_CONTRACT; BEGIN_QCALL; @@ -1966,7 +1828,7 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_GetTypicalMethodDefinition(MethodD if (pMethodTypical != pMethod) { GCX_COOP(); - refMethod.Set(pMethodTypical->GetStubMethodInfo()); + refMethod.Set(pMethodTypical->AllocateStubMethodInfo()); } END_QCALL; @@ -1992,7 +1854,7 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_StripMethodInstantiation(MethodDes if (pMethodStripped != pMethod) { GCX_COOP(); - refMethod.Set(pMethodStripped->GetStubMethodInfo()); + refMethod.Set(pMethodStripped->AllocateStubMethodInfo()); } END_QCALL; @@ -2026,75 +1888,71 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_StripMethodInstantiation(MethodDes // 3. create an UnboxingStub for a method in a value type. In this case instArray will be null. // For case 2 and 3, an instantiating stub or unboxing stub might not be needed in which case the original // MethodDesc is returned. -FCIMPL3(MethodDesc*, RuntimeMethodHandle::GetStubIfNeeded, +FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetStubIfNeededInternal, MethodDesc *pMethod, - ReflectClassBaseObject *pTypeUNSAFE, - PtrArray* instArrayUNSAFE) + ReflectClassBaseObject *pTypeUNSAFE) { - CONTRACTL { - FCALL_CHECK; - } - CONTRACTL_END; + FCALL_CONTRACT; REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); - PTRARRAYREF instArray = (PTRARRAYREF)ObjectToOBJECTREF(instArrayUNSAFE); - - if (refType == NULL) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); TypeHandle instType = refType->GetType(); - MethodDesc *pNewMethod = pMethod; - - // error conditions - if (!pMethod) - FCThrowRes(kArgumentException, W("Arg_InvalidHandle")); - - if (instType.IsNull()) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); // Perf optimization: this logic is actually duplicated in FindOrCreateAssociatedMethodDescForReflection, but since it // is the more common case it's worth the duplicate check here to avoid the helper method frame - if ( instArray == NULL && - ( pMethod->HasMethodInstantiation() || - ( !instType.IsValueType() && - ( !instType.HasInstantiation() || instType.IsGenericTypeDefinition() ) ) ) ) + if (pMethod->HasMethodInstantiation() + || (!instType.IsValueType() + && (!instType.HasInstantiation() || instType.IsGenericTypeDefinition()))) { - return pNewMethod; + return pMethod; } - HELPER_METHOD_FRAME_BEGIN_RET_2(refType, instArray); - { - TypeHandle *inst = NULL; - DWORD ntypars = 0; + return NULL; +} +FCIMPLEND - if (instArray != NULL) - { - ntypars = instArray->GetNumComponents(); +// See RuntimeMethodHandle::GetStubIfNeededInternal for more details. +extern "C" MethodDesc* QCALLTYPE RuntimeMethodHandle_GetStubIfNeededSlow(MethodDesc* pMethod, QCall::TypeHandle declaringTypeHandle, QCall::ObjectHandleOnStack methodInstantiation) +{ + QCALL_CONTRACT; - size_t size = ntypars * sizeof(TypeHandle); - if ((size / sizeof(TypeHandle)) != ntypars) // uint over/underflow - COMPlusThrow(kArgumentException); - inst = (TypeHandle*) _alloca(size); + MethodDesc *pNewMethod = NULL; - for (DWORD i = 0; i < ntypars; i++) - { - REFLECTCLASSBASEREF instRef = (REFLECTCLASSBASEREF)instArray->GetAt(i); + BEGIN_QCALL; + + GCX_COOP(); - if (instRef == NULL) - COMPlusThrowArgumentNull(W("inst"), W("ArgumentNull_ArrayElement")); + TypeHandle instType = declaringTypeHandle.AsTypeHandle(); - inst[i] = instRef->GetType(); - } - } + TypeHandle* inst = NULL; + DWORD ntypars = 0; + + // Construct TypeHandle array for instantiation. + if (methodInstantiation.Get() != NULL) + { + ntypars = ((PTRARRAYREF)methodInstantiation.Get())->GetNumComponents(); - pNewMethod = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMethod, instType, Instantiation(inst, ntypars)); + size_t size = ntypars * sizeof(TypeHandle); + if ((size / sizeof(TypeHandle)) != ntypars) // uint over/underflow + COMPlusThrow(kArgumentException); + inst = (TypeHandle*) _alloca(size); + + for (DWORD i = 0; i < ntypars; i++) + { + REFLECTCLASSBASEREF instRef = (REFLECTCLASSBASEREF)((PTRARRAYREF)methodInstantiation.Get())->GetAt(i); + if (instRef == NULL) + COMPlusThrowArgumentNull(W("inst"), W("ArgumentNull_ArrayElement")); + + inst[i] = instRef->GetType(); + } } - HELPER_METHOD_FRAME_END(); + + pNewMethod = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMethod, instType, Instantiation(inst, ntypars)); + + END_QCALL; return pNewMethod; } -FCIMPLEND - FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pMethod, ReflectClassBaseObject *pTypeUNSAFE) { @@ -2114,170 +1972,160 @@ FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pM } FCIMPLEND - -FCIMPL2(RuntimeMethodBody *, RuntimeMethodHandle::GetMethodBody, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE) +extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, QCall::TypeHandle pDeclaringType, QCall::ObjectHandleOnStack result) { - CONTRACTL - { - FCALL_CHECK; - } - CONTRACTL_END; + QCALL_CONTRACT; + + _ASSERTE(pMethod != NULL); - struct _gc + BEGIN_QCALL; + + GCX_COOP(); + + struct { RUNTIMEMETHODBODYREF MethodBodyObj; RUNTIMEEXCEPTIONHANDLINGCLAUSEREF EHClauseObj; RUNTIMELOCALVARIABLEINFOREF RuntimeLocalVariableInfoObj; - U1ARRAYREF U1Array; - BASEARRAYREF TempArray; - REFLECTCLASSBASEREF declaringType; - REFLECTMETHODREF refMethod; + U1ARRAYREF U1Array; + BASEARRAYREF TempArray; } gc; - gc.MethodBodyObj = NULL; gc.EHClauseObj = NULL; gc.RuntimeLocalVariableInfoObj = NULL; gc.U1Array = NULL; gc.TempArray = NULL; - gc.declaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE); - gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE); - - - if (!gc.refMethod) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - - MethodDesc* pMethod = gc.refMethod->GetMethod(); - - TypeHandle declaringType = gc.declaringType == NULL ? TypeHandle() : gc.declaringType->GetType(); + GCPROTECT_BEGIN(gc); - if (!pMethod->IsIL()) - return NULL; + TypeHandle declaringType = pDeclaringType.AsTypeHandle(); - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); + COR_ILMETHOD* pILHeader = NULL; + if (pMethod->IsIL()) { - MethodDesc *pMethodIL = pMethod; + MethodDesc* pMethodIL = pMethod; if (pMethod->IsWrapperStub()) pMethodIL = pMethod->GetWrappedMethodDesc(); - COR_ILMETHOD* pILHeader = pMethodIL->GetILHeader(); + pILHeader = pMethodIL->GetILHeader(); + } - if (pILHeader) - { - MethodTable * pExceptionHandlingClauseMT = CoreLibBinder::GetClass(CLASS__RUNTIME_EH_CLAUSE); - TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY); + if (pILHeader) + { + MethodTable * pExceptionHandlingClauseMT = CoreLibBinder::GetClass(CLASS__RUNTIME_EH_CLAUSE); + TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY); - MethodTable * pLocalVariableMT = CoreLibBinder::GetClass(CLASS__RUNTIME_LOCAL_VARIABLE_INFO); - TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY); + MethodTable * pLocalVariableMT = CoreLibBinder::GetClass(CLASS__RUNTIME_LOCAL_VARIABLE_INFO); + TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY); - Module* pModule = pMethod->GetModule(); - COR_ILMETHOD_DECODER::DecoderStatus status; - COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status); + Module* pModule = pMethod->GetModule(); + COR_ILMETHOD_DECODER::DecoderStatus status; + COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status); - if (status != COR_ILMETHOD_DECODER::SUCCESS) + if (status != COR_ILMETHOD_DECODER::SUCCESS) + { + if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR) { - if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR) - { - // Throw a verification HR - COMPlusThrowHR(COR_E_VERIFICATION); - } - else - { - COMPlusThrowHR(COR_E_BADIMAGEFORMAT); - } + // Throw a verification HR + COMPlusThrowHR(COR_E_VERIFICATION); } + else + { + COMPlusThrowHR(COR_E_BADIMAGEFORMAT); + } + } - gc.MethodBodyObj = (RUNTIMEMETHODBODYREF)AllocateObject(CoreLibBinder::GetClass(CLASS__RUNTIME_METHOD_BODY)); + gc.MethodBodyObj = (RUNTIMEMETHODBODYREF)AllocateObject(CoreLibBinder::GetClass(CLASS__RUNTIME_METHOD_BODY)); - gc.MethodBodyObj->_maxStackSize = header.GetMaxStack(); - gc.MethodBodyObj->_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals); + gc.MethodBodyObj->_maxStackSize = header.GetMaxStack(); + gc.MethodBodyObj->_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals); - if (header.IsFat()) - gc.MethodBodyObj->_localVarSigToken = header.GetLocalVarSigTok(); - else - gc.MethodBodyObj->_localVarSigToken = 0; + if (header.IsFat()) + gc.MethodBodyObj->_localVarSigToken = header.GetLocalVarSigTok(); + else + gc.MethodBodyObj->_localVarSigToken = 0; - // Allocate the array of IL and fill it in from the method header. - BYTE* pIL = const_cast(header.Code); - COUNT_T cIL = header.GetCodeSize(); - gc.U1Array = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL); + // Allocate the array of IL and fill it in from the method header. + BYTE* pIL = const_cast(header.Code); + COUNT_T cIL = header.GetCodeSize(); + gc.U1Array = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_IL, gc.U1Array); - memcpyNoGCRefs(gc.MethodBodyObj->_IL->GetDataPtr(), pIL, cIL); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_IL, gc.U1Array); + memcpyNoGCRefs(gc.MethodBodyObj->_IL->GetDataPtr(), pIL, cIL); - // Allocate the array of exception clauses. - INT32 cEh = (INT32)header.EHCount(); - const COR_ILMETHOD_SECT_EH* ehInfo = header.EH; - gc.TempArray = (BASEARRAYREF) AllocateSzArray(thEHClauseArray, cEh); + // Allocate the array of exception clauses. + INT32 cEh = (INT32)header.EHCount(); + const COR_ILMETHOD_SECT_EH* ehInfo = header.EH; + gc.TempArray = (BASEARRAYREF) AllocateSzArray(thEHClauseArray, cEh); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_exceptionClauses, gc.TempArray); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_exceptionClauses, gc.TempArray); - for (INT32 i = 0; i < cEh; i++) - { - COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff; - const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause = - (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff); + for (INT32 i = 0; i < cEh; i++) + { + COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff; + const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause = + (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff); - gc.EHClauseObj = (RUNTIMEEXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT); + gc.EHClauseObj = (RUNTIMEEXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT); - gc.EHClauseObj->_flags = ehClause->GetFlags(); - gc.EHClauseObj->_tryOffset = ehClause->GetTryOffset(); - gc.EHClauseObj->_tryLength = ehClause->GetTryLength(); - gc.EHClauseObj->_handlerOffset = ehClause->GetHandlerOffset(); - gc.EHClauseObj->_handlerLength = ehClause->GetHandlerLength(); + gc.EHClauseObj->_flags = ehClause->GetFlags(); + gc.EHClauseObj->_tryOffset = ehClause->GetTryOffset(); + gc.EHClauseObj->_tryLength = ehClause->GetTryLength(); + gc.EHClauseObj->_handlerOffset = ehClause->GetHandlerOffset(); + gc.EHClauseObj->_handlerLength = ehClause->GetHandlerLength(); - if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0) - gc.EHClauseObj->_catchToken = ehClause->GetClassToken(); - else - gc.EHClauseObj->_filterOffset = ehClause->GetFilterOffset(); + if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0) + gc.EHClauseObj->_catchToken = ehClause->GetClassToken(); + else + gc.EHClauseObj->_filterOffset = ehClause->GetFilterOffset(); - gc.MethodBodyObj->_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj); - SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->_methodBody), (OBJECTREF)gc.MethodBodyObj); - } + gc.MethodBodyObj->_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj); + SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->_methodBody), (OBJECTREF)gc.MethodBodyObj); + } - if (header.LocalVarSig != NULL) + if (header.LocalVarSig != NULL) + { + SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation()); + MetaSig metaSig(header.LocalVarSig, + header.cbLocalVarSig, + pModule, + &sigTypeContext, + MetaSig::sigLocalVars); + INT32 cLocals = metaSig.NumFixedArgs(); + gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); + + for (INT32 i = 0; i < cLocals; i ++) { - SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation()); - MetaSig metaSig(header.LocalVarSig, - header.cbLocalVarSig, - pModule, - &sigTypeContext, - MetaSig::sigLocalVars); - INT32 cLocals = metaSig.NumFixedArgs(); - gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); - - for (INT32 i = 0; i < cLocals; i ++) - { - gc.RuntimeLocalVariableInfoObj = (RUNTIMELOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT); + gc.RuntimeLocalVariableInfoObj = (RUNTIMELOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT); - gc.RuntimeLocalVariableInfoObj->_localIndex = i; + gc.RuntimeLocalVariableInfoObj->_localIndex = i; - metaSig.NextArg(); + metaSig.NextArg(); - CorElementType eType; - IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType)); - if (ELEMENT_TYPE_PINNED == eType) - gc.RuntimeLocalVariableInfoObj->_isPinned = TRUE; + CorElementType eType; + IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType)); + if (ELEMENT_TYPE_PINNED == eType) + gc.RuntimeLocalVariableInfoObj->_isPinned = TRUE; - TypeHandle tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext); - OBJECTREF refLocalType = tempType.GetManagedClassObject(); - gc.RuntimeLocalVariableInfoObj->SetType(refLocalType); - gc.MethodBodyObj->_localVariables->SetAt(i, (OBJECTREF) gc.RuntimeLocalVariableInfoObj); - } - } - else - { - INT32 cLocals = 0; - gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); + TypeHandle tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext); + OBJECTREF refLocalType = tempType.GetManagedClassObject(); + gc.RuntimeLocalVariableInfoObj->SetType(refLocalType); + gc.MethodBodyObj->_localVariables->SetAt(i, (OBJECTREF) gc.RuntimeLocalVariableInfoObj); } } + else + { + INT32 cLocals = 0; + gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); + } } - HELPER_METHOD_FRAME_END(); - return (RuntimeMethodBody*)OBJECTREFToObject(gc.MethodBodyObj); + result.Set(gc.MethodBodyObj); + + GCPROTECT_END(); + END_QCALL; } -FCIMPLEND FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsConstructor, MethodDesc *pMethod) { @@ -2592,7 +2440,7 @@ extern "C" void QCALLTYPE ModuleHandle_GetDynamicMethod(QCall::ModuleHandle pMod // create a handle to hold the resolver objectref OBJECTHANDLE resolverHandle = AppDomain::GetCurrentDomain()->CreateLongWeakHandle(resolver.Get()); pNewMD->GetLCGMethodResolver()->SetManagedResolver(resolverHandle); - result.Set(pNewMD->GetStubMethodInfo()); + result.Set(pNewMD->AllocateStubMethodInfo()); } LoaderAllocator *pLoaderAllocator = pModule->GetLoaderAllocator(); diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 5dd2f5ff5676e..dd549987bb9fe 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -11,7 +11,6 @@ #include "typectxt.h" typedef void* EnregisteredTypeHandle; -class SignatureNative; // NOTE: These are defined in CallingConventions.cs. typedef enum ReflectionCallConv { @@ -41,14 +40,13 @@ typedef DPTR(RuntimeMethodBody) RUNTIMEMETHODBODYREF; typedef DPTR(RuntimeLocalVariableInfo) RUNTIMELOCALVARIABLEINFOREF; #endif -class RuntimeExceptionHandlingClause : Object +class RuntimeExceptionHandlingClause : public Object { -private: +public: // Disallow creation and copy construction of these. - RuntimeExceptionHandlingClause() { } - RuntimeExceptionHandlingClause(RuntimeExceptionHandlingClause &r) { } + RuntimeExceptionHandlingClause() = delete; + RuntimeExceptionHandlingClause(const RuntimeExceptionHandlingClause&) = delete; -public: RUNTIMEMETHODBODYREF _methodBody; CorExceptionFlag _flags; INT32 _tryOffset; @@ -59,14 +57,13 @@ class RuntimeExceptionHandlingClause : Object INT32 _filterOffset; }; -class RuntimeMethodBody : Object +class RuntimeMethodBody : public Object { -private: +public: // Disallow creation and copy construction of these. - RuntimeMethodBody() { } - RuntimeMethodBody(RuntimeMethodBody &r) { } + RuntimeMethodBody() = delete; + RuntimeMethodBody(const RuntimeMethodBody&) = delete; -public: U1ARRAYREF _IL; PTRARRAYREF _exceptionClauses; PTRARRAYREF _localVariables; @@ -77,14 +74,12 @@ class RuntimeMethodBody : Object CLR_BOOL _initLocals; }; -class RuntimeLocalVariableInfo : Object +class RuntimeLocalVariableInfo : public Object { -private: - // Disallow creation and copy construction of these. - RuntimeLocalVariableInfo() { } - RuntimeLocalVariableInfo(RuntimeLocalVariableInfo &r) { } - public: + // Disallow creation and copy construction of these. + RuntimeLocalVariableInfo() = delete; + RuntimeLocalVariableInfo(const RuntimeLocalVariableInfo&) = delete; REFLECTCLASSBASEREF GetType() { @@ -118,13 +113,9 @@ class RuntimeTypeHandle static FCDECL1(LPCUTF8, GetUtf8Name, MethodTable* pMT); static FCDECL1(INT32, GetArrayRank, ReflectClassBaseObject* pType); - static FCDECL1(ReflectMethodObject*, GetDeclaringMethod, ReflectClassBaseObject *pType); - static FCDECL1(FC_BOOL_RET, IsUnmanagedFunctionPointer, ReflectClassBaseObject *pTypeUNSAFE); - static FCDECL2(FC_BOOL_RET, CanCastTo, ReflectClassBaseObject *pType, ReflectClassBaseObject *pTarget); - - static FCDECL6(FC_BOOL_RET, SatisfiesConstraints, PTR_ReflectClassBaseObject pGenericParameter, TypeHandle *typeContextArgs, INT32 typeContextCount, TypeHandle *methodContextArgs, INT32 methodContextCount, PTR_ReflectClassBaseObject pGenericArgument); + static FCDECL2(TypeHandle::CastResult, CanCastToInternal, ReflectClassBaseObject *pType, ReflectClassBaseObject *pTarget); static FCDECL1(FC_BOOL_RET, IsGenericVariable, PTR_ReflectClassBaseObject pType); @@ -179,6 +170,7 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_PrepareMemberInfoCache(QCall::TypeHa extern "C" void QCALLTYPE RuntimeTypeHandle_ConstructName(QCall::TypeHandle pTypeHandle, DWORD format, QCall::StringHandleOnStack retString); extern "C" void QCALLTYPE RuntimeTypeHandle_GetInterfaces(MethodTable* pMT, QCall::ObjectHandleOnStack result); extern "C" BOOL QCALLTYPE RuntimeTypeHandle_IsVisible(QCall::TypeHandle pTypeHandle); +extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, QCall::TypeHandle typeContext, MethodDesc* methodContext, QCall::TypeHandle toType); extern "C" void QCALLTYPE RuntimeTypeHandle_GetInstantiation(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType, BOOL fAsRuntimeTypeArray); extern "C" void QCALLTYPE RuntimeTypeHandle_Instantiate(QCall::TypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType); extern "C" void QCALLTYPE RuntimeTypeHandle_GetGenericTypeDefinition(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType); @@ -191,6 +183,7 @@ extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetMethodAt(MethodTable* pMT, extern "C" BOOL QCALLTYPE RuntimeTypeHandle_GetFields(MethodTable* pMT, intptr_t* result, INT32* pCount); extern "C" void QCALLTYPE RuntimeTypeHandle_VerifyInterfaceIsImplemented(QCall::TypeHandle pTypeHandle, QCall::TypeHandle pIFaceHandle); extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetInterfaceMethodImplementation(QCall::TypeHandle pTypeHandle, QCall::TypeHandle pOwner, MethodDesc * pMD); +extern "C" void QCALLTYPE RuntimeTypeHandle_GetDeclaringMethodForGenericParameter(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack result); extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable(EnregisteredTypeHandle pTypeHandle); extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandle(EnregisteredTypeHandle pTypeHandle); extern "C" void QCALLTYPE RuntimeTypeHandle_RegisterCollectibleTypeDependency(QCall::TypeHandle pTypeHandle, QCall::AssemblyHandle pAssembly); @@ -202,7 +195,7 @@ class RuntimeMethodHandle static FCDECL1(INT32, GetImplAttributes, ReflectMethodObject *pMethodUNSAFE); static FCDECL1(MethodTable*, GetMethodTable, MethodDesc *pMethod); static FCDECL1(INT32, GetSlot, MethodDesc *pMethod); - static FCDECL1(INT32, GetMethodDef, ReflectMethodObject *pMethodUNSAFE); + static FCDECL1(INT32, GetMethodDef, MethodDesc *pMethod); static FCDECL1(LPCUTF8, GetUtf8Name, MethodDesc *pMethod); static FCDECL1(FC_BOOL_RET, HasMethodInstantiation, MethodDesc *pMethod); @@ -217,7 +210,7 @@ class RuntimeMethodHandle FCDECL1(INT32, GetGenericParameterCount, MethodDesc * pMethod); // see comment in the cpp file - static FCDECL3(MethodDesc*, GetStubIfNeeded, MethodDesc *pMethod, ReflectClassBaseObject *pType, PtrArray* instArray); + static FCDECL2(MethodDesc*, GetStubIfNeededInternal, MethodDesc *pMethod, ReflectClassBaseObject *pType); static FCDECL2(MethodDesc*, GetMethodFromCanonical, MethodDesc *pMethod, PTR_ReflectClassBaseObject pType); static @@ -226,9 +219,6 @@ class RuntimeMethodHandle static FCDECL1(Object*, GetResolver, MethodDesc * pMethod); - - static FCDECL2(RuntimeMethodBody*, GetMethodBody, ReflectMethodObject *pMethodUNSAFE, PTR_ReflectClassBaseObject pDeclaringType); - static FCDECL1(FC_BOOL_RET, IsConstructor, MethodDesc *pMethod); static FCDECL1(Object*, GetLoaderAllocatorInternal, MethodDesc *pMethod); @@ -257,6 +247,8 @@ extern "C" BOOL QCALLTYPE RuntimeMethodHandle_GetIsCollectible(MethodDesc * pMet extern "C" void QCALLTYPE RuntimeMethodHandle_GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_Destroy(MethodDesc * pMethod); +extern "C" MethodDesc* QCALLTYPE RuntimeMethodHandle_GetStubIfNeededSlow(MethodDesc* pMethod, QCall::TypeHandle declaringTypeHandle, QCall::ObjectHandleOnStack methodInstantiation); +extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, QCall::TypeHandle pDeclaringType, QCall::ObjectHandleOnStack result); class RuntimeFieldHandle { @@ -305,38 +297,40 @@ class AssemblyHandle extern "C" void QCALLTYPE AssemblyHandle_GetManifestModuleSlow(QCall::ObjectHandleOnStack assembly, QCall::ObjectHandleOnStack module); -class SignatureNative; +extern "C" void QCALLTYPE Signature_Init( + QCall::ObjectHandleOnStack sigObj, + PCCOR_SIGNATURE pCorSig, DWORD cCorSig, + FieldDesc* pFieldDesc, + MethodDesc* pMethodDesc); -typedef DPTR(SignatureNative) PTR_SignatureNative; +extern "C" BOOL QCALLTYPE Signature_AreEqual( + PCCOR_SIGNATURE sig1, INT32 cSig1, QCall::TypeHandle handle1, + PCCOR_SIGNATURE sig2, INT32 cSig2, QCall::TypeHandle handle2); -#ifdef USE_CHECKED_OBJECTREFS -typedef REF SIGNATURENATIVEREF; -#else -typedef PTR_SignatureNative SIGNATURENATIVEREF; -#endif +extern "C" void QCALLTYPE Signature_GetCustomModifiersAtOffset( + QCall::ObjectHandleOnStack sigObj, + INT32 offset, + BOOL fRequired, + QCall::ObjectHandleOnStack result); class SignatureNative : public Object { - friend class RuntimeMethodHandle; + friend void QCALLTYPE Signature_Init( + QCall::ObjectHandleOnStack sigObj, + PCCOR_SIGNATURE pCorSig, DWORD cCorSig, + FieldDesc* pFieldDesc, + MethodDesc* pMethodDesc); friend class ArgIteratorForMethodInvoke; public: - static FCDECL6(void, GetSignature, - SignatureNative* pSignatureNative, - PCCOR_SIGNATURE pCorSig, DWORD cCorSig, - FieldDesc *pFieldDesc, ReflectMethodObject *pMethodUNSAFE, - ReflectClassBaseObject *pDeclaringType); - static FCDECL3(INT32, GetParameterOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 parameterIndex); - static FCDECL3(INT32, GetTypeParameterOffset, SignatureNative* pSig, INT32 offset, INT32 index); + static FCDECL4(INT32, GetTypeParameterOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 offset, INT32 index); - static FCDECL2(FC_INT8_RET, GetCallingConventionFromFunctionPointerAtOffset, SignatureNative* pSig, INT32 offset); + static FCDECL3(INT32, GetCallingConventionFromFunctionPointerAtOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 offset); - static FCDECL3(Object *, GetCustomModifiersAtOffset, SignatureNative* pSig, INT32 offset, FC_BOOL_ARG fRequired); - - BOOL HasThis() { LIMITED_METHOD_CONTRACT; return (m_managedCallingConvention & CALLCONV_HasThis); } - INT32 NumFixedArgs() { WRAPPER_NO_CONTRACT; return m_PtrArrayarguments->GetNumComponents(); } + BOOL HasThis() { LIMITED_METHOD_CONTRACT; return (_managedCallingConventionAndArgIteratorFlags & CALLCONV_HasThis); } + INT32 NumFixedArgs() { WRAPPER_NO_CONTRACT; return _arguments->GetNumComponents(); } TypeHandle GetReturnTypeHandle() { CONTRACTL { @@ -346,11 +340,11 @@ class SignatureNative : public Object } CONTRACTL_END; - return ((REFLECTCLASSBASEREF)m_returnType)->GetType(); + return ((REFLECTCLASSBASEREF)_returnTypeORfieldType)->GetType(); } - PCCOR_SIGNATURE GetCorSig() { LIMITED_METHOD_CONTRACT; return m_sig; } - DWORD GetCorSigSize() { LIMITED_METHOD_CONTRACT; return m_cSig; } + PCCOR_SIGNATURE GetCorSig() { LIMITED_METHOD_CONTRACT; return _sig; } + DWORD GetCorSigSize() { LIMITED_METHOD_CONTRACT; return _csig; } Module* GetModule() { WRAPPER_NO_CONTRACT; return GetDeclaringType().GetModule(); } TypeHandle GetArgumentAt(INT32 position) @@ -362,31 +356,31 @@ class SignatureNative : public Object } CONTRACTL_END; - REFLECTCLASSBASEREF refArgument = (REFLECTCLASSBASEREF)m_PtrArrayarguments->GetAt(position); + REFLECTCLASSBASEREF refArgument = (REFLECTCLASSBASEREF)_arguments->GetAt(position); return refArgument->GetType(); } DWORD GetArgIteratorFlags() { LIMITED_METHOD_CONTRACT; - return VolatileLoad(&m_managedCallingConvention) >> CALLCONV_ArgIteratorFlags_Shift; + return VolatileLoad(&_managedCallingConventionAndArgIteratorFlags) >> CALLCONV_ArgIteratorFlags_Shift; } INT32 GetSizeOfArgStack() { LIMITED_METHOD_CONTRACT; - return m_nSizeOfArgStack; + return _nSizeOfArgStack; } TypeHandle GetDeclaringType() { LIMITED_METHOD_CONTRACT; - return m_declaringType->GetType(); + return _declaringType->GetType(); } MethodDesc* GetMethod() { LIMITED_METHOD_CONTRACT; - return m_pMethod; + return _pMethod; } const SigTypeContext * GetTypeContext(SigTypeContext *pTypeContext) @@ -399,9 +393,9 @@ class SignatureNative : public Object } CONTRACTL_END; - _ASSERTE(m_pMethod || !GetDeclaringType().IsNull()); - if (m_pMethod) - return SigTypeContext::GetOptionalTypeContext(m_pMethod, GetDeclaringType(), pTypeContext); + _ASSERTE(_pMethod || !GetDeclaringType().IsNull()); + if (_pMethod) + return SigTypeContext::GetOptionalTypeContext(_pMethod, GetDeclaringType(), pTypeContext); else return SigTypeContext::GetOptionalTypeContext(GetDeclaringType(), pTypeContext); } @@ -415,7 +409,7 @@ class SignatureNative : public Object MODE_COOPERATIVE; } CONTRACTL_END; - SetObjectReference(&m_returnType, returnType); + SetObjectReference(&_returnTypeORfieldType, returnType); } void SetKeepAlive(OBJECTREF keepAlive) @@ -426,18 +420,7 @@ class SignatureNative : public Object MODE_COOPERATIVE; } CONTRACTL_END; - SetObjectReference(&m_keepalive, keepAlive); - } - - void SetDeclaringType(REFLECTCLASSBASEREF declaringType) - { - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - SetObjectReference((OBJECTREF*)&m_declaringType, (OBJECTREF)declaringType); + SetObjectReference(&_keepAlive, keepAlive); } void SetArgumentArray(PTRARRAYREF ptrArrayarguments) @@ -448,7 +431,7 @@ class SignatureNative : public Object MODE_COOPERATIVE; } CONTRACTL_END; - SetObjectReference((OBJECTREF*)&m_PtrArrayarguments, (OBJECTREF)ptrArrayarguments); + SetObjectReference((OBJECTREF*)&_arguments, (OBJECTREF)ptrArrayarguments); } void SetArgument(INT32 argument, OBJECTREF argumentType) @@ -460,19 +443,19 @@ class SignatureNative : public Object } CONTRACTL_END; - m_PtrArrayarguments->SetAt(argument, argumentType); + _arguments->SetAt(argument, argumentType); } void SetArgIteratorFlags(DWORD flags) { LIMITED_METHOD_CONTRACT; - return VolatileStore(&m_managedCallingConvention, (INT32)(m_managedCallingConvention | (flags << CALLCONV_ArgIteratorFlags_Shift))); + return VolatileStore(&_managedCallingConventionAndArgIteratorFlags, (INT32)(_managedCallingConventionAndArgIteratorFlags | (flags << CALLCONV_ArgIteratorFlags_Shift))); } void SetSizeOfArgStack(INT32 nSizeOfArgStack) { LIMITED_METHOD_CONTRACT; - m_nSizeOfArgStack = nSizeOfArgStack; + _nSizeOfArgStack = nSizeOfArgStack; } void SetCallingConvention(INT32 mdCallingConvention) @@ -480,35 +463,39 @@ class SignatureNative : public Object LIMITED_METHOD_CONTRACT; if ((mdCallingConvention & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_VARARG) - m_managedCallingConvention = CALLCONV_VarArgs; + _managedCallingConventionAndArgIteratorFlags = CALLCONV_VarArgs; else - m_managedCallingConvention = CALLCONV_Standard; + _managedCallingConventionAndArgIteratorFlags = CALLCONV_Standard; if ((mdCallingConvention & IMAGE_CEE_CS_CALLCONV_HASTHIS) != 0) - m_managedCallingConvention |= CALLCONV_HasThis; + _managedCallingConventionAndArgIteratorFlags |= CALLCONV_HasThis; if ((mdCallingConvention & IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS) != 0) - m_managedCallingConvention |= CALLCONV_ExplicitThis; + _managedCallingConventionAndArgIteratorFlags |= CALLCONV_ExplicitThis; } // Mirrored in the managed world (System.Signature) // // this is the layout the classloader chooses by default for the managed struct. // - PTRARRAYREF m_PtrArrayarguments; - REFLECTCLASSBASEREF m_declaringType; - OBJECTREF m_returnType; - OBJECTREF m_keepalive; - PCCOR_SIGNATURE m_sig; - INT32 m_managedCallingConvention; - INT32 m_nSizeOfArgStack; - DWORD m_cSig; - MethodDesc* m_pMethod; + PTRARRAYREF _arguments; + REFLECTCLASSBASEREF _declaringType; + OBJECTREF _returnTypeORfieldType; + OBJECTREF _keepAlive; + PCCOR_SIGNATURE _sig; + DWORD _csig; + INT32 _managedCallingConventionAndArgIteratorFlags; + INT32 _nSizeOfArgStack; + MethodDesc* _pMethod; }; -extern "C" BOOL QCALLTYPE Signature_AreEqual( - PCCOR_SIGNATURE sig1, INT32 cSig1, QCall::TypeHandle handle1, - PCCOR_SIGNATURE sig2, INT32 cSig2, QCall::TypeHandle handle2); +typedef DPTR(SignatureNative) PTR_SignatureNative; + +#ifdef USE_CHECKED_OBJECTREFS +typedef REF SIGNATURENATIVEREF; +#else +typedef PTR_SignatureNative SIGNATURENATIVEREF; +#endif class ReflectionPointer : public Object { diff --git a/src/coreclr/vm/typehandle.h b/src/coreclr/vm/typehandle.h index 5d20d6d5f7d00..862e2fa137aee 100644 --- a/src/coreclr/vm/typehandle.h +++ b/src/coreclr/vm/typehandle.h @@ -267,7 +267,8 @@ class TypeHandle // Note that if the TypeHandle is a valuetype, the caller is responsible // for checking that the valuetype is in its boxed form before calling // CanCastTo. Otherwise, the caller should be using IsBoxedAndCanCastTo() - typedef enum { CannotCast, CanCast, MaybeCast } CastResult; + // See CastCache.cs for matching managed type. + typedef enum { CannotCast = 0, CanCast = 1, MaybeCast = 2 } CastResult; BOOL CanCastTo(TypeHandle type, TypeHandlePairList *pVisited = NULL) const; BOOL IsBoxedAndCanCastTo(TypeHandle type, TypeHandlePairList *pVisited) const; diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastCache.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastCache.cs index 8b538af931edf..c5602eff0d282 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastCache.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastCache.cs @@ -8,6 +8,7 @@ namespace System.Runtime.CompilerServices { + // See typehandle.h for matching unmanaged type. internal enum CastResult { CannotCast = 0, diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index 2b30db584b659..c243053aead38 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -268,7 +268,6 @@ public override bool IsAssignableFrom([NotNullWhen(true)] Type? c) // For runtime type, let the VM decide. if (c.UnderlyingSystemType is RuntimeType fromType) { - // both this and c (or their underlying system types) are runtime types return RuntimeTypeHandle.CanCastTo(fromType, this); }