Expand description
Containing a failure the Studio did not expect.
The Studio runs the kernel, the English parser and the prover on the page’s own thread, so a bug in any of them — a panic, or the engine running out of stack on a deeply nested term — would take the whole page down with it. The web build aborts on panic, and an abort in wasm is a trap: it throws straight out of the module and leaves the page frozen mid-action.
contain runs work behind a boundary that turns such a failure into a Fault and leaves
the page running. In the browser the boundary is a JavaScript try/catch around a call back
into the module: a trap unwinds only the frames inside it. What the trap leaves behind is the
module’s shadow-stack pointer, still set to the depth where the work died, so the boundary puts
it back before any Rust runs again (build.rs exports __stack_pointer for this). A panic’s
own message is taken on its way out by a panic hook, because the trap that ends it carries
none. Natively a panic unwinds, and the boundary is catch_unwind.
What a trap cannot give back: the heap the abandoned frames owned stays allocated, and a
RefCell they held borrowed stays borrowed — a later use of it faults again, and is contained
again. And once a panic has been contained, std::thread::panicking() answers true for the
rest of the page’s life, because the abort that ended the panic never let std count it done.
Structs§
- Action
Fault - A Studio action that stopped on a fault: which action, and what stopped it.
- Fault
- A failure
containcaught.
Enums§
- Cause
- Why contained work stopped.