grow:Wasm 文字指令

grow 記憶體指令 會將記憶體例項的大小增加指定的頁數。

如果操作成功,該指令會將記憶體的先前大小(以頁為單位)新增到棧頂;如果操作失敗,則會新增 -1。目前每頁為 64KiB。

試一試

(module
  (import "console" "log" (func $log (param i32)))
  (memory 1 2) ;; start with one memory page, and max of 2 pages
  (func $main

    ;; grow memory by 1 page
    ;; grow returns in 1 for success and -1 for failure
    ;; will fail if you change to more more than 1 page
    (memory.grow (i32.const 1))
    call $log ;; log the result

  )
  (start $main)
)
const url = "{%wasm-url%}";
await WebAssembly.instantiateStreaming(fetch(url), { console });

語法

增長預設記憶體

wat
;; Grow default memory by a number of pages indicated by the top value on the stack
i32.const 3  ;; Number of pages to grow the memory (3)
memory.grow  ;; Grow the memory (by 3 pages)
;; the top item on the stack will now either be the previous number of pages (success) or `-1` (failure)

;; grow default memory by two pages using an S-function
(memory.grow (i32.const 2))

增長指定記憶體(如果支援多記憶體)

wat
;; Grow memory with index 1
i32.const 1 ;; Number of pages to grow specified memory (1)
memory.grow (memory 1) ;; Grow memory index 1

;; Grow memory with name $memory1
i32.const 1  ;; Number of pages to grow specified memory (1)
memory.grow (memory $memory1) ;; Grow $memory1 by 1 page

;; Grow memory with name $memory1 by three pages using an S-function
(memory.grow (memory $memory1) (i32.const 3))
;; Will return -1 as max value is 4!

指令和操作碼

指令 二進位制操作碼
memory.grow 0x40

示例

增長預設記憶體

新增到 Wasm 模組的第一個記憶體是預設記憶體,索引為 0。我們可以透過首先新增一個指定記憶體增長量的變數,然後呼叫 grow 來增長此記憶體。

下面的程式碼顯示了一個演示此的 WAT 檔案

wat
(module
  (import "console" "log" (func $log (param i32)))
  (memory 1 2) ;; default memory with one page and max of 2 pages

  (func $main
    ;; grow default memory by 1 page
    i32.const 1
    memory.grow
    call $log ;; log the result (previous no. pages = 1)

    ;; grow default memory, using an S-function
    (memory.grow (i32.const 1))
    call $log ;; log the result (-1: max is 2 pages for default memory declared above!)
  )
  (start $main) ;; call immediately on loading
)

上面我們不需要在 grow 指令中指定記憶體索引,但我們可以使用預設記憶體的名稱或索引(0)來做到這一點。下面的示例顯示了這一點。

為了完整起見,我們可以使用上面檔案 grow.wasm 的編譯版本,其程式碼與下面所示類似(log 函式被匯入到模組中,並由模組呼叫)

js
start();
async function start() {
  const importObject = {
    console: {
      log(arg) {
        console.log(arg);
      },
    },
  };
  const result = await WebAssembly.instantiateStreaming(
    fetch("grow.wasm"),
    importObject,
  );
}
start();

增長指定記憶體

當記憶體定義在 Wasm 模組中時,它們會從零開始按順序分配索引號。你可以透過在 grow 指令之後指定 memory 指令以及所需的索引或名稱(如果它有的話)來增長特定記憶體。如果你不指定特定記憶體,則使用索引為 0 的預設記憶體。

下面的模組顯示瞭如何直接按索引引用記憶體。

wat
(module
  (import "console" "log" (func $log (param i32)))
  (memory 1 2)  ;; Default memory with one page and max of 2 pages
  (memory $memory1 1 4)  ;; Memory with index 1, initial 1 page, max 4 pages
  (func $main
    ;; grow memory with index 1 by 1 page
    i32.const 1
    memory.grow (memory 1)
    call $log ;; log the result (previous no. pages = 1)
  )
  (start $main)
)

$main 函式的主體也可以使用以下任何選項來編寫

wat
i32.const 1
memory.grow (memory $memory1)  ;; referencing memory by name

;; Using S-functions
(memory.grow (memory 1) (i32.const 1))  ;; reference memory by index
(memory.grow (memory $memory1) (i32.const 1)) ;; reference memory by name

我們在示例中沒有使用預設記憶體。但如果你願意,也可以選擇指定此索引

wat
i32.const 1
memory.grow (memory 0)  ;; referencing memory by index

;; Using S-functions
(memory.grow (memory 0) (i32.const 1))  ;; reference default memory by index
;; We can't reference this particular default memory by name, because it doesn't have one!

可以使用與第一個示例相同的 JavaScript 程式碼載入 WAT 檔案。

規範

規範
未知規範
# syntax-instr-memory

瀏覽器相容性

webassembly.api.Memory.grow

webassembly.multiMemory

注意:multiMemory 相容性表顯示了 grow 可以與指定記憶體一起使用的版本。