Skip to content

fix(windows): qualify Wasmer V8 after upstream drops Sys compiler support #208

Description

@f0rr0

Decision and scope

Evaluate Wasmer's supported V8 backend on Windows before investing in a downstream Windows Sys/LLVM exception implementation. This issue tracks feasibility and qualification, not an already-approved engine migration or a claim that V8 fixes every Oliphaunt requirement.

Related: patch-consolidation follow-up #201 and correctness PR #202. This corrects the earlier recommendation in #201 to prioritize implementing MSVC exception handling ourselves: we had identified the missing implementation but missed upstream's explicit platform decision.

Upstream evidence

  • Wasmer PR #6826, merged 2026-08-06, drops Windows support for the Sys compiler backends (LLVM, Cranelift, Singlepass) in favor of V8. The author explicitly cites incomplete Windows support, including exception handling, relative to Linux/macOS.
  • Wasmer 7.4.0 LLVM source has a Windows compile_error! directing consumers to V8. This checks the compiler's build host; cross-compiling an AOT on Linux is not proof of a supported Windows execution path.
  • Wasmer 7.4.0 MSVC exception runtime still contains panic stubs. Updating the pinned dependency without changing the execution architecture is not a fix.
  • Windows and Rust embedding are not abandoned. Wasmer's Rust API supports a native V8 backend separately from its JavaScript-host backend. Do not conflate using V8 through Rust with reverting to our old TS/Wasmer-JS SDK path or borrowing Node's V8 isolate.

Prefer the merged implementation and exact versioned sources over stale general backend-support tables.

Actual Oliphaunt failure

On source 8e45be7e, Windows job 101905963703 successfully serialized, validated and installed AOT assets, then crashed in savepoints_error_recovery_and_indexed_updates at Wasmer 7.2.1 libcalls/eh/mod.rs:36, throw, exit 0xe06d7363. The earlier deliberate callback-panic test passed and was not the cause.

For an application, this means a query requiring ordinary PostgreSQL error recovery can abort execution instead of returning a recoverable SQL error. Successful startup/simple queries and successful AOT production do not establish correctness.

A retained small Linux-host cross-compilation probe also established that the consumed LLVM Windows target emits ELF/DWARF .eh_frame and GCC-style exception tables; the Windows loader's unwind registry expects Windows function metadata and ignores its eh_frame input. Fixing only the panic stubs would leave an incomplete compiler/loader/runtime contract. This inspection is not Windows execution proof.

Work plan

1. Small, bounded Windows feasibility probe

  • Choose and record an exact released Wasmer/V8/WASIX version combination, native Rust MSVC toolchain, V8 distribution and Windows runner image. Check required features and platform/version support in actual code/tests.
  • Run the smallest guest throw/catch/subsequent-call fixture on an actual Windows runner, through Wasmer's Rust V8 API. Exercise supported compiled-module caching/serialization separately; do not feed Sys/LLVM AOT artifacts to V8.
  • Cover nested exceptions, cross-module/imported tags, payload ownership/destruction, host callback boundaries, and normal calls after errors. Engine traps and Rust panics must remain distinct from recoverable guest exceptions.
  • Establish whether the WASIX features our embedded PostgreSQL actually uses work on this backend: memory sharing/growth, imports, dynamic linking/extensions where claimed, async/stack-switching paths, blocking I/O and shutdown. Stop and record a concrete blocker if not; a generic V8 feature checkbox is insufficient.

2. Integrate and validate the product only if the probe passes

  • Keep the public Rust and N-API APIs stable where possible. Explicitly assess library/isolate ownership in Node, Bun and Deno; do not assume their JS engines can be reused interchangeably.
  • Run real PostgreSQL in memory and durable directory modes: initialization/reopen, invalid SQL, constraints, savepoints, PL/pgSQL error cleanup, rollback, successful queries after errors, COPY/disconnect/reconnect and shutdown.
  • Validate directory durability without disabling fsync/synchronous_commit/full_page_writes. Include bounded terminal-fault teardown; no hangs or swallowed failures.
  • Validate deep-recursion SQL errors and subsequent reuse. The experimental wasmer-vm::remaining_execution_stack() API measures Sys coroutine stacks, not V8's stack. V8 needs its own proven safety strategy; browser behavior is separately scoped.
  • Compare startup/cold compilation, warm reopening/cache behavior, query RTT, varied INSERT/read/JSONB/mixed workloads, memory and package size. Preserve binaries and raw results; identify shared-host noise. A functioning backend is not automatically a performance win.

3. Consumption and release contract

  • Define Windows artifact identity, cache versioning/invalidation, distribution and licensing. Existing LLVM AOT payloads cannot simply be relabelled as V8 payloads. No assumption of equivalent AOT caching or startup cost.
  • Prove clean downstream Rust and N-API package consumption without an unpublished local Cargo patch. Record dependency ownership and supported versions.
  • Run focused Windows CI and Linux/macOS non-regression before changing supported-platform claims. Keep browser and non-WASIX native PostgreSQL products unchanged unless a separately justified change is required.
  • Record the outcome: adopt the qualified V8 path, address a bounded supported-backend defect, or explicitly decide whether to fund/maintain unsupported Sys/LLVM Windows support. Do not silently select the latter.

Acceptance / non-goals

Done means actual Windows SQL error recovery and continued use, both storage modes, clear terminal-fault behavior, distributable SDK artifacts, and measured/documented performance and packaging trade-offs. Compilation alone is not acceptance.

Do not close this by skipping recovery tests, swallowing exceptions, changing to GNU, silently falling back to native PostgreSQL, dropping Windows claims without a product decision, or blanket-increasing a stack size. Implementing a fresh Windows unwinder is not the default plan. Linux/macOS Sys stack-safety work may proceed independently, but does not close this issue.

Retained local diagnostic inputs

These are maintainer-local evidence, not public downloadable assets:

  • /home/sid/dev/wasmer-stack-budget-20260908/guest-probe/: WAT/source, retained Linux controls, Windows-target compiler dumps and inspection logs.
  • /home/sid/dev/wasmer-stack-budget-20260908/STACK-BUDGET-PROTOTYPE.md: exact experiment scope and results. Its earlier Windows-native SEH preference is superseded by this issue's V8-first decision.
  • target/patch-consolidation-evidence/windows-wasm-eh-20260908/ in the consolidation checkout: retained failing-CI excerpt and versioned runtime source.

No V8 migration or Windows fix has been implemented or qualified at issue creation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions