- WebAssembly 教程
- WebAssembly - 首页
- WebAssembly - 概述
- WebAssembly - 简介
- WebAssembly - WASM
- WebAssembly - 安装
- WebAssembly - 编译成 WASM 的工具
- WebAssembly - 程序结构
- WebAssembly - Javascript
- WebAssembly - Javascript API
- WebAssembly - 在 Firefox 中调试 WASM
- WebAssembly - “Hello World”
- WebAssembly - 模块
- WebAssembly - 验证
- WebAssembly - 文本格式
- WebAssembly - 将 WAT 转换为 WASM
- WebAssembly - 动态链接
- WebAssembly - 安全性
- WebAssembly - 使用 C 语言
- WebAssembly - 使用 C++
- WebAssembly - 使用 Rust
- WebAssembly - 使用 Go
- WebAssembly - 使用 Nodejs
- WebAssembly - 示例
- WebAssembly 有用资源
- WebAssembly - 快速指南
- WebAssembly - 有用资源
- WebAssembly - 讨论
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 命令。
示例
(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 将给出local value 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
)
)
函数 $add 必须使用 export 关键字导出,如下所示:
(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。