2017-05-30 41 views
3

我刚刚开始看WebAssembly MVP,并注意到没有访问堆栈和堆栈指针,或者确实有任何结构化的异常处理支持(throw/catch)等。如何在WebAssembly中实现setjmp/longjmp?

鉴于它应该是一个C编译目标,它肯定有可能实现setjmplongjmp,但我无法理解这可以如何很好地完成。这个构造看起来如何呢?

回答

3

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

C++异常处理和setjmp/longjmp目前实现通过由具有各try或“调用”执行与延续的JavaScript调用WebAssembly的C++代码Emscripten。然后抛出一个JavaScript异常,它将展开堆栈并处理展开代码所在的“着陆板”(通常是析构函数调用和块)。这意味着每个continuation都会收到一个布尔值:异常路径或常规路径。

这是超级贵!如果LLVM不能证明函数调用不能抛出,那么它的IR包含一个invoke指令,并且Emscripten依靠这个来插入异常处理代码。 C++中的默认值是任何东西都可以抛出,所以如果你看看LLVM IR,当你编译异常的时候,全是invoke

零成本exception handling is being worked on at the moment,所以这种情况应该最终解决。这将用于实现setjmp/longjmp。这可以启用所有定义的行为setjmp/longjmp,即在不调用C++析构函数的情况下展开堆栈。然而,它并不允许未定义的行为跳转到一个已经解开的堆栈,有时用于实现协程。

+0

啊哈!难怪我无法弄清楚它!这远非理想,但为了公平,我认为最大的收获是目前所有主要的浏览器供应商都在船上并运送或即将发运MVP。 – mseddon