WebAssembly - 文本格式
WebAssembly 具有称为 WASM 的二进制格式的代码。 您还可以在 WebAssembly 中获取文本格式,它称为 WAT(WebAssembly 文本格式)。 作为开发人员,您不应该在 WebAssembly 中编写代码,相反,您必须将 C、C++ 和 Rust 等高级语言编译为 WebAssembly。
WAT 代码
让我们逐步编写WAT代码。
步骤 1 − WAT 的起点是声明模块。
(module)
步骤 2 − 现在让我们以函数的形式为其添加一些功能。
函数声明如下所示 −
(func <parameters/result> <local variables> <function body>)
函数以 func 关键字开头,后跟参数或结果。
参数/结果
参数和结果返回值。
wasm 支持的参数可以是以下类型 −
- i32:32 位整数
- i64:64 位整数
- f32:32 位浮点数
- f64:64 位浮点数
函数的参数如下所示 −
- (param i32)
- (param i64)
- (param f32)
- (param f64)
结果会写成如下 −
- (result i32)
- (result i64)
- (result f32)
- (result 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_local和set_local command.
示例
(module (func (param i32) (param i32) (local i32) (result i64) get_local 0 get_local 1 get_local 2 ) )
根据函数签名,
get_local 0 将给出 param 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。