-
Notifications
You must be signed in to change notification settings - Fork 5k
moduleLoaderImportModule: thread referrer asyncEvaluationOrder for TLA self-deadlock skip #32437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
9e7e662
moduleLoaderImportModule: pass referrer asyncEvaluationOrder to JSC::…
Jarred-Sumner 0e9e62c
moduleLoaderImportModule: include query string in referrer registry-k…
Jarred-Sumner cdd26eb
Upgrade WebKit to cd821fecca0d (oven-sh/WebKit#254)
Jarred-Sumner 566cb13
Merge branch 'main' into claude/tla-referrer-async-order
Jarred-Sumner File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 The
!query.isEmpty()branch added in bfdabd0 is unreachable: Bun'sSourceOriginfor file modules is built fromResolvedSource.source_url, which is always set topath.text(the query-stripped filesystem path) and then run throughWTF::URL::fileURLWithFileSystemPath(), sosourceURL.queryWithLeadingQuestionMark()is always empty. A referrer registered as/abs/wrapper.mjs?v=1is therefore still looked up as/abs/wrapper.mjs,asyncEvaluationOrderForKeyreturns -1, and the #30634 fix doesn't apply to query-keyed TLA referrers — the CodeRabbit comment marked '✅ Addressed' isn't actually addressed. Not a regression (the no-query #30634 case is fixed), but consider either threading the query intoResolvedSource.source_url/ the SourceOrigin, or dropping the dead branch.Extended reasoning...
What the bug is
Commit bfdabd0 was added in response to the CodeRabbit inline comment: when the referrer module's registry key includes a query string (e.g.
/abs/wrapper.mjs?v=1), theasyncEvaluationOrderForKey()lookup should include that query so it matches the registry entry. The fix readssourceURL.queryWithLeadingQuestionMark()and, if non-empty, appends it to the filesystem path before the lookup.The problem is that for file-protocol referrers in Bun,
sourceURLnever has a query component, soquery.isEmpty()is always true and themakeString(...)branch is dead code. The CodeRabbit comment is marked "✅ Addressed in commit bfdabd0", but the query-keyed-referrer case it describes remains unfixed.The code path
sourceURLhere issourceOrigin.url(). For file modules theSourceOriginis constructed inZigSourceProvider.cpp:Every assignment of
ResolvedSource.source_urlin the loaders —ModuleLoader.zig:109,348,362,371,380,392,410,445,588,...,RuntimeTranspilerStore.rs:556,AsyncModule.zig:731,VirtualMachine.zig:1596,1610— sets it to the content ofpath.textviainput_specifier.createIfDifferent(path.text)(orString.init(path.text)).createIfDifferent(string.zig:117-125) returnsother.dupeRef()whenotherequalsutf8_slice, elsecloneUTF8(utf8_slice)— i.e. its result is always semantically equal to the second argument,path.text.path.textis the resolved on-disk path. The query was already split off bynormalizeSpecifierForResolution(VirtualMachine.zig:1712-1721) /normalizeSpecifier(options.zig:935-966) beforeFs.Path.init, and is never re-joined intopath.text. Sosource_urlis always the query-less filesystem path. (And even if a?survived,fileURLWithFileSystemPath()percent-encodes it into the path component, so the resultingWTF::URLwould still have an empty query.)Why existing code doesn't prevent it
Registry keys do include the query: the same function builds
resolvedIdentifier = makeString(resolved.result.value, queryString)at line 3547, so a module imported as./wrapper.mjs?v=1lives in the loader registry under/abs/wrapper.mjs?v=1. But the referrer lookup key is derived fromsourceOrigin.url(), which — as shown above — never carries the query. CodeRabbit's premise ("that query is present insourceURL") is wrong for Bun's file modules; bfdabd0 implemented exactly what it suggested, so it inherits the wrong premise.Step-by-step proof
Given:
consumer1.mjs?v=1resolves./wrapper.mjs?v=1→ registry key/abs/wrapper.mjs?v=1(line 3547 path)./abs/wrapper.mjs;ResolvedSource.source_url = path.text = "/abs/wrapper.mjs"(no query).ZigSourceProviderbuildsSourceOrigin(fileURLWithFileSystemPath("/abs/wrapper.mjs"))→file:///abs/wrapper.mjs.wrapper.mjsrunsawait import('./inner.mjs');moduleLoaderImportModulereceivessourceOrigin.url() = file:///abs/wrapper.mjs.queryWithLeadingQuestionMark()→"";referrerKey = "/abs/wrapper.mjs".asyncEvaluationOrderForKey("/abs/wrapper.mjs")misses (registry has/abs/wrapper.mjs?v=1) → returns-1.referrerAsyncOrder = -1is forwarded toJSC::importModule, so the TLA self-deadlock skip never fires for this referrer — the [1.3.14] ESM TDZ error when importing Lexical React modules that re-export through top-level await #30634 TDZ behaviour persists for query-keyed wrappers.Impact
Not a regression: pre-PR there was no
referrerAsyncOrderat all, so query-keyed referrers were equally broken. The no-query case — which is what #30634 actually reports and what the new test covers — is fixed. The impact is (a) misleading dead code, and (b) the "✅ Addressed" mark on the review thread is inaccurate: the query-stringed-referrer edge case remains unfixed.How to fix
Either:
sourceURLactually carries it — e.g. setResolvedSource.source_urlto the full registry key (path + query) instead of barepath.text, or append the query before callingfileURLWithFileSystemPathand re-set it on the resulting URL; or!query.isEmpty()branch and leave a comment that query-keyed referrers aren't yet handled, so the code doesn't imply otherwise.If you keep the fix, a variant of the new test that imports
./wrapper.mjs?v=1would exercise it.