duktape
duktape copied to clipboard
Using duktape without setjmp/longjmp or C++ exceptions
I do not need the ability to catch JS exceptions in my application. In fact, it is acceptable to me if the whole process aborts when a JS-level exception is thrown. If I use something like:
#define DUK_SETJMP(...)
# define DUK_LONGJMP(...) abort()
This seems like what I want. Will this cause other bad side effects in duktape (that is, are setjmp/longjmp used for internal purposes other than implementing JS-level exceptions?) Grepping the code it seems these are not called in many places, so I'm hoping this will do what I want.
First off, you'd be treading on a somewhat risky path as setjmp/longjmp (or C++ exceptions) are assumed to work throughout. So I can't really recommend this - can you describe quickly why you want to avoid setjmp/longjmp, e.g. are they not available by default and you don't want to tackle implementing them?
But, as for the question itself:
There used to be a case for handling a complex return (when a return
needs unwinding of lexical scopes) which used longjmp() even when no JS-level exception occurred from the user's perspective.
I think this should no longer happen (it was optimized away to benefit e.g. Emscripten builds), but if you're trying this approach, you should ensure that e.g. this works:
function test() {
with ({}) {
return 123; // Would cause an internal longjmp() in older versions
}
}
print(test());
Another case where longjmp() is still used is a coroutine yield. It will cause a longjmp() even when no JS-level exception occurs.
are they not available by default and you don't want to tackle implementing them?
Correct. I'm in a non-browser WASM environment.
Thanks for the pointers! I expect we can also live without yield at the moment, but a good case to keep in mind that I hadn't thought of.
FWIW, I've compiled Duktape with the WASI SDK (https://github.com/CraneStation/wasi-sdk) and it does run if one defined DUK_SETJMP as 0
and DUK_LONGJMP as abort()
. Obviously this is not ideal because duk_cmdline depends on setjmp AFAICT, so code runs until an exception is hit :-) When I say it runs, I mean using the wasmtime runtime.
The test in https://github.com/svaarala/duktape/issues/2071#issuecomment-487415550 runs properly too.
There is currently no support for setjmp/longjmp nor C++ exceptions: https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-intro.md#cc due to the lack of unwinding support on WebAssembly, apparently.
Now, this is all very experimental, but exciting none the less :-) @svaarala do you have any ideas on what to do in order to get duk_cmdline working without setjmp so exceptions also work?
At present there is a hard assumption on having some long control transfer primitive, i.e. longjmp or C++ exception throw. Removing this assumption would mean that the entire public API would need to use a different philosophy: every call would need an explicit success/failure return value, and call sites would need a lot of tedious cold path error checking. There would be upsides to a different API too, but for me the Lua-style API (with long control transfer on error) is definitely preferable.
Gotcha. Fron the linked document: WASI doesn't yet support setjmp/longjmp or C++ exceptions, as it is waiting for unwinding support in WebAssembly.
so it looks like we'll just have to wait unti some exception handling is added to WASI.
Thanks for chiming in!
It's a bit surprising exception handling is not part of the MVP: setjmp/longjmp are standard functions and used by several libraries (at least parsers) and C++ exceptions are also very widely used. Let's hope exceptions come soon :)
For the curious, here is my hack wasiduk: https://github.com/saghul/wasi-lab/tree/master/wasiduk