Beispiel #1
0
        private void OutputGenericInstantiationDetails(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            if (_type.HasInstantiation && !_type.IsTypeDefinition)
            {
                objData.EmitPointerRelocOrIndirectionReference(factory.NecessaryTypeSymbol(_type.GetTypeDefinition()));

                GenericCompositionDetails details;
                if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType)
                {
                    // Generic array enumerators use special variance rules recognized by the runtime
                    details = new GenericCompositionDetails(_type.Instantiation, new[] { GenericVariance.ArrayCovariant });
                }
                else if (factory.TypeSystemContext.IsGenericArrayInterfaceType(_type))
                {
                    // Runtime casting logic relies on all interface types implemented on arrays
                    // to have the variant flag set (even if all the arguments are non-variant).
                    // This supports e.g. casting uint[] to ICollection<int>
                    details = new GenericCompositionDetails(_type, forceVarianceInfo: true);
                }
                else
                {
                    details = new GenericCompositionDetails(_type);
                }

                objData.EmitPointerReloc(factory.GenericComposition(details));
            }
        }
Beispiel #2
0
        protected virtual void OutputInterfaceMap(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            Debug.Assert(EmitVirtualSlotsAndInterfaces);

            foreach (var itf in _type.RuntimeInterfaces)
            {
                objData.EmitPointerRelocOrIndirectionReference(GetInterfaceTypeNode(factory, itf));
            }
        }
        public virtual void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation, GenericDictionaryNode dictionary)
        {
            ISymbolNode target = GetTarget(factory, typeInstantiation, methodInstantiation, dictionary);

            if (LookupResultReferenceType(factory) == GenericLookupResultReferenceType.ConditionalIndirect)
            {
                builder.EmitPointerRelocOrIndirectionReference(target);
            }
            else
            {
                builder.EmitPointerReloc(target);
            }
        }
Beispiel #4
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            bool hasVariance = _details.Variance != null;

            var builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.AddSymbol(this);

            builder.RequireInitialPointerAlignment();

            builder.EmitShort((short)checked ((UInt16)_details.Instantiation.Length));

            builder.EmitByte((byte)(hasVariance ? 1 : 0));

            // TODO: general purpose padding
            builder.EmitByte(0);
            if (factory.Target.PointerSize == 8)
            {
                builder.EmitInt(0);
            }

            foreach (var typeArg in _details.Instantiation)
            {
                builder.EmitPointerRelocOrIndirectionReference(factory.NecessaryTypeSymbol(typeArg));
            }

            if (hasVariance)
            {
                foreach (var argVariance in _details.Variance)
                {
                    builder.EmitByte(checked ((byte)argVariance));
                }
            }

            return(builder.ToObjectData());
        }