Beispiel #1
0
        /// <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)
                    );
            }
        }
Beispiel #2
0
        /// <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)
                    );
            }
        }
Beispiel #3
0
 internal AssemblyBuilderEmitResult(byte[] peFile, TokenMapping tokenMapping)
 {
     m_peFile       = peFile;
     m_tokenMapping = tokenMapping;
 }
Beispiel #4
0
        /// <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));
        }