public override void SetValue(StringToken tkn, string val) { MetadataStream strs = this.Stream; uint idx = tkn.Token.Index; uint c = 0; while (strs.Data[idx + c] != 0) { c++; } c++; byte[] dat = Encoding.UTF8.GetBytes(val); MetadataWriter wtr = new MetadataWriter(strs); if (c == dat.Length + 1) { strs.Position = tkn.Token.Index; wtr.Write(dat); } else { ResizeChild(tkn, (uint)dat.Length + 1); strs.Position = tkn.Token.Index; wtr.Write(dat); wtr.Write((byte)0); } }
public override void SetValue(USToken tkn, string val) { MetadataStream strs = this.Stream; strs.Position = tkn.Token.Index; MetadataReader rdr = new MetadataReader(strs); uint len = rdr.ReadCompressedUInt(); MetadataWriter wtr = new MetadataWriter(strs); byte[] b = Encoding.Unicode.GetBytes(val); if (len == b.Length) { strs.Position = tkn.Token.Index; wtr.WriteCompressedUInt(len); wtr.Write(b); } else { ResizeChild(tkn, (uint)b.Length); strs.Position = tkn.Token.Index; wtr.WriteCompressedInt(b.Length); wtr.Write(b); } }
protected override void WriteImpl(MetadataWriter mw) { // PDB id PositionPdbId = mw.Position; WritePdbId(mw, guid, timestamp); // EntryPoint // LAMESPEC the spec says "The same value as stored in CLI header of the PE file.", // but the intent is clearly to allow a separate "user" entry point // (i.e. it should default to the entry point defined in the PE file, but SetUserEntryPoint should override it) mw.Write(entryPointToken); // ReferencedTypeSystemTables var bit = 1L; var valid = 0L; foreach (var table in referencedTables) { if (table != null && table.RowCount != 0) { valid |= bit; } bit <<= 1; } mw.Write(valid); // TypeSystemTableRows foreach (var table in referencedTables) { if (table != null && table.RowCount != 0) { mw.Write(table.RowCount); } } }
void WriteTableToken(int col, MetadataTable tbl, MetadataWriter wtr, uint[] lens, object val) { if (lens[(int)(val as TableToken).Token.Type] > ushort.MaxValue) { wtr.Write((uint)(val as TableToken).Token.Value); } else { wtr.Write((ushort)(val as TableToken).Token.Value); } }
void WriteBlobToken(int col, MetadataTable tbl, MetadataWriter wtr, uint[] lens, object val) { BlobHeap bh = wtr.BaseStream.Root[MetadataStreamType.Blob].Heap as BlobHeap; if (bh.Stream.Length > ushort.MaxValue) { wtr.Write((uint)(val as BlobToken).Token.Value); } else { wtr.Write((ushort)(val as BlobToken).Token.Value); } }
void WriteGUIDToken(int col, MetadataTable tbl, MetadataWriter wtr, uint[] lens, object val) { GUIDHeap gh = wtr.BaseStream.Root[MetadataStreamType.GUID].Heap as GUIDHeap; if (gh.Stream.Length > ushort.MaxValue) { wtr.Write((uint)(val as GUIDToken).Token.Value); } else { wtr.Write((ushort)(val as GUIDToken).Token.Value); } }
void WriteStringToken(int col, MetadataTable tbl, MetadataWriter wtr, uint[] lens, object val) { StringsHeap sh = wtr.BaseStream.Root[MetadataStreamType.Strings].Heap as StringsHeap; if (sh.Stream.Length > ushort.MaxValue) { wtr.Write((uint)(val as StringToken).Token.Value); } else { wtr.Write((ushort)(val as StringToken).Token.Value); } }
public void Save() { MetadataWriter wtr = new MetadataWriter(str); str.Position = 0; wtr.Write(res); wtr.Write(maVer); wtr.Write(miVer); wtr.Write((byte)f); wtr.Write(res2); wtr.Write((ulong)v); wtr.Write((ulong)s); FillLens(); foreach (MetadataTable i in mt) { if (i != null) { wtr.Write((uint)i.Rows.Count); } } TableRw rw = new TableRw(); foreach (MetadataTable i in mt) { if (i != null) { rw.Save(i, wtr, len); } } }
public override StringToken NewChildCore(uint len) { StringToken ret = new StringToken(this); ret.Token = new MetadataToken(MetadataTokenType.Unknown, (uint)this.Stream.Data.Length); this.Stream.SetLength(this.Stream.Data.Length + len + 1); MetadataWriter wtr = new MetadataWriter(this.Stream); this.Stream.Position = ret.Token.Index; for (int i = 0; i < len; i++) { wtr.Write((byte)0xff); } wtr.Write((byte)0); return(ret); }
internal void WriteMethodDefRecord(int baseRVA, MetadataWriter mw, ref int paramList) { if (rva != -1) { mw.Write(rva + baseRVA); } else { mw.Write(0); } mw.Write((short)implFlags); mw.Write((short)attributes); mw.WriteStringIndex(nameIndex); mw.WriteBlobIndex(signature); mw.WriteParam(paramList); if (parameters != null) { paramList += parameters.Count; } }
internal void WriteTypeDefRecord(MetadataWriter mw, ref int fieldList, ref int methodList) { mw.Write((int)attribs); mw.WriteStringIndex(typeName); mw.WriteStringIndex(typeNameSpace); mw.WriteTypeDefOrRef(extends); mw.WriteField(fieldList); mw.WriteMethodDef(methodList); methodList += methods.Count; fieldList += fields.Count; }
public override void SetValue(GUIDToken tkn, Guid val) { if (tkn.Token.Index == 0) { return; } MetadataStream strs = this.Stream; MetadataWriter wtr = new MetadataWriter(strs); strs.Position = (tkn.Token.Index - 1) * 16; wtr.Write(val.ToByteArray()); }
protected override void ComputeMetadata(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) { var ms = new MemoryStream(); var writer = new MetadataWriter(); // Run an empty transform pass. This doesn't matter. We just need an instance of the MetadataTransform. var transformed = MetadataTransform.Run(new Policy(), Array.Empty <ModuleDesc>()); MetadataTransform transform = transformed.Transform; // 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(); if (!_stackTraceEmissionPolicy.ShouldIncludeMethod(method)) { continue; } MetadataRecord record = CreateStackTraceRecord(transform, method); stackTraceRecords.Add(new KeyValuePair <MethodDesc, MetadataRecord>( method, record)); writer.AdditionalRootRecords.Add(record); } 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 stack trace metadata mapping foreach (var stackTraceRecord in stackTraceRecords) { stackTraceMapping.Add(new MetadataMapping <MethodDesc>(stackTraceRecord.Key, writer.GetRecordHandle(stackTraceRecord.Value))); } }
private void EnsureMetadataGenerated() { if (_metadataBlob != null) { return; } var transformed = MetadataTransform.Run(new DummyMetadataPolicy(this), _modulesSeen); // 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); var ms = new MemoryStream(); writer.Write(ms); _metadataBlob = ms.ToArray(); // Generate type definition mappings foreach (var definition in _typeDefinitionsGenerated) { 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 _methodsGenerated) { MetadataRecord record = transformed.GetTransformedMethodDefinition(method.GetTypicalMethodDefinition()); if (record != null) { _methodMappings.Add(new MetadataMapping <MethodDesc>(method, writer.GetRecordHandle(record))); } } }
public override void SetValue(BlobToken tkn, byte[] val) { MetadataStream strs = this.Stream; strs.Position = tkn.Token.Index; MetadataReader rdr = new MetadataReader(strs); uint len = rdr.ReadCompressedUInt(); MetadataWriter wtr = new MetadataWriter(strs); if (len == val.Length) { strs.Position = tkn.Token.Index; wtr.WriteCompressedUInt(len); wtr.Write(val); } else { ResizeChild(tkn, (uint)val.Length); strs.Position = tkn.Token.Index; wtr.WriteCompressedInt(val.Length); wtr.Write(val); } }
internal void WriteFieldRecords(MetadataWriter mw) { mw.Write((short)attribs); mw.WriteStringIndex(nameIndex); mw.WriteBlobIndex(signature); }
protected override void ComputeMetadata(NodeFactory factory, out byte[] metadataBlob, out List <MetadataMapping <MetadataType> > typeMappings, out List <MetadataMapping <MethodDesc> > methodMappings, out List <MetadataMapping <FieldDesc> > fieldMappings) { foreach (var type in factory.MetadataManager.GetTypesWithEETypes()) { var definition = type.GetTypeDefinition() as Internal.TypeSystem.Ecma.EcmaType; if (definition == null) { continue; } if (factory.CompilationModuleGroup.ContainsType(definition)) { _typeDefinitionsToGenerate.Add(definition); _modulesSeen.Add(definition.Module); } } foreach (var method in GetCompiledMethods()) { var typicalMethod = method.GetTypicalMethodDefinition() as Internal.TypeSystem.Ecma.EcmaMethod; if (typicalMethod != null) { var owningType = (MetadataType)typicalMethod.OwningType; if (factory.CompilationModuleGroup.ContainsType(owningType)) { _typeDefinitionsToGenerate.Add(owningType); _modulesSeen.Add(owningType.Module); _methodDefinitionsToGenerate.Add(typicalMethod); } } } var transformed = MetadataTransform.Run(new GeneratedTypesAndCodeMetadataPolicy(this), _modulesSeen); // 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); 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> >(); // 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; } 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()) { Field record = transformed.GetTransformedFieldDefinition(field.GetTypicalFieldDefinition()); if (record != null) { fieldMappings.Add(new MetadataMapping <FieldDesc>(field, writer.GetRecordHandle(record))); } } } }
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); }
internal static void WritePdbId(MetadataWriter mw, Guid guid, uint timestamp) { mw.Write(guid.ToByteArray()); mw.Write(timestamp); }
internal void WriteParamRecord(MetadataWriter mw) { mw.Write(flags); mw.Write(sequence); mw.WriteStringIndex(nameIndex); }
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 = CreateStackTraceRecord(transform, method); 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))); } } HashSet <MethodDesc> canonicalGenericMethods = new HashSet <MethodDesc>(); foreach (var method in GetCompiledMethods()) { if ((method.HasInstantiation && method.IsCanonicalMethod(CanonicalFormKind.Specific)) || (!method.HasInstantiation && method.GetCanonMethodTarget(CanonicalFormKind.Specific) != method)) { // Methods that are not in their canonical form are not interesting with the exception // of generic methods: their dictionaries convey their identity. continue; } if (IsReflectionBlocked(method.Instantiation) || IsReflectionBlocked(method.OwningType.Instantiation)) { continue; } if ((GetMetadataCategory(method) & MetadataCategory.RuntimeMapping) == 0) { continue; } // If we already added a canonically equivalent generic method, skip this one. if (method.HasInstantiation && !canonicalGenericMethods.Add(method.GetCanonMethodTarget(CanonicalFormKind.Specific))) { continue; } MetadataRecord record = transformed.GetTransformedMethodDefinition(method.GetTypicalMethodDefinition()); if (record != null) { methodMappings.Add(new MetadataMapping <MethodDesc>(method, writer.GetRecordHandle(record))); } } HashSet <FieldDesc> canonicalFields = new HashSet <FieldDesc>(); foreach (var field in GetFieldsWithRuntimeMapping()) { FieldDesc fieldToAdd = field; if (!field.IsStatic) { TypeDesc canonOwningType = field.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific); if (canonOwningType != field.OwningType) { FieldDesc canonField = _typeSystemContext.GetFieldForInstantiatedType(field.GetTypicalFieldDefinition(), (InstantiatedType)canonOwningType); // If we already added a canonically equivalent field, skip this one. if (!canonicalFields.Add(canonField)) { continue; } fieldToAdd = canonField; } } Field record = transformed.GetTransformedFieldDefinition(fieldToAdd.GetTypicalFieldDefinition()); if (record != null) { fieldMappings.Add(new MetadataMapping <FieldDesc>(fieldToAdd, writer.GetRecordHandle(record))); } } // Generate stack trace metadata mapping foreach (var stackTraceRecord in stackTraceRecords) { stackTraceMapping.Add(new MetadataMapping <MethodDesc>(stackTraceRecord.Key, writer.GetRecordHandle(stackTraceRecord.Value))); } }
internal void WriteMetadata(MetadataWriter mw) { mw.Write(0x424A5342); // Signature ("BSJB") mw.Write((ushort)1); // MajorVersion mw.Write((ushort)1); // MinorVersion mw.Write(0); // Reserved byte[] version = StringToPaddedUTF8(asm.ImageRuntimeVersion); mw.Write(version.Length); // Length mw.Write(version); mw.Write((ushort)0); // Flags // #Blob is the only optional heap if (Blobs.IsEmpty) { mw.Write((ushort)4); // Streams } else { mw.Write((ushort)5); // Streams } int offset = GetHeaderLength(); // Streams mw.Write(offset); // Offset mw.Write(Tables.Length); // Size mw.Write(StringToPaddedUTF8("#~")); offset += Tables.Length; mw.Write(offset); // Offset mw.Write(Strings.Length); // Size mw.Write(StringToPaddedUTF8("#Strings")); offset += Strings.Length; mw.Write(offset); // Offset mw.Write(UserStrings.Length); // Size mw.Write(StringToPaddedUTF8("#US")); offset += UserStrings.Length; mw.Write(offset); // Offset mw.Write(Guids.Length); // Size mw.Write(StringToPaddedUTF8("#GUID")); offset += Guids.Length; if (!Blobs.IsEmpty) { mw.Write(offset); // Offset mw.Write(Blobs.Length); // Size mw.Write(StringToPaddedUTF8("#Blob")); } Tables.Write(mw); Strings.Write(mw); UserStrings.Write(mw); Guids.Write(mw); if (!Blobs.IsEmpty) { Blobs.Write(mw); } }
void WriteRva(int col, MetadataTable tbl, MetadataWriter wtr, uint[] lens, object val) { wtr.Write(((Rva)val).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); }
void WriteUInt32(int col, MetadataTable tbl, MetadataWriter wtr, uint[] lens, object val) { wtr.Write((uint)val); }
void WriteByte(int col, MetadataTable tbl, MetadataWriter wtr, uint[] lens, object val) { wtr.Write((byte)val); }
void WriteUInt16Flag(int col, MetadataTable tbl, MetadataWriter wtr, uint[] lens, object val) { wtr.Write((ushort)val); }
protected override void ComputeMetadata(NodeFactory factory, out byte[] metadataBlob, out List <MetadataMapping <MetadataType> > typeMappings, out List <MetadataMapping <MethodDesc> > methodMappings, out List <MetadataMapping <FieldDesc> > fieldMappings) { var transformed = MetadataTransform.Run(new GeneratedTypesAndCodeMetadataPolicy(this), _modulesSeen); // 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); var ms = new MemoryStream(); writer.Write(ms); metadataBlob = ms.ToArray(); typeMappings = new List <MetadataMapping <MetadataType> >(); methodMappings = new List <MetadataMapping <MethodDesc> >(); fieldMappings = new List <MetadataMapping <FieldDesc> >(); // Generate type definition mappings foreach (var definition in _typeDefinitionsGenerated) { 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; } 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()) { Field record = transformed.GetTransformedFieldDefinition(field.GetTypicalFieldDefinition()); if (record != null) { fieldMappings.Add(new MetadataMapping <FieldDesc>(field, writer.GetRecordHandle(record))); } } } }
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))); } }