grow:Wasm 文本指令

grow 内存指令 将内存实例的大小增加指定的页数。

如果操作成功,该指令会将内存的先前大小(以页为单位)添加到堆栈的顶部;如果操作失败,则会添加 -1。目前,每页为 64KiB。

尝试一下

语法

扩展默认内存

wasm
;; 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))

扩展指定内存(如果支持多内存)

wasm
;; 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 文件

wasm
(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,并使用类似于以下代码的代码(日志函数导入到模块中,并由模块调用)

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 的默认内存。

下面的模块展示了如何通过索引直接引用内存。

wasm
(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 函数的主体也可以使用以下任何选项编写

wasm
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

我们没有在示例中使用默认内存。但您也可以选择指定此索引,如果您需要的话。

wasm
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

浏览器兼容性

注意: Wasm 模块中的 grow 支持与 JavaScript Memory.grow() API 中的增长支持相匹配。multiMemory 键指示可以在其中使用 grow 的版本,并指定了内存。

webassembly.api.Memory.grow

BCD 表格仅在浏览器中加载

webassembly.multiMemory

BCD 表格仅在浏览器中加载