Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would setjmp/longjmp be implemented in WebAssembly?

Tags:

webassembly

I've just started looking at WebAssembly MVP, and notice that there is no access to the stack and stack pointer, or indeed any structured exception handling support (throw/catch) etc.

Given it is supposed to be a C compilation target, it surely must be possible to implement setjmp and longjmp, but I can't fathom how this can be done nicely. How does this construct look in wast?

like image 282
mseddon Avatar asked May 30 '17 13:05

mseddon


Video Answer


1 Answers

Zero-cost exception handling isn't supported in the WebAssembly MVP.

C++ exception handling and setjmp/longjmp are currently implemented through Emscripten by having each try or "invoke" perform a call to JavaScript with a continuation to WebAssembly's C++ code. A throw then throws a JavaScript exception, which unwinds the stack and handles the "landingpad" where unwinding code lives (usually destructor calls and catch blocks). This means that every continuation receives a boolean value: exception path or regular path.

This is super expensive! If LLVM can't prove that a function call can't throw then its IR contains an invoke instruction, and Emscripten relies on this to insert exception handling code. The default in C++ is that anything can throw, so if you look at LLVM IR there are invokes all over the place when you compile with exceptions.

Zero-cost exception handling is being worked on at the moment, so this situation should resolve eventually. This will be used to implement setjmp/longjmp. This can enable all of the defined behavior of setjmp/longjmp, namely unwinding the stack without calling C++ destructors. It does not, however, allow the undefined behavior case of jumping forward to a stack that was already unwound which is sometimes used to implement coroutines.

like image 110
JF Bastien Avatar answered Sep 20 '22 00:09

JF Bastien