Investigation scaffolding for the Chrome-only KiCad coroutine renderer crash.
Adds isolated reproduction probes exercising the coroutine/Asyncify/fiber layer
under KiCad-like conditions, runnable in BOTH Firefox and system Chrome.
- tests/playwright-coroutine.config.ts + test:coroutine:firefox|chrome npm
scripts: run the coroutine specs in Firefox AND system Chrome (the old e2e
config only used bundled Chromium, which never reproduced the crash).
- tests/apps/standalone/coroutine-pthread/: no-wx + pthreads reproduction probes
(fiber-in-main, nested invoke_/dynCall boundaries, RunMainStack, embind,
main-loop/rAF activation) + worker_dom_stub.js for wx+pthreads builds.
- tests/apps/Makefile.wasm: coroutine-pthread{,-main,-nested,-nested-ex,-wx,
-embind,-mainloop} targets.
- scripts/common/shims/diagnostics.js: add EM_ASYNC_JS handleSleep enter/wake
tracking (DIAG_SLEEP) to detect nested-async at the crash.
Findings (details in research notes): every isolated factor so far — direct /
nested / RunMainStack fiber, wx event loop + all 13 scenarios incl EM_ASYNC_JS,
pthreads, and main-loop/rAF activation — runs CLEAN in system Chrome. The
coroutine/Asyncify layer is exonerated; GL/WebGL is the remaining untested factor
(next). The reliable FF-pass/Chrome-fail repro is still the KiCad pcbnew e2e.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Main-repo side of a multi-part WIP covering the KiCad WASM tool-selection
and nested-Asyncify work. Submodule commits are in kicad@f6e9239aaa
(libcontext hygiene) and wxwidgets@bb80f91e8b (auibar registration +
dialog diagnostics).
## scripts/common/inject-dyncall-shims.sh
Wrap Asyncify.handleSleep / allocateData to save-and-restore Asyncify.currData
around each EM_ASYNC_JS sleep. This fixes the nested Asyncify collision where
a fiber swap that fired during a modal's event loop clobbered currData, and
the modal's later doRewind used the fiber's buffer and hit "RuntimeError:
index out of bounds". Root cause documented as Emscripten Issue #9153
(wontfix upstream).
Diagnostic-rewind logging (forcedBottomOfCallStack, callStack traces) is
retained to help future debugging of Asyncify state corruption.
## tests/
- tests/playwright-kicad.config.ts: add `channel: 'chrome'` for the
chromium project so --project=chromium --headed uses system Chrome
(real GPU) instead of SwiftShader on ARM Mac. Also switch trace to
retain-on-failure + screenshot on-failure for easier E2E debugging.
- tests/kicad/pcbnew.spec.ts: replace `tool.checked` assertions with a
label-suffix check (`[checked]`) since our auibar registration encodes
checked state in the label (no schema change to the registry).
- tests/apps/Makefile.wasm: add `coroutine-nested` build target + include
it in the all: list.
- tests/apps/standalone/coroutine/: kicad_coroutine_harness.h + test app
reproducing KiCad COROUTINE semantics against real libcontext.
- tests/apps/standalone/coroutine-nested/: nested_test.cpp reproduces the
EM_ASYNC_JS-modal + fiber-swap nesting bug in isolation. 8 scenarios
from baseline_modal_alone through nested_fibers_inside_modal.
- tests/e2e/coroutine.spec.ts + coroutine-nested.spec.ts: Playwright specs
that load the standalone apps and assert all case cases pass via
[COROUTINE_TEST] SUMMARY log parsing.
## research/ and features/browser-tools/
Three background docs capturing the investigation trajectory:
- features/browser-tools/0001-kicad-wasm-tool-activation-investigation.md
Early investigation: why tools don't activate; initial dynCall-empty-
callback hypothesis.
- features/browser-tools/0002-wasm-coroutine-deep-dive.md
Deep dive on Asyncify internals, fiber API, QEMU's coroutine-wasm
reference implementation.
- features/browser-tools/0003-wxauitoolbar-registration-fix.md
The narrow fix: why wxAuiToolBar needs a registration block, where to
add it, what the fallback plan is.
- research/threading_1.md: corrected root-cause analysis after reading
runtime logs — nested-Asyncify currData collision, Emscripten #9153.
- research/threading_2.md: extended research on alternative approaches
(JSPI/WasmFX/state-machines) and why they don't help here.
## Submodule pointer updates
kicad: f6e9239aaa (wip: libcontext WASM hygiene cleanup)
wxwidgets: bb80f91e8b (wip: wxAuiToolBar element-registry registration +
dialog diagnostics)
## Open threads not yet in scope
- Firefox/Chrome divergent behavior: "indirect call signature mismatch"
traps in Firefox vs renderer crash in system Chrome (tracked in
plans/peaceful-hugging-pnueli.md and the research docs).
- E2E pixel-diff for Draw Lines fails because the test's diff region does
not cover where the line is actually drawn; tool activation works, the
line is visible in test-results/pcbnew-draw-lines-02-after-drawing.png.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Update wasm/Makefile to compile ALL scenario files using wildcard
- Add conditional compilation to scenario_bitmap.cpp (#ifdef __EMSCRIPTEN__)
to handle OpenGL-specific shader workaround code for native only
- Change canvas dimensions to 1600x1200 to match native baseline (2x Retina)
- Set white background color to match native screenshots
- Update gal-webgl.spec.ts to hide UI overlay before taking screenshots
- Improve test-gal-regression.sh with better ImageMagick comparison
All 28 scenarios now compile and run on both native and WebGL backends.
Native vs baseline: PASSED (28/28 matching)
WebGL rendering: In progress (primitives not yet visible)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix coordinate system for 1:1 pixel mapping (was using nm scale)
- Set worldUnitLength to 1/96 to match native test setup
- Add SetLookAtPoint and SetZoomFactor for proper view transformation
- Fix glDrawBuffers for WebGL 2.0 (array index must match attachment)
- Add legacy_gl_stubs.js for wxWidgets compatibility
- Add isReady() check to prevent race condition in Playwright tests
All 28 GAL test scenarios now render correctly in WebGL.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add wasm_stubs.cpp with WASM-specific stub implementations for
COLOR4D::BLACK/WHITE, GLU tesselator, PGM_BASE, and other KiCad
dependencies
- Update Makefile to include KiCad sources (GAL base class, display
options, HiDPI canvas) and test scenarios
- Fix kiglew.h to define GLEW guard (__glew_h__) preventing conflicts
with Emscripten's GLEW header
- Update test HTML to create canvas before module load (MODULARIZE
requires passing canvas in Module config, not preRun)
- Update Playwright tests to find canvas elements correctly
- Add #window-container for wxWidgets GL canvas support
Build produces 8.4MB WASM with full WEBGL_GAL implementation.
Tests pass but rendering still shows dark output (debugging in progress).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add complete test infrastructure for WebGL GAL visual regression testing:
- scripts/test-gal-regression.sh: Master script that builds both backends,
runs tests, and performs two-level comparison (native vs baseline,
webgl vs native)
- scripts/build-gal-webgl-test.sh: WASM build using Makefile with em++
- tests/gal-regression/wasm/: WebGL test harness (stub WEBGL_GAL)
- tests/e2e/gal-webgl.spec.ts: Playwright test for screenshot capture
Fix Homebrew Emscripten environment in scripts/common/env.sh:
- Set EMSDK_PYTHON for Python 3.10+ (em++ reads this, not $PYTHON)
- Add bundled LLVM to PATH (Emscripten needs its clang with WASM backend)
Verified: Native vs Baseline passes (28/28), WebGL generates blank
screenshots as expected (WEBGL_GAL implementation is Phase 2).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace test.skip() with proper expect() assertions when app fails to load
- Remove button-finder utility (no longer needed with element registry)
- Remove kicad tests (tested separately)
- Add findByName/clickByName helpers for bitmap buttons
- Fix element lookups: use clickByName for bitmap buttons, clickTreeItem
for treebook pages, selectComboItem for wxChoice items
- Add SetName() to shape buttons in bitmapbuttons_test.cpp
- Remove verbose logging from print and threadpool tests
- Update README to reflect current test infrastructure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Build images.tar.gz bitmap archive for KiCad icons
- Fetch resources at runtime via HTTP instead of bundling in WASM
- Write to Emscripten virtual FS at compile-time KICAD_DATA path
- Fix rsync timestamp handling for correct make change detection
- Update kicad submodule with WASM settings manager fix
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>