Skip to content

Merge PR #40: OOM-safe VM pointer in loadLinked (jtakakura) + refinements#44

Merged
chaploud merged 2 commits intomainfrom
develop/fix-oom-uninit-vm
Apr 24, 2026
Merged

Merge PR #40: OOM-safe VM pointer in loadLinked (jtakakura) + refinements#44
chaploud merged 2 commits intomainfrom
develop/fix-oom-uninit-vm

Conversation

@chaploud
Copy link
Copy Markdown
Contributor

Closes #39. Based on @jtakakura's #40 (DRAFT) — his commit is preserved as the base of this branch for contributor credit.

Summary

  • Feature (by @jtakakura, 1 commit, rebased onto v1.9.0): Makes WasmModule.vm a nullable pointer (?*Vm). If allocator.create(Vm) fails in loadLinked after Phase 1 has already written into the shared store, the module stays alive (to keep the store consistent) with vm = null and apply_error = error.OutOfMemory. Subsequent invoke()/invokeInterpreterOnly() return the new error.ModuleNotFullyLoaded.
  • Refinement (on top, 1 commit): flattens the two invoke guards to const vm = self.vm orelse return error.ModuleNotFullyLoaded; and adds the missed null guard to WasmModule.cancel() (segfault fix for partially-loaded modules, matches the already-documented C API contract).
  • Rebase: conflict resolution on loadCore (combines @jtakakura's const vm = self.vm.?; extraction with the cancellable override line added in v1.9.0). CHANGELOG entry relocated under new [Unreleased] with PR/issue credit.

Test plan

  • zig build test — 399/399 pass (one more than v1.9.0: the new OOM-path test)
  • python3 test/spec/run_spec.py --build --summary — 62263/62263, 0 fail, 0 skip
  • bash test/e2e/run_e2e.sh --convert --summary — 796/796, 0 fail
  • bash test/realworld/run_compat.sh — PASS=50, FAIL=0, CRASH=0
  • bash test/c_api/run_ffi_test.sh --build — 80/80 pass
  • Minimal build — 268/283 (1 more than v1.9.0), 15 skip
  • Ubuntu x86_64 Merge Gate (running via OrbStack)
  • CI green

jtakakura and others added 2 commits April 24, 2026 18:09
Zig idiomatic pass on the null guards introduced for the `vm: ?*Vm` nullable
pointer. Replaces the two `if (self.vm) |vm| { ... } else return
error.ModuleNotFullyLoaded` blocks in `invoke`/`invokeInterpreterOnly` with
a single `const vm = self.vm orelse return error.ModuleNotFullyLoaded;` line,
flattening the body and matching how the rest of the codebase handles this
pattern.

Also adds a missed guard on `cancel()` — after the nullable refactor, calling
`self.vm.cancel()` on a partially-loaded module (OOM after Phase 1) would
segfault. The new `if (self.vm) |vm| vm.cancel();` matches the C API contract
that already documents cancel as a no-op on idle modules.

No behaviour change on the happy path; tests still 399/399.
@chaploud chaploud merged commit 9c9d1b6 into main Apr 24, 2026
5 checks passed
@chaploud chaploud deleted the develop/fix-oom-uninit-vm branch April 30, 2026 15:15
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.

WasmModule.loadLinked may return partially initialized module on OOM

2 participants