Skip to content

Bump WebKit (oven-sh/WebKit#702 preview): in a generator, yield in the parameters of an arrow function nested in another's parameters is a SyntaxError - #43497

Draft
robobun wants to merge 7 commits into
mainfrom
robobun/49bd07c0/webkit-yield-in-nested-arrow-parameters
Draft

robobun wants to merge 7 commits into
mainfrom
robobun/49bd07c0/webkit-yield-in-nested-arrow-parameters

Conversation

@robobun

@robobun robobun commented Sep 19, 2026 •

Copy link
Copy Markdown
Collaborator

Blocked on oven-sh/WebKit#702. A draft until the pin is a commit of the fork's main.

Problem

  • In a generator, yield in arrow function parameters is a SyntaxError. Bun accepts it when that arrow function is in the parameters of another arrow function: (0, eval)("(function* () { (a = (yield) => 1) => a })"). With BUN_JSC_useSourceProviderCache=0 it throws SyntaxError: Cannot use 'yield' as a parameter name in a generator function. Node rejects it.
  • The cause is in JavaScriptCore's parser. isArrowFunctionParameters() parses ( ... ) in a scope that is never a generator, and the nested arrow function goes to the parser's function cache from there. The parse that knows the generator then skips it.

Fix

Background

  • WEBKIT_VERSION in scripts/build/deps/webkit.ts names the oven-sh/WebKit release that the build downloads. A pull request there publishes a prerelease, autobuild-preview-pr-<n>-<sha8>.
  • ArrowParameters[?Yield]: arrow function parameters take the [Yield] of the code around them, so in a generator yield is not an identifier in them.
  • The parser's function cache (SourceProviderCache) lets JavaScriptCore skip a function that it parsed before.
Notes

Where Bun users can see it. Only where text goes to JavaScriptCore as it is: eval, new Function, node:vm. For a file, Bun's transpiler rejects the same text first (error: Invalid binding pattern). The test uses eval.

The preview is the current pin (ebd5a6145b) plus the six commits of oven-sh/WebKit#702 (the last one is the change, it removes what the first five did). #43402 (the preview of oven-sh/WebKit#699) changes the same line of scripts/build/deps/webkit.ts. One bump can carry both when they are on the fork's main.

Earlier pins of this PR. The first five commits of oven-sh/WebKit#702 left the parameter check as it was and made the parser refuse a cache item instead. Three of those previews made valid programs fail: a refused item means a second parse of valid code, and that parse has bugs of its own (oven-sh/WebKit#430, #43569). Examples: (async function* () { ((...[a = () => await => 1]) => a); }) threw a SyntaxError, and a generator with ({ yield: b } = { yield: N }) => { var N = 7; return b; } in arrow function parameters threw ReferenceError: N is not defined. The current version parses no valid code again. The test has these programs (shadowed, yieldAsPropertyName, yieldAsVariable, and the must-parse list).

The test. 19 expressions, each in 5 generator contexts (must throw; in the four that are not strict mode code, with the message of the parse without the cache) and in 3 contexts where yield is an identifier (must parse). Eight valid programs must still parse: three with await as an identifier in an async generator, two with await in a generator, three with yield as a property name or a function name. The last test calls nested arrow functions from a generator and from a plain function and checks what they capture. The first version of the test also gave the text to new Function. That hit an unrelated exception check failure on the ASAN lane (#43524), so the test uses eval only.

Found during this work, not fixed here.

Other suites. I ran only this test file on linux x64 with the debug ASAN build. oven-sh/WebKit#702 has the engine side: both JSTests lanes, a test262 differential run, and generated corpora.


[policy-decision:webkit] gate passed · iteration 1 · 2 files touched

passes on PR (with fix)
Test-only change.

Debug/ASAN (expected pass):
$ bun bd test 'test/js/bun/jsc/parser-yield-in-arrow-parameters.test.ts'
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test test/js/bun/jsc/parser-yield-in-arrow-parameters.test.ts
bun test v1.4.3 (367d939d9)

test/js/bun/jsc/parser-yield-in-arrow-parameters.test.ts:
(pass) yield in the parameters of an arrow function > the text around the expressions is valid [14.53ms]
(pass) yield in the parameters of an arrow function > (a = (yield) => 1) => a is a SyntaxError in a generator [9.77ms]
(pass) yield in the parameters of an arrow function > (a = (b = yield) => b) => a is a SyntaxError in a generator [8.52ms]
(pass) yield in the parameters of an arrow function > (b = (yield) => 1, c) => b is a SyntaxError in a generator [5.75ms]
(pass) yield in the parameters of an arrow function > (a = (...yield) => 1) => a is a SyntaxError in a generator [5.47ms]
(pass) yield in the parameters of an arrow function > (a = ({ b = yield }) => 1) => a is a SyntaxError in a generator [7.02ms]
(pass) yield in the parameters of an arrow function > (a = async (yield) => 1) => a is a SyntaxError in a generator [6.21ms]
(pass) yield in the parameters of an arrow function > async (a = (yield) => 1) => a is a SyntaxError in a generator [5.55ms]
(pass) yield in the parameters of an arrow function > ({ a = (yield) => 1 }) => a is a SyntaxError in a generator [5.94ms]
(pass) yield in the parameters of an arrow function > ([a = (b = yield) => b]) => a is a SyntaxError in a generator [6.47ms]
(pass) yield in the parameters of an arrow function > (...[a = (yield) => 1]) => a is a SyntaxError in a generator [5.28ms]
(pass) yield in the parameters of an arrow function > (a = (b = (c = yield) => c) => b) => a is a SyntaxError in a generator [8.64ms]
(pass) yield in the parameters of an arrow function > (a = (b = { yield }) => b) => a is a SyntaxError in a generator [5.28ms]
(pass) yield in the parameters of an arrow function > (a = (b = [yield] = []) => b) => a is a SyntaxError in a generator [7.07ms]
(pass) yield in the parameters of 
... (truncated)
Exit: 0
diff hotspot
scripts/build/deps/webkit.ts                       |   2 +-
 .../jsc/parser-yield-in-arrow-parameters.test.ts   | 135 +++++++++++++++++++++
 2 files changed, 136 insertions(+), 1 deletion(-)

gate history · 1 passed · 1 rejected · iteration 1

evidence per changed file
file                                                      reads  edits  tests
scripts/build/deps/webkit.ts                                  0      0     27
test/js/bun/jsc/parser-yield-in-arrow-parameters.test.ts      3      3     27

…parameters of an arrow function nested in another's parameters is a SyntaxError

Pins WEBKIT_VERSION to the preview build of oven-sh/WebKit#702
(autobuild-preview-pr-702-62724908) and adds
test/js/bun/jsc/parser-yield-in-arrow-parameters.test.ts.

Not mergeable as it is: a preview tag is not a fork-main commit, and with
this WebKit alone three valid async generator programs that Bun 1.4.3 and
node 26 accept become SyntaxErrors (fixed by oven-sh/WebKit#430).
@robobun

robobun commented Sep 19, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 5:29 AM PT - Sep 20th, 2026

✅ @robobun, your commit 7002d5c74fd665bf76eb756810ed5797f32cf7fe passed in Build #118922! 🎉


🧪   To try this PR locally:

bunx bun-pr 43497

That installs a local version of the PR into your bun-43497 executable, so you can run:

bun-43497 --bun

new Function() with text that has a syntax error fails exception check
validation on the ASAN lane: constructFunctionSkippingEvalEnabledCheck()
throws the SyntaxError without a check of the scope, and the hook that
computes the error info declares a throw scope. That happens for any syntax
error, with and without the parser change that this test is for. eval gives
the same text to the same parser.
@robobun

robobun commented Sep 19, 2026 •

Copy link
Copy Markdown
Collaborator Author

Reproduced with bun 1.4.3-canary.1+367d939d9: (0, eval)("(function* () { (a = (yield) => 1) => a })") is accepted. With BUN_JSC_useSourceProviderCache=0 it throws SyntaxError: Cannot use 'yield' as a parameter name in a generator function. node 26 rejects it too.

The engine change is oven-sh/WebKit#702. This PR pins its preview build (autobuild-preview-pr-702-54004fef) and adds the test. USE_SYSTEM_BUN=1 bun test test/js/bun/jsc/parser-yield-in-arrow-parameters.test.ts fails 16 of 47. bun bd test on this branch passes all 47, also with BUN_JSC_validateExceptionChecks=1.

…7b36463)

The WebKit change no longer parses valid arrow functions again. The cache
item of an arrow function records that `yield` is an identifier in its
parameters, and only a generator does not use such an item. The valid async
generator programs that the first preview rejected parse again.

The test also calls an arrow function whose default value captures a variable
that its body declares again, in a generator and next to `yield` as a
variable. Both go through the parser's function cache.
@robobun robobun changed the title WebKit: in a generator, yield in the parameters of an arrow function nested in another's parameters is a SyntaxError (blocked on oven-sh/WebKit#702) Bump WebKit (oven-sh/WebKit#702 preview): in a generator, yield in the parameters of an arrow function nested in another's parameters is a SyntaxError Sep 19, 2026
@robobun
robobun marked this pull request as ready for review September 19, 2026 21:50
@coderabbitai

coderabbitai Bot commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review paused — included plan limit reached

Keep your review moving with free on-demand reviews.

  • Run this review for free

On-demand reviews are free for one more day.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Promotion and pricing details

On-demand reviews are free for one more day. After that, they cost $0.25 per reviewed file.

Review limit details

Or wait 2 minutes for your next included review.

Check out review usage here.

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: oven-sh/bun/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Essentials

Run ID: b395694d-a6d0-403f-a13b-d31952f491df

📥 Commits

Reviewing files that changed from the base of the PR and between 26e7a4b and 7a51c60.

📒 Files selected for processing (2)
  • scripts/build/deps/webkit.ts
  • test/js/bun/jsc/parser-yield-in-arrow-parameters.test.ts

Comment @coderabbitai help to get the list of available commands.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings marked 🟡 are optional suggestions and need no follow-up push.

Comment thread scripts/build/deps/webkit.ts Outdated
Comment thread test/js/bun/jsc/parser-yield-in-arrow-parameters.test.ts Outdated
Comment thread test/js/bun/jsc/parser-yield-in-arrow-parameters.test.ts Outdated
…nerator context, and valid programs with await

The four generator contexts that are not strict mode code give the message of
the plain generator body, so the test asks for it in each of them. A new case
checks that the text around the expressions parses, so a SyntaxError in the
class context is about the expression.

Five valid programs must still parse. Three of them use `await` as an
identifier in a function in the parameters of an arrow function in an async
generator: a version of the engine change that parsed cached arrow functions
again rejected them.
@robobun
robobun marked this pull request as draft September 19, 2026 22:12

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review found no issues

No high-confidence issues detected in this change.

…s a property name

The engine change now marks a cache item only where `yield` is bound or
referenced in the parameters of the arrow function. A property name `yield`
is valid in a generator, and the parser still takes such an arrow function
from its cache there. The preview before this one did not, and the new case
in the last test failed with it.

More cases: `yield` as a shorthand property, in an array assignment pattern
and with an escape must throw in a generator. `yield` as a property name, as
the name of a getter or a method, and as the name of a function expression
must parse.
One more commit there: an escaped `yield` as a shorthand property does not
mark the cache item of the arrow function. JavaScriptCore accepts that
shorthand in a generator, so the parser must not parse the arrow function
again for it.
…of a generator expression

The engine change is now in isArrowFunctionParameters(): it parses the
parameters with [+Yield] in a generator, as the parse that follows it does.
The cache item marks of the earlier previews are gone.

New case: `function* yi\u0065ld() {}` in the parameters of an arrow function
in arrow function parameters in a generator. It was an error only without the
parser's function cache, also with the preview before this one.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant