Merge PR #28: Execution cancellation API (jtakakura) + refinements#43
Merged
Merge PR #28: Execution cancellation API (jtakakura) + refinements#43
Conversation
perf: optimize atomic memory ordering in cancellation logic and add VS Code project settings
Restore the pre-cancellation `WasmModule.loadLinked(allocator, bytes, shared_store)` signature. The positional bool was breaking source compatibility and reading poorly at call sites (`loadLinked(..., true)` gave no clue what the literal meant). The VM default `cancellable = true` covers every current caller. Hosts that need to opt out can set `result.module.vm.cancellable = false` immediately after the call; a docstring note points at this escape hatch.
`WasmModule.Config` consistently uses `?T = null` for fields that override a Vm default, with null meaning "keep the default." `cancellable` stuck out as the lone non-optional. Normalise it to `?bool = null` and apply in `loadCore` only when set; this mirrors how `fuel`, `force_interpreter`, and friends are handled. The C API surface is unchanged — `zwasm_config_set_cancellable` still takes a plain bool — and `CApiConfig.toModuleConfig` now forwards the C-side value as a concrete optional. The default (true) is identical to the Vm default, so C callers who never touch the setter see no behavioural change.
The Zig docstring said "Has no effect if no function is currently executing," which understated an easy-to-miss sharp edge: `invoke()` calls `vm.reset()` before dispatching, which clears the cancel flag. A host that pre-arms cancel on an idle module has the request silently dropped when the next `invoke()` starts. Spell this out so callers know to race the cancel against a live invocation (the FFI test already encodes this by looping cancel calls across `invoke` start).
Captures the design behind PR #28: atomic flag piggybacking on the existing deadline checkpoints, JIT fuel cap to periodically fire the helper, reset-at- invoke semantics, and the cancellable=false opt-out for peak-throughput hosts.
Document the Zig/C/CLI surface added by PR #28 and the default-on JIT checkpoint behaviour so v1.9.0 release notes can be assembled from the Unreleased block without archaeology.
Mac aarch64 / ReleaseSafe / hyperfine 5 runs + 3 warmup. Long benches (st_fib2, st_sieve, st_matrix, tgo_nqueens, tgo_list, tgo_mfr) are all within ±1% of the v1.8.0 baseline — the default-on JIT periodic check-in has no measurable impact on the hot path. Several sub-10ms and string-heavy benches show high variance (hyperfine flagged statistical outliers on gc_tree_cached specifically), which is laptop-class measurement noise rather than a signal. The authoritative Ubuntu x86_64 numbers will land at Merge Gate time.
This was referenced Apr 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #27. Supersedes #28 (keeps @jtakakura's commits intact as the first three on this branch).
Summary
Vm.cancel()/WasmModule.cancel()/zwasm_module_cancel()— thread-safe async abort via atomic flag, polled at the existing deadline checkpoints (interpreter: every ~1024 instructions; JIT: viajit_fuelcap firingjitFuelCheckHelper).Config.cancellable/zwasm_config_set_cancellable().error.Canceled, FFI cross-thread test, docs + book (en/ja).loadLinked(..., cancellable: bool)signature breakage — rely on Vm default, expose opt-out via post-load flag flip.Config.cancellable→?bool = nullto match sibling fields (fuel,force_interpreter, ...).WasmModule.cancel()Zig API.D134decision entry in.dev/decisions.md.[Unreleased]Added/Changed block.PR28inbench/history.yaml(long benches ±1% of v1.8.0).Test plan
zig build test— 398/398 pass, 0 leak (Mac aarch64)python3 test/spec/run_spec.py --build --summary— 62263/62263, 0 fail, 0 skipbash test/e2e/run_e2e.sh --convert --summary— 796/796, 0 failbash test/realworld/run_compat.sh— PASS=50, FAIL=0, CRASH=0bash test/c_api/run_ffi_test.sh --build— 80/80 pass (includes cross-thread cancel test)-Djit=false -Dcomponent=false -Dwat=false— 267 pass, 15 skip