Skip to content

fix: auto-detect schedule_reinit and tighten termination guard#5083

Merged
guybedford merged 10 commits into
mainfrom
feat/abort-reinit
Apr 8, 2026
Merged

fix: auto-detect schedule_reinit and tighten termination guard#5083
guybedford merged 10 commits into
mainfrom
feat/abort-reinit

Conversation

@guybedford

@guybedford guybedford commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

This disables the auto-reinit functionality of aborts with --experimental-reset-state-function to instead require an explicit call to the schedule_reinit() function. In addition, any use of schedule_reinit() will automatically bring in the reinit machinery by treating it as an intrinsic.

schedule_reinit() sets a private JS-side flag instead of writing to a __instance_terminated sentinel value. This means:

  • schedule_reinit() can be called during normal execution without triggering a trap — the current call completes normally and the reset happens on the next export call
  • the abort-then-reinit path still works: the abort hook fires, calls schedule_reinit(), and the guard resets instead of throwing
  • __instance_terminated is a clean boolean (0 = live, 1 = terminated) with no internal sentinel values leaked into the public spec

Usage for abort on reinit:

fn on_abort() {
    wasm_bindgen::handler::schedule_reinit();
}

#[wasm_bindgen(start)]
fn start() {
    wasm_bindgen::handler::set_on_abort(on_abort);
    wasm_bindgen::handler::set_on_reinit(on_reinit);
}

A new guide section is added "Handling Aborts" covering these behaviours as a separate guide page to "Catching Panics".

What changed:

  • renamed reinit() to schedule_reinit() to reflect that it schedules reinitialization for the next export call
  • __wbindgen_reinit intrinsic now sets a JS variable (__wbg_reinit_scheduled) instead of writing -1 to linear memory
  • __wbg_handle_catch unconditionally writes 1 (no conditional to preserve a sentinel)
  • __wbg_reset_state only references __wbg_called_abort / __wbg_reinit_scheduled when the catch handler machinery is active, fixing a ReferenceError on panic=abort builds with --experimental-reset-state-function
  • auto-detection of schedule_reinit() usage emits private reinit machinery without --experimental-reset-state-function
  • updated guide: __instance_terminated documented as boolean, schedule_reinit docs note it works outside abort context
  • remove on_reinit for now, now that we support multiple start functions instead

Test coverage: termination, termination_abort_handler, termination_reset_state, termination_reinit, and termination_reinit_auto_detect all pass.

@guybedford guybedford changed the title feat: add --abort-reinit flag for automatic module reinitialization fix: remove --abort-reinit flag, fix termination guard sentinel handling Apr 7, 2026
@guybedford guybedford changed the title fix: remove --abort-reinit flag, fix termination guard sentinel handling fix: termination guard sentinel handling, stabilize --reset-state-function Apr 7, 2026
@guybedford guybedford force-pushed the feat/abort-reinit branch 3 times, most recently from 7498784 to ecfa5e4 Compare April 8, 2026 00:08
@guybedford guybedford changed the title fix: termination guard sentinel handling, stabilize --reset-state-function fix: auto-detect schedule_reinit and tighten termination guard Apr 8, 2026
@guybedford guybedford force-pushed the feat/abort-reinit branch 2 times, most recently from b6d6d15 to 0b1e7fc Compare April 8, 2026 01:27
Auto-detect the __wbindgen_reinit intrinsic so schedule_reinit() emits
private reinit machinery without --experimental-reset-state-function.
Keep the experimental flag only for the public __wbg_reset_state()
export and instance-id tracking.

Tighten termination handling to distinguish hard termination from
scheduled reinit, preserve the sentinel through __wbg_handle_catch,
and invoke the abort hook for host-initiated termination before
re-checking the flag. Rename reinit() to schedule_reinit() and update
coverage and guide docs accordingly.
…to boolean

Decouples reinit from the abort path — schedule_reinit() no longer
triggers a Wasm trap, so the current call completes normally and the
reset happens on the next export call. The abort-then-reinit path still
works: the abort hook fires, calls schedule_reinit(), and the guard
resets instead of throwing.

The __instance_terminated address is now a simple boolean (0/1). Reinit
state is tracked via a private __wbg_reinit_scheduled JS variable.

Also removes the imports_without_catch_wrapper mechanism since the reinit
intrinsic no longer writes to the terminated flag.

@hoodmane hoodmane left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine to me.

Comment thread crates/cli/src/wasm_bindgen.rs Outdated
@guybedford guybedford merged commit a44bc04 into main Apr 8, 2026
62 of 63 checks passed
@guybedford guybedford deleted the feat/abort-reinit branch April 8, 2026 23:35
@guybedford guybedford mentioned this pull request Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants