Repository: dotnet/runtime
File: src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs (C#)

Code before:
                }
            }

            WasmFuncType[] uniqueSignatures = new WasmFuncType[signatureMap.Count];
            foreach (var kvp in signatureMap)
            {
                uniqueSignatures[kvp.Value] = kvp.Key;
            }

            EmitWasmHeader(outputFileStream);
            EmitSection(() => WriteTypeSection(uniqueSignatures, logger), outputFileStream, logger);
            EmitSection(() => WriteFunctionSection(methodSignatures.ToArray(), signatureMap, logger), outputFileStream, logger);
            EmitSection(() => WriteExportSection(methodBodies.ToArray(), methodSignatures.ToArray(), signatureMap, logger), outputFileStream, logger);
            EmitSection(() => WriteCodeSection(methodBodies.ToArray(), logger),  outputFileStream, logger);
        }

        private WasmSection WriteExportSection(IReadOnlyCollection<IMethodBodyNode> methodNodes, IReadOnlyCollection<WasmFuncType> methodSignatures,
            Dictionary<WasmFuncType, int> signatureMap, Logger logger)
        {
            WasmSection exportSection = new WasmSection(WasmSectionType.Export, new SectionData(), "export");
            SectionWriter writer = exportSection.Writer;
            // Write the number of exports
            writer.WriteULEB128((ulong)methodNodes.Count);
            for (int i = 0; i < methodNodes.Count; i++)
            {
                var methodNode = methodNodes.ElementAt(i);
                var methodSignature = methodSignatures.ElementAt(i);
                string exportName = methodNode.GetMangledName(_nodeFactory.NameMangler);

                var length = Encoding.UTF8.GetByteCount(exportName);
                writer.WriteULEB128((ulong)length);
                writer.WriteUtf8StringNoNull(exportName);
                writer.WriteByte(0x00); // export kind: function
                writer.WriteULEB128((ulong)i);
                if (logger.IsVerbose)
                {
                    logger.LogMessage($"Emitting export: {exportName} for function index {i}");
                }
            }

            return exportSection;
        }

        private WasmSection WriteCodeSection(IReadOnlyCollection<IMethodBodyNode> methodBodies, Logger logger)
        {
            WasmSection codeSection = new WasmSection(WasmSectionType.Code, new SectionData(), "code");

            SectionWriter writer = codeSection.Writer;
            // Write the number of functions
            writer.WriteULEB128((ulong)methodBodies.Count);
            foreach (IMethodBodyNode methodBody in methodBodies)

Review comment (performance):
nit: Can we use `IReadOnlyList` here, these `ElementAt`s make me itch even if the underlying implementation is optimized

Code after:
            {
                if (logger.IsVerbose)
                {
                    logger.LogMessage($"Emitting function signature: {signature}");
                }

                int signatureSize = signature.EncodeSize();
                signature.Encode(buffer.GetSpan(signatureSize));
                buffer.Advance(signatureSize);
            }

            return typeSection;
        }

        private WasmSection WriteFunctionSection(ArrayBuilder<WasmFuncType> allFunctionSignatures, Dictionary<WasmFuncType, int> signatureMap, Logger logger)
        {
            WasmSection functionSection = new WasmSection(WasmSectionType.Function, new SectionData(), "function");
            SectionWriter writer = functionSection.Writer;
            // Write the number of functions
            writer.WriteULEB128((ulong)allFunctionSignatures.Count);
            for (int i = 0; i < allFunctionSignatures.Count; i++)
            {
                WasmFuncType signature = allFunctionSignatures[i];
                writer.WriteULEB128((ulong)signatureMap[signature]);
            }
            return functionSection;
        }

        private void EmitSection(Func<WasmSection> writeFunc, Stream outputFileStream, Logger logger)
        {
            WasmSection section = writeFunc();
            Span<byte> headerBuffer = stackalloc byte[section.HeaderSize];

            section.EncodeHeader(headerBuffer);
            outputFileStream.Write(headerBuffer);
            if (logger.IsVerbose)
            {
                logger.LogMessage($"Wrote section header of size {headerBuffer.Length} bytes.");
            }

            section.Data.GetReadStream().CopyTo(outputFileStream);
            if (logger.IsVerbose)
            {
                logger.LogMessage($"Emitted section: {section.Name} of type `{section.Type}` with size {section.Data.Length} bytes.");
            }
        }

        protected internal override void UpdateSectionAlignment(int sectionIndex, int alignment) => throw new NotImplementedException();
        private WasmSection CreateSection(WasmSectionType sectionType, string symbolName, int sectionIndex) => throw new NotImplementedException();
        private protected override void CreateSection(ObjectNodeSection section, Utf8String comdatName, Utf8String symbolName, int sectionIndex, Stream sectionStream) => throw new NotImplementedException();
        private protected override void EmitObjectFile(Stream outputFileStream) => throw new NotImplementedException();