WebAssembly - 文本格式


WebAssembly 的代码采用二进制格式,称为 WASM。您还可以在 WebAssembly 中获取文本格式,它称为 WAT(WebAssembly 文本格式)。作为开发人员,您不应该在 WebAssembly 中编写代码,相反,您必须将 C、C++ 和 Rust 等高级语言编译为 WebAssembly。

瓦特代码

让我们逐步编写WAT代码。

步骤 1 - WAT 的起点是声明模块。

(module)

步骤 2 - 现在让我们以函数的形式向其添加一些功能。

该函数声明如下 -

(func <parameters/result> <local variables> <function body>)

该函数以 func 关键字开头,后跟参数或结果。

参数/结果

参数和返回值作为结果。

wasm 支持的参数可以是以下类型 -

  • i32:32 位整数
  • i64:64 位整数
  • f32:32 位浮点数
  • f64:64 位浮点数

函数的参数编写如下 -

  • (参数 i32)
  • (参数 i64)
  • (参数 f32)
  • (参数 f64)

结果将写成如下 -

  • (结果 i32)
  • (结果 i64)
  • (结果 f32)
  • (结果 f64)

带有参数和返回值的函数定义如下 -

(func (param i32) (param i32) (result i64) <function body>)

局部变量

局部变量是您的函数中需要的变量。该函数的局部值将定义如下 -

(func (param i32) (param i32) (local i32) (result i64) <function body>)

函数体

函数体是要执行的逻辑。最终的程序将如下所示 -

(module (func (param i32) (param i32) (local i32) (result i64) <function body>) )

步骤 3 - 读取和设置参数和局部变量。

要读取参数和局部变量,请使用get_localset_local命令。

例子

(module 
   (func (param i32) (param i32) (local i32) (result i64) get_local 0 
      get_local 1 
      get_local 2 
   ) 
)

根据函数签名,

  • get_local 0将给出参数 i32

  • get_local 1将给出下一个参数param i32

  • get_local 2将给出本地值 i32

您也可以在参数之前使用名称,并在名称前加上美元符号作为前缀,而不是使用 0、1、2 等数值来引用参数和局部变量。

以下示例显示如何将名称与参数和局部变量一起使用。

例子

(module 
   (func 
      (param $a i32) 
      (param $b i32) 
      (local $c i32) 
      (result i64) get_local $a get_local $b get_local $c 
   ) 
)

步骤 4 - 函数体中的指令和执行。

wasm 中的执行遵循堆栈策略。执行的指令被一条一条地送入堆栈。例如,指令 get_local $a 将推送值,它在堆栈上读取。

像i32.add这样添加的指令将从堆栈中弹出元素。

(func (param $a i32) (param $b i32) 
   get_local $a 
   get_local $b 
   i32.add
)

i32.add的指令是($a+$b)。i32.add 的最终值将被推送到堆栈上,并将其分配给结果。

如果函数签名声明了结果,则执行结束时堆栈中应该有一个值。如果没有结果参数,则堆栈最后必须为空。

因此,最终代码和函数体如下 -

(module 
   (func (param $a i32) (param $b i32) (result i32) 
      get_local $a
      get_local $b 
      i32.add
   )
)

步骤 5 - 调用该函数。

函数体的最终代码如步骤 4 所示。现在,要调用该函数,我们需要导出它。

要导出函数,可以使用 0,1 等索引值来完成,但是,我们也可以给出名称。该名称将以 $ 为前缀,并将其添加在 func 关键字之后。

例子

(module 
   (func $add (param $a i32) (param $b i32) (result i32) 
      get_local $a 
      get_local $b i32.add
   ) 
)

必须使用 export 关键字导出函数 $add ,如下所示 -

(module 
   (func $add 
      (param $a i32) 
      (param $b i32) 
      (result i32) 
      get_local $a get_local $b i32.add
   ) 
   (export "add" (func $add))
)

要在浏览器中测试上述代码,您必须将其转换为二进制形式(.wasm)。请参阅下一章,了解如何将.WAT 转换为 .WASM。