Summary
WASM resolves dispatch-table dynamic edges to specific function targets; native emits a sink edge to the file node instead.
Divergence
Fixture: pts-javascript — dispatch-table.js
wasm=0 native=1: dispatch-table.js:runDispatch(function) -> dispatch-table.js:dispatch-table.js(file) conf=0 dyn=1
wasm=1 native=0: dispatch-table.js:runDispatch(function) -> dispatch-table.js:dtFn1(function) conf=0.9 dyn=1
wasm=1 native=0: dispatch-table.js:runDispatch(function) -> dispatch-table.js:dtFn2(function) conf=0.9 dyn=1
WASM correctly resolves the dispatch-table pattern {a:fnA,b:fnB}[k]() to the actual target functions (dtFn1, dtFn2) with conf=0.9, dyn=1 via PTS wildcard resolution. Native emits a single unresolved sink edge to the file node (conf=0, dyn=1).
Root cause (localization)
Pattern is wasm=A, native=B → Rust pipeline missing the dispatch-table PTS resolution. The dispatch-table DynamicKind is classified in the JS extractor and then resolved in build-edges.ts via points-to analysis. The Rust build_edges.rs either doesn't receive the dynamicKind field (serialization boundary) or doesn't implement dispatch-table resolution.
Fix
Two steps:
- Ensure the
dynamic_kind field from the JS extractor flows through the NativeFileEntry → build_edges.rs boundary (check SerializedExtractorOutput and the FileEdgeInput structs).
- Add dispatch-table resolution in
crates/codegraph-core/src/domain/graph/builder/stages/build_edges.rs to mirror the JS PTS wildcard resolution for DynamicKind::DispatchTable.
Summary
WASM resolves dispatch-table dynamic edges to specific function targets; native emits a sink edge to the file node instead.
Divergence
Fixture:
pts-javascript—dispatch-table.jsWASM correctly resolves the dispatch-table pattern
{a:fnA,b:fnB}[k]()to the actual target functions (dtFn1,dtFn2) with conf=0.9, dyn=1 via PTS wildcard resolution. Native emits a single unresolved sink edge to the file node (conf=0, dyn=1).Root cause (localization)
Pattern is
wasm=A, native=B→ Rust pipeline missing the dispatch-table PTS resolution. Thedispatch-tableDynamicKindis classified in the JS extractor and then resolved inbuild-edges.tsvia points-to analysis. The Rustbuild_edges.rseither doesn't receive thedynamicKindfield (serialization boundary) or doesn't implement dispatch-table resolution.Fix
Two steps:
dynamic_kindfield from the JS extractor flows through theNativeFileEntry→build_edges.rsboundary (checkSerializedExtractorOutputand theFileEdgeInputstructs).crates/codegraph-core/src/domain/graph/builder/stages/build_edges.rsto mirror the JS PTS wildcard resolution forDynamicKind::DispatchTable.