← All issues

[JSC] Walk star-export graph once when building a module namespace

66c577c

Source/JavaScriptCore/runtime/AbstractModuleRecord.h

+(JSC::AbstractModuleRecord::Resolution::isSameBinding const): Added.

ES module namespaces are constructed by GetModuleNamespace, which must enumerate all names reachable through transitive export * chains. The spec's ResolveExport is recursive and carries a resolveSet to break cycles. The old implementation called this per-name, redundantly re-walking the star-export graph for every name — O(names × star-edges). The new implementation fuses the graph walk with binding collection: it traverses each star edge once, accumulates per-name candidate sets, and fast-paths names with exactly one Local/Namespace binding as Resolved. Indirect entries fall back to resolveExport(); ambiguous names with two-or-more distinct bindings are excluded. Benchmarks show ~17x for deep barrel modules with 9000 exports across ~1500 star edges.

This restructures a core spec algorithm with a fast path whose correctness depends on non-obvious invariants about binding uniqueness and shadow rules — exactly the kind of change that can introduce subtle divergence from spec behavior.

🔒

The new fast path's correctness rests on several subtle invariants — edge cases in the graph walk and binding equivalence logic are worth security investigation.

Subscribe to read more