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

Code before:
            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 {signatureMap[methodSignature]}");
                }
            }

            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)
            {
                ObjectNode objectNode = methodBody as ObjectNode;
                ObjectNode.ObjectData body = objectNode.GetData(_nodeFactory);

                writer.WriteULEB128((ulong)body.Data.Length);
                writer.EmitData(body.Data);
            }

            return codeSection;
        }


Review comment (suggestion):
The log message references `signatureMap[methodSignature]` which is the signature's type index, but the export index written to the file is `i` (the function index). This could be confusing. The log message should use `i` instead to accurately reflect what's being emitted.
```suggestion
                    logger.LogMessage($"Emitting export: {exportName} for function index {i}");
```

Code after:
        }

        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();
        private protected override void EmitRelocations(int sectionIndex, List<SymbolicRelocation> relocationList) => throw new NotImplementedException();
        private protected override void EmitSymbolTable(IDictionary<Utf8String, SymbolDefinition> definedSymbols, SortedSet<Utf8String> undefinedSymbols) => throw new NotImplementedException();
    }

    // TODO: This is a placeholder implementation. The real implementation will derive the Wasm function signature
    // from the MethodDesc's signature and type system information.
    public static class WasmAbiContext
    {
        public static WasmFuncType GetSignature(MethodDesc method)
        {
            return PlaceholderValues.CreateWasmFunc_i32_i32();
        }