public static SigTypeContext FromMethod(MetadataReader metadataReader, Handle methodHandle) { object typeContext; object methodContext; switch (methodHandle.HandleType) { case HandleType.MemberReference: typeContext = GetTypeContext(metadataReader, methodHandle); methodContext = default(HandleCollection); break; case HandleType.MethodInstantiation: MethodInstantiation methodInst = methodHandle.ToMethodInstantiationHandle(metadataReader).GetMethodInstantiation(metadataReader); typeContext = GetTypeContext(metadataReader, methodInst.Method); methodContext = methodInst.GenericTypeArguments; break; case HandleType.QualifiedMethod: QualifiedMethod qualifiedMethod = methodHandle.ToQualifiedMethodHandle(metadataReader).GetQualifiedMethod(metadataReader); typeContext = GetTypeContext(metadataReader, qualifiedMethod.EnclosingType); methodContext = qualifiedMethod.Method.GetMethod(metadataReader).GenericParameters; break; default: Debug.Assert(false); return(default(SigTypeContext)); } return(new SigTypeContext(typeContext, methodContext)); }
private MethodInfo GetEmittableMethodInstantiation(MethodInstantiation methodInstantiation) { var emittableGenericMethodDefinition = GetEmittableMethod(methodInstantiation.GetGenericMethodDefinition()); var emittableTypeArguments = methodInstantiation.GetGenericArguments().Select(GetEmittableType).ToArray(); // Should *not* be MakeTypePipeGenericMethod. return(emittableGenericMethodDefinition.MakeGenericMethod(emittableTypeArguments)); }
private void InitializeMethodInstantiation(Cts.MethodDesc entity, MethodInstantiation record) { Cts.InstantiatedMethod instantiation = (Cts.InstantiatedMethod)entity; record.Method = HandleQualifiedMethod(instantiation.GetMethodDefinition()); record.GenericTypeArguments.Capacity = instantiation.Instantiation.Length; foreach (Cts.TypeDesc typeArgument in instantiation.Instantiation) { record.GenericTypeArguments.Add(HandleType(typeArgument)); } }
/// <summary> /// Emit generic method instantiation to the output string builder. /// </summary> /// <param name="methodInstHandle">Method instantiation handle</param> private void EmitMethodInstantiationName(MethodInstantiationHandle methodInstHandle) { MethodInstantiation methodInst = _metadataReader.GetMethodInstantiation(methodInstHandle); MemberReferenceHandle methodRefHandle = methodInst.Method.ToMemberReferenceHandle(_metadataReader); MemberReference methodRef = methodRefHandle.GetMemberReference(_metadataReader); MethodSignature methodSignature; EmitReturnTypeContainingTypeAndMethodName(methodRef, out methodSignature); EmitGenericArguments(methodInst.GenericTypeArguments); EmitMethodParameters(methodSignature); }
public void SetUp() { _typeParameter = MutableGenericParameterObjectMother.Create(); _parameter = CustomParameterInfoObjectMother.Create(); _genericMethodDefinition = CustomMethodInfoObjectMother.Create(parameters: new[] { _parameter }, typeArguments: new[] { _typeParameter }); _typeArgument = CustomTypeObjectMother.Create(); var info = new MethodInstantiationInfo(_genericMethodDefinition, new[] { _typeArgument }); _instantiation = new MethodInstantiation(info); }
private Object ResolveMethodInstantiation(MethodInstantiationHandle handle) { MethodInstantiation methodInstantiation = _metadataReader.GetMethodInstantiation(handle); MethodDesc genericMethodDef = (MethodDesc)GetObject(methodInstantiation.Method, null); ArrayBuilder <TypeDesc> instantiation = new ArrayBuilder <TypeDesc>(); foreach (Handle genericArgHandle in methodInstantiation.GenericTypeArguments) { instantiation.Add(GetType(genericArgHandle)); } return(Context.GetInstantiatedMethod(genericMethodDef, new Instantiation(instantiation.ToArray()))); }
public void SetUp() { _typeArgument = ReflectionObjectMother.GetSomeType(); var genericTypeDefinition = typeof(GenericType <>); _genericTypeParameter = genericTypeDefinition.GetGenericArguments().Single(); _declaringType = TypeInstantiationObjectMother.Create(genericTypeDefinition, new[] { _typeArgument }); _memberOnTypeInstantiation = MethodOnTypeInstantiationObjectMother.Create(_declaringType); var genericMethodDefinition = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(() => GenericMethod <Dev.T>()); _genericMethodParameter = genericMethodDefinition.GetGenericArguments().Single(); _methodInstantiation = MethodInstantiationObjectMother.Create(genericMethodDefinition, typeArguments: new[] { _typeArgument }); }
/// <summary> /// Emit generic method instantiation to the output string builder. /// </summary> /// <param name="methodInstHandle">Method instantiation handle</param> private void EmitMethodInstantiationName(MethodInstantiationHandle methodInstHandle) { MethodInstantiation methodInst = _metadataReader.GetMethodInstantiation(methodInstHandle); MethodSignature methodSignature; if (methodInst.Method.HandleType == HandleType.MemberReference) { MemberReferenceHandle methodRefHandle = methodInst.Method.ToMemberReferenceHandle(_metadataReader); MemberReference methodRef = methodRefHandle.GetMemberReference(_metadataReader); EmitContainingTypeAndMethodName(methodRef, out methodSignature); } else { QualifiedMethodHandle qualifiedMethodHandle = methodInst.Method.ToQualifiedMethodHandle(_metadataReader); QualifiedMethod qualifiedMethod = _metadataReader.GetQualifiedMethod(qualifiedMethodHandle); EmitContainingTypeAndMethodName(qualifiedMethod, out methodSignature); } EmitGenericArguments(methodInst.GenericTypeArguments); EmitMethodParameters(methodSignature); }
protected void ComputeMetadata <TPolicy>( TPolicy policy, NodeFactory factory, out byte[] metadataBlob, out List <MetadataMapping <MetadataType> > typeMappings, out List <MetadataMapping <MethodDesc> > methodMappings, out List <MetadataMapping <FieldDesc> > fieldMappings, out List <MetadataMapping <MethodDesc> > stackTraceMapping) where TPolicy : struct, IMetadataPolicy { var transformed = MetadataTransform.Run(policy, GetCompilationModulesWithMetadata()); MetadataTransform transform = transformed.Transform; // TODO: DeveloperExperienceMode: Use transformed.Transform.HandleType() to generate // TypeReference records for _typeDefinitionsGenerated that don't have metadata. // (To be used in MissingMetadataException messages) // Generate metadata blob var writer = new MetadataWriter(); writer.ScopeDefinitions.AddRange(transformed.Scopes); // Generate entries in the blob for methods that will be necessary for stack trace purposes. var stackTraceRecords = new List <KeyValuePair <MethodDesc, MetadataRecord> >(); foreach (var methodBody in GetCompiledMethodBodies()) { MethodDesc method = methodBody.Method; MethodDesc typicalMethod = method.GetTypicalMethodDefinition(); // Methods that will end up in the reflection invoke table should not have an entry in stack trace table // We'll try looking them up in reflection data at runtime. if (transformed.GetTransformedMethodDefinition(typicalMethod) != null && ShouldMethodBeInInvokeMap(method) && (GetMetadataCategory(method) & MetadataCategory.RuntimeMapping) != 0) { continue; } if (!_stackTraceEmissionPolicy.ShouldIncludeMethod(method)) { continue; } MetadataRecord record = transform.HandleQualifiedMethod(typicalMethod); // As a twist, instantiated generic methods appear as if instantiated over their formals. if (typicalMethod.HasInstantiation) { var methodInst = new MethodInstantiation { Method = record, }; methodInst.GenericTypeArguments.Capacity = typicalMethod.Instantiation.Length; foreach (EcmaGenericParameter typeArgument in typicalMethod.Instantiation) { var genericParam = new TypeReference { TypeName = (ConstantStringValue)typeArgument.Name, }; methodInst.GenericTypeArguments.Add(genericParam); } record = methodInst; } stackTraceRecords.Add(new KeyValuePair <MethodDesc, MetadataRecord>( method, record)); writer.AdditionalRootRecords.Add(record); } var ms = new MemoryStream(); // .NET metadata is UTF-16 and UTF-16 contains code points that don't translate to UTF-8. var noThrowUtf8Encoding = new UTF8Encoding(false, false); using (var logWriter = _metadataLogFile != null ? new StreamWriter(File.Open(_metadataLogFile, FileMode.Create, FileAccess.Write, FileShare.Read), noThrowUtf8Encoding) : null) { writer.LogWriter = logWriter; writer.Write(ms); } metadataBlob = ms.ToArray(); typeMappings = new List <MetadataMapping <MetadataType> >(); methodMappings = new List <MetadataMapping <MethodDesc> >(); fieldMappings = new List <MetadataMapping <FieldDesc> >(); stackTraceMapping = new List <MetadataMapping <MethodDesc> >(); // Generate type definition mappings foreach (var type in factory.MetadataManager.GetTypesWithEETypes()) { MetadataType definition = type.IsTypeDefinition ? type as MetadataType : null; if (definition == null) { continue; } MetadataRecord record = transformed.GetTransformedTypeDefinition(definition); // Reflection requires that we maintain type identity. Even if we only generated a TypeReference record, // if there is an EEType for it, we also need a mapping table entry for it. if (record == null) { record = transformed.GetTransformedTypeReference(definition); } if (record != null) { typeMappings.Add(new MetadataMapping <MetadataType>(definition, writer.GetRecordHandle(record))); } } foreach (var method in GetCompiledMethods()) { if (method.IsCanonicalMethod(CanonicalFormKind.Specific)) { // Canonical methods are not interesting. continue; } if (IsReflectionBlocked(method.Instantiation) || IsReflectionBlocked(method.OwningType.Instantiation)) { continue; } if ((GetMetadataCategory(method) & MetadataCategory.RuntimeMapping) == 0) { continue; } MetadataRecord record = transformed.GetTransformedMethodDefinition(method.GetTypicalMethodDefinition()); if (record != null) { methodMappings.Add(new MetadataMapping <MethodDesc>(method, writer.GetRecordHandle(record))); } } foreach (var eetypeGenerated in GetTypesWithEETypes()) { if (eetypeGenerated.IsGenericDefinition) { continue; } if (eetypeGenerated.HasInstantiation) { // Collapsing of field map entries based on canonicalization, to avoid redundant equivalent entries TypeDesc canonicalType = eetypeGenerated.ConvertToCanonForm(CanonicalFormKind.Specific); if (canonicalType != eetypeGenerated && TypeGeneratesEEType(canonicalType)) { continue; } } foreach (FieldDesc field in eetypeGenerated.GetFields()) { if (IsReflectionBlocked(field.OwningType.Instantiation)) { continue; } Field record = transformed.GetTransformedFieldDefinition(field.GetTypicalFieldDefinition()); if (record != null) { fieldMappings.Add(new MetadataMapping <FieldDesc>(field, writer.GetRecordHandle(record))); } } } // Generate stack trace metadata mapping foreach (var stackTraceRecord in stackTraceRecords) { stackTraceMapping.Add(new MetadataMapping <MethodDesc>(stackTraceRecord.Key, writer.GetRecordHandle(stackTraceRecord.Value))); } }
private List <MetadataMapping <MethodDesc> > GenerateStackTraceMetadata(NodeFactory factory) { var transformed = MetadataTransform.Run(new NoDefinitionMetadataPolicy(), Array.Empty <ModuleDesc>()); MetadataTransform transform = transformed.Transform; // Generate metadata blob var writer = new MetadataWriter(); // Only emit stack trace metadata for those methods which don't have reflection metadata HashSet <MethodDesc> methodInvokeMap = new HashSet <MethodDesc>(); foreach (var mappingEntry in GetMethodMapping(factory)) { var method = mappingEntry.Entity; if (ShouldMethodBeInInvokeMap(method)) { methodInvokeMap.Add(method); } } // Generate entries in the blob for methods that will be necessary for stack trace purposes. var stackTraceRecords = new List <KeyValuePair <MethodDesc, MetadataRecord> >(); foreach (var methodBody in GetCompiledMethodBodies()) { NonExternMethodSymbolNode methodNode = methodBody as NonExternMethodSymbolNode; if (methodNode != null && !methodNode.HasCompiledBody) { continue; } MethodDesc method = methodBody.Method; if (methodInvokeMap.Contains(method)) { continue; } if (!_stackTraceEmissionPolicy.ShouldIncludeMethod(method)) { continue; } // In the metadata, we only represent the generic definition MethodDesc methodToGenerateMetadataFor = method.GetTypicalMethodDefinition(); MetadataRecord record = transform.HandleQualifiedMethod(methodToGenerateMetadataFor); // As a twist, instantiated generic methods appear as if instantiated over their formals. if (methodToGenerateMetadataFor.HasInstantiation) { var methodInst = new MethodInstantiation { Method = record, }; methodInst.GenericTypeArguments.Capacity = methodToGenerateMetadataFor.Instantiation.Length; foreach (EcmaGenericParameter typeArgument in methodToGenerateMetadataFor.Instantiation) { var genericParam = new TypeReference { TypeName = (ConstantStringValue)typeArgument.Name, }; methodInst.GenericTypeArguments.Add(genericParam); } record = methodInst; } stackTraceRecords.Add(new KeyValuePair <MethodDesc, MetadataRecord>( method, record)); writer.AdditionalRootRecords.Add(record); } var ms = new MemoryStream(); writer.Write(ms); _stackTraceBlob = ms.ToArray(); var result = new List <MetadataMapping <MethodDesc> >(); // Generate stack trace metadata mapping foreach (var stackTraceRecord in stackTraceRecords) { result.Add(new MetadataMapping <MethodDesc>(stackTraceRecord.Key, writer.GetRecordHandle(stackTraceRecord.Value))); } return(result); }