/// <summary> /// Writes the property definition to the dynamic assembly metadata. /// </summary> /// <param name="builder">The <see cref="MetadataBuilder"/> into which to write the property /// definition.</param> /// <param name="tokenMapping">The token map for patching accessor method handles.</param> internal void writeMetadata(MetadataBuilder builder, TokenMapping tokenMapping) { var propHandle = builder.AddProperty(attributes, m_nameHandle, m_sigHandle); if ((attributes & PropertyAttributes.HasDefault) != 0) { builder.AddConstant(propHandle, m_constantValue); } if (m_getter != null) { builder.AddMethodSemantics( propHandle, MethodSemanticsAttributes.Getter, (MethodDefinitionHandle)tokenMapping.getMappedHandle(m_getter.handle) ); } if (m_setter != null) { builder.AddMethodSemantics( propHandle, MethodSemanticsAttributes.Setter, (MethodDefinitionHandle)tokenMapping.getMappedHandle(m_setter.handle) ); } Span <MethodBuilder> otherMethods = m_otherMethods.asSpan(); for (int i = 0; i < otherMethods.Length; i++) { builder.AddMethodSemantics( propHandle, MethodSemanticsAttributes.Other, (MethodDefinitionHandle)tokenMapping.getMappedHandle(otherMethods[i].handle) ); } }
/// <summary> /// Writes the event definition to the dynamic assembly metadata. /// </summary> /// <param name="builder">The <see cref="MetadataBuilder"/> into which to write the property /// definition.</param> /// <param name="tokenMapping">The token map for patching event method handles.</param> internal void writeMetadata(MetadataBuilder builder, TokenMapping tokenMapping) { var eventHandle = builder.AddEvent(attributes, m_nameHandle, m_eventTypeHandle); if (m_add != null) { builder.AddMethodSemantics( eventHandle, MethodSemanticsAttributes.Adder, (MethodDefinitionHandle)tokenMapping.getMappedHandle(m_add.handle) ); } if (m_remove != null) { builder.AddMethodSemantics( eventHandle, MethodSemanticsAttributes.Remover, (MethodDefinitionHandle)tokenMapping.getMappedHandle(m_remove.handle) ); } if (m_fire != null) { builder.AddMethodSemantics( eventHandle, MethodSemanticsAttributes.Raiser, (MethodDefinitionHandle)tokenMapping.getMappedHandle(m_fire.handle) ); } Span <MethodBuilder> otherMethods = m_otherMethods.asSpan(); for (int i = 0; i < otherMethods.Length; i++) { builder.AddMethodSemantics( eventHandle, MethodSemanticsAttributes.Other, (MethodDefinitionHandle)tokenMapping.getMappedHandle(otherMethods[i].handle) ); } }
internal AssemblyBuilderEmitResult(byte[] peFile, TokenMapping tokenMapping) { m_peFile = peFile; m_tokenMapping = tokenMapping; }
/// <summary> /// Emits this dynamic assembly to a Portable Executable file image. /// </summary> /// <returns>An <see cref="AssemblyBuilderEmitResult"/> instance containing the /// emitted PE image.</returns> /// <remarks> /// This method can be called only once. Any subsequent calls will throw an exception. /// </remarks> public AssemblyBuilderEmitResult emit() { if (m_isPEFileCreated) { throw new InvalidOperationException("The PE file for this assembly has already been created."); } m_isPEFileCreated = true; var tokenMap = new TokenMapping(m_metadataContext.fieldDefRowCount, m_metadataContext.methodDefRowCount); BlobBuilder ilStream; lock (m_typeBuildersLock) { var typeBuilders = m_typeBuilders.asReadOnlyArrayView(); int currentMethodBodyAddress = 0; for (int i = 0; i < typeBuilders.length; i++) { currentMethodBodyAddress = typeBuilders[i].assignMethodBodyAddresses(currentMethodBodyAddress); } var genParamEntries = new DynamicArray <GenericParameter>(); using (var mdBuilder = m_metadataContext.getMetadataBuilder()) { for (int i = 0; i < typeBuilders.length; i++) { typeBuilders[i].writeTypeMetadata(mdBuilder.value, tokenMap); } for (int i = 0; i < typeBuilders.length; i++) { typeBuilders[i].writeMethodImplEntries(mdBuilder.value, tokenMap); } } for (int i = 0; i < typeBuilders.length; i++) { typeBuilders[i].appendGenParamEntries(tokenMap, ref genParamEntries); } m_metadataContext.emitMethodSpecTable(tokenMap); _sortAndWriteGenParamEntries(ref genParamEntries); ilStream = new BlobBuilder(currentMethodBodyAddress); for (int i = 0; i < typeBuilders.length; i++) { typeBuilders[i].writeMethodBodies(ilStream, tokenMap); } } BlobBuilder peFileBlob = new BlobBuilder(); MethodDefinitionHandle entryPoint = default; if (!m_entryPoint.IsNil) { entryPoint = (MethodDefinitionHandle)tokenMap.getMappedHandle(m_entryPoint); } using (var mdBuilder = m_metadataContext.getMetadataBuilder()) { var metadataRootBuilder = new MetadataRootBuilder(mdBuilder.value, null, true); var peHeader = m_peHeader ?? new PEHeaderBuilder(Machine.I386); var peBuilder = new ManagedPEBuilder(peHeader, metadataRootBuilder, ilStream, entryPoint: entryPoint); peBuilder.Serialize(peFileBlob); } return(new AssemblyBuilderEmitResult(peFileBlob.ToArray(), tokenMap)); }