public static bool TryGetVirtualResolveData(IntPtr moduleHandle,
                                             RuntimeTypeHandle methodHandleDeclaringType, RuntimeTypeHandle[] genericArgs,
                                             ref MethodSignatureComparer methodSignatureComparer,
                                             out VirtualResolveDataResult lookupResult)
 {
     throw new NotImplementedException();
 }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        private static bool TryGetVirtualMethodFromSlot(TypeDesc definingType, int vtableSlotIndex, out MethodDesc slotDefiningMethod)
        {
            MethodNameAndSignature methodNameAndSig;
            bool success = TypeLoaderEnvironment.TryGetMethodMethodNameAndSigFromVTableSlotForPregeneratedOrTemplateType
                               (definingType.Context, definingType.GetRuntimeTypeHandle(), vtableSlotIndex, out methodNameAndSig);

            if (!success)
            {
                slotDefiningMethod = null;
                return(false);
            }

            TypeSystem.NativeFormat.NativeFormatType metadataDefiningType = definingType.GetClosestDefType().GetTypeDefinition() as TypeSystem.NativeFormat.NativeFormatType;

            // We're working with a NoMetadataType, or an ArrayType, neither of which have full metadata
            if (metadataDefiningType == null)
            {
                slotDefiningMethod = null;
                return(false);
            }

            // TryGetMethodMethodNameAndSigFromVTableSlotForPregeneratedOrTemplateType is expected to only return methodNameAndSig with NativeLayoutSignatures in them.
            // If we start hitting the more general case, we can improve this algorithm.
            Debug.Assert(methodNameAndSig.Signature.IsNativeLayoutSignature);

            foreach (TypeSystem.NativeFormat.NativeFormatMethod method in metadataDefiningType.GetMethods())
            {
                if (!method.IsVirtual)
                {
                    continue;
                }

                if (method.HasInstantiation)
                {
                    continue;
                }

                if (!method.Name.Equals(methodNameAndSig.Name))
                {
                    continue;
                }

                MethodSignatureComparer sigComparer = new MethodSignatureComparer(method.MetadataReader, method.Handle);
                if (!sigComparer.IsMatchingNativeLayoutMethodNameAndSignature(methodNameAndSig.Name, methodNameAndSig.Signature))
                {
                    continue;
                }

                // At this point we've matched
                slotDefiningMethod = method;
                return(true);
            }

            // Didn't find the method
            slotDefiningMethod = null;
            return(false);
        }
 public static bool TryGetMethodInvokeMetadata(
     MetadataReader metadataReader,
     RuntimeTypeHandle declaringTypeHandle,
     MethodHandle methodHandle,
     RuntimeTypeHandle[] genericMethodTypeArgumentHandles,
     ref MethodSignatureComparer methodSignatureComparer,
     CanonicalFormKind canonFormKind,
     out MethodInvokeMetadata methodInvokeMetadata)
 {
     throw new NotImplementedException();
 }
 public static bool TryGetMethodInvokeMetadata(
     MetadataReader metadataReader,
     RuntimeTypeHandle declaringTypeHandle,
     MethodHandle methodHandle,
     RuntimeTypeHandle[] genericMethodTypeArgumentHandles,
     ref MethodSignatureComparer methodSignatureComparer,
     CanonicalFormKind canonFormKind,
     out MethodInvokeMetadata methodInvokeMetadata)
 {
     throw new NotImplementedException();
 }
        public bool CompareMethodSignatures(RuntimeMethodSignature signature1, RuntimeMethodSignature signature2)
        {
            IntPtr nativeLayoutSignature1 = signature1.NativeLayoutSignature;
            IntPtr nativeLayoutSignature2 = signature2.NativeLayoutSignature;

            if ((nativeLayoutSignature1 != IntPtr.Zero) && (nativeLayoutSignature2 != IntPtr.Zero))
            {
                if (nativeLayoutSignature1 == nativeLayoutSignature2)
                {
                    return(true);
                }

                NativeReader reader1 = GetNativeLayoutInfoReader(RuntimeAugments.GetModuleFromPointer(nativeLayoutSignature1));
                NativeParser parser1 = new NativeParser(reader1, reader1.AddressToOffset(nativeLayoutSignature1));

                NativeReader reader2 = GetNativeLayoutInfoReader(RuntimeAugments.GetModuleFromPointer(nativeLayoutSignature2));
                NativeParser parser2 = new NativeParser(reader2, reader2.AddressToOffset(nativeLayoutSignature2));

                return(CompareMethodSigs(parser1, parser2));
            }
            else if (nativeLayoutSignature1 != IntPtr.Zero)
            {
                int            token          = signature2.Token;
                MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(signature2.ModuleHandle);

                MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader));
                return(comparer.IsMatchingNativeLayoutMethodSignature(nativeLayoutSignature1));
            }
            else if (nativeLayoutSignature2 != IntPtr.Zero)
            {
                int            token          = signature1.Token;
                MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(signature1.ModuleHandle);

                MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader));
                return(comparer.IsMatchingNativeLayoutMethodSignature(nativeLayoutSignature2));
            }
            else
            {
                // For now, RuntimeMethodSignatures are only used to compare for method signature equality (along with their Name)
                // So we can implement this with the simple equals check
                if (signature1.Token != signature2.Token)
                {
                    return(false);
                }

                if (signature1.ModuleHandle != signature2.ModuleHandle)
                {
                    return(false);
                }

                return(true);
            }
        }
Beispiel #7
0
        public bool CompareMethodSignatures(RuntimeSignature signature1, RuntimeSignature signature2)
        {
            if (signature1.IsNativeLayoutSignature && signature2.IsNativeLayoutSignature)
            {
                if (signature1.StructuralEquals(signature2))
                {
                    return(true);
                }

                NativeFormatModuleInfo module1 = ModuleList.GetModuleInfoByHandle(new TypeManagerHandle(signature1.ModuleHandle));
                NativeReader           reader1 = GetNativeLayoutInfoReader(signature1);
                NativeParser           parser1 = new NativeParser(reader1, signature1.NativeLayoutOffset);

                NativeFormatModuleInfo module2 = ModuleList.GetModuleInfoByHandle(new TypeManagerHandle(signature2.ModuleHandle));
                NativeReader           reader2 = GetNativeLayoutInfoReader(signature2);
                NativeParser           parser2 = new NativeParser(reader2, signature2.NativeLayoutOffset);

                return(CompareMethodSigs(parser1, module1, parser2, module2));
            }
            else if (signature1.IsNativeLayoutSignature)
            {
                int            token          = signature2.Token;
                MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(new TypeManagerHandle(signature2.ModuleHandle));

                MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader));
                return(comparer.IsMatchingNativeLayoutMethodSignature(signature1));
            }
            else if (signature2.IsNativeLayoutSignature)
            {
                int            token          = signature1.Token;
                MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(new TypeManagerHandle(signature1.ModuleHandle));

                MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader));
                return(comparer.IsMatchingNativeLayoutMethodSignature(signature2));
            }
            else
            {
                // For now, RuntimeSignatures are only used to compare for method signature equality (along with their Name)
                // So we can implement this with the simple equals check
                if (signature1.Token != signature2.Token)
                {
                    return(false);
                }

                if (signature1.ModuleHandle != signature2.ModuleHandle)
                {
                    return(false);
                }

                return(true);
            }
        }
        public bool CompareMethodSignatures(RuntimeMethodSignature signature1, RuntimeMethodSignature signature2)
        {
            IntPtr nativeLayoutSignature1 = signature1.NativeLayoutSignature;
            IntPtr nativeLayoutSignature2 = signature2.NativeLayoutSignature;

            if ((nativeLayoutSignature1 != IntPtr.Zero) && (nativeLayoutSignature2 != IntPtr.Zero))
            {
                if (nativeLayoutSignature1 == nativeLayoutSignature2)
                    return true;

                NativeReader reader1 = GetNativeLayoutInfoReader(RuntimeAugments.GetModuleFromPointer(nativeLayoutSignature1));
                NativeParser parser1 = new NativeParser(reader1, reader1.AddressToOffset(nativeLayoutSignature1));

                NativeReader reader2 = GetNativeLayoutInfoReader(RuntimeAugments.GetModuleFromPointer(nativeLayoutSignature2));
                NativeParser parser2 = new NativeParser(reader2, reader2.AddressToOffset(nativeLayoutSignature2));

                return CompareMethodSigs(parser1, parser2);
            }
            else if (nativeLayoutSignature1 != IntPtr.Zero)
            {
                int token = signature2.Token;
                MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(signature2.ModuleHandle);

                MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader));
                return comparer.IsMatchingNativeLayoutMethodSignature(nativeLayoutSignature1);
            }
            else if (nativeLayoutSignature2 != IntPtr.Zero)
            {
                int token = signature1.Token;
                MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(signature1.ModuleHandle);

                MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader));
                return comparer.IsMatchingNativeLayoutMethodSignature(nativeLayoutSignature2);
            }
            else
            {
                // For now, RuntimeMethodSignatures are only used to compare for method signature equality (along with their Name)
                // So we can implement this with the simple equals check
                if (signature1.Token != signature2.Token)
                    return false;

                if (signature1.ModuleHandle != signature2.ModuleHandle)
                    return false;

                return true;
            }
        }
Beispiel #9
0
        /// <summary>
        /// Get the virtual slot index of a given virtual method. (This is only valid for non-interface virtuals)
        /// </summary>
        /// <param name="virtualMethod">virtual method to get slot index of</param>
        /// <returns>slot index, or -1</returns>
        public static int VirtualMethodToSlotIndex(MethodDesc virtualMethod)
        {
            Debug.Assert(virtualMethod.IsVirtual);
            Debug.Assert(!virtualMethod.OwningType.IsInterface);

            MethodDesc definingMethod = virtualMethod;

            // If not newslot, make sure we've got the defining method here
            if (!definingMethod.IsNewSlot)
            {
                definingMethod = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(definingMethod);
            }
            TypeDesc definingType = definingMethod.OwningType;

            // Two possible cases for determining slot index that will work
            //  1. The definingType is a R2R type with full metadata. Compute the MethodDesc, by scanning the list of virtuals present in metadata. Its possible to not get a slot index. In that case return -1
            //  2. The definingType is pregenerated, but we can go from metadata to slot index via the runtime mapping tables.

            if (!IsPregeneratedOrTemplateTypeLoaded(definingType))
            {
                // Case 1

                MetadataType definingMetadataType = (MetadataType)definingType;
                int          baseTypeSlotCount    = 0;

                if (definingMetadataType.BaseType != null)
                {
                    unsafe
                    {
                        if (definingMetadataType.BaseType.RetrieveRuntimeTypeHandleIfPossible())
                        {
                            baseTypeSlotCount = definingMetadataType.BaseType.GetRuntimeTypeHandle().ToEETypePtr()->NumVtableSlots;
                        }
                        else
                        {
                            baseTypeSlotCount = definingMetadataType.BaseType.GetOrCreateTypeBuilderState().NumVTableSlots;
                        }
                    }
                }

                int currentSlot = baseTypeSlotCount;

                if (definingMetadataType.ConvertToCanonForm(CanonicalFormKind.Specific).IsCanonicalSubtype(CanonicalFormKind.Specific))
                {
                    // Deal with the space reserved for the canonical dictionary
                    currentSlot++;
                }

                foreach (MethodDesc method in definingMetadataType.GetMethods())
                {
                    if (!MethodDefinesVTableSlot(method))
                    {
                        continue;
                    }

                    if (method == definingMethod)
                    {
                        return(currentSlot);
                    }
                    else
                    {
                        currentSlot++;
                    }
                }

                // No slot index defined.
                return(-1);
            }
            else
            {
                // Case 2, pregenerated type
                TypeSystem.NativeFormat.NativeFormatMethod definingMethodOpenType = (TypeSystem.NativeFormat.NativeFormatMethod)definingMethod.GetTypicalMethodDefinition();
                MethodSignatureComparer methodSignatureComparer = new MethodSignatureComparer(
                    definingMethodOpenType.MetadataReader, definingMethodOpenType.Handle);

                if (!definingType.RetrieveRuntimeTypeHandleIfPossible())
                {
                    new TypeBuilder().BuildType(definingType);
                }

                TypeSystem.NativeFormat.NativeFormatType definingNativeFormatType = (TypeSystem.NativeFormat.NativeFormatType)definingType.GetTypeDefinition();
                NativeFormatModuleInfo moduleToLookIn = definingNativeFormatType.MetadataUnit.RuntimeModuleInfo;

                TypeLoaderEnvironment.VirtualResolveDataResult virtualSlotInfo;
                if (!TypeLoaderEnvironment.TryGetVirtualResolveData(moduleToLookIn, definingType.RuntimeTypeHandle, Array.Empty <RuntimeTypeHandle>(), ref methodSignatureComparer, out virtualSlotInfo))
                {
                    return(-1);
                }

                Debug.Assert(!virtualSlotInfo.IsGVM);
                return(virtualSlotInfo.SlotIndex);
            }
        }
 public static bool TryGetVirtualResolveData(IntPtr moduleHandle,
     RuntimeTypeHandle methodHandleDeclaringType, RuntimeTypeHandle[] genericArgs,
     ref MethodSignatureComparer methodSignatureComparer,
     out VirtualResolveDataResult lookupResult)
 {
     throw new NotImplementedException();
 }
        private static bool TryGetVirtualMethodFromSlot(TypeDesc definingType, int vtableSlotIndex, out MethodDesc slotDefiningMethod)
        {
            MethodNameAndSignature methodNameAndSig;
            bool success = TypeLoaderEnvironment.TryGetMethodMethodNameAndSigFromVTableSlotForPregeneratedOrTemplateType
                (definingType.Context, definingType.GetRuntimeTypeHandle(), vtableSlotIndex, out methodNameAndSig);

            if (!success)
            {
                slotDefiningMethod = null;
                return false;
            }

            TypeSystem.NativeFormat.NativeFormatType metadataDefiningType = definingType.GetClosestDefType().GetTypeDefinition() as TypeSystem.NativeFormat.NativeFormatType;

            // We're working with a NoMetadataType, or an ArrayType, neither of which have full metadata
            if (metadataDefiningType == null)
            {
                slotDefiningMethod = null;
                return false;
            }

            // TryGetMethodMethodNameAndSigFromVTableSlotForPregeneratedOrTemplateType is expected to only return methodNameAndSig with NativeLayoutSignatures in them. 
            // If we start hitting the more general case, we can improve this algorithm.
            Debug.Assert(methodNameAndSig.Signature.IsNativeLayoutSignature);

            foreach (TypeSystem.NativeFormat.NativeFormatMethod method in metadataDefiningType.GetMethods())
            {
                if (!method.IsVirtual)
                    continue;

                if (method.HasInstantiation)
                    continue;

                if (!method.Name.Equals(methodNameAndSig.Name))
                    continue;

                MethodSignatureComparer sigComparer = new MethodSignatureComparer(method.MetadataReader, method.Handle);
                if (!sigComparer.IsMatchingNativeLayoutMethodNameAndSignature(methodNameAndSig.Name, methodNameAndSig.Signature.NativeLayoutSignature))
                    continue;

                // At this point we've matched
                slotDefiningMethod = method;
                return true;
            }

            // Didn't find the method
            slotDefiningMethod = null;
            return false;
        }
        /// <summary>
        /// Get the virtual slot index of a given virtual method. (This is only valid for non-interface virtuals)
        /// </summary>
        /// <param name="virtualMethod">virtual method to get slot index of</param>
        /// <returns>slot index, or -1</returns>
        public static int VirtualMethodToSlotIndex(MethodDesc virtualMethod)
        {
            Debug.Assert(virtualMethod.IsVirtual);
            Debug.Assert(!virtualMethod.OwningType.IsInterface);

            MethodDesc definingMethod = virtualMethod;

            // If not newslot, make sure we've got the defining method here
            if (!definingMethod.IsNewSlot)
            {
                definingMethod = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(definingMethod);
            }
            TypeDesc definingType = definingMethod.OwningType;

            // Two possible cases for determining slot index that will work
            //  1. The definingType is a R2R type with full metadata. Compute the MethodDesc, by scanning the list of virtuals present in metadata. Its possible to not get a slot index. In that case return -1
            //  2. The definingType is pregenerated, but we can go from metadata to slot index via the runtime mapping tables.

            if (!IsPregeneratedOrTemplateTypeLoaded(definingType))
            {
                // Case 1

                MetadataType definingMetadataType = (MetadataType)definingType;
                int baseTypeSlotCount = 0;

                if (definingMetadataType.BaseType != null)
                {
                    unsafe
                    {
                        if (definingMetadataType.BaseType.RetrieveRuntimeTypeHandleIfPossible())
                        {
                            baseTypeSlotCount = definingMetadataType.BaseType.GetRuntimeTypeHandle().ToEETypePtr()->NumVtableSlots;
                        }
                        else
                        {
                            baseTypeSlotCount = definingMetadataType.BaseType.GetOrCreateTypeBuilderState().NumVTableSlots;
                        }
                    }
                }

                int currentSlot = baseTypeSlotCount;

                if (definingMetadataType.ConvertToCanonForm(CanonicalFormKind.Specific).IsCanonicalSubtype(CanonicalFormKind.Specific))
                {
                    // Deal with the space reserved for the canonical dictionary
                    currentSlot++;
                }

                foreach (MethodDesc method in definingMetadataType.GetMethods())
                {
                    if (!MethodDefinesVTableSlot(method))
                        continue;

                    if (method == definingMethod)
                        return currentSlot;
                    else
                        currentSlot++;
                }

                // No slot index defined.
                return -1;
            }
            else
            {
                // Case 2, pregenerated type
                TypeSystem.NativeFormat.NativeFormatMethod definingMethodOpenType = (TypeSystem.NativeFormat.NativeFormatMethod)definingMethod.GetTypicalMethodDefinition();
                MethodSignatureComparer methodSignatureComparer = new MethodSignatureComparer(
                    definingMethodOpenType.MetadataReader, definingMethodOpenType.Handle);

                if (!definingType.RetrieveRuntimeTypeHandleIfPossible())
                {
                    new TypeBuilder().BuildType(definingType);
                }

                TypeSystem.NativeFormat.NativeFormatType definingNativeFormatType = (TypeSystem.NativeFormat.NativeFormatType)definingType.GetTypeDefinition();
                IntPtr moduleToLookIn = definingNativeFormatType.MetadataUnit.RuntimeModule;

                TypeLoaderEnvironment.VirtualResolveDataResult virtualSlotInfo;
                if (!TypeLoaderEnvironment.TryGetVirtualResolveData(moduleToLookIn, definingType.RuntimeTypeHandle, Array.Empty<RuntimeTypeHandle>(), ref methodSignatureComparer, out virtualSlotInfo))
                    return -1;

                Debug.Assert(!virtualSlotInfo.IsGVM);
                return virtualSlotInfo.SlotIndex;
            }
        }
        /// <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;
        }