[WebAssembly] Add missing implementation for --initial/max-memory args
authorNicholas Wilson <nicholas@nicholaswilson.me.uk>
Wed, 14 Mar 2018 13:53:58 +0000 (13:53 +0000)
committerNicholas Wilson <nicholas@nicholaswilson.me.uk>
Wed, 14 Mar 2018 13:53:58 +0000 (13:53 +0000)
Previously, Config->InitialMemory/MaxMemory were hooked up to some
commandline args but had no effect at all.

Differential Revision: https://reviews.llvm.org/D44393

llvm-svn: 327508

lld/test/wasm/data-layout.ll
lld/test/wasm/import-memory.test
lld/wasm/Writer.cpp

index c4f6924..ece5f20 100644 (file)
@@ -16,7 +16,10 @@ target triple = "wasm32-unknown-unknown-wasm"
 ; 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 @@ target triple = "wasm32-unknown-unknown-wasm"
 ; 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 ab38c7a..955d2df 100644 (file)
 # 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 5bce63f..b6ffd1e 100644 (file)
@@ -117,6 +117,7 @@ private:
 
   uint64_t FileSize = 0;
   uint32_t NumMemoryPages = 0;
+  uint32_t MaxMemoryPages = 0;
 
   std::vector<const WasmSignature *> Types;
   DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo> TypeIndices;
@@ -163,6 +164,10 @@ void Writer::createImportSection() {
     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 @@ void Writer::createMemorySection() {
   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 @@ void Writer::layoutMemory() {
     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,