Example #1
0
        /// <summary>
        /// Attempt a virtual dispatch on a given instanceType based on the method found via a metadata token
        /// </summary>
        private static bool TryDispatchMethodOnTarget_Inner(NativeFormatModuleInfo module, int metadataToken, RuntimeTypeHandle targetInstanceType, out IntPtr methodAddress)
        {
#if SUPPORTS_NATIVE_METADATA_TYPE_LOADING
            TypeSystemContext context = TypeSystemContextFactory.Create();

            NativeFormatMetadataUnit metadataUnit = context.ResolveMetadataUnit(module);
            MethodDesc targetMethod = metadataUnit.GetMethod(metadataToken.AsHandle(), null);
            TypeDesc   instanceType = context.ResolveRuntimeTypeHandle(targetInstanceType);

            MethodDesc realTargetMethod = targetMethod;

            // For non-interface methods we support the target method not being the exact target. (This allows
            // a canonical method to be passed in and work for any generic type instantiation.)
            if (!targetMethod.OwningType.IsInterface)
            {
                realTargetMethod = instanceType.FindMethodOnTypeWithMatchingTypicalMethod(targetMethod);
            }

            bool success = LazyVTableResolver.TryDispatchMethodOnTarget(instanceType, realTargetMethod, out methodAddress);

            TypeSystemContextFactory.Recycle(context);
            return(success);
#else
            methodAddress = IntPtr.Zero;
            return(false);
#endif
        }
        /// <summary>
        /// Resolve a dispatch on an interface EEType/slot index pair to a function pointer
        /// </summary>
        private bool TryResolveTypeSlotDispatch_Inner(IntPtr targetTypeAsIntPtr, IntPtr interfaceTypeAsIntPtr, ushort slot, out IntPtr methodAddress)
        {
            methodAddress = IntPtr.Zero;

#if SUPPORTS_NATIVE_METADATA_TYPE_LOADING
            TypeSystemContext context = TypeSystemContextFactory.Create();

            TypeDesc targetType;
            TypeDesc interfaceType;

            unsafe
            {
                targetType    = context.ResolveRuntimeTypeHandle(((EEType *)targetTypeAsIntPtr.ToPointer())->ToRuntimeTypeHandle());
                interfaceType = context.ResolveRuntimeTypeHandle(((EEType *)interfaceTypeAsIntPtr.ToPointer())->ToRuntimeTypeHandle());
            }

            if (!(interfaceType.GetTypeDefinition() is MetadataType))
            {
                // If the interface open type is not a metadata type, this must be an interface not known in the metadata world.
                // Use the redhawk resolver for this directly.
                TypeDesc pregeneratedType = LazyVTableResolver.GetMostDerivedPregeneratedOrTemplateLoadedType(targetType);
                pregeneratedType.RetrieveRuntimeTypeHandleIfPossible();
                interfaceType.RetrieveRuntimeTypeHandleIfPossible();
                methodAddress = RuntimeAugments.ResolveDispatchOnType(pregeneratedType.RuntimeTypeHandle, interfaceType.RuntimeTypeHandle, slot);
            }
            else
            {
                MethodDesc interfaceMethod;

                if (!LazyVTableResolver.TryGetMethodFromInterfaceSlot(interfaceType, slot, out interfaceMethod))
                {
                    return(false);
                }

                if (!LazyVTableResolver.TryDispatchMethodOnTarget(targetType, interfaceMethod, out methodAddress))
                {
                    return(false);
                }
            }

            TypeSystemContextFactory.Recycle(context);

            return(true);
#else
            return(false);
#endif
        }