protected override Instantiation ConvertInstantiationToCanonForm(Instantiation instantiation, CanonicalFormKind kind, out bool changed) { if (CanonMode == CanonicalizationMode.Standard) return StandardCanonicalizationAlgorithm.ConvertInstantiationToCanonForm(instantiation, kind, out changed); else return RuntimeDeterminedCanonicalizationAlgorithm.ConvertInstantiationToCanonForm(instantiation, kind, out changed); }
/// <summary> /// Returns a new instantiation that canonicalizes all types in <paramref name="instantiation"/> /// if possible under the policy of '<paramref name="kind"/>' /// </summary> /// <param name="changed">True if the returned instantiation is different from '<paramref name="instantiation"/>'.</param> public static Instantiation ConvertInstantiationToCanonForm(Instantiation instantiation, CanonicalFormKind kind, out bool changed) { TypeDesc[] newInstantiation = null; for (int i = 0; i < instantiation.Length; i++) { TypeDesc typeToConvert = instantiation[i]; TypeDesc convertedType = ConvertToCanon(typeToConvert, kind); if (typeToConvert != convertedType || newInstantiation != null) { if (newInstantiation == null) { newInstantiation = new TypeDesc[instantiation.Length]; for (int j = 0; j < i; j++) newInstantiation[j] = instantiation[j]; } newInstantiation[i] = convertedType; } } changed = newInstantiation != null; if (changed) { return new Instantiation(newInstantiation); } return instantiation; }
public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind) { TypeDesc canonicalizedTypeOfTargetMethod = OwningType.ConvertToCanonForm(kind); if (canonicalizedTypeOfTargetMethod == OwningType) return this; return Context.GetMethodForInstantiatedType(GetTypicalMethodDefinition(), (InstantiatedType)canonicalizedTypeOfTargetMethod); }
public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind) { TypeDesc canonicalizedTypeOfTargetMethod = _owningType.ConvertToCanonForm(kind); if (canonicalizedTypeOfTargetMethod == _owningType) return this; return ((ArrayType)canonicalizedTypeOfTargetMethod).GetArrayMethod(_kind); }
protected override TypeDesc ConvertToCanonFormImpl(CanonicalFormKind kind) { TypeDesc paramTypeConverted = CanonUtilites.ConvertToCanon(ParameterType, kind); if (paramTypeConverted != ParameterType) return Context.GetPointerType(paramTypeConverted); return this; }
internal CanonicallyEquivalentEntryLocator(DefType typeToFind, CanonicalFormKind kind) { _genericArgs = null; _genericDefinition = default(RuntimeTypeHandle); _typeToFind = default(RuntimeTypeHandle); _canonKind = kind; _defType = typeToFind; }
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 bool TryGetMethodInvokeMetadata( MetadataReader metadataReader, RuntimeTypeHandle declaringTypeHandle, MethodHandle methodHandle, RuntimeTypeHandle[] genericMethodTypeArgumentHandles, ref MethodSignatureComparer methodSignatureComparer, CanonicalFormKind canonFormKind, out MethodInvokeMetadata methodInvokeMetadata) { throw new NotImplementedException(); }
public override bool IsCanonicalSubtype(CanonicalFormKind policy) { if (_signature.ReturnType.IsCanonicalSubtype(policy)) return true; for (int i = 0; i < _signature.Length; i++) if (_signature[i].IsCanonicalSubtype(policy)) return true; return false; }
/// <summary> /// Returns the canonical form of this type /// </summary> public TypeDesc ConvertToCanonForm(CanonicalFormKind kind) { TypeDesc canonForm = GetCachedCanonValue(kind); if (canonForm == null) { canonForm = ConvertToCanonFormImpl(kind); SetCachedCanonValue(kind, canonForm); } return canonForm; }
public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind) { if (!OwningType.HasInstantiation) return this; DefType canonicalizedTypeOfTargetMethod = (DefType)OwningType.ConvertToCanonForm(kind); if (canonicalizedTypeOfTargetMethod == OwningType) return this; return Context.ResolveRuntimeMethod(this.UnboxingStub, canonicalizedTypeOfTargetMethod, this.NameAndSignature, IntPtr.Zero, false); }
protected override TypeDesc ConvertToCanonFormImpl(CanonicalFormKind kind) { bool needsChange; Instantiation canonInstantiation = CanonUtilites.ConvertInstantiationToCanonForm(Instantiation, kind, out needsChange); if (needsChange) { MetadataType openType = (MetadataType)GetTypeDefinition(); return Context.GetInstantiatedType(openType, canonInstantiation); } return this; }
public override bool IsCanonicalSubtype(CanonicalFormKind policy) { foreach (TypeDesc t in Instantiation) { if (t.IsCanonicalSubtype(policy)) { return true; } } return false; }
protected override TypeDesc ConvertToCanonFormImpl(CanonicalFormKind kind) { TypeDesc paramTypeConverted = Context.ConvertToCanon(ParameterType, kind); if (paramTypeConverted != ParameterType) { // Note: don't use the Rank property here, as that hides the difference // between a single dimensional MD array and an SZArray. return Context.GetArrayType(paramTypeConverted, _rank); } return this; }
protected override TypeDesc ConvertToCanonFormImpl(CanonicalFormKind kind) { MethodSignatureBuilder sigBuilder = new MethodSignatureBuilder(_signature); sigBuilder.ReturnType = Context.ConvertToCanon(_signature.ReturnType, kind); for (int i = 0; i < _signature.Length; i++) sigBuilder[i] = Context.ConvertToCanon(_signature[i], kind); MethodSignature canonSignature = sigBuilder.ToSignature(); if (canonSignature != _signature) return Context.GetFunctionPointerType(canonSignature); return this; }
InstantiatedMethod GetCachedCanonValue(CanonicalFormKind kind) { switch (kind) { case CanonicalFormKind.Specific: return(_specificCanonCache); case CanonicalFormKind.Universal: return(_universalCanonCache); default: Debug.Fail("Invalid CanonicalFormKind: " + kind); return(null); } }
InstantiatedMethod GetCachedCanonValue(CanonicalFormKind kind) { switch (kind) { case CanonicalFormKind.Specific: return _specificCanonCache; case CanonicalFormKind.Universal: return _universalCanonCache; default: Debug.Fail("Invalid CanonicalFormKind: " + kind); return null; } }
/// <summary> /// Helper API to convert a type to its canonical or universal canonical form. /// Note that for now, there is no mixture between specific canonical and universal canonical forms, /// meaning that the canonical form or Foo<string, int> can either be Foo<__Canon, int> or /// Foo<__UniversalCanon, __UniversalCanon>. It cannot be Foo<__Canon, __UniversalCanon> (yet) /// for simplicity. We can always change that rule in the futue and add support for the mixture, but /// for now we are keeping it simple. /// </summary> public static TypeDesc ConvertToCanon(TypeDesc typeToConvert, CanonicalFormKind kind) { TypeSystemContext context = typeToConvert.Context; if (kind == CanonicalFormKind.Universal) { return(context.UniversalCanonType); } else if (kind == CanonicalFormKind.Specific) { if (typeToConvert == context.UniversalCanonType) { return(context.UniversalCanonType); } else if (typeToConvert.IsSignatureVariable) { return(typeToConvert); } else if (typeToConvert.IsDefType) { if (!typeToConvert.IsValueType) { return(context.CanonType); } else if (typeToConvert.HasInstantiation) { return(typeToConvert.ConvertToCanonForm(CanonicalFormKind.Specific)); } else { return(typeToConvert); } } else if (typeToConvert.IsArray) { return(context.CanonType); } else { return(typeToConvert.ConvertToCanonForm(CanonicalFormKind.Specific)); } } else { Debug.Assert(false); return(null); } }
public static Instantiation ConvertInstantiationToCanonForm(Instantiation instantiation, CanonicalFormKind kind, out bool changed) { TypeDesc[] canonInstantiation = null; CanonicalFormKind currentKind = kind; CanonicalFormKind startLoopKind; // This logic is wrapped in a loop because we might potentially need to restart canonicalization if the policy // changes due to one of the instantiation arguments already being universally canonical. do { startLoopKind = currentKind; for (int instantiationIndex = 0; instantiationIndex < instantiation.Length; instantiationIndex++) { TypeDesc typeToConvert = instantiation[instantiationIndex]; TypeDesc canonForm = ConvertToCanon(typeToConvert, ref currentKind); if (typeToConvert != canonForm || canonInstantiation != null) { if (canonInstantiation == null) { canonInstantiation = new TypeDesc[instantiation.Length]; for (int i = 0; i < instantiationIndex; i++) canonInstantiation[i] = instantiation[i]; } canonInstantiation[instantiationIndex] = canonForm; } } // Optimization: even if canonical policy changed, we don't actually need to re-run the loop // for instantiations that only have a single element. if (instantiation.Length == 1) { break; } } while (currentKind != startLoopKind); changed = canonInstantiation != null; if (changed) { return new Instantiation(canonInstantiation); } return instantiation; }
public CanonicallyEquivalentEntryLocator(RuntimeTypeHandle typeToFind, CanonicalFormKind kind) { if (RuntimeAugments.IsGenericType(typeToFind)) { _genericDefinition = RuntimeAugments.GetGenericInstantiation(typeToFind, out _genericArgs); } else { _genericArgs = null; _genericDefinition = default(RuntimeTypeHandle); } _typeToFind = typeToFind; _canonKind = kind; _defType = null; }
/// <summary> /// Returns true if and only if the '<paramref name="type"/>' is __Canon or __UniversalCanon /// that matches the <paramref name="kind"/> parameter. /// </summary> public bool IsCanonicalDefinitionType(TypeDesc type, CanonicalFormKind kind) { if (kind == CanonicalFormKind.Any) { return type == CanonType || type == UniversalCanonType; } else if (kind == CanonicalFormKind.Specific) { return type == CanonType; } else { Debug.Assert(kind == CanonicalFormKind.Universal); return type == UniversalCanonType; } }
/// <summary> /// Returns true if and only if the '<paramref name="type"/>' is __Canon or __UniversalCanon /// that matches the <paramref name="kind"/> parameter. /// </summary> public bool IsCanonicalDefinitionType(TypeDesc type, CanonicalFormKind kind) { if (kind == CanonicalFormKind.Any) { return(type == CanonType || type == UniversalCanonType); } else if (kind == CanonicalFormKind.Specific) { return(type == CanonType); } else { Debug.Assert(kind == CanonicalFormKind.Universal); return(type == UniversalCanonType); } }
public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind) { if (!OwningType.HasInstantiation) { return(this); } DefType canonicalizedTypeOfTargetMethod = (DefType)OwningType.ConvertToCanonForm(kind); if (canonicalizedTypeOfTargetMethod == OwningType) { return(this); } return(Context.ResolveRuntimeMethod(this.UnboxingStub, canonicalizedTypeOfTargetMethod, this.NameAndSignature, IntPtr.Zero, false)); }
/// <summary> /// True if either the containing type instantiation or any of this method's generic arguments /// are canonical /// </summary> public override bool IsCanonicalMethod(CanonicalFormKind policy) { if (OwningType.HasInstantiation && OwningType.IsCanonicalSubtype(policy)) { return(true); } foreach (TypeDesc type in Instantiation) { if (type.IsCanonicalSubtype(policy)) { return(true); } } return(false); }
public override bool IsCanonicalSubtype(CanonicalFormKind policy) { if (_signature.ReturnType.IsCanonicalSubtype(policy)) { return(true); } for (int i = 0; i < _signature.Length; i++) { if (_signature[i].IsCanonicalSubtype(policy)) { return(true); } } return(false); }
/// <summary> /// True if either the containing type instantiation or any of this method's generic arguments /// are canonical /// </summary> public override bool IsCanonicalMethod(CanonicalFormKind policy) { if (OwningType.HasInstantiation && OwningType.IsCanonicalSubtype(policy)) { return true; } foreach (TypeDesc type in Instantiation) { if (type.IsCanonicalSubtype(policy)) { return true; } } return false; }
void SetCachedCanonValue(CanonicalFormKind kind, TypeDesc value) { switch (kind) { case CanonicalFormKind.Specific: Debug.Assert(_specificCanonCache == null || _specificCanonCache == value); _specificCanonCache = value; break; case CanonicalFormKind.Universal: Debug.Assert(_universalCanonCache == null || _universalCanonCache == value); _universalCanonCache = value; break; default: Debug.Fail("Invalid CanonicalFormKind: " + kind); break; } }
protected override TypeDesc ConvertToCanonFormImpl(CanonicalFormKind kind) { MethodSignatureBuilder sigBuilder = new MethodSignatureBuilder(_signature); sigBuilder.ReturnType = Context.ConvertToCanon(_signature.ReturnType, kind); for (int i = 0; i < _signature.Length; i++) { sigBuilder[i] = Context.ConvertToCanon(_signature[i], kind); } MethodSignature canonSignature = sigBuilder.ToSignature(); if (canonSignature != _signature) { return(Context.GetFunctionPointerType(canonSignature)); } return(this); }
/// <summary> /// Returns the result of canonicalizing this method over the given kind of Canon /// </summary> public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind) { InstantiatedMethod canonicalMethodResult = GetCachedCanonValue(kind); if (canonicalMethodResult != null) { return(canonicalMethodResult); } MethodDesc openMethodOnCanonicalizedType = _methodDef.GetCanonMethodTarget(kind); // TODO: We should avoid the array allocation if conversion to canon is not change (take hint from MethodDesc.InstantiateSignature) Instantiation newInstantiation = CanonUtilites.ConvertInstantiationToCanonForm(Context, Instantiation, kind); canonicalMethodResult = Context.GetInstantiatedMethod(openMethodOnCanonicalizedType, newInstantiation); SetCachedCanonValue(kind, canonicalMethodResult); return(GetCachedCanonValue(kind)); }
void SetCachedCanonValue(CanonicalFormKind kind, InstantiatedMethod value) { switch(kind) { case CanonicalFormKind.Specific: Debug.Assert(_specificCanonCache == null || _specificCanonCache == value); _specificCanonCache = value; break; case CanonicalFormKind.Universal: Debug.Assert(_universalCanonCache == null || _universalCanonCache == value); _universalCanonCache = value; break; default: Debug.Fail("Invalid CanonicalFormKind: " + kind); break; } }
/// <summary> /// Returns the result of canonicalizing this method over the given kind of Canon /// </summary> public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind) { InstantiatedMethod canonicalMethodResult = GetCachedCanonValue(kind); if (canonicalMethodResult == null) { bool needsChange; Instantiation canonInstantiation = CanonUtilites.ConvertInstantiationToCanonForm(Instantiation, kind, out needsChange); if (needsChange) { MethodDesc openMethodOnCanonicalizedType = _methodDef.GetCanonMethodTarget(kind); canonicalMethodResult = Context.GetInstantiatedMethod(openMethodOnCanonicalizedType, canonInstantiation); } else { canonicalMethodResult = this; } SetCachedCanonValue(kind, canonicalMethodResult); } return canonicalMethodResult; }
/// <summary> /// Returns the result of canonicalizing this method over the given kind of Canon /// </summary> public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind) { InstantiatedMethod canonicalMethodResult = GetCachedCanonValue(kind); if (canonicalMethodResult == null) { bool instantiationChanged; Instantiation canonInstantiation = Context.ConvertInstantiationToCanonForm(Instantiation, kind, out instantiationChanged); MethodDesc openMethodOnCanonicalizedType = _methodDef.GetCanonMethodTarget(kind); if (instantiationChanged || (openMethodOnCanonicalizedType != _methodDef)) { canonicalMethodResult = Context.GetInstantiatedMethod(openMethodOnCanonicalizedType, canonInstantiation); } else { canonicalMethodResult = this; } SetCachedCanonValue(kind, canonicalMethodResult); } return canonicalMethodResult; }
/// <summary> /// Returns the result of canonicalizing this method over the given kind of Canon /// </summary> public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind) { InstantiatedMethod canonicalMethodResult = GetCachedCanonValue(kind); if (canonicalMethodResult == null) { bool needsChange; Instantiation canonInstantiation = CanonUtilites.ConvertInstantiationToCanonForm(Instantiation, kind, out needsChange); if (needsChange) { MethodDesc openMethodOnCanonicalizedType = _methodDef.GetCanonMethodTarget(kind); canonicalMethodResult = Context.GetInstantiatedMethod(openMethodOnCanonicalizedType, canonInstantiation); } else { canonicalMethodResult = this; } SetCachedCanonValue(kind, canonicalMethodResult); } return(canonicalMethodResult); }
/// <summary> /// Helper API to convert a type to its canonical or universal canonical form. /// Note that for now, there is no mixture between specific canonical and universal canonical forms, /// meaning that the canonical form or Foo<string, int> can either be Foo<__Canon, int> or /// Foo<__UniversalCanon, __UniversalCanon>. It cannot be Foo<__Canon, __UniversalCanon> (yet) /// for simplicity. We can always change that rule in the futue and add support for the mixture, but /// for now we are keeping it simple. /// </summary> public static TypeDesc ConvertToCanon(TypeDesc typeToConvert, CanonicalFormKind kind) { TypeSystemContext context = typeToConvert.Context; if (kind == CanonicalFormKind.Universal) { return context.UniversalCanonType; } else if (kind == CanonicalFormKind.Specific) { if (typeToConvert == context.UniversalCanonType) { return context.UniversalCanonType; } else if (typeToConvert.IsDefType) { if (!typeToConvert.IsValueType) return context.CanonType; else if (typeToConvert.HasInstantiation) return typeToConvert.ConvertToCanonForm(CanonicalFormKind.Specific); else return typeToConvert; } else if (typeToConvert.IsArray) { return context.CanonType; } else { return typeToConvert.ConvertToCanonForm(CanonicalFormKind.Specific); } } else { Debug.Assert(false); return null; } }
/// <summary> /// Returns the result of canonicalizing this method over the given kind of Canon /// </summary> public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind) { InstantiatedMethod canonicalMethodResult = GetCachedCanonValue(kind); if (canonicalMethodResult == null) { bool instantiationChanged; Instantiation canonInstantiation = Context.ConvertInstantiationToCanonForm(Instantiation, kind, out instantiationChanged); MethodDesc openMethodOnCanonicalizedType = _methodDef.GetCanonMethodTarget(kind); if (instantiationChanged || (openMethodOnCanonicalizedType != _methodDef)) { canonicalMethodResult = Context.GetInstantiatedMethod(openMethodOnCanonicalizedType, canonInstantiation); } else { canonicalMethodResult = this; } SetCachedCanonValue(kind, canonicalMethodResult); } return(canonicalMethodResult); }
public override bool IsCanonicalMethod(CanonicalFormKind policy) { return _owningType.IsCanonicalSubtype(policy); }
/// <summary> /// Returns a new instantiation that canonicalizes all types in <paramref name="instantiation"/> /// if possible under the policy of '<paramref name="kind"/>' /// </summary> /// <param name="instantiation">Instantiation to canonicalize.</param> /// <param name="kind">The type of cannonicalization to apply.</param> /// <param name="changed">True if the returned instantiation is different from '<paramref name="instantiation"/>'.</param> public static Instantiation ConvertInstantiationToCanonForm(Instantiation instantiation, CanonicalFormKind kind, out bool changed) { TypeDesc[] canonInstantiation = null; CanonicalFormKind currentKind = kind; CanonicalFormKind startLoopKind; // This logic is wrapped in a loop because we might potentially need to restart canonicalization if the policy // changes due to one of the instantiation arguments already being universally canonical. do { startLoopKind = currentKind; for (int instantiationIndex = 0; instantiationIndex < instantiation.Length; instantiationIndex++) { TypeDesc typeToConvert = instantiation[instantiationIndex]; TypeDesc canonForm = ConvertToCanon(typeToConvert, ref currentKind); if (typeToConvert != canonForm || canonInstantiation != null) { if (canonInstantiation == null) { canonInstantiation = new TypeDesc[instantiation.Length]; for (int i = 0; i < instantiationIndex; i++) { canonInstantiation[i] = instantiation[i]; } } canonInstantiation[instantiationIndex] = canonForm; } } // Optimization: even if canonical policy changed, we don't actually need to re-run the loop // for instantiations that only have a single element. if (instantiation.Length == 1) { break; } } while (currentKind != startLoopKind); changed = canonInstantiation != null; if (changed) { return(new Instantiation(canonInstantiation)); } return(instantiation); }
// Helper API to convert a type to its canonical or universal canonical form. // Note that for now, there is no mixture between specific canonical and universal canonical forms, // meaning that the canonical form or Foo<string, int> can either be Foo<__Canon, int> or // Foo<__UniversalCanon, __UniversalCanon>. It cannot be Foo<__Canon, __UniversalCanon> (yet) // for simplicity. We can always change that rule in the futue and add support for the mixture, but // for now we are keeping it simple. public static TypeDesc ConvertToCanon(TypeDesc typeToConvert, CanonicalFormKind kind) { // Wrap the call to the version that potentially modifies the parameter. External // callers are not interested in that. return(ConvertToCanon(typeToConvert, ref kind)); }
protected override TypeDesc ConvertToCanonFormImpl(CanonicalFormKind kind) { Debug.Assert(kind == CanonicalFormKind.Universal); return this; }
/// <summary> /// Returns a new instantiation that canonicalizes all types in <paramref name="instantiation"/> /// if possible under the policy of '<paramref name="kind"/>' /// </summary> /// <param name="changed">True if the returned instantiation is different from '<paramref name="instantiation"/>'.</param> public static Instantiation ConvertInstantiationToCanonForm(Instantiation instantiation, CanonicalFormKind kind, out bool changed) { TypeDesc[] newInstantiation = null; for (int i = 0; i < instantiation.Length; i++) { TypeDesc typeToConvert = instantiation[i]; TypeDesc convertedType = ConvertToCanon(typeToConvert, kind); if (typeToConvert != convertedType || newInstantiation != null) { if (newInstantiation == null) { newInstantiation = new TypeDesc[instantiation.Length]; for (int j = 0; j < i; j++) { newInstantiation[j] = instantiation[j]; } } newInstantiation[i] = convertedType; } } changed = newInstantiation != null; if (changed) { return(new Instantiation(newInstantiation)); } return(instantiation); }
public override bool IsCanonicalSubtype(CanonicalFormKind policy) { Debug.Assert(!HasInstantiation, "Why is this generic?"); return(false); }
protected override Instantiation ConvertInstantiationToCanonForm(Instantiation instantiation, CanonicalFormKind kind, out bool changed) { if (_genericsMode == SharedGenericsMode.CanonicalReferenceTypes) { return(RuntimeDeterminedCanonicalizationAlgorithm.ConvertInstantiationToCanonForm(instantiation, kind, out changed)); } Debug.Assert(_genericsMode == SharedGenericsMode.Disabled); changed = false; return(instantiation); }
public sealed override bool IsCanonicalSubtype(CanonicalFormKind policy) { Debug.Assert(false, "IsCanonicalSubtype of an indefinite type"); return(false); }
protected sealed override TypeDesc ConvertToCanonFormImpl(CanonicalFormKind kind) { Debug.Assert(false, "ConvertToCanonFormImpl for an indefinite type"); return(this); }
/// <summary> /// Converts an instantiation into its canonical form. Returns the canonical instantiation. The '<paramref name="changed"/>' /// parameter indicates whether the returned canonical instantiation is different from the specific instantiation /// passed as the input. /// </summary> protected internal virtual Instantiation ConvertInstantiationToCanonForm(Instantiation instantiation, CanonicalFormKind kind, out bool changed) { throw new NotSupportedException(); }
public CanonicallyEquivalentEntryLocator(RuntimeTypeHandle typeToFind, CanonicalFormKind kind) { _typeToFind = typeToFind; }
/// <summary> /// Returns a new instantiation that canonicalizes all types in <paramref name="instantiation"/> /// if possible under the policy of <paramref name="kind"/> /// </summary> public static Instantiation ConvertInstantiationToCanonForm(TypeSystemContext context, Instantiation instantiation, CanonicalFormKind kind) { TypeDesc[] newInstantiation = new TypeDesc[instantiation.Length]; for (int i = 0; i < instantiation.Length; i++) { newInstantiation[i] = ConvertToCanon(instantiation[i], kind); } return(new Instantiation(newInstantiation)); }
/// <summary> /// Returns true if canonicalizing this instantiation produces a different instantiation /// </summary> /// <param name="kind">Canonicalization policy to apply</param> public static bool ConversionToCanonFormIsAChange(TypeSystemContext context, Instantiation instantiation, CanonicalFormKind kind) { foreach (TypeDesc type in instantiation) { TypeDesc potentialCanonType = ConvertToCanon(type, kind); if (type != potentialCanonType) { return(true); } } return(false); }
/// <summary> /// Converts an instantiation into its canonical form. /// </summary> public Instantiation ConvertInstantiationToCanonForm(Instantiation instantiation, CanonicalFormKind kind) { bool changed; return(ConvertInstantiationToCanonForm(instantiation, kind, out changed)); }
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) { // This is a generic struct type. If the generic struct is instantiated over universal canon, // the entire struct becomes universally canonical. if (typeToConvert.IsCanonicalSubtype(CanonicalFormKind.Universal)) { kind = CanonicalFormKind.Universal; return(context.UniversalCanonType); } TypeDesc canonicalType = typeToConvert.ConvertToCanonForm(CanonicalFormKind.Specific); // We could still have ended up with a universal canonical form here because conversion to // canon form strips runtime determined types from their constituents. // MyStruct<T__UniversalCanon> (which is not universally canonical) becomes MyStruct<__UniversalCanon>. 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); } }
protected override TypeDesc ConvertToCanonFormImpl(CanonicalFormKind kind) { Debug.Assert(false, "ConvertToCanonFormImpl for an indefinite type"); return this; }
/// <summary> /// Try to look up field acccess info for given canon in metadata blobs for all available modules. /// </summary> /// <param name="metadataReader">Metadata reader for the declaring type</param> /// <param name="declaringTypeHandle">Declaring type for the method</param> /// <param name="fieldHandle">Field handle</param> /// <param name="canonFormKind">Canonical form to use</param> /// <param name="fieldAccessMetadata">Output - metadata information for field accessor construction</param> /// <returns>true when found, false otherwise</returns> private static bool TryGetFieldAccessMetadataFromFieldAccessMap( MetadataReader metadataReader, RuntimeTypeHandle declaringTypeHandle, FieldHandle fieldHandle, CanonicalFormKind canonFormKind, ref FieldAccessMetadata fieldAccessMetadata) { CanonicallyEquivalentEntryLocator canonWrapper = new CanonicallyEquivalentEntryLocator(declaringTypeHandle, canonFormKind); IntPtr fieldHandleModule = ModuleList.Instance.GetModuleForMetadataReader(metadataReader); bool isDynamicType = RuntimeAugments.IsDynamicType(declaringTypeHandle); string fieldName = null; RuntimeTypeHandle declaringTypeHandleDefinition = Instance.GetTypeDefinition(declaringTypeHandle); foreach (IntPtr mappingTableModule in ModuleList.Enumerate(RuntimeAugments.GetModuleFromTypeHandle(declaringTypeHandle))) { NativeReader fieldMapReader; if (!TryGetNativeReaderForBlob(mappingTableModule, ReflectionMapBlob.FieldAccessMap, out fieldMapReader)) { continue; } NativeParser fieldMapParser = new NativeParser(fieldMapReader, 0); NativeHashtable fieldHashtable = new NativeHashtable(fieldMapParser); ExternalReferencesTable externalReferences = default(ExternalReferencesTable); if (!externalReferences.InitializeCommonFixupsTable(mappingTableModule)) { continue; } var lookup = fieldHashtable.Lookup(canonWrapper.LookupHashCode); NativeParser entryParser; while (!(entryParser = lookup.GetNext()).IsNull) { // Grammar of a hash table entry: // Flags + DeclaringType + MdHandle or Name + Cookie or Ordinal or Offset FieldTableFlags entryFlags = (FieldTableFlags)entryParser.GetUnsigned(); if ((canonFormKind == CanonicalFormKind.Universal) != entryFlags.HasFlag(FieldTableFlags.IsUniversalCanonicalEntry)) { continue; } RuntimeTypeHandle entryDeclaringTypeHandle = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); if (!entryDeclaringTypeHandle.Equals(declaringTypeHandle) && !canonWrapper.IsCanonicallyEquivalent(entryDeclaringTypeHandle)) { continue; } if (entryFlags.HasFlag(FieldTableFlags.HasMetadataHandle)) { Handle entryFieldHandle = (((int)HandleType.Field << 24) | (int)entryParser.GetUnsigned()).AsHandle(); if (!fieldHandle.Equals(entryFieldHandle)) { continue; } } else { if (fieldName == null) { MetadataReader mdReader; TypeDefinitionHandle typeDefHandleUnused; bool success = Instance.TryGetMetadataForNamedType( declaringTypeHandleDefinition, out mdReader, out typeDefHandleUnused); Debug.Assert(success); fieldName = mdReader.GetString(fieldHandle.GetField(mdReader).Name); } string entryFieldName = entryParser.GetString(); if (fieldName != entryFieldName) { continue; } } int cookieOrOffsetOrOrdinal = (int)entryParser.GetUnsigned(); int fieldOffset; IntPtr fieldAddressCookie = IntPtr.Zero; if (canonFormKind == CanonicalFormKind.Universal) { if (!TypeLoaderEnvironment.Instance.TryGetFieldOffset(declaringTypeHandle, (uint)cookieOrOffsetOrOrdinal, out fieldOffset)) { Debug.Assert(false); return(false); } } else { #if CORERT fieldOffset = cookieOrOffsetOrOrdinal; #else fieldOffset = (int)externalReferences.GetRvaFromIndex((uint)cookieOrOffsetOrOrdinal); #endif } if ((entryFlags & FieldTableFlags.StorageClass) == FieldTableFlags.ThreadStatic) { if (canonFormKind != CanonicalFormKind.Universal) { fieldAddressCookie = RvaToNonGenericStaticFieldAddress(mappingTableModule, fieldOffset); } if (!entryDeclaringTypeHandle.Equals(declaringTypeHandle)) { // In this case we didn't find an exact match, but we did find a canonically equivalent match // We might be in the dynamic type case, or the canonically equivalent, but not the same case. if (!RuntimeAugments.IsDynamicType(declaringTypeHandle)) { int offsetToCreateCookieFor = fieldOffset; // We're working with a statically generated type, but we didn't find an exact match in the tables if (canonFormKind != CanonicalFormKind.Universal) { offsetToCreateCookieFor = checked ((int)TypeLoaderEnvironment.GetThreadStaticTypeOffsetFromThreadStaticCookie(fieldAddressCookie)); } fieldAddressCookie = TypeLoaderEnvironment.Instance.TryGetThreadStaticFieldOffsetCookieForTypeAndFieldOffset(declaringTypeHandle, checked ((uint)offsetToCreateCookieFor)); } } } fieldAccessMetadata.MappingTableModule = mappingTableModule; fieldAccessMetadata.Cookie = fieldAddressCookie; fieldAccessMetadata.Flags = entryFlags; fieldAccessMetadata.Offset = fieldOffset; return(true); } } return(false); }
/// <summary> /// Wrapper helper function around the IsCanonicalDefinitionType API on the TypeSystemContext /// </summary> public static bool IsCanonicalDefinitionType(this TypeDesc type, CanonicalFormKind kind) { return(type.Context.IsCanonicalDefinitionType(type, kind)); }
public bool CanInstantiationsShareCode(RuntimeTypeHandle[] genericArgHandles1, RuntimeTypeHandle[] genericArgHandles2, CanonicalFormKind kind) { if (genericArgHandles1.Length != genericArgHandles2.Length) return false; bool match = true; TypeSystemContext context = TypeSystemContextFactory.Create(); for (int i = 0; i < genericArgHandles1.Length; i++) { TypeDesc genericArg1 = context.ResolveRuntimeTypeHandle(genericArgHandles1[i]); TypeDesc genericArg2 = context.ResolveRuntimeTypeHandle(genericArgHandles2[i]); if (context.ConvertToCanon(genericArg1, kind) != context.ConvertToCanon(genericArg2, kind)) { match = false; break; } } TypeSystemContextFactory.Recycle(context); return match; }
public override bool IsCanonicalSubtype(CanonicalFormKind policy) { return policy == CanonicalFormKind.Universal || policy == CanonicalFormKind.Any; }
public bool ConversionToCanonFormIsAChange(RuntimeTypeHandle[] genericArgHandles, CanonicalFormKind kind) { // Todo: support for universal canon type? TypeSystemContext context = TypeSystemContextFactory.Create(); Instantiation genericArgs = context.ResolveRuntimeTypeHandles(genericArgHandles); bool result; context.ConvertInstantiationToCanonForm(genericArgs, kind, out result); TypeSystemContextFactory.Recycle(context); return result; }
public override bool IsCanonicalSubtype(CanonicalFormKind policy) { return policy == CanonicalFormKind.Specific || policy == CanonicalFormKind.Any; }
/// <summary> /// Converts a constituent of a constructed type to it's canonical form. Note this method is different /// from <see cref="TypeDesc.ConvertToCanonForm(CanonicalFormKind)"/>. /// </summary> protected internal virtual TypeDesc ConvertToCanon(TypeDesc typeToConvert, CanonicalFormKind kind) { throw new NotSupportedException(); }