public override bool ShouldProduceFullType(TypeDesc type)
        {
            // TODO: Remove this once we have delgate constructor transform added and GetMethods() tells us about
            //       the virtuals we add on to delegate types.
            if (type.IsDelegate)
            {
                return(false);
            }

            // Fully build all types when building a library
            if (BuildingLibrary)
            {
                return(true);
            }

            // Fully build all shareable types so they will be identical in each module
            if (EETypeNode.IsTypeNodeShareable(type))
            {
                return(true);
            }

            // If referring to a type from another module, VTables, interface maps, etc should assume the
            // type is fully build.
            if (!ContainsType(type))
            {
                return(true);
            }

            return(false);
        }
예제 #2
0
        private void AddTypeNode(EETypeNode node)
        {
            if (node != null && !_nodes.Contains(node) && !_visited.Contains(node))
            {
                _visited.Add(node);
                EETypeNode baseTypeNode;
                if (node.Type.BaseType != null)
                {
                    TypeDesc baseType = node.Type.BaseType;
                    if (!node.Type.IsGenericDefinition && baseType.IsCanonicalSubtype(CanonicalFormKind.Any))
                    {
                        baseType = baseType.ConvertToCanonForm(CanonicalFormKind.Specific);
                    }

                    _typeToNodeMap.TryGetValue(baseType, out baseTypeNode);
                    if (!node.Type.IsPrimitive)
                    {
                        AddTypeNode(baseTypeNode);
                    }
                    else if (!_nodes.Contains(baseTypeNode))
                    {
                        _nodes.Add(baseTypeNode);
                    }
                }
                if (!node.Type.IsGenericDefinition)
                {
                    foreach (var field in node.Type.GetFields())
                    {
                        EETypeNode fieldNode;
                        _typeToNodeMap.TryGetValue(field.FieldType, out fieldNode);
                        if (fieldNode == null)
                        {
                            if (field.FieldType.IsValueType)
                            {
                                AddTypeNode((EETypeNode)_factory.NecessaryTypeSymbol(field.FieldType));
                            }
                        }
                        else
                        {
                            if (fieldNode.Type.IsValueType)
                            {
                                if (!fieldNode.Type.IsPrimitive)
                                {
                                    AddTypeNode(fieldNode);
                                }
                                else if (!_nodes.Contains(fieldNode))
                                {
                                    _nodes.Add(fieldNode);
                                }
                            }
                        }
                    }
                }
                if (!_nodes.Contains(node))
                {
                    _nodes.Add(node);
                }
            }
        }
예제 #3
0
        public GenericDictionaryLookup ComputeGenericLookup(MethodDesc contextMethod, ReadyToRunHelperId lookupKind, object targetOfLookup)
        {
            GenericContextSource contextSource;

            if (contextMethod.RequiresInstMethodDescArg())
            {
                contextSource = GenericContextSource.MethodParameter;
            }
            else if (contextMethod.RequiresInstMethodTableArg())
            {
                contextSource = GenericContextSource.TypeParameter;
            }
            else
            {
                Debug.Assert(contextMethod.AcquiresInstMethodTableFromThis());
                contextSource = GenericContextSource.ThisObject;
            }

            // Can we do a fixed lookup? Start by checking if we can get to the dictionary.
            // Context source having a vtable with fixed slots is a prerequisite.
            if (contextSource == GenericContextSource.MethodParameter ||
                HasFixedSlotVTable(contextMethod.OwningType))
            {
                DictionaryLayoutNode dictionaryLayout;
                if (contextSource == GenericContextSource.MethodParameter)
                {
                    dictionaryLayout = _nodeFactory.GenericDictionaryLayout(contextMethod);
                }
                else
                {
                    dictionaryLayout = _nodeFactory.GenericDictionaryLayout(contextMethod.OwningType);
                }

                // If the dictionary layout has fixed slots, we can compute the lookup now. Otherwise defer to helper.
                if (dictionaryLayout.HasFixedSlots)
                {
                    int pointerSize = _nodeFactory.Target.PointerSize;

                    GenericLookupResult lookup = ReadyToRunGenericHelperNode.GetLookupSignature(_nodeFactory, lookupKind, targetOfLookup);
                    int dictionarySlot         = dictionaryLayout.GetSlotForEntry(lookup);
                    int dictionaryOffset       = dictionarySlot * pointerSize;

                    if (contextSource == GenericContextSource.MethodParameter)
                    {
                        return(GenericDictionaryLookup.CreateFixedLookup(contextSource, dictionaryOffset));
                    }
                    else
                    {
                        int vtableSlot   = VirtualMethodSlotHelper.GetGenericDictionarySlot(_nodeFactory, contextMethod.OwningType);
                        int vtableOffset = EETypeNode.GetVTableOffset(pointerSize) + vtableSlot * pointerSize;
                        return(GenericDictionaryLookup.CreateFixedLookup(contextSource, vtableOffset, dictionaryOffset));
                    }
                }
            }

            // Fixed lookup not possible - use helper.
            return(GenericDictionaryLookup.CreateHelperLookup(contextSource));
        }
예제 #4
0
        public ExternalTypeNode(NodeFactory factory, TypeDesc type)
        {
            _type = type;

            //
            // This check encodes rules specific to CoreRT. Ie, no function pointer classes allowed.
            // Eventually we will hit situations where this check fails when it shouldn't and we'll need to
            // split the logic. It's a good sanity check for the time being though.
            //
            EETypeNode.CheckCanGenerateEEType(factory, type);
        }
예제 #5
0
 private void AddTypeNode(EETypeNode node)
 {
     if (node != null && !_nodes.Contains(node) && !_visited.Contains(node))
     {
         _visited.Add(node);
         EETypeNode baseTypeNode;
         if (node.Type.BaseType != null)
         {
             _typeToNodeMap.TryGetValue(node.Type.BaseType, out baseTypeNode);
             if (!node.Type.IsPrimitive)
             {
                 AddTypeNode(baseTypeNode);
             }
             else if (!_nodes.Contains(baseTypeNode))
             {
                 _nodes.Add(baseTypeNode);
             }
         }
         if (!node.Type.IsGenericDefinition)
         {
             foreach (var field in node.Type.GetFields())
             {
                 EETypeNode fieldNode;
                 _typeToNodeMap.TryGetValue(field.FieldType, out fieldNode);
                 if (fieldNode == null)
                 {
                     if (field.FieldType.IsValueType)
                     {
                         AddTypeNode((EETypeNode)_factory.NecessaryTypeSymbol(field.FieldType));
                     }
                 }
                 else
                 {
                     if (fieldNode.Type.IsValueType)
                     {
                         if (!fieldNode.Type.IsPrimitive)
                         {
                             AddTypeNode(fieldNode);
                         }
                         else if (!_nodes.Contains(fieldNode))
                         {
                             _nodes.Add(fieldNode);
                         }
                     }
                 }
             }
         }
         if (!_nodes.Contains(node))
         {
             _nodes.Add(node);
         }
     }
 }
예제 #6
0
        public override bool ShouldProduceFullType(TypeDesc type)
        {
            // Fully build all shareable types so they will be identical in each module
            if (EETypeNode.IsTypeNodeShareable(type))
            {
                return(true);
            }

            // If referring to a type from another module, VTables, interface maps, etc should assume the
            // type is fully build.
            if (!ContainsType(type))
            {
                return(true);
            }

            return(false);
        }
예제 #7
0
 private void AddTypeNode(EETypeNode node)
 {
     if (node != null && !_nodes.Contains(node) && !_visited.Contains(node))
     {
         _visited.Add(node);
         EETypeNode baseTypeNode;
         if (node.Type.BaseType != null)
         {
             _typeToNodeMap.TryGetValue(node.Type.BaseType, out baseTypeNode);
             if (!node.Type.IsPrimitive)
             {
                 AddTypeNode(baseTypeNode);
             }
             else if (!_nodes.Contains(baseTypeNode))
             {
                 _nodes.Add(baseTypeNode);
             }
         }
         foreach (var field in node.Type.GetFields())
         {
             EETypeNode fieldNode;
             _typeToNodeMap.TryGetValue(field.FieldType, out fieldNode);
             if (fieldNode != null)
             {
                 if (fieldNode.Type.IsValueType)
                 {
                     if (!fieldNode.Type.IsPrimitive)
                     {
                         AddTypeNode(fieldNode);
                     }
                     else if (!_nodes.Contains(fieldNode))
                     {
                         _nodes.Add(fieldNode);
                     }
                 }
             }
         }
         if (!_nodes.Contains(node))
         {
             _nodes.Add(node);
         }
     }
 }
예제 #8
0
        public GenericDictionaryLookup ComputeGenericLookup(MethodDesc contextMethod, ReadyToRunHelperId lookupKind, object targetOfLookup)
        {
            if (targetOfLookup is TypeSystemEntity typeSystemEntity)
            {
                _nodeFactory.TypeSystemContext.DetectGenericCycles(contextMethod, typeSystemEntity);
            }

            GenericContextSource contextSource;

            if (contextMethod.RequiresInstMethodDescArg())
            {
                contextSource = GenericContextSource.MethodParameter;
            }
            else if (contextMethod.RequiresInstMethodTableArg())
            {
                contextSource = GenericContextSource.TypeParameter;
            }
            else
            {
                Debug.Assert(contextMethod.AcquiresInstMethodTableFromThis());
                contextSource = GenericContextSource.ThisObject;
            }

            //
            // Some helpers represent logical concepts that might not be something that can be looked up in a dictionary
            //

            // Downgrade type handle for casting to a normal type handle if possible
            if (lookupKind == ReadyToRunHelperId.TypeHandleForCasting)
            {
                var type = (TypeDesc)targetOfLookup;
                if (!type.IsRuntimeDeterminedType ||
                    (!((RuntimeDeterminedType)type).CanonicalType.IsCanonicalDefinitionType(CanonicalFormKind.Universal) &&
                     !((RuntimeDeterminedType)type).CanonicalType.IsNullable))
                {
                    if (type.IsNullable)
                    {
                        targetOfLookup = type.Instantiation[0];
                    }
                    lookupKind = ReadyToRunHelperId.NecessaryTypeHandle;
                }
            }

            // We don't have separate entries for necessary type handles to avoid possible duplication
            if (lookupKind == ReadyToRunHelperId.NecessaryTypeHandle)
            {
                lookupKind = ReadyToRunHelperId.TypeHandle;
            }

            // Can we do a fixed lookup? Start by checking if we can get to the dictionary.
            // Context source having a vtable with fixed slots is a prerequisite.
            if (contextSource == GenericContextSource.MethodParameter ||
                HasFixedSlotVTable(contextMethod.OwningType))
            {
                DictionaryLayoutNode dictionaryLayout;
                if (contextSource == GenericContextSource.MethodParameter)
                {
                    dictionaryLayout = _nodeFactory.GenericDictionaryLayout(contextMethod);
                }
                else
                {
                    dictionaryLayout = _nodeFactory.GenericDictionaryLayout(contextMethod.OwningType);
                }

                // If the dictionary layout has fixed slots, we can compute the lookup now. Otherwise defer to helper.
                if (dictionaryLayout.HasFixedSlots)
                {
                    int pointerSize = _nodeFactory.Target.PointerSize;

                    GenericLookupResult lookup = ReadyToRunGenericHelperNode.GetLookupSignature(_nodeFactory, lookupKind, targetOfLookup);
                    int dictionarySlot         = dictionaryLayout.GetSlotForFixedEntry(lookup);
                    if (dictionarySlot != -1)
                    {
                        int dictionaryOffset = dictionarySlot * pointerSize;

                        bool indirectLastOffset = lookup.LookupResultReferenceType(_nodeFactory) == GenericLookupResultReferenceType.Indirect;

                        if (contextSource == GenericContextSource.MethodParameter)
                        {
                            return(GenericDictionaryLookup.CreateFixedLookup(contextSource, dictionaryOffset, indirectLastOffset: indirectLastOffset));
                        }
                        else
                        {
                            int vtableSlot   = VirtualMethodSlotHelper.GetGenericDictionarySlot(_nodeFactory, contextMethod.OwningType);
                            int vtableOffset = EETypeNode.GetVTableOffset(pointerSize) + vtableSlot * pointerSize;
                            return(GenericDictionaryLookup.CreateFixedLookup(contextSource, vtableOffset, dictionaryOffset, indirectLastOffset: indirectLastOffset));
                        }
                    }
                }
            }

            // Fixed lookup not possible - use helper.
            return(GenericDictionaryLookup.CreateHelperLookup(contextSource, lookupKind, targetOfLookup));
        }