From 04a5980ec64eb5f83348e055093a702992e12bbd Mon Sep 17 00:00:00 2001 From: Mark Peerdeman Date: Wed, 4 Oct 2023 12:31:37 +0200 Subject: [PATCH] Fix memory for WASI mode Make sure that in WASI mode, memory is created internally. --- llvm/include/llvm/Cheerp/WasmWriter.h | 1 + llvm/lib/CheerpWriter/CheerpWasmWriter.cpp | 46 ++++++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/Cheerp/WasmWriter.h b/llvm/include/llvm/Cheerp/WasmWriter.h index 7f81c37a6e13..38160b994ca0 100644 --- a/llvm/include/llvm/Cheerp/WasmWriter.h +++ b/llvm/include/llvm/Cheerp/WasmWriter.h @@ -371,6 +371,7 @@ class CheerpWasmWriter final : public CheerpBaseWriter void compileFunctionSection(); void compileImportSection(); void compileTableSection(); + void compileMemorySection(); void compileGlobalSection(); void compileExportSection(); void compileElementSection(); diff --git a/llvm/lib/CheerpWriter/CheerpWasmWriter.cpp b/llvm/lib/CheerpWriter/CheerpWasmWriter.cpp index e8ecc4884a4f..fa5497ab62a8 100644 --- a/llvm/lib/CheerpWriter/CheerpWasmWriter.cpp +++ b/llvm/lib/CheerpWriter/CheerpWasmWriter.cpp @@ -4427,14 +4427,18 @@ void CheerpWasmWriter::compileImportSection() numberOfImportedFunctions = importedTotal; + if (!useWasmLoader && importedTotal == 0) + return; + Section section(0x02, "Import", this); // Encode number of entries in the import section. - // The +1 is for memory that we import unconditionally. - encodeULEB128(importedTotal + 1, section); + // We import the memory in all cases, except when the target is WASI. + encodeULEB128(importedTotal + useWasmLoader, section); - // Import the memory - compileImportMemory(section); + // Import the memory if target is not WASI. + if (useWasmLoader) + compileImportMemory(section); for (const Function* F : globalDeps.asmJSImports()) { @@ -4586,6 +4590,37 @@ CheerpWasmWriter::GLOBAL_CONSTANT_ENCODING CheerpWasmWriter::shouldEncodeConstan } } +void CheerpWasmWriter::compileMemorySection() +{ + // Define the memory for the module in WasmPage units. The heap size is + // defined in MiB and the wasm page size is 64 KiB. Thus, the wasm heap + // max size parameter is defined as: heapSize << 20 >> 16 = heapSize << 4. + uint32_t maxMemory = heapSize << 4; + uint32_t minMemory = (linearHelper.getHeapStart() + 65535) >> 16; + + // TODO use WasmPage variable instead of hardcoded '1>>16'. + assert(WasmPage == 64 * 1024); + + if (noGrowMemory) + minMemory = maxMemory; + + { + Section section(0x05, "Memory", this); + encodeULEB128(1, section); + // from the spec: + //limits ::= 0x00 n:u32 => {min n, max e, unshared} + // 0x01 n:u32 m:u32 => {min n, max m, unshared} + // 0x03 n:u32 m:u32 => {min n, max m, shared} + // We use 0x01 and 0x03 only for now + int memType = sharedMemory ? 0x03 : 0x01; + encodeULEB128(memType, section); + // Encode minimum and maximum memory parameters. + encodeULEB128(minMemory, section); + encodeULEB128(maxMemory, section); + section.encode(); + } +} + void CheerpWasmWriter::compileGlobalSection() { // Temporary map for the globalized constants. We update the global one at the end, to avoid @@ -5065,6 +5100,9 @@ void CheerpWasmWriter::compileModule() compileTableSection(); + if (!useWasmLoader) + compileMemorySection(); + compileGlobalSection(); compileExportSection();