public EETypeNode(TypeDesc type) { Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Specific)); Debug.Assert(!type.IsRuntimeDeterminedSubtype); _type = type; _optionalFieldsNode = new EETypeOptionalFieldsNode(this); }
public EETypeNode(NodeFactory factory, TypeDesc type) { Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Specific)); Debug.Assert(!type.IsRuntimeDeterminedSubtype); _type = type; _optionalFieldsNode = new EETypeOptionalFieldsNode(this); // Note: The fact that you can't create invalid EETypeNode is used from many places that grab // an EETypeNode from the factory with the sole purpose of making sure the validation has run // and that the result of the positive validation is "cached" (by the presence of an EETypeNode). CheckCanGenerateEEType(factory, type); }
// Get the GC layout of a type. Handles pre-created, universal template, and non-universal template cases // Only to be used for getting the instance layout of non-valuetypes. /// <summary> /// Get the GC layout of a type. Handles pre-created, universal template, and non-universal template cases /// Only to be used for getting the instance layout of non-valuetypes that are used as base types /// </summary> /// <param name="type"></param> /// <returns></returns> private unsafe TypeBuilder.GCLayout GetInstanceGCLayout(TypeDesc type) { Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Any)); Debug.Assert(!type.IsValueType); if (type.RetrieveRuntimeTypeHandleIfPossible()) { return new TypeBuilder.GCLayout(type.RuntimeTypeHandle); } if (type.IsTemplateCanonical()) { var templateType = type.ComputeTemplate(); bool success = templateType.RetrieveRuntimeTypeHandleIfPossible(); Debug.Assert(success && !templateType.RuntimeTypeHandle.IsNull()); return new TypeBuilder.GCLayout(templateType.RuntimeTypeHandle); } else { TypeBuilderState state = type.GetOrCreateTypeBuilderState(); if (state.InstanceGCLayout == null) return TypeBuilder.GCLayout.None; else return new TypeBuilder.GCLayout(state.InstanceGCLayout, true); } }
private uint getClassAttribsInternal(TypeDesc type) { // TODO: Support for verification (CORINFO_FLG_GENERIC_TYPE_VARIABLE) CorInfoFlag result = (CorInfoFlag)0; // The array flag is used to identify the faked-up methods on // array types, i.e. .ctor, Get, Set and Address if (type.IsArray) result |= CorInfoFlag.CORINFO_FLG_ARRAY; if (type.IsInterface) result |= CorInfoFlag.CORINFO_FLG_INTERFACE; if (type.IsArray || type.IsString) result |= CorInfoFlag.CORINFO_FLG_VAROBJSIZE; if (type.IsValueType) { result |= CorInfoFlag.CORINFO_FLG_VALUECLASS; // TODO // if (type.IsUnsafeValueType) // result |= CorInfoFlag.CORINFO_FLG_UNSAFE_VALUECLASS; } if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) result |= CorInfoFlag.CORINFO_FLG_SHAREDINST; if (type.HasVariance) result |= CorInfoFlag.CORINFO_FLG_VARIANCE; if (type.IsDelegate) result |= CorInfoFlag.CORINFO_FLG_DELEGATE; var metadataType = type as MetadataType; if (metadataType != null) { if (metadataType.ContainsGCPointers) result |= CorInfoFlag.CORINFO_FLG_CONTAINS_GC_PTR; if (metadataType.IsBeforeFieldInit) result |= CorInfoFlag.CORINFO_FLG_BEFOREFIELDINIT; if (metadataType.IsSealed) result |= CorInfoFlag.CORINFO_FLG_FINAL; } return (uint)result; }
public EETypeNode(TypeDesc type) { Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Specific)); Debug.Assert(!type.IsRuntimeDeterminedSubtype); _type = type; }
public TypeGenericDictionaryNode(TypeDesc owningType) { Debug.Assert(!owningType.IsCanonicalSubtype(CanonicalFormKind.Any)); Debug.Assert(!owningType.IsRuntimeDeterminedSubtype); Debug.Assert(owningType.HasInstantiation); _owningType = owningType; }
public static TypeDesc ConvertToCanon(TypeDesc typeToConvert, ref CanonicalFormKind kind) { TypeSystemContext context = typeToConvert.Context; if (kind == CanonicalFormKind.Universal) { return context.UniversalCanonType; } else if (kind == CanonicalFormKind.Specific) { if (typeToConvert == context.UniversalCanonType) { kind = CanonicalFormKind.Universal; return context.UniversalCanonType; } else if (typeToConvert.IsSignatureVariable) { return typeToConvert; } else if (typeToConvert.IsDefType) { if (!typeToConvert.IsValueType) { return context.CanonType; } else if (typeToConvert.HasInstantiation) { TypeDesc canonicalType = typeToConvert.ConvertToCanonForm(CanonicalFormKind.Specific); // This is a generic struct type. If the generic struct is instantiated over universal canon, // the entire struct becomes universally canonical. if (canonicalType.IsCanonicalSubtype(CanonicalFormKind.Universal)) { kind = CanonicalFormKind.Universal; return context.UniversalCanonType; } return canonicalType; } else if (typeToConvert.IsRuntimeDeterminedType) { // For non-universal canon cases, RuntimeDeterminedType's passed into this function are either // reference types (which are turned into normal Canon), or instantiated types (which are handled // by the above case.). But for UniversalCanon, we can have non-instantiated universal canon // which will reach this case. // We should only ever reach this for T__UniversalCanon. Debug.Assert(((RuntimeDeterminedType)typeToConvert).CanonicalType == context.UniversalCanonType); kind = CanonicalFormKind.Universal; return context.UniversalCanonType; } else { return typeToConvert; } } else if (typeToConvert.IsArray) { return context.CanonType; } else { if (typeToConvert.IsCanonicalSubtype(CanonicalFormKind.Universal)) { kind = CanonicalFormKind.Universal; return context.UniversalCanonType; } return typeToConvert.ConvertToCanonForm(CanonicalFormKind.Specific); } } else { Debug.Assert(false); return null; } }
private static TypeDesc ConvertToCanon(TypeDesc typeToConvert, ref CanonicalFormKind kind) { TypeSystemContext context = typeToConvert.Context; if (kind == CanonicalFormKind.Universal) { return(context.UniversalCanonType); } else if (kind == CanonicalFormKind.Specific) { if (typeToConvert == context.UniversalCanonType) { kind = CanonicalFormKind.Universal; return(context.UniversalCanonType); } else if (typeToConvert.IsSignatureVariable) { return(typeToConvert); } else if (typeToConvert.IsDefType) { if (!typeToConvert.IsValueType) { return(context.CanonType); } else if (typeToConvert.HasInstantiation) { TypeDesc convertedType = typeToConvert.ConvertToCanonForm(CanonicalFormKind.Specific); if (convertedType.IsCanonicalSubtype(CanonicalFormKind.Universal)) { kind = CanonicalFormKind.Universal; return(context.UniversalCanonType); } return(convertedType); } else { return(typeToConvert); } } else if (typeToConvert.IsArray) { return(context.CanonType); } else { TypeDesc convertedType = typeToConvert.ConvertToCanonForm(CanonicalFormKind.Specific); if (convertedType.IsCanonicalSubtype(CanonicalFormKind.Universal)) { kind = CanonicalFormKind.Universal; return(context.UniversalCanonType); } return(convertedType); } } else { Debug.Assert(false); return(null); } }
public static TypeDesc ConvertToCanon(TypeDesc typeToConvert, ref CanonicalFormKind kind) { TypeSystemContext context = typeToConvert.Context; if (kind == CanonicalFormKind.Universal) { return(context.UniversalCanonType); } else if (kind == CanonicalFormKind.Specific) { if (typeToConvert == context.UniversalCanonType) { kind = CanonicalFormKind.Universal; return(context.UniversalCanonType); } else if (typeToConvert.IsSignatureVariable) { return(typeToConvert); } else if (typeToConvert.IsDefType) { if (!typeToConvert.IsValueType) { return(context.CanonType); } else if (typeToConvert.HasInstantiation) { TypeDesc canonicalType = typeToConvert.ConvertToCanonForm(CanonicalFormKind.Specific); // This is a generic struct type. If the generic struct is instantiated over universal canon, // the entire struct becomes universally canonical. if (canonicalType.IsCanonicalSubtype(CanonicalFormKind.Universal)) { kind = CanonicalFormKind.Universal; return(context.UniversalCanonType); } return(canonicalType); } else if (typeToConvert.IsRuntimeDeterminedType) { // For non-universal canon cases, RuntimeDeterminedType's passed into this function are either // reference types (which are turned into normal Canon), or instantiated types (which are handled // by the above case.). But for UniversalCanon, we can have non-instantiated universal canon // which will reach this case. // We should only ever reach this for T__UniversalCanon. Debug.Assert(((RuntimeDeterminedType)typeToConvert).CanonicalType == context.UniversalCanonType); kind = CanonicalFormKind.Universal; return(context.UniversalCanonType); } else { return(typeToConvert); } } else if (typeToConvert.IsArray) { return(context.CanonType); } else { if (typeToConvert.IsCanonicalSubtype(CanonicalFormKind.Universal)) { kind = CanonicalFormKind.Universal; return(context.UniversalCanonType); } return(typeToConvert.ConvertToCanonForm(CanonicalFormKind.Specific)); } } else { Debug.Assert(false); return(null); } }
internal void GetFieldSizeAlignment(TypeDesc fieldType, out int size, out int alignment) { Debug.Assert(!fieldType.IsCanonicalSubtype(CanonicalFormKind.Any)); // All reference and array types are pointer-sized if (!fieldType.IsValueType) { size = IntPtr.Size; alignment = IntPtr.Size; return; } // Is this a type that already exists? If so, get its size from the EEType directly if (fieldType.RetrieveRuntimeTypeHandleIfPossible()) { unsafe { EEType* eeType = fieldType.RuntimeTypeHandle.ToEETypePtr(); size = (int)eeType->ValueTypeSize; alignment = eeType->FieldAlignmentRequirement; return; } } // The type of the field must be a generic valuetype that is dynamically being constructed Debug.Assert(fieldType.IsValueType); DefType fieldDefType = (DefType)fieldType; TypeBuilderState state = fieldType.GetOrCreateTypeBuilderState(); size = fieldDefType.InstanceFieldSize; alignment = fieldDefType.InstanceFieldAlignment; }