/// <summary> /// Resolve a MethodDesc to a callable method address and unboxing stub address. /// </summary> /// <param name="method">Native metadata method description object</param> /// <param name="methodAddress">Resolved method address</param> /// <param name="unboxingStubAddress">Resolved unboxing stub address</param> /// <returns>true when the resolution succeeded, false when not</returns> public static bool TryGetMethodAddressFromMethodDesc( MethodDesc method, out IntPtr methodAddress, out IntPtr unboxingStubAddress, out MethodAddressType foundAddressType) { methodAddress = IntPtr.Zero; unboxingStubAddress = IntPtr.Zero; foundAddressType = MethodAddressType.None; #if SUPPORTS_R2R_LOADING TryGetCodeTableEntry(method, out methodAddress, out unboxingStubAddress, out foundAddressType); #endif #if SUPPORT_DYNAMIC_CODE if (foundAddressType == MethodAddressType.None) { MethodEntrypointStubs.TryGetMethodEntrypoint(method, out methodAddress, out unboxingStubAddress, out foundAddressType); } #endif if (foundAddressType != MethodAddressType.None) { return(true); } // Otherwise try to find it via an invoke map return(TryGetMethodAddressFromTypeSystemMethodViaInvokeMap(method, out methodAddress, out unboxingStubAddress, out foundAddressType)); }
/// <summary> /// Resolve a MethodDesc to a callable method address and unboxing stub address by searching /// by searching in the InvokeMaps. This function is a wrapper around TryGetMethodInvokeDataFromInvokeMap /// that produces output in the format which matches the code table system. /// </summary> /// <param name="method">Native metadata method description object</param> /// <param name="methodAddress">Resolved method address</param> /// <param name="unboxingStubAddress">Resolved unboxing stub address</param> /// <param name="foundAddressType">Output - The type of method address match found. A canonical address may require extra parameters to call.</param> /// <returns>true when the resolution succeeded, false when not</returns> private static bool TryGetMethodAddressFromTypeSystemMethodViaInvokeMap( MethodDesc method, out IntPtr methodAddress, out IntPtr unboxingStubAddress, out MethodAddressType foundAddressType) { methodAddress = IntPtr.Zero; unboxingStubAddress = IntPtr.Zero; foundAddressType = MethodAddressType.None; #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING NativeFormatMethod nativeFormatMethod = method.GetTypicalMethodDefinition() as NativeFormatMethod; if (nativeFormatMethod == null) { return(false); } MethodSignatureComparer methodSignatureComparer = new MethodSignatureComparer( nativeFormatMethod.MetadataReader, nativeFormatMethod.Handle); // Try to find a specific canonical match, or if that fails, a universal match if (TryGetMethodInvokeDataFromInvokeMap( nativeFormatMethod, method, ref methodSignatureComparer, CanonicalFormKind.Specific, out methodAddress, out foundAddressType) || TryGetMethodInvokeDataFromInvokeMap( nativeFormatMethod, method, ref methodSignatureComparer, CanonicalFormKind.Universal, out methodAddress, out foundAddressType)) { if (method.OwningType.IsValueType && !method.Signature.IsStatic) { // In this case the invoke map found an unboxing stub, and we should pull the method address out as well unboxingStubAddress = methodAddress; methodAddress = RuntimeAugments.GetCodeTarget(unboxingStubAddress); if (!method.HasInstantiation && ((foundAddressType != MethodAddressType.Exact) || method.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any))) { IntPtr underlyingTarget; // unboxing and instantiating stub handling if (!TypeLoaderEnvironment.TryGetTargetOfUnboxingAndInstantiatingStub(methodAddress, out underlyingTarget)) { Environment.FailFast("Expected this to be an unboxing and instantiating stub."); } methodAddress = underlyingTarget; } } return(true); } #endif return(false); }
/// <summary> /// Resolve a MethodDesc to a callable method address and unboxing stub address by searching /// by searching in the InvokeMaps. This function is a wrapper around TryGetMethodInvokeDataFromInvokeMap /// that produces output in the format which matches the code table system. /// </summary> /// <param name="method">Native metadata method description object</param> /// <param name="methodAddress">Resolved method address</param> /// <param name="unboxingStubAddress">Resolved unboxing stub address</param> /// <returns>true when the resolution succeeded, false when not</returns> private static bool TryGetMethodAddressFromTypeSystemMethodViaInvokeMap( MethodDesc method, out IntPtr methodAddress, out IntPtr unboxingStubAddress, out MethodAddressType foundAddressType) { methodAddress = IntPtr.Zero; unboxingStubAddress = IntPtr.Zero; foundAddressType = MethodAddressType.None; #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING NativeFormatMethod nativeFormatMethod = method.GetTypicalMethodDefinition() as NativeFormatMethod; if (nativeFormatMethod == null) return false; MethodSignatureComparer methodSignatureComparer = new MethodSignatureComparer( nativeFormatMethod.MetadataReader, nativeFormatMethod.Handle); // Try to find a specific canonical match, or if that fails, a universal match if (TryGetMethodInvokeDataFromInvokeMap( nativeFormatMethod, method, ref methodSignatureComparer, CanonicalFormKind.Specific, out methodAddress, out foundAddressType) || TryGetMethodInvokeDataFromInvokeMap( nativeFormatMethod, method, ref methodSignatureComparer, CanonicalFormKind.Universal, out methodAddress, out foundAddressType)) { if (method.OwningType.IsValueType && !method.Signature.IsStatic) { // In this case the invoke map found an unboxing stub, and we should pull the method address out as well unboxingStubAddress = methodAddress; methodAddress = RuntimeAugments.GetCodeTarget(unboxingStubAddress); if (!method.HasInstantiation && ((foundAddressType != MethodAddressType.Exact) || method.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any))) { IntPtr underlyingTarget; // unboxing and instantiating stub handling if (!TypeLoaderEnvironment.TryGetTargetOfUnboxingAndInstantiatingStub(methodAddress, out underlyingTarget)) { Environment.FailFast("Expected this to be an unboxing and instantiating stub."); } methodAddress = underlyingTarget; } } return true; } #endif return false; }
/// <summary> /// Resolve a MethodDesc to a callable method address and unboxing stub address. /// </summary> /// <param name="method">Native metadata method description object</param> /// <param name="methodAddress">Resolved method address</param> /// <param name="unboxingStubAddress">Resolved unboxing stub address</param> /// <returns>true when the resolution succeeded, false when not</returns> internal static bool TryGetMethodAddressFromMethodDesc( MethodDesc method, out IntPtr methodAddress, out IntPtr unboxingStubAddress, out MethodAddressType foundAddressType) { #if SUPPORTS_R2R_LOADING // Try to find the method via a code table if (TryGetCodeTableEntry( method, out methodAddress, out unboxingStubAddress, out foundAddressType)) { return(true); } #endif // Otherwise try to find it via an invoke map return(TryGetMethodAddressFromTypeSystemMethodViaInvokeMap(method, out methodAddress, out unboxingStubAddress, out foundAddressType)); }
/// <summary> /// Resolve a MethodDesc to a callable method address and unboxing stub address. /// </summary> /// <param name="method">Native metadata method description object</param> /// <param name="methodAddress">Resolved method address</param> /// <param name="unboxingStubAddress">Resolved unboxing stub address</param> /// <returns>true when the resolution succeeded, false when not</returns> internal static bool TryGetMethodAddressFromMethodDesc( MethodDesc method, out IntPtr methodAddress, out IntPtr unboxingStubAddress, out MethodAddressType foundAddressType) { #if SUPPORTS_R2R_LOADING // Try to find the method via a code table if (TryGetCodeTableEntry( method, out methodAddress, out unboxingStubAddress, out foundAddressType)) { return true; } #endif // Otherwise try to find it via an invoke map return TryGetMethodAddressFromTypeSystemMethodViaInvokeMap(method, out methodAddress, out unboxingStubAddress, out foundAddressType); }