Skip to main content

guarded

Function guarded 

Source
pub fn guarded(
    out: &mut CodeValue,
    source: &str,
    body: impl FnOnce(&mut CodeValue),
)
Expand description

Run a module’s dispatch body so that a panic inside it becomes an exception rather than killing the host.

Wrap every code_module_dispatch in this. The guarantee it provides cannot be provided by the host: a panic escaping an extern "C" function aborts the process rather than unwinding, so the host’s own catch_unwind never runs — the catch has to happen on this side of the FFI boundary, which is here.

What it covers is most of what “a badly written module” means in practice: unwrap/expect on None or Err, slice and index bounds, arithmetic overflow, explicit panic!/assert!, and panics raised inside dependencies. What it cannot cover is a deliberate exit, an infinite loop, or undefined behaviour reached through unsafe.

#[no_mangle]
pub unsafe extern "C" fn code_module_dispatch(
    out: *mut CodeValue,
    particle: *const CodeValue,
) {
    guarded(&mut *out, "mymodule", |out| match read_field_str(&*particle, "_class") {
        Some("Double") => { /* ... */ }
        _ => null(out),
    })
}