wasm-bindgen target/wasm32-unknown-unknown/debug/hello_world.wasm --out-dir ./pkg
浏览器调用顺序以下显示了当我们在浏览器中访问localhost:8080时发生的函数调用序列 。- index.js
- hello_world.js (调用hello_world_bg.js)
- helloworld_bg.wasm
const rust = import('./pkg/hello_world.js');rust.then(m => m.helloworld('World!')).catch(console.error);
index.js 导入了 hello_world.js 并调用其中的 helloworld 函数 。hello_world.js下面是hello_world.js的内容,在其中它调用了helloworld_bg.wasm
import * as wasm from "./hello_world_bg.wasm";import { __wbg_set_wasm } from "./hello_world_bg.js";__wbg_set_wasm(wasm);export * from "./hello_world_bg.js";
hello_world_bg.js// ...省去了部分代码export function helloworld(name) {const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);const len0 = WASM_VECTOR_LEN;wasm.helloworld(ptr0, len0);}
hello_world_bg.js 文件是由wasm-bindgen自动生成的,它包含了用于将DOM和JavaScript函数导入到Rust中的JavaScript粘合代码 。它还在生成的WebAssembly函数上向JavaScript公开了API 。Rust WebAssembly专注于将WebAssembly与现有的JavaScript应用程序集成在一起 。为了实现这一目标,我们需要在JavaScript和WebAssembly函数之间「传递不同的值、对象或结构 。这并不容易,因为需要协调两个不同系统的不同对象类型」 。
更糟糕的是,当前WebAssembly仅支持「整数」和「浮点数」,不支持字符串 。这意味着我们不能简单地将字符串传递给WebAssembly函数 。
要将字符串传递给WebAssembly,我们需要「将字符串转换为数字」(请注意在webpack.config.js中指定的TextEncoderAPI),将这些数字放入WebAssembly的内存空间中,最后「返回一个指向字符串的指针」给WebAssembly函数,以便在JavaScript中使用它 。在最后 , 我们需要释放WebAssembly使用的字符串内存空间 。
如果我们查看上面的JavaScript代码,这正是自动执行的操作 。helloworld函数首先调用passStringToWasm 。
- 这个函数在WebAssembly中「创建一些内存空间」,将我们的字符串转换为数字,将数字写入内存空间,并返回一个指向字符串的指针 。
文章插图
图片
- 然后将指针传递给wasm.helloworld来执行JavaScript的alert 。最后,wasm.__wbindgen_free释放了内存 。
反编译wasm到txt在前面的步骤中,我们注意到wasm-bindgen生成了一个hello_world.js文件 , 其中的函数调用到我们生成的hello_world_bg.wasm中的WebAssembly代码 。
基本上 , hello_world.js充当其他JavaScript(如index.js)与生成的WebAssembly的helloworld_bg.wasm之间的桥梁 。
我们可以通过输入以下命令进一步探索helloworld_bg.wasm:
wasm2wat hello_world_bg.wasm > hello_world.txt
这个命令使用wabt将WebAssembly转换为WebAssembly文本格式,并将其保存到一个hello_world.txt文件中 。打开helloworld.txt文件,然后查找$helloworld函数 。这是我们在src/lib.rs中定义的helloworld函数的生成WebAssembly函数 。$helloworld函数
文章插图
图片
在helloworld.txt中查找以下行:
(export "helloworld" (func $helloworld))
这一行导出了wasm.helloworld供宿主调用的WebAssembly函数 。我们通过hello_world_bg.js中的wasm.helloworld来调用这个WebAssembly函数 。文章插图
图片
接下来 , 查找以下行:
(import "./hello_world_bg.js" "__wbg_alert_9ea5a791b0d4c7a3" (func $hello_world::alert::__wbg_alert_9ea5a791b0d4c7a3::h93c656ecd0e94e40 (type 4)))
这对应于在hello_world_bg.js中生成的以下JavaScript函数:
推荐阅读
- AI 智能体能否取代工程经理?
- 学习Go编程
- 邮政编码的数字代表的都是什么,邮政编码的每一个数字代表什么?
- 部编版小学语文三年级下册第三单元测试卷
- ps能怎么样保存,ps编辑好的图片怎么保存
- C++中的多线程编程:一种高效的并发处理方式
- 利用Java AOP实现面向切面编程的关键技术
- 麻花的毛衣编织方法视频教程 麻花的毛衣编织方法
- 魔兽争霸3怎么编队,魔兽争霸3冰封王座编队快捷键技巧
- 64位和32位的区别,64位与32位编程的数据类型区别