fix(wasm): dynCall signature-mismatch fallback + eeschema collab wire converters
Two things, both verified in the real web app (two-tab eeschema collab). 1. dynCall crash fix (all apps) — scripts/common/shims/dyncall-binding.js.tmpl. Programmatic editor edits trapped with 'indirect call signature mismatch': the asyncify-instrumented wasmExports[dynCall_<sig>] trampoline does call_indirect with a stale type for some table indices (post-asyncify+O2) even though the table entry is valid. Proven by patching the built js: at the trap getWasmTableEntry(index) SUCCEEDS where the trampoline fails. Fix: the shim now catches the 'signature mismatch' RuntimeError and falls back to getWasmTableEntry; the Asyncify unwind sentinel and real exceptions re-throw, so instrumentation/unwind is untouched for normal calls. This unblocks ALL programmatic edits, not just collab (e.g. eeschema SCH_ITEM::Move). 2. eeschema collab apply converters (wasm/bindings/eeschema_embind.cpp). doApply now handles added-item construction (build the SCH_ITEM with the delta's uuid via const_cast — as the s-expr parser does — + commit.Add) and richer SCH_LINE serialization (start/end/layer) so wire edits reconstruct on the peer. Implemented for SCH_LINE (wires) + SCH_JUNCTION; other types log 'no converter for added type' and are skipped (next batch). eeschema re-enabled in the web app collab gate. Tests: eeschema-collab.spec snapshot (green); apply/two-tab skipped — they no-op headless because the e2e harness's kicadOpenFile returns false (OpenProjectFiles bails before building the connectivity graph), so SCH_COMMIT::Push doesn't persist. Verified in-app. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4f8c2d1f56
commit
b5b1a0ac05
5 changed files with 228 additions and 55 deletions
|
|
@ -1,5 +1,6 @@
|
|||
#!/bin/bash
|
||||
# Post-process Emscripten-generated pcbnew.js for KiCad WASM.
|
||||
# Post-process the Emscripten-generated <app>.js for KiCad WASM (pcbnew, eeschema,
|
||||
# pl_editor, calculator, …).
|
||||
#
|
||||
# The actual JavaScript that gets injected lives in readable, standalone files in
|
||||
# scripts/common/shims/ (not inline heredocs):
|
||||
|
|
|
|||
|
|
@ -4,9 +4,22 @@
|
|||
//
|
||||
// Binds the bare name to the REAL asyncify-instrumented wasm export
|
||||
// (wasmExports["dynCall_<sig>"], present because the build links -sDYNCALLS=1).
|
||||
// Falls back to getWasmTableEntry only if no such export exists.
|
||||
// Falls back to getWasmTableEntry if no such export exists, OR if the instrumented
|
||||
// trampoline traps with "indirect call signature mismatch": post-asyncify+O2 the
|
||||
// trampoline can call_indirect with a stale type for some table indices even though
|
||||
// the table entry itself is valid (hit by programmatic editor edits, e.g. eeschema
|
||||
// SCH_ITEM::Move via invoke_vii — see features/yjs-bridge/0003). The direct
|
||||
// getWasmTableEntry call uses the correct per-entry signature and succeeds. Only the
|
||||
// mismatch trap is caught; the Asyncify unwind sentinel and real exceptions re-throw,
|
||||
// so instrumentation/unwind still work for every normal indirect call.
|
||||
function dynCall_@SIG@(@ARGS@) {
|
||||
var f = (typeof wasmExports !== 'undefined') && wasmExports["dynCall_@SIG@"];
|
||||
if (f) return f(@ARGS@);
|
||||
if (f) {
|
||||
try { return f(@ARGS@); }
|
||||
catch (_dce) {
|
||||
if (!(_dce instanceof WebAssembly.RuntimeError) || !/signature mismatch/.test(_dce.message))
|
||||
throw _dce;
|
||||
}
|
||||
}
|
||||
return getWasmTableEntry(index)(@CALLARGS@);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue