如何在WebAssembly中实现setjmp/longjmp?

mse*_*don 5 webassembly

我刚刚开始查看WebAssembly MVP,并注意到无法访问堆栈和堆栈指针,或者确实存在任何结构化异常处理支持(throw/catch)等.

鉴于它应该是一个C语言编译目标,这想必一定是可以实现setjmplongjmp,但我无法捉摸如何能够很好地完成.这个构造如何看待wast?

JF *_*ien 6

WebAssembly MVP不支持零成本异常处理.

C++异常处理和setjmp/ longjmp目前通过Emscripten实现,让每个try或"调用"执行对JavaScript的调用,并继续使用WebAssembly的C++代码.然后抛出一个JavaScript异常,它会展开堆栈并处理展开代码所在的"登陆板"(通常是析构函数调用和catch块).这意味着每个延续都会收到一个布尔值:异常路径或常规路径.

这太贵了!如果LLVM无法证明函数调用不能抛出,则其IR包含一条invoke指令,而Emscripten依赖于它来插入异常处理代码.C++中的默认设置是任何东西都可以抛出,所以如果你看一下LLVM IR,invoke当你用异常进行编译时就会出现这种情况.

目前正在开展零成本异常处理,因此这种情况最终应该得到解决.这将用于实现setjmp/ longjmp.这可以使得所有定义的行为setjmp/ longjmp,即展开堆栈而不调用C++析构函数.但是,它不允许未定义的行为情况向前跳转到已经展开的堆栈,有时用于实现协同程序.