Index: lld/trunk/test/wasm/data-layout.ll =================================================================== --- lld/trunk/test/wasm/data-layout.ll +++ lld/trunk/test/wasm/data-layout.ll @@ -16,7 +16,10 @@ ; RUN: wasm-ld -no-gc-sections --check-signatures --allow-undefined -o %t.wasm %t.o %t.hello.o ; RUN: obj2yaml %t.wasm | FileCheck %s -; CHECK: - Type: GLOBAL +; CHECK: - Type: MEMORY +; CHECK-NEXT: Memories: +; CHECK-NEXT: - Initial: 0x00000002 +; CHECK-NEXT: - Type: GLOBAL ; CHECK-NEXT: Globals: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Type: I32 @@ -54,6 +57,18 @@ ; CHECK-NEXT: - Type: CUSTOM +; RUN: wasm-ld -no-gc-sections --check-signatures --allow-undefined \ +; RUN: --initial-memory=131072 --max-memory=131072 -o %t_max.wasm %t.o \ +; RUN: %t.hello.o +; RUN: obj2yaml %t_max.wasm | FileCheck %s -check-prefix=CHECK-MAX + +; CHECK-MAX: - Type: MEMORY +; CHECK-MAX-NEXT: Memories: +; CHECK-MAX-NEXT: - Flags: [ HAS_MAX ] +; CHECK-MAX-NEXT: Initial: 0x00000002 +; CHECK-MAX-NEXT: Maximum: 0x00000002 + + ; RUN: wasm-ld --check-signatures --relocatable -o %t_reloc.wasm %t.o %t.hello.o ; RUN: obj2yaml %t_reloc.wasm | FileCheck %s -check-prefix=RELOC Index: lld/trunk/test/wasm/import-memory.test =================================================================== --- lld/trunk/test/wasm/import-memory.test +++ lld/trunk/test/wasm/import-memory.test @@ -11,3 +11,23 @@ # CHECK-NEXT: Kind: MEMORY # CHECK-NEXT: Memory: # CHECK-NEXT: Initial: 0x00000002 +# CHECK-NEXT: - Type: + + + +# RUN: wasm-ld --check-signatures --import-memory --initial-memory=262144 \ +# RUN: --max-memory=327680 -o %t.max.wasm %t.start.o +# RUN: obj2yaml %t.max.wasm | FileCheck -check-prefix=CHECK-MAX %s + +# Verify the --initial-memory and --max-memory arguments work with imports + +# CHECK-MAX: - Type: IMPORT +# CHECK-MAX-NEXT: Imports: +# CHECK-MAX-NEXT: - Module: env +# CHECK-MAX-NEXT: Field: memory +# CHECK-MAX-NEXT: Kind: MEMORY +# CHECK-MAX-NEXT: Memory: +# CHECK-MAX-NEXT: Flags: [ HAS_MAX ] +# CHECK-MAX-NEXT: Initial: 0x00000004 +# CHECK-MAX-NEXT: Maximum: 0x00000005 +# CHECK-MAX-NEXT: - Type: Index: lld/trunk/wasm/Writer.cpp =================================================================== --- lld/trunk/wasm/Writer.cpp +++ lld/trunk/wasm/Writer.cpp @@ -117,6 +117,7 @@ uint64_t FileSize = 0; uint32_t NumMemoryPages = 0; + uint32_t MaxMemoryPages = 0; std::vector Types; DenseMap TypeIndices; @@ -163,6 +164,10 @@ Import.Kind = WASM_EXTERNAL_MEMORY; Import.Memory.Flags = 0; Import.Memory.Initial = NumMemoryPages; + if (MaxMemoryPages != 0) { + Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX; + Import.Memory.Maximum = MaxMemoryPages; + } writeImport(OS, Import); } @@ -209,9 +214,12 @@ SyntheticSection *Section = createSyntheticSection(WASM_SEC_MEMORY); raw_ostream &OS = Section->getStream(); + bool HasMax = MaxMemoryPages != 0; writeUleb128(OS, 1, "memory count"); - writeUleb128(OS, 0, "memory limits flags"); + writeUleb128(OS, HasMax ? WASM_LIMITS_FLAG_HAS_MAX : 0, "memory limits flags"); writeUleb128(OS, NumMemoryPages, "initial pages"); + if (HasMax) + writeUleb128(OS, MaxMemoryPages, "max pages"); } void Writer::createGlobalSection() { @@ -599,9 +607,26 @@ log("mem: heap base = " + Twine(MemoryPtr)); } + if (Config->InitialMemory != 0) { + if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize)) + error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned"); + if (MemoryPtr > Config->InitialMemory) + error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed"); + else + MemoryPtr = Config->InitialMemory; + } uint32_t MemSize = alignTo(MemoryPtr, WasmPageSize); NumMemoryPages = MemSize / WasmPageSize; log("mem: total pages = " + Twine(NumMemoryPages)); + + if (Config->MaxMemory != 0) { + if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize)) + error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned"); + if (MemoryPtr > Config->MaxMemory) + error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed"); + MaxMemoryPages = Config->MaxMemory / WasmPageSize; + log("mem: max pages = " + Twine(MaxMemoryPages)); + } } SyntheticSection *Writer::createSyntheticSection(uint32_t Type,