feat(wasm-eh): migrate the WASM build to native wasm exceptions (+ 3D viewer default-on)
Replace the legacy Emscripten JS-exceptions model with native wasm-EH (legacy encoding) across the whole build, keeping Asyncify coroutines working via a from-source Binaryen --hoist-cpp-catches pre-pass. Net result: native-EH is the only build mode, the 3D viewer is on by default, and pcbnew shrinks substantially. Highlights: - Binaryen submodule everywhere + --hoist-cpp-catches integration in apply-asyncify; post-link Asyncify covers every app wasm (not just standalone test wasm). - Build deps (incl. OpenCASCADE without OCC_CONVERT_SIGNALS) and all KiCad apps with -fwasm-exceptions; emscripten_sleep added to the post-link asyncify-imports. - libcontext fiber entry wired under native exceptions; while-loop main loop + currData shim injected into all wx apps. - Native-EH collab apply fixed: DEBUG-define the embind TU + match all out-of-CMake C++ TUs' ABI flags to the core, fixing the vtable-layout skew / mis-dispatch. - 3D viewer enabled by default (real raytracer linked, not the stub). - Retire the EH-spike scaffolding; flip the asyncify-races ablation pins to shim-redundancy pins (native-EH stays clean with the legacy shims ablated). - Fix the asyncify-races quiescence check to not require Asyncify.currData==0: under the native-EH per-frame-yield top loop the main stack is asyncify-suspended every frame, so currData legitimately churns (a freed-but-not-yet-nulled buffer, not a leak). Refresh the pcbnew toolbar screenshot baseline for the new kicad. - CI: drop the obsolete binaryen_version input/env (the build uses the binaryen submodule fork's wasm-opt, not a version download); key the wasm-output cache on the binaryen submodule SHA instead. Bumps the wxwidgets + binaryen submodules to their squashed feature commits. Validated green: all 7 apps native-EH (real 3D in pcbnew); KiCad e2e 63/63 Firefox + Chromium (3D viewer renders); wx 336; coroutine 34/34 both engines; asyncify 7/7 both engines. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b8c8dee355
commit
c1ef489cfa
75 changed files with 4976 additions and 680 deletions
|
|
@ -163,17 +163,29 @@ EM_JS( void, races_mark_done, ( const char* aName ), {
|
|||
Module.__racesDone[UTF8ToString( aName )] = true;
|
||||
} );
|
||||
|
||||
// Quiescence invariant sampled from C++ between scenarios. NOTE: this runs on a
|
||||
// stack that may itself have been resumed via Fibers.trampoline(), in which case
|
||||
// Fibers.trampolineRunning is legitimately true — so the guard is deliberately
|
||||
// NOT part of this check (a genuinely stuck guard wedges the next fiber swap and
|
||||
// is caught by the scenario watchdogs instead).
|
||||
// Quiescence invariant sampled from C++ between scenarios.
|
||||
//
|
||||
// Two things are deliberately NOT checked:
|
||||
// * Fibers.trampolineRunning — this can run on a stack itself resumed via
|
||||
// Fibers.trampoline(), in which case the guard is legitimately true.
|
||||
// * Asyncify.currData — under native wasm-EH the top-level event loop is a
|
||||
// per-frame-yield while-loop (wxWasmYieldToBrowser, an EM_ASYNC_JS rAF
|
||||
// suspend that re-arms every frame; see wxwidgets/src/wasm/evtloop.cpp). So
|
||||
// the main stack is asyncify-suspended between frames and currData is
|
||||
// legitimately churning — it is non-zero while a frame yield is pending, and
|
||||
// can momentarily hold a freed-but-not-yet-nulled buffer right after a
|
||||
// concurrent suspension resumes. That is a transient bookkeeping value, NOT a
|
||||
// leak (the buffers are _malloc/_free'd each frame — addresses are reused),
|
||||
// so requiring currData==0 here is a stale legacy assumption from the old
|
||||
// throw-to-park loop. A genuinely stuck suspension is caught by state != 0
|
||||
// (Suspending/Rewinding never clearing) and by the scenario watchdogs.
|
||||
// What's left is the real invariant: the asyncify machine is back to Normal and
|
||||
// no fiber is queued.
|
||||
EM_JS( int, races_quiescent, (), {
|
||||
try {
|
||||
var stOk = ( typeof Asyncify === 'undefined' ) || Asyncify.state === 0;
|
||||
var cdOk = ( typeof Asyncify === 'undefined' ) || !Asyncify.currData;
|
||||
var nfOk = ( typeof Fibers === 'undefined' ) || !Fibers.nextFiber;
|
||||
return ( stOk && cdOk && nfOk ) ? 1 : 0;
|
||||
return ( stOk && nfOk ) ? 1 : 0;
|
||||
} catch( e ) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue