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

Code before:
        }

        private protected override void EmitRelocations(int sectionIndex, List<SymbolicRelocation> relocationList)
        {
            // This is a no-op for now under Wasm
        }

        const int StackPointerGlobalIndex = 0;
        const int R2RStartGlobalIndex = 1;

        private WasmImport[] _defaultImports = new[]
        {
            null, // placeholder for memory, which is set up dynamically in WriteImports()
            new WasmImport("env", "__stack_pointer", WasmExternalKind.Global, new WasmGlobalType(WasmValueType.I32, WasmMutabilityType.Mut), index: StackPointerGlobalIndex),
            new WasmImport("env", "__r2r_start", WasmExternalKind.Global, new WasmGlobalType(WasmValueType.I32, WasmMutabilityType.Const), index: R2RStartGlobalIndex),
        };

        private void WriteImports()
        {
            // Calculate the minimum required memory size based on the combined data section size
            ulong contentSize = (ulong)SectionByName(WasmObjectNodeSection.CombinedDataSection.Name).ContentSize;
            uint dataPages = checked((uint)((contentSize + (1<<16) - 1) >> 16));
            uint numPages = Math.Max(dataPages, 1); // Ensure at least one page is allocated for the minimum

            _defaultImports[0] = new WasmImport("env", "memory", WasmExternalKind.Memory,
                new WasmMemoryType(WasmLimitType.HasMin, numPages)); // memory limits: flags (0 = only minimum)

            int[] assignedImportIndices = new int[(int)WasmExternalKind.Count];
            foreach (WasmImport import in _defaultImports)
            {
                if (import.Index.HasValue)
                {
                    int assigned = assignedImportIndices[(int)import.Kind];
                    if (assigned != import.Index.Value)
                    {
                        throw new InvalidOperationException($"Import {import.Module}.{import.Name} of kind {import.Kind} assigned index {assigned}, needs {import.Index.Value}");
                    }
                }
                assignedImportIndices[(int)import.Kind]++;
                WriteImport(import);
            }
        }

        private void WriteExports()
        {
            WriteTableExport("table", 0);
            string[] functionExports = _uniqueSymbols.Keys.ToArray();
            // TODO-WASM: Handle exports better (e.g., only export public methods, etc.)
            // Also, see if we could leverage definedSymbols for this instead of doing our own bookkeeping in _uniqueSymbols.
            foreach (string name in functionExports.OrderBy(name => name))
            {

Review comment (suggestion):
The PR description says the new import section currently imports `__stack_pointer` and `__r2r_start`, but the implementation also changes the module to *import* `env.memory` (and removes the previously emitted memory section/export). Please update the PR description (or the code) so reviewers/consumers understand this behavioral/interface change.

Code after:
        }

        private protected override void EmitRelocations(int sectionIndex, List<SymbolicRelocation> relocationList)
        {
            // This is a no-op for now under Wasm
        }

        const int StackPointerGlobalIndex = 0;
        const int R2RStartGlobalIndex = 1;

        private WasmImport[] _defaultImports = new[]
        {
            null, // placeholder for memory, which is set up dynamically in WriteImports()
            new WasmImport("env", "__stack_pointer", import: new WasmGlobalImportType(WasmValueType.I32, WasmMutabilityType.Mut), index: StackPointerGlobalIndex),
            new WasmImport("env", "__r2r_start", import: new WasmGlobalImportType(WasmValueType.I32, WasmMutabilityType.Const), index: R2RStartGlobalIndex),
        };

        private void WriteImports()
        {
            // Calculate the minimum required memory size based on the combined data section size
            ulong contentSize = (ulong)SectionByName(WasmObjectNodeSection.CombinedDataSection.Name).ContentSize;
            uint dataPages = checked((uint)((contentSize + (1<<16) - 1) >> 16));
            uint numPages = Math.Max(dataPages, 1); // Ensure at least one page is allocated for the minimum

            _defaultImports[0] = new WasmImport("env", "memory", import: new WasmMemoryImportType(WasmLimitType.HasMin, numPages)); // memory limits: flags (0 = only minimum)

            int[] assignedImportIndices = new int[(int)WasmExternalKind.Count];
            foreach (WasmImport import in _defaultImports)
            {
                if (import.Index.HasValue)
                {
                    int assigned = assignedImportIndices[(int)import.Kind];
                    if (assigned != import.Index.Value)
                    {
                        throw new InvalidOperationException($"Import {import.Module}.{import.Name} of kind {import.Kind} assigned index {assigned}, needs {import.Index.Value}");
                    }
                }
                assignedImportIndices[(int)import.Kind]++;
                WriteImport(import);
            }
        }

        private void WriteExports()
        {
            WriteTableExport("table", 0);
            string[] functionExports = _uniqueSymbols.Keys.ToArray();
            // TODO-WASM: Handle exports better (e.g., only export public methods, etc.)
            // Also, see if we could leverage definedSymbols for this instead of doing our own bookkeeping in _uniqueSymbols.
            foreach (string name in functionExports.OrderBy(name => name))
            {
                WriteFunctionExport(name, _uniqueSymbols[name]);