I'm working on a Rust wrapper for the Duktape JavaScript interpreter. In a normal use case, the call stack will look like this:
- Rust: Arbitrary application code.
- Rust: My library wrapper.
- C: The Duktape interpreter.
- Rust: My Rust code.
- Rust: Arbitrary callbacks into application code.
What happens if (5) calls panic!
? According to various Rust developers on IRC, attempting to panic!
from inside non-Rust callframes like (3) may result in undefined behavior.
But according the Rust documentation, the only way to catch a panic!
is using std::task::try
, which spawns an extra thread. There's also rustrt::unwind::try
, which cannot be nested twice within a single thread, among other restrictions.
One solution, proposed by Benjamin Herr, is to abort the process if the code in (5) panics. I've packaged his solution as abort_on_panic
, and it appears to work, for values of "work" that include "crashing the entire program, but at least not corrupting things subtly":
abort_on_panic!("cannot panic inside this block", {
panic!("something went wrong!");
});
But is a way to emulate std::task::try
without the overhead of thread/task creation?
std::task::try
to actually spawn a new OS thread? It seems like it could be implemented to save some runtime state, invoke the "task" in the same OS thread, and restore the runtime state when it finishes. This would maintain the same public API as the current version, but it might save the cost of callingpthread_new
everything JavaScript calls out to Rust. – Adown