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)); } }
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); } }
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()); }