WebAssembly模块可以抛出异常,以便解锁事件循环,以便可以通过其他同步代码来处理事件.目前我能找到的唯一这样的例子是Rust's winit crate.请注意,throw的实现方式如下:

pub fn throw(msg: &str) {
    wasm_bindgen::throw_str(msg);
}

我预计抛出这样的异常将展开WebAssembly堆栈.此外,即使堆栈没有展开,一旦处理了事件(如果有),如何才能重新展开堆栈呢?

推荐答案

抛出一个WASM异常并不是"让步".它不会"倒带堆栈".它更类似于panic-它将终止当前的执行,直到某个东西(通常是浏览器)捕捉到它.没有任何工具可以在代码引发时恢复执行代码.

现在,浏览器可以通过执行其他处理程序和事件再次调用您的代码,但您抛出的点上的堆栈已经消失-类似于在捕捉到catch_unwind死机后恢复执行.


对于为什么Winit的run函数会这样做的特定问题:

EventLoop::run函数的约定是它启动事件循环并永远运行而不再返回(因此返回类型为!).对于桌面平台,这是相当简单的,因为EventLoop类型负责实际设置和运行事件循环.

但在浏览器中,情况要复杂得多.实际的事件循环是由浏览器运行的,而不是由Winit运行的,EventLoop::run需要将控制权返回给该事件循环,以便它可以"启动",但实际上不会返回到Rust代码.

最简单的方法是抛出一个伪异常.异常将中断WASM代码进入浏览器,然后浏览器将开始执行winit和其他设置的所有事件和回调.

Rust相关问答推荐

重新导出proc宏导致未解决的extern crate错误""

空字符串转换为Box字符串时是否分配?<>

泛型属性比较

为什么幻影数据不能自动推断?

创建包含缺失值的框架

Rust:跨多个线程使用hashmap Arc和rwlock

为什么我可以跟踪以前borrow 过的变量?房主在哪里?

像这样的铁 rust 图案除了‘选项’之外,还有其他 Select 吗?

更合理的方法来设计样条线函数器?

Nom 解析器无法消耗无效输入

更新 rust ndarray 中矩阵的一行

Rust中的位移操作对范围有什么影响?

如何限制通用 const 参数中允许的值?

一个函数调用会产生双重borrow 错误,而另一个则不会

如何使用泛型满足 tokio 异步任务中的生命周期界限

内部值发生变化时 Rc 的行为

如何使返回 XMLError 的方法与 anyhow::Error 兼容?

将文件的第一行分别读取到文件的其余部分的最有效方法是什么?

BigUint 二进制补码

如何在 Rust 中构建一个 str