/// <summary> /// Read a method that describes the type system to metadata mappings. /// </summary> private void ReadMetadataMethod(MethodIL methodOfMappings, Dictionary <MetadataType, int> typeMappings, Dictionary <MethodDesc, int> methodMappings, Dictionary <FieldDesc, int> fieldMappings, HashSet <ModuleDesc> metadataModules) { ILStreamReader il = new ILStreamReader(methodOfMappings); // structure is // REPEAT N TIMES // ldtoken type/method/field OR ldc.i4 0. If ldtoken instruction is replaced with a ldc.i4, skip this entry // ldc.i4 metadata value // pop // pop while (true) { if (il.TryReadRet()) // ret { break; } TypeSystemEntity tse; if (il.TryReadLdtokenAsTypeSystemEntity(out tse)) { int metadataTokenValue = il.ReadLdcI4(); il.ReadPop(); il.ReadPop(); if (tse is MetadataType) { MetadataType type = (MetadataType)tse; metadataModules.Add(type.Module); typeMappings.Add(type, metadataTokenValue); } else if (tse is MethodDesc) { MethodDesc method = (MethodDesc)tse; // Finalizers are called via a field on the EEType. They should not be reflectable. if (!method.IsFinalizer) { metadataModules.Add(((MetadataType)method.OwningType).Module); methodMappings.Add(method, metadataTokenValue); } } else if (tse is FieldDesc) { FieldDesc field = (FieldDesc)tse; metadataModules.Add(((MetadataType)field.OwningType).Module); fieldMappings.Add(field, metadataTokenValue); } } else { int deadLdtokenSignifier = il.ReadLdcI4(); Debug.Assert(deadLdtokenSignifier == 0); il.ReadLdcI4(); il.ReadPop(); il.ReadPop(); } } }
/// <summary> /// Read a method that describes the type system to metadata mappings. /// </summary> private void ReadMetadataMethod(MethodIL methodOfMappings, out List <MetadataMapping <MetadataType> > typeMappings, out List <MetadataMapping <MethodDesc> > methodMappings, out List <MetadataMapping <FieldDesc> > fieldMappings, ref HashSet <ModuleDesc> metadataModules) { typeMappings = new List <MetadataMapping <MetadataType> >(); methodMappings = new List <MetadataMapping <MethodDesc> >(); fieldMappings = new List <MetadataMapping <FieldDesc> >(); ILStreamReader il = new ILStreamReader(methodOfMappings); // structure is // REPEAT N TIMES // ldtoken type/method/field OR ldc.i4 0. If ldtoken instruction is replaced with a ldc.i4, skip this entry // ldc.i4 metadata value // pop // pop while (true) { if (il.TryReadRet()) // ret { break; } TypeSystemEntity tse; if (il.TryReadLdtokenAsTypeSystemEntity(out tse)) { int metadataTokenValue = il.ReadLdcI4(); il.ReadPop(); il.ReadPop(); if (tse is MetadataType) { MetadataType type = (MetadataType)tse; metadataModules.Add(type.Module); typeMappings.Add(new MetadataMapping <MetadataType>(type, metadataTokenValue)); } else if (tse is MethodDesc) { MethodDesc method = (MethodDesc)tse; metadataModules.Add(((MetadataType)method.OwningType).Module); methodMappings.Add(new MetadataMapping <MethodDesc>(method, metadataTokenValue)); } else if (tse is FieldDesc) { FieldDesc field = (FieldDesc)tse; metadataModules.Add(((MetadataType)field.OwningType).Module); fieldMappings.Add(new MetadataMapping <FieldDesc>(field, metadataTokenValue)); } } else { int deadLdtokenSignifier = il.ReadLdcI4(); Debug.Assert(deadLdtokenSignifier == 0); il.ReadLdcI4(); il.ReadPop(); il.ReadPop(); } } }
private void ReadRequiredTemplates(MethodIL methodIL, HashSet <TypeDesc> typeTemplates, HashSet <MethodDesc> methodTemplates, HashSet <FieldDesc> fieldTemplates) { ILStreamReader il = new ILStreamReader(methodIL); if (!_typeSystemContext.SupportsUniversalCanon) { return; } // // Types, methods and field tokens listed here are *open* generic definitions determined by the reducer as needing reflection. // Type tokens listed are tokens of generic type definitions that will need reflection support. // Method tokens listed are either tokens of generic method definitions, or non-generic methods on generic containing type definitions, and need reflection support. // Field tokens listed are for fields on generic type definitions that will need reflection support // The canonical form supported by the typesystem context will determine how to instantiate the types/methods/fields listed here, and templatize them for // reflection support at runtime (templates used by the dynamic TypeLoader component of the runtime). // // structure is // REPEAT N TIMES //ldtoken type //pop while (true) { if (il.TryReadRet()) // ret { break; } TypeSystemEntity tse; il.TryReadLdtokenAsTypeSystemEntity(out tse); il.ReadPop(); if (tse == null) { throw new BadImageFormatException(); } if (tse is MetadataType) { MetadataType type = (MetadataType)tse; Debug.Assert(type.IsGenericDefinition && type.HasInstantiation); type = _typeSystemContext.GetInstantiatedType(type, GetUniversalCanonicalInstantiation(type.Instantiation.Length)); typeTemplates.Add(type); } else if (tse is MethodDesc) { MethodDesc method = (MethodDesc)tse; TypeDesc containingType = method.OwningType; Debug.Assert(method.IsTypicalMethodDefinition); Debug.Assert(method.HasInstantiation || method.OwningType.HasInstantiation); if (containingType.HasInstantiation) { containingType = _typeSystemContext.GetInstantiatedType((MetadataType)containingType, GetUniversalCanonicalInstantiation(containingType.Instantiation.Length)); method = containingType.GetMethod(method.Name, method.GetTypicalMethodDefinition().Signature); typeTemplates.Add(containingType); } if (method.HasInstantiation) { method = _typeSystemContext.GetInstantiatedMethod(method, GetUniversalCanonicalInstantiation(method.Instantiation.Length)); } methodTemplates.Add(method); } else if (tse is FieldDesc) { FieldDesc field = (FieldDesc)tse; TypeDesc containingType = field.OwningType; Debug.Assert(containingType.HasInstantiation && containingType.IsGenericDefinition); containingType = _typeSystemContext.GetInstantiatedType((MetadataType)containingType, GetUniversalCanonicalInstantiation(containingType.Instantiation.Length)); field = containingType.GetField(field.Name); typeTemplates.Add(containingType); fieldTemplates.Add(field); } } }
private IEnumerable <TypeSystemEntity> ReadRequiredGenericsEntities(MethodIL method) { ILStreamReader il = new ILStreamReader(method); // structure is // REPEAT N TIMES //ldtoken generic type/method/field //pop while (true) { if (il.TryReadRet()) // ret { yield break; } TypeSystemEntity tse; il.TryReadLdtokenAsTypeSystemEntity(out tse); il.ReadPop(); if (tse == null) { throw new BadImageFormatException(); } if (tse is TypeDesc) { if (tse is DefType) { if (((TypeDesc)tse).Instantiation.CheckValidInstantiationArguments() && ((TypeDesc)tse).CheckConstraints()) { yield return(tse); } } else if (tse is ByRefType) { // Skip by ref types. } else { throw new BadImageFormatException(); } } else if (tse is FieldDesc) { TypeDesc owningType = ((FieldDesc)tse).OwningType; if (owningType.Instantiation.CheckValidInstantiationArguments() && owningType.CheckConstraints()) { yield return(tse); } } else if (tse is MethodDesc) { MethodDesc genericMethod = (MethodDesc)tse; if (genericMethod.Instantiation.CheckValidInstantiationArguments() && genericMethod.OwningType.Instantiation.CheckValidInstantiationArguments() && genericMethod.CheckConstraints()) { // TODO: Detect large number of instantiations of the same method and collapse to using dynamic // USG instantiations at runtime, to avoid infinite generic expansion and large compilation times. yield return(tse); } } } }