- 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 - 模块
我们已经了解了如何从 c/c++ 代码中获取 .wasm 文件。在本章中,我们将把 wasm 转换为 WebAssembly 模块,并在浏览器中执行它。
让我们使用如下所示的 C++ 阶乘代码 -
int fact(int n) { if ((n==0)||(n==1)) return 1; else return n*fact(n-1); }
打开 Wasm Explorer,它位于 https://mbebenita.github.io/WasmExplorer/ 如下所示 -
第一列包含 C++ 阶乘函数,第二列包含 WebAssembly 文本格式,最后一列包含 x86 汇编代码。
WebAssembly 文本格式 -
(module (table 0 anyfunc) (memory $0 1) (export "memory" (memory $0)) (export "_Z4facti" (func $_Z4facti)) (func $_Z4facti (; 0 ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (i32.const 1) ) (block $label$0 (br_if $label$0 (i32.eq (i32.or (get_local $0) (i32.const 1) ) (i32.const 1) ) ) (set_local $1 (i32.const 1) ) (loop $label$1 (set_local $1 (i32.mul (get_local $0) (get_local $1) ) ) (br_if $label$1 (i32.ne (i32.or (tee_local $0 (i32.add (get_local $0) (i32.const -1) ) ) (i32.const 1) ) (i32.const 1) ) ) ) ) (get_local $1) ) )
C++ 函数 fact 已在 WebAssembly 文本格式中导出为“_Z4facti”。
单击下载按钮下载 wasm 代码,并将文件保存为 factorial.wasm。
现在,要将 .wasm 代码转换为模块,我们需要执行以下操作 -
步骤 1
使用 ArrayBuffer. 将 .wasm 转换为数组缓冲区。ArrayBuffer 对象将返回一个固定长度的二进制数据缓冲区。
步骤 2
来自 ArrayBuffer 的字节必须使用 WebAssembly.compile(buffer) 函数编译成模块。
WebAssembly.compile() 函数编译并从给定的字节返回一个 WebAssembly.Module。
这是步骤 1 和 2 中讨论的 Javascript 代码。
<script type="text/javascript"> let factorial; fetch("factorial.wasm") .then(bytes => bytes.arrayBuffer()) .then(mod => WebAssembly.compile(mod)) .then(module => {return new WebAssembly.Instance(module) }) .then(instance => { factorial = instance.exports._Z4facti; console.log('Test the output in Brower Console by using factorial(n)'); }); </script>
代码说明
Javascript 浏览器 API fetch 用于获取 factorial.wasm 的内容。
使用 arrayBuffer() 将内容转换为字节。
通过调用 WebAssembly.compile(mod) 从字节创建模块。
使用 new 创建模块的实例
WebAssembly.Instance(module)
阶乘函数导出 _Z4facti 通过使用 WebAssembly.Module.exports() 分配给变量 factorial。
示例
这是 module.html 以及 javascript 代码 -
module.html
<!doctype html> <html> <head> <meta charset="utf-8"> <title>WebAssembly Module</title> </head> <body> <script> let factorial; fetch("factorial.wasm") .then(bytes => bytes.arrayBuffer()) .then(mod => WebAssembly.compile(mod)) .then(module => {return new WebAssembly.Instance(module) }) .then(instance => { factorial = instance.exports._Z4facti; console.log('Test the output in Browser Console by using factorial(n)'); }); </script> </body> </html>
输出
在浏览器中执行 module.html 以查看输出 -