我刚刚开始查看WebAssembly MVP,并注意到无法访问堆栈和堆栈指针,或者确实存在任何结构化异常处理支持(throw / catch)等。
鉴于它应该是一个C编译目标,肯定必须能够实现setjmp
和longjmp
,但我无法理解如何做得很好。这个构造如何看待wast?
答案 0 :(得分:6)
WebAssembly MVP不支持零成本异常处理。
C ++异常处理和setjmp
/ longjmp
目前通过Emscripten实现,让每个try
或“invoke”执行对JavaScript的调用,并继续使用WebAssembly的C ++代码。然后抛出一个JavaScript异常,它会展开堆栈并处理展开代码所在的“登陆板”(通常是析构函数调用和catch
块)。这意味着每个延续都会收到一个布尔值:异常路径或常规路径。
这太贵了!如果LLVM无法证明函数调用无法抛出,那么其IR包含invoke
指令,并且Emscripten依赖此函数来插入异常处理代码。 C ++中的默认设置是任何东西都可以抛出,所以如果你看一下LLVM IR,当你用异常进行编译时,整个地方都会有invoke
。
零成本exception handling is being worked on at the moment,因此这种情况最终应该解决。这将用于实施setjmp
/ longjmp
。这可以启用setjmp
/ longjmp
的所有已定义行为,即在不调用C ++析构函数的情况下展开堆栈。但是,它不允许未定义的行为情况向前跳转到已经解开的堆栈,有时用于实现协同程序。