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; } MetadataRecord record = CreateStackTraceRecord(transform, method); 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); }
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); }