public static bool TryCreate(MethodDesc method, out RuntimeSignature methodSignature)
        {
#if SUPPORTS_NATIVE_METADATA_TYPE_LOADING
            MethodDesc typicalMethod = method.GetTypicalMethodDefinition();

            if (typicalMethod is TypeSystem.NativeFormat.NativeFormatMethod)
            {
                TypeSystem.NativeFormat.NativeFormatMethod nativeFormatMethod = (TypeSystem.NativeFormat.NativeFormatMethod)typicalMethod;
                methodSignature = RuntimeSignature.CreateFromMethodHandle(nativeFormatMethod.MetadataUnit.RuntimeModule, nativeFormatMethod.Handle.ToInt());
                return(true);
            }
#if ECMA_METADATA_SUPPORT
            if (typicalMethod is TypeSystem.Ecma.EcmaMethod)
            {
                unsafe
                {
                    TypeSystem.Ecma.EcmaMethod ecmaMethod = (TypeSystem.Ecma.EcmaMethod)typicalMethod;
                    methodSignature = RuntimeSignature.CreateFromMethodHandle(new IntPtr(ecmaMethod.Module.RuntimeModuleInfo.DynamicModulePtr), System.Reflection.Metadata.Ecma335.MetadataTokens.GetToken(ecmaMethod.Handle));
                }
                return(true);
            }
#endif
#endif
            methodSignature = default(RuntimeSignature);
            return(false);
        }
示例#2
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);
            }
        }