예제 #1
0
        public EagerlyBuiltVTableSliceNode(TypeDesc type)
            : base(type)
        {
            var slots = new ArrayBuilder <MethodDesc>();

            MethodDesc finalizerMethod = type.GetFinalizer();
            DefType    defType         = _type.GetClosestDefType();

            foreach (var method in defType.GetAllMethods())
            {
                if (!method.IsVirtual)
                {
                    continue;
                }

                // GVMs are not emitted in the type's vtable.
                if (method.HasInstantiation)
                {
                    continue;
                }

                // Finalizers are called via a field on the EEType, not through the VTable
                if (finalizerMethod == method || (type.IsObject && method.Name == "Finalize"))
                {
                    continue;
                }

                slots.Add(method);
            }

            _slots = slots.ToArray();
        }
예제 #2
0
        public EagerlyBuiltVTableSliceNode(TypeDesc type)
            : base(type)
        {
            var slots = new ArrayBuilder <MethodDesc>();

            DefType defType = _type.GetClosestDefType();

            foreach (var method in defType.GetAllMethods())
            {
                if (!method.IsVirtual)
                {
                    continue;
                }

                // GVMs are not emitted in the type's vtable.
                if (method.HasInstantiation)
                {
                    continue;
                }

                slots.Add(method);
            }

            _slots = slots.ToArray();
        }
예제 #3
0
        /// <summary>
        /// Gets a value indicating whether '<paramref name="type"/>' might have a non-empty dispatch map.
        /// Note that this is only an approximation because we might not be able to take into account
        /// whether the interface methods are actually used.
        /// </summary>
        public static bool MightHaveInterfaceDispatchMap(TypeDesc type, NodeFactory factory)
        {
            if (type.IsArrayTypeWithoutGenericInterfaces())
            {
                return(false);
            }

            if (!type.IsArray && !type.IsDefType)
            {
                return(false);
            }

            TypeDesc declType = type.GetClosestDefType();

            for (int interfaceIndex = 0; interfaceIndex < declType.RuntimeInterfaces.Length; interfaceIndex++)
            {
                DefType          interfaceType             = declType.RuntimeInterfaces[interfaceIndex];
                InstantiatedType interfaceOnDefinitionType = interfaceType.IsTypeDefinition ?
                                                             null :
                                                             (InstantiatedType)declType.GetTypeDefinition().RuntimeInterfaces[interfaceIndex];

                IEnumerable <MethodDesc> slots;

                // If the vtable has fixed slots, we can query it directly.
                // If it's a lazily built vtable, we might not be able to query slots
                // just yet, so approximate by looking at all methods.
                VTableSliceNode vtableSlice = factory.VTable(interfaceType);
                if (vtableSlice.HasFixedSlots)
                {
                    slots = vtableSlice.Slots;
                }
                else
                {
                    slots = interfaceType.GetAllMethods();
                }

                foreach (MethodDesc slotMethod in slots)
                {
                    MethodDesc declMethod = slotMethod;
                    if (interfaceOnDefinitionType != null)
                    {
                        declMethod = factory.TypeSystemContext.GetMethodForInstantiatedType(declMethod.GetTypicalMethodDefinition(), interfaceOnDefinitionType);
                    }

                    if (declMethod.Signature.IsStatic)
                    {
                        continue;
                    }

                    var implMethod = declType.GetTypeDefinition().ResolveInterfaceMethodToVirtualMethodOnType(declMethod);
                    if (implMethod != null)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #4
0
        public override IEnumerable <CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory)
        {
            // VirtualMethodUse of Foo<SomeType>.Method will bring in VirtualMethodUse
            // of Foo<__Canon>.Method. This in turn should bring in Foo<OtherType>.Method.
            DefType defType = _type.GetClosestDefType();

            foreach (var method in defType.GetAllMethods())
            {
                if (!method.IsVirtual)
                {
                    continue;
                }

                yield return(new CombinedDependencyListEntry(
                                 factory.VirtualMethodUse(method),
                                 factory.VirtualMethodUse(method.GetCanonMethodTarget(CanonicalFormKind.Specific)),
                                 "Canonically equivalent virtual method use"));
            }
        }
예제 #5
0
        public EagerlyBuiltVTableSliceNode(TypeDesc type)
            : base(type)
        {
            var slots = new ArrayBuilder <MethodDesc>();

            DefType defType = _type.GetClosestDefType();

            foreach (var method in defType.GetAllMethods())
            {
                if (!method.IsVirtual)
                {
                    continue;
                }

                slots.Add(method);
            }

            _slots = slots.ToArray();
        }