Upgrade WebKit to 2603e9eb41f0 - #34373
Conversation
Bumps WEBKIT_VERSION to the preview build from oven-sh/WebKit#300 (autobuild-preview-pr-300-2cfd017b) and updates bindings for the upstream API changes in d81bcc3d833c..c8b6308aaa69: - DeferredWorkTimer::Ticket is now ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr; addPendingWork returns WeakTicket, scheduleWorkSoon became scheduleWorkSoonIfActive. JSCTaskScheduler hooks updated to the new Ref<Ticket>&& / Ticket& signatures. - DateCache::resetIfNecessarySlow() became clearForTimeZoneChange(); lastTimeZoneID moved to WTF. Callers now bump WTF::timeZoneDidChange() then clear the per-VM cache. - SparseArrayValueMap is now a HashSet of SparseArrayEntry; iterator yields the entry directly (.key became .index()). - ArrayBuffer::isLocked() folded into isDetachable(). Before merging this PR, WEBKIT_VERSION must be updated to the autobuild-<sha> tag once oven-sh/WebKit#300 is merged.
|
Updated 2:43 AM PT - Jul 19th, 2026
❌ @robobun, your commit f6a634c has 1 failures in 🧪 To try this PR locally: bunx bun-pr 34373That installs a local version of the PR into your bun-34373 --bun |
|
The WebKit preview tag is now Temporal is now disabled by default in Bun ( The gate and CI will fail on Fixes applied to the WebKit branch:
Once oven-sh/WebKit#300 is merged, |
|
Found 11 issues this PR may fix:
🤖 Generated with Claude Code |
|
Re: the issue-finder suggestions above: #15853 is directly addressed (Temporal is enabled by default in this JSC range, covered by |
|
This PR may be a duplicate of:
🤖 Generated with Claude Code |
|
Re: the duplicate finder: #33956 targets upstream |
oven-sh/WebKit#300 was rebuilt at ddece060 to keep the flat JavaScriptCore/Headers layout on Apple (upstream's new USE_FRAMEWORK_BUNDLES block was redirecting it to JavaScriptCore.framework/Headers, breaking the packaging cp).
oven-sh/WebKit#300 @ a67975c4 captures and restores Bun's async context in the new InternalMicrotask::AsyncGeneratorDriverResume path (upstream's cooperative async-generator driving), and fixes the listenForTimeZoneChangeNotifications() stub guard to key on OS(DARWIN). Adds AsyncLocalStorage.test.ts coverage for for-await over pristine async generators (the driver fast path), interleaved stores, and the throw-from-generator branch.
…hutdown handling
WebKit: merged 8be995561a (AsyncContextSwapScope RAII refactor),
ae5110d307 (reifyStaticProperty termination), 365cb02471 (Dockerfile.windows)
into the upgrade branch. JSMicrotask.cpp resolved by keeping upstream's
microtaskCallCache threading and asyncFunctionGeneratorBodyCall extraction on
top of the new RAII helper; AsyncGeneratorDriverResume now uses
wrapWithCurrent / unwrapContextTuple like its siblings.
Bun: merged origin/main. JSCTaskScheduler.{h,cpp} resolved by keeping the
new m_isShuttingDown gate, dropPendingTicketLocked, markShuttingDown and
Bun__deleteDeferredWorkTask from #34293, updated to the new
DeferredWorkTimer::Ticket / Ref<Ticket>&& / Ticket& API.
WEBKIT_VERSION bumped to the preview tag for the new WebKit head.
oven-sh/WebKit#300 @ 67898ceb drops cocoa/TimeZoneCocoa.cpp from the JSCOnly build (matching upstream's pending fix for webkit.org/b/319480) and compiles the no-op listenForTimeZoneChangeNotifications() stub on every Bun platform.
…eb now published)
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
💤 Files with no reviewable changes (1)
WalkthroughChangesRuntime compatibility
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Comment |
oven-sh/WebKit#300 @ 4c5f4e80 drops the ThrowScope from setUpStaticFunctionSlot and keys on the reified offset instead, so that getOwnStaticPropertySlot / getOwnNonIndexPropertySlot callers on the property-lookup fast path are not forced to add RETURN_IF_EXCEPTION (the previous shape tripped validateExceptionChecks=1 on the ASAN lane). SerializedScriptValue: the old isLocked() gate let a Bun-pinned ArrayBuffer through so transferTo() took its copyTo() fallback (the contract documented at bindings.cpp JSC__JSValue__pinArrayBuffer). isDetachable() also fires for a nonzero pinCount, so a pinned buffer would have thrown on structuredClone/postMessage transfer instead of copying. Drop the gate and let transferTo() handle both. dispatch.rs: update the stale ~Ref<TicketData> comment to ~Ref<Ticket>.
Locks in the SerializedScriptValue.cpp divergence from upstream WebCore: a Bun-pinned (native-borrowed) ArrayBuffer in a transfer list must fall through to transferTo()'s copyTo() path rather than hit upstream's !isDetachable() TypeError gate.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/build/deps/webkit.ts`:
- Line 10: Update the WEBKIT_VERSION constant to use the merged autobuild-<sha>
tag instead of the expiring autobuild-preview-pr-300-4c5f4e80 preview pin.
In `@test/js/web/workers/structured-clone.test.ts`:
- Line 459: Update the test around structuredCloneFn(...) and the zlib.deflate
invocation so the deflate promise is awaited from a finally block. Ensure the
promise settles even when structuredCloneFn(...) or assertions throw, preventing
asynchronous rejection after the test completes.
- Around line 458-472: Update the test around the zlib deflate call and
structuredCloneFn assertion so the clone operation and expectations run inside a
try block, with the existing promise always awaited in a finally block. Preserve
the current assertions and success behavior while ensuring deflate is awaited
even when cloning or assertion evaluation throws.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: c10e6497-b39f-41cb-82b2-4ba065f44bec
📒 Files selected for processing (13)
scripts/build/deps/webkit.tssrc/jsc/bindings/BunClientData.cppsrc/jsc/bindings/JSCTaskScheduler.cppsrc/jsc/bindings/JSCTaskScheduler.hsrc/jsc/bindings/JSEnvironmentVariableMap.cppsrc/jsc/bindings/ZigGlobalObject.cppsrc/jsc/bindings/bindings.cppsrc/jsc/bindings/webcore/SerializedScriptValue.cppsrc/jsc/modules/BunJSCModule.hsrc/runtime/dispatch.rstest/js/bun/jsc/temporal-global.test.tstest/js/node/async_hooks/AsyncLocalStorage.test.tstest/js/web/workers/structured-clone.test.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/js/web/workers/structured-clone.test.ts`:
- Around line 464-475: Update the structured-clone test around the deflate
promise and structuredCloneFn call so ab.byteLength is asserted only after the
finally block awaits completion. Preserve the existing clone assertions, but
move the origLength check into a post-completion assertion to verify the
buffer’s final detached or retained state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8c2aff7a-80c2-40f2-aa73-01eeb377ee52
📒 Files selected for processing (1)
test/js/web/workers/structured-clone.test.ts
There was a problem hiding this comment.
All prior review feedback is addressed (the isDetachable() transfer gate, the missing pinned-buffer test, the stale TicketData comment, and the module-scope deflate import). No new issues found. Deferring to a human reviewer given this is a 211-commit JSC upgrade touching ref-counted concurrency paths (DeferredWorkTimer::Ticket) and a deliberate divergence from upstream in SerializedScriptValue; also note WEBKIT_VERSION still points at the preview tag pending oven-sh/WebKit#300 merge.
What was reviewed:
JSCTaskSchedulerticket refactor:Ref<Ticket>ownership acrossonAddPendingWork/onScheduleWorkSoon/onCancelPendingWork, shutdown drain, and event-loop ref balancing look correct.SerializedScriptValuegate removal: confirmedtransferTo()'scopyTo()fallback covers both locked and pinned; new test locks it in.- Timezone paths: all three call sites (
process.env.TZ,JSGlobalObject__setTimeZone,bun:jsc setTimeZone) now bumpWTF::timeZoneDidChange()beforeclearForTimeZoneChange(). SparseArrayValueMapiterator:.key→.index()is a straight rename.
Extended reasoning...
Overview
This PR upgrades Bun's WebKit fork across 211 upstream JSC/WTF/bmalloc commits and adapts Bun's bindings to four upstream API changes: the DeferredWorkTimer::Ticket refactor (TicketData → Ticket, now ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr, hooks take Ref<Ticket>&&/Ticket&), DateCache::resetIfNecessarySlow() → WTF::timeZoneDidChange() + clearForTimeZoneChange(), SparseArrayValueMap becoming a HashSet<SparseArrayEntry> (iterator yields entries directly), and ArrayBuffer::isLocked() folding into isDetachable(). It also adds tests for Temporal (now enabled by default upstream), async-generator AsyncLocalStorage propagation (new cooperative driver microtask), and the pinned-ArrayBuffer structured-clone contract.
Security risks
None introduced by the binding changes themselves. The upstream range includes libpas OoB/race fixes and divideRoundedUp/calculateBase64EncodedSize overflow fixes, which are net security improvements. The SerializedScriptValue change removes a throw gate but restores pre-existing Bun behavior (pinned buffers copy on transfer), which is memory-safe — the pin keeps the native borrow's bytes alive.
Level of scrutiny
High. WebKit upgrades change the JS engine underneath every Bun program; the JSCTaskScheduler changes touch cross-thread ref-counted state under a lock (Atomics.waitAsync/FinalizationRegistry shutdown paths), and the SerializedScriptValue change is a deliberate Bun-specific divergence from upstream WebCore that a future sync could silently revert. These are exactly the areas REVIEW.md flags as most-blocked (memory safety, ref-count balance, thread affinity). A maintainer familiar with prior WebKit bumps should sign off.
Other factors
Over three review rounds I flagged (1) the !isDetachable() gate breaking the pin contract, (2) missing automated coverage for that path, (3) a stale ~Ref<TicketData> comment in dispatch.rs, and (4) a require("zlib") in the new test — all four are now fixed in the current diff. CodeRabbit's finally-await feedback is also addressed. The one intentionally-open item is WEBKIT_VERSION = "autobuild-preview-pr-300-4c5f4e80", which the author has stated will be swapped to the merged autobuild-<sha> tag before this lands. The bug-hunting system found nothing new on the current revision.
So the catch can't swallow a loop-body assertion failure and still pass.
Replaces the preview tag now that the WebKit upgrade PR has landed on oven-sh/WebKit main. The merged commit also carries oven-sh/WebKit#304 (Windows WallTime/MonotonicTime), #306 (reifyStaticProperty ThrowScope drop on main) and #310 (preCommitStackMemory guard).
Resolves the WEBKIT_VERSION conflict: main bumped to 639550acdc via #34669; this branch already pointed at a0e65bf298 (the squash-merge of oven-sh/WebKit#300, which has 639550acdc as its parent). Keep a0e65bf298 in main's bare-sha format.
There was a problem hiding this comment.
No new findings this pass — the earlier inline issues (Wasm-memory transfer gate, bare-catch in the async-generator test, Temporal env hermeticity, zlib import) are all addressed in the current diff. Deferring to a human for the merge decision: this is a 211-commit JSC/WTF upgrade that reworks DeferredWorkTimer::Ticket ref-counting across the thread-safe scheduler, changes ArrayBuffer transfer-list semantics, and flips Temporal's default — worth a maintainer's eyes before landing.
What was reviewed
JSCTaskSchedulerRef<Ticket>signatures: checked thatdropPendingTicketLockedstill identity-compares by.ptr()and the shutdown / cancel paths balance the event-loop ref.SerializedScriptValue::create: confirmed theisWasmMemory()gate uses the enclosing function's throw scope (the removed innerDECLARE_THROW_SCOPEwas redundant) and pinned buffers still reachtransferTo()'scopyTo()fallback.- The three timezone call sites now consistently pair
WTF::timeZoneDidChange()withdateCache.clearForTimeZoneChange(). runPendingWork'sjob->task(job->ticket.get())matches the newTasksignature takingTicket&.
Extended reasoning...
Overview
Bumps WEBKIT_VERSION to the merged autobuild-a0e65bf298 tag (oven-sh/WebKit#300) and adapts Bun's C++ bindings to four upstream API changes: the DeferredWorkTimer::TicketData → Ticket rename with ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr semantics (JSCTaskScheduler.{cpp,h}, BunClientData.cpp, dispatch.rs comment), the DateCache::resetIfNecessarySlow() → WTF::timeZoneDidChange() + clearForTimeZoneChange() split (three call sites), the SparseArrayValueMap iterator shape change (.key → .index() in bindings.cpp), and ArrayBuffer::isLocked() folding into isDetachable() (SerializedScriptValue.cpp). It also pins useTemporal() = false since upstream flipped it on by default, and adds three test files covering Temporal exposure, async-generator ALS context propagation through the new cooperative driver, and pinned-vs-Wasm ArrayBuffer transfer semantics.
Security risks
None introduced by the binding diff itself. The transfer-list change went through an iteration where dropping the isLocked() gate would have silently copied WebAssembly.Memory linear memory instead of rejecting it — that was caught in an earlier review pass and the isWasmMemory() gate is now reinstated with a test. The upstream range itself carries the usual JIT/GC/Wasm surface (libpas OoB fixes, YARR changes, BBQ strength-reduction) that any engine bump does.
Level of scrutiny
High. This swaps the JS engine (211 JSC/WTF/bmalloc commits) and touches thread-safety-critical code: JSCTaskScheduler::onScheduleWorkSoon / onCancelPendingWork now take Ref<Ticket>&& / Ticket& instead of the old raw-pointer Ticket, and the pending-set removal + event-loop ref balancing must remain correct under concurrent Atomics.notify and worker shutdown. The SerializedScriptValue change alters user-visible transfer semantics. WebKit upgrades in this repo are maintainer-reviewed by convention.
Other factors
- All prior inline findings from earlier passes are resolved and verified against the current diff.
- CI (build #75473) is green except a Tart infra failure and
test-http2-reset-flood.json debian x64-asan, which robobun's analysis attributes to a pre-existingworker.terminate()race whose window widened under the new microtask dispatch — not introduced here, but worth a maintainer's judgment on whether it blocks. - The
WEBKIT_VERSIONis now the final merged sha (no longer the preview tag), so the pre-merge blocker noted earlier in the thread is cleared. - The removed
static getVM(Ticket&)helper was dead after the signature change;JSCDeferredWorkTask::vm()covers the remaining use.
Conflicts were all the WebKit-upgrade (#34373) TZ-change API: resetIfNecessarySlow() -> WTF::timeZoneDidChange() + clearForTimeZoneChange(). resetDateCachesAfterTimeZoneChange now calls the new pair (and still runs the per-instance heap-walk); the three call sites keep the resetDateCachesAfterTimeZoneChange wrapper so the isMainThread gate and per-instance invalidation stay single-sourced. Parallelized the two worker probes in the TZ-worker-isolation test so it fits the default 5s timeout on debug.
…nstructVersions to RETURN_IF_EXCEPTION setUpStaticFunctionSlot now wraps reifyStaticProperty in DeferTerminationForAWhile and treats a pending exception as slot-not-found (oven-sh/WebKit#282, #306, landed in bun via #34373). reifyStaticProperty itself early-returns on an empty callback result instead of putDirect'ing it. So PropertyCallback builders can RETURN_IF_EXCEPTION(scope, {}) and the exception propagates to JS correctly. This removes the builder-level DeferTerminationForAWhile this PR had added to constructStdioWriteStream/constructStdin/constructEnv/constructNextTickFn and callLazyProcessBuilder (now redundant with the JSC-side wrapping), and reverts constructVersions to main's RETURN_IF_EXCEPTION. The pre-existing clear-and-report patterns on main are left alone.
### What does this PR do? Enables JavaScriptCore's `Temporal` implementation by default by setting `JSC::Options::useTemporal() = true` alongside the other JSC option defaults in `ZigGlobalObject.cpp`. This exposes the `Temporal` global and `Date.prototype.toTemporalInstant`. `BUN_JSC_useTemporal=0` still turns it back off, because the `BUN_JSC_*` environment overrides are applied after the defaults block. Fixes #15853. ### Why now JSC's Temporal implementation has improved a lot since the 40% test262 pass rate reported on #15853 in early 2025. Measured with `temporal-test262-runner` 0.4.0 (the same tool that produced that 40% figure) against test262 `de8e621c`, with Node v26.3.0 (which ships Temporal on by default) for comparison: | Suite | Tests | Bun | Node 26.3 | |---|---|---|---| | `built-ins/Temporal` (core spec) | 4603 | 100.0% | 98.7% | | `built-ins/Date/prototype/toTemporalInstant` | 8 | 100% | 100% | | `intl402/DateTimeFormat` + `DurationFormat` on Temporal objects | 259 | 99.2% | 91.9% | | `intl402/Temporal` (non-ISO calendars) | 2029 | 56.2% | 38.3% | Every one of the 136 tests where Bun is behind Node is in `intl402/Temporal`, which is non-ISO calendar behavior. Outside of that there is not a single test262 test where Bun is behind Node. I also byte-diffed the output of 20,500 deterministic Temporal operations (seeded identically in both engines): the iso8601, gregory, and roc calendars, 2000 DST-disambiguation cases, all offset-option handling, Instant rounding, and formatting options produced zero divergences. The full test262 run was repeated on a debug + ASAN build of this branch's parent: zero crashes, zero ASAN reports, zero assertion failures, and a pass/fail set identical to release across all 6634 tests. Chrome 144, Firefox, and Node 26 ship Temporal on by default. TypeScript 6.0 ships the type declarations and its `lib.esnext.d.ts` references `esnext.temporal`, so nothing is needed in `bun-types`. ### The Windows blocker is resolved This PR was converted to a draft when CI showed `Temporal.PlainDate.prototype.since` throwing `RangeError: Duration is outside the representable range` on trivial input, on Windows x64 and Windows aarch64 only (the two platforms where WTF's `Int128` is the emulated `Int128Impl` rather than native `__int128`). The WebKit upgrade in #34373 (`2603e9eb41f0`) brought in upstream's Temporal duration-arithmetic and spec-alignment fixes, and the bug no longer reproduces. Verified on current main's canary (`1.4.0-canary.1+6b6fb1a33`) on both Windows 2019 x64 and Windows 11 aarch64 with `BUN_JSC_useTemporal=1`: the previously failing expression returns `P17M14D`, and a 10-expression smoke covering `since`/`until`, `Duration.round`/`total`/`compare`, `Instant` arithmetic, epoch nanoseconds, and ZonedDateTime DST transitions produces byte-identical output to Linux on both. ### Cost The `Temporal` namespace object is installed the same way `Intl` is (one line above it in `JSGlobalObject::init`): a single small object whose nine sub-constructors are `PropertyCallback` lookup-table entries created on first access, with their structures registered via `initLater`. Measured over 420 cold starts of `bun -e ''`: 1887 us/start with `useTemporal` off, 1875 us/start with it on (within measurement noise). RSS is 31.5 MB vs 31.4 MB. The implementation was already compiled into the binary behind the runtime flag, so there is no size change. ### Known gaps, all non-ISO calendars and all upstream JavaScriptCore - `dayOfYear` ignores the calendar and returns the ISO day of year. Every other calendar-dependent field getter has a non-ISO branch through `TemporalCore`; this one does not, and `TemporalZonedDateTimePrototype.cpp` already has a source comment acknowledging it. - The buddhist calendar's `year` returns the ISO year instead of BE, because `TemporalCore::calendarYear()` uses ICU's `UCAL_EXTENDED_YEAR`, which is the Gregorian year for the `GregorianCalendar`-derived calendars. The same function already special-cases `roc` for this exact quirk. - Chinese/dangi leap-month placement disagrees with the reference on 2-3% of dates, and the `ad`/`bc` era aliases are not accepted (`ce`/`bce` are). - Legacy IANA time zone IDs such as `CET` and `EST5EDT` are rejected. This is not Temporal-specific: `new Date()` and `Intl.DateTimeFormat().resolvedOptions().timeZone` already fall back to `UTC` for them today. The first two are being filed upstream on bugs.webkit.org with one-line reproductions. None of these are regressions this PR can introduce; they are pre-existing in the JSC implementation, which is only reachable behind `BUN_JSC_useTemporal=1` today. ### Nothing else needed to change - `test/js/node/test/common/globals.js` already handles the new global conditionally (`if (global.Temporal) intrinsics.add('Temporal')`). - `test/js/bun/jsc/temporal-global.test.ts` (added by #34373 to pin the off-by-default state) is updated to assert the new default and the `BUN_JSC_useTemporal=0` opt-out; the subprocess flag tests live there, next to the other JSC option coverage, and the in-process functional coverage lives in `test/js/web/temporal/temporal.test.ts`. - `structuredClone` and `postMessage` correctly reject Temporal objects with a `DataCloneError`, matching Node. - Temporal string parsing uses its own strict ISO 8601 grammar in `ISO8601.cpp`. It never touches the date parser selected by `useV8DateParser`, which has exactly one call site (`DateCache::parseDate`), so there is no interaction with that override. ### LeakSanitizer The x64-asan lane flags JSC's Temporal time zone bridge on any test that touches a named time zone. `JSC::TemporalCore::withTimeZone` keeps a process-lifetime `LazyNeverDestroyed` LRU of at most 8 open `UCalendar`s (evicted entries are `ucal_close`d), and the `TimeZoneCacheEntry` that owns each one lives in bmalloc memory, which LeakSanitizer does not scan as a root region, so the libc-allocated `UCalendar` is misreported as a direct leak. This PR adds the one `test/leaksan.supp` entry for it with a comment. It is bounded and intentional, not a real leak. ### How did you verify your code works? `test/js/bun/jsc/temporal-global.test.ts` covers the global being present by default and the `BUN_JSC_useTemporal=0` escape hatch. `test/js/web/temporal/temporal.test.ts` covers the spec property attributes, all nine namespaces, `Temporal.Now`, parsing/arithmetic/DST-disambiguation round-trips, `Date.prototype.toTemporalInstant`, `Intl.DateTimeFormat` formatting of Temporal objects, and `structuredClone` rejection. ``` $ USE_SYSTEM_BUN=1 bun test test/js/bun/jsc/temporal-global.test.ts test/js/web/temporal/temporal.test.ts 1 pass 9 fail $ bun bd test test/js/bun/jsc/temporal-global.test.ts test/js/web/temporal/temporal.test.ts 10 pass 0 fail ``` `test/js/web/workers/structured-clone.test.ts` (231 tests) also passes with the flag on. <!-- robobun:evidence:begin --> --- **[review]** gate passed · iteration 4 · 4 files touched <details><summary>fails on main (without fix)</summary> ```console ASAN without fix: 9 FAILED $ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/js/bun/jsc/temporal-global.test.ts test/js/web/temporal/temporal.test.ts bun test v1.4.0 (f2e0cd5) test/js/bun/jsc/temporal-global.test.ts: 9 | cmd: [bunExe(), "-e", `process.stdout.write(typeof Temporal + " " + typeof Temporal.Now.instant)`], 10 | env: { ...bunEnv, BUN_JSC_useTemporal: undefined }, 11 | stderr: "pipe", 12 | }); 13 | const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]); 14 | expect({ stdout, stderr, exitCode }).toEqual({ stdout: "object function", stderr: expect.any(String), exitCode: 0 }); ^ error: expect(received).toEqual(expected) { - "exitCode": 0, - "stderr": Any<String>, - "stdout": "object function", + "exitCode": 1, + "stderr": + "1 | process.stdout.write(typeof Temporal + " " + typeof Temporal.Now.instant) + ^ + ReferenceError: Temporal is not defined + at /workspace/bun/[eval]:1:53 + + Bun v1.4.0-debug+f2e0cd5 ... (truncated) release without fix: all passed bun test v1.4.0-canary.1 (2f503b5) test/js/bun/jsc/temporal-global.test.ts: (pass) Temporal is exposed by default [18.29ms] (pass) BUN_JSC_useTemporal=0 disables Temporal [17.95ms] test/js/web/temporal/temporal.test.ts: (pass) Temporal global > is installed with the spec property attributes [0.03ms] (pass) Temporal global > exposes all nine namespaces [0.05ms] (pass) Temporal core operations > Temporal.Now [5.26ms] (pass) Temporal core operations > parsing, arithmetic, and formatting round-trip [0.17ms] (pass) Temporal core operations > DST disambiguation [0.09ms] (pass) Temporal core operations > Date.prototype.toTemporalInstant [0.04ms] (pass) Temporal core operations > Intl.DateTimeFormat formats Temporal objects [2.06ms] (pass) Temporal core operations > structuredClone rejects Temporal objects [0.12ms] 10 pass 0 fail 27 expect() calls Ran 10 tests across 2 files. [175.00ms] __F:0:S:0 ``` </details> <details><summary>passes on PR (with fix)</summary> ```console ASAN with fix: all passed $ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/js/bun/jsc/temporal-global.test.ts test/js/web/temporal/temporal.test.ts bun test v1.4.0 (f2e0cd5) test/js/bun/jsc/temporal-global.test.ts: (pass) Temporal is exposed by default [1284.32ms] (pass) BUN_JSC_useTemporal=0 disables Temporal [1302.12ms] test/js/web/temporal/temporal.test.ts: (pass) Temporal global > is installed with the spec property attributes [2.15ms] (pass) Temporal global > exposes all nine namespaces [3.39ms] (pass) Temporal core operations > Temporal.Now [168.15ms] (pass) Temporal core operations > parsing, arithmetic, and formatting round-trip [9.26ms] (pass) Temporal core operations > DST disambiguation [6.56ms] (pass) Temporal core operations > Date.prototype.toTemporalInstant [2.74ms] (pass) Temporal core operations > Intl.DateTimeFormat formats Temporal objects [27.37ms] (pass) Temporal core operations > structuredClone rejects Temporal objects [7.59ms] 10 pass 0 fail 27 expect() calls Ran 10 tests across 2 files. [3.65s] __F:0:S:0 release with fix: all passed $ bun scripts/build.ts --profile=release [configured] bun-profile → bun (stripped) in 711ms (unchanged) ninja: Entering directory `/workspace/bun/build/release' [1/7] cxx obj/src/jsc/bindings/ZigGlobalObject.cpp.o [2/7] gen cpp.rs (cppbind) [2/7] cargo bun_bin → libbun_rust.a (--target x86_64-unknown-linux-gnu) nightly-2026-07-20-x86_64-unknown-linux-gnu unchanged - rustc 1.99.0-nightly (9f36de775 2026-07-19) �[1m�[92m Compiling�[0m bun_core v0.0.0 (/workspace/bun/src/bun_core) �[1m�[92m Compiling�[0m bun_errno v0.0.0 (/workspace/bun/src/errno) �[1m�[92m Compiling�[0m bun_ptr v0.0.0 (/workspace/bun/src/ptr) �[1m�[92m Compiling�[0m bun_boringssl_sys v0.0.0 (/workspace/bun/src/boringssl_sys) �[1m�[92m Compiling�[0m bun_safety v0.0.0 (/workspace/bun/src/safety) �[1m�[92m Compiling�[0m bun_zlib_sys v0.0.0 (/workspace/bun/src/zlib_sys) �[1m�[92m Compiling�[0m bun_cares_sys v0.0.0 (/workspace/bun/src/cares_sys) �[1m�[92m Compiling�[0m bun_zstd v0.0.0 (/workspace/bun/src/zstd) �[1m�[92m Compiling�[0m bun_picohttp v0.0.0 (/workspace/bun/src/picohttp) �[1m�[92m Compiling�[0m bun_brotli v0.0.0 (/workspace/bun/src/brotli) �[1m�[92m Compiling�[0m b ... (truncated) ``` </details> <details><summary>diff hotspot</summary> ``` src/jsc/bindings/ZigGlobalObject.cpp | 5 +- test/js/bun/jsc/temporal-global.test.ts | 20 ++++---- test/js/web/temporal/temporal.test.ts | 88 +++++++++++++++++++++++++++++++++ test/leaksan.supp | 9 +++- 4 files changed, 107 insertions(+), 15 deletions(-) ``` </details> **gate history** · 2 passed · 0 rejected · iteration 4 <details><summary>evidence per changed file</summary> ``` file reads edits tests src/jsc/bindings/ZigGlobalObject.cpp 2 1 8 test/js/bun/jsc/temporal-global.test.ts 0 0 0 test/js/web/temporal/temporal.test.ts 0 2 7 test/leaksan.supp 0 0 10 ``` </details> <!-- robobun:evidence:end -->
### What does this PR do? Enables JavaScriptCore's `Temporal` implementation by default by setting `JSC::Options::useTemporal() = true` alongside the other JSC option defaults in `ZigGlobalObject.cpp`. This exposes the `Temporal` global and `Date.prototype.toTemporalInstant`. `BUN_JSC_useTemporal=0` still turns it back off, because the `BUN_JSC_*` environment overrides are applied after the defaults block. Fixes oven-sh#15853. ### Why now JSC's Temporal implementation has improved a lot since the 40% test262 pass rate reported on oven-sh#15853 in early 2025. Measured with `temporal-test262-runner` 0.4.0 (the same tool that produced that 40% figure) against test262 `de8e621c`, with Node v26.3.0 (which ships Temporal on by default) for comparison: | Suite | Tests | Bun | Node 26.3 | |---|---|---|---| | `built-ins/Temporal` (core spec) | 4603 | 100.0% | 98.7% | | `built-ins/Date/prototype/toTemporalInstant` | 8 | 100% | 100% | | `intl402/DateTimeFormat` + `DurationFormat` on Temporal objects | 259 | 99.2% | 91.9% | | `intl402/Temporal` (non-ISO calendars) | 2029 | 56.2% | 38.3% | Every one of the 136 tests where Bun is behind Node is in `intl402/Temporal`, which is non-ISO calendar behavior. Outside of that there is not a single test262 test where Bun is behind Node. I also byte-diffed the output of 20,500 deterministic Temporal operations (seeded identically in both engines): the iso8601, gregory, and roc calendars, 2000 DST-disambiguation cases, all offset-option handling, Instant rounding, and formatting options produced zero divergences. The full test262 run was repeated on a debug + ASAN build of this branch's parent: zero crashes, zero ASAN reports, zero assertion failures, and a pass/fail set identical to release across all 6634 tests. Chrome 144, Firefox, and Node 26 ship Temporal on by default. TypeScript 6.0 ships the type declarations and its `lib.esnext.d.ts` references `esnext.temporal`, so nothing is needed in `bun-types`. ### The Windows blocker is resolved This PR was converted to a draft when CI showed `Temporal.PlainDate.prototype.since` throwing `RangeError: Duration is outside the representable range` on trivial input, on Windows x64 and Windows aarch64 only (the two platforms where WTF's `Int128` is the emulated `Int128Impl` rather than native `__int128`). The WebKit upgrade in oven-sh#34373 (`2603e9eb41f0`) brought in upstream's Temporal duration-arithmetic and spec-alignment fixes, and the bug no longer reproduces. Verified on current main's canary (`1.4.0-canary.1+6b6fb1a33`) on both Windows 2019 x64 and Windows 11 aarch64 with `BUN_JSC_useTemporal=1`: the previously failing expression returns `P17M14D`, and a 10-expression smoke covering `since`/`until`, `Duration.round`/`total`/`compare`, `Instant` arithmetic, epoch nanoseconds, and ZonedDateTime DST transitions produces byte-identical output to Linux on both. ### Cost The `Temporal` namespace object is installed the same way `Intl` is (one line above it in `JSGlobalObject::init`): a single small object whose nine sub-constructors are `PropertyCallback` lookup-table entries created on first access, with their structures registered via `initLater`. Measured over 420 cold starts of `bun -e ''`: 1887 us/start with `useTemporal` off, 1875 us/start with it on (within measurement noise). RSS is 31.5 MB vs 31.4 MB. The implementation was already compiled into the binary behind the runtime flag, so there is no size change. ### Known gaps, all non-ISO calendars and all upstream JavaScriptCore - `dayOfYear` ignores the calendar and returns the ISO day of year. Every other calendar-dependent field getter has a non-ISO branch through `TemporalCore`; this one does not, and `TemporalZonedDateTimePrototype.cpp` already has a source comment acknowledging it. - The buddhist calendar's `year` returns the ISO year instead of BE, because `TemporalCore::calendarYear()` uses ICU's `UCAL_EXTENDED_YEAR`, which is the Gregorian year for the `GregorianCalendar`-derived calendars. The same function already special-cases `roc` for this exact quirk. - Chinese/dangi leap-month placement disagrees with the reference on 2-3% of dates, and the `ad`/`bc` era aliases are not accepted (`ce`/`bce` are). - Legacy IANA time zone IDs such as `CET` and `EST5EDT` are rejected. This is not Temporal-specific: `new Date()` and `Intl.DateTimeFormat().resolvedOptions().timeZone` already fall back to `UTC` for them today. The first two are being filed upstream on bugs.webkit.org with one-line reproductions. None of these are regressions this PR can introduce; they are pre-existing in the JSC implementation, which is only reachable behind `BUN_JSC_useTemporal=1` today. ### Nothing else needed to change - `test/js/node/test/common/globals.js` already handles the new global conditionally (`if (global.Temporal) intrinsics.add('Temporal')`). - `test/js/bun/jsc/temporal-global.test.ts` (added by oven-sh#34373 to pin the off-by-default state) is updated to assert the new default and the `BUN_JSC_useTemporal=0` opt-out; the subprocess flag tests live there, next to the other JSC option coverage, and the in-process functional coverage lives in `test/js/web/temporal/temporal.test.ts`. - `structuredClone` and `postMessage` correctly reject Temporal objects with a `DataCloneError`, matching Node. - Temporal string parsing uses its own strict ISO 8601 grammar in `ISO8601.cpp`. It never touches the date parser selected by `useV8DateParser`, which has exactly one call site (`DateCache::parseDate`), so there is no interaction with that override. ### LeakSanitizer The x64-asan lane flags JSC's Temporal time zone bridge on any test that touches a named time zone. `JSC::TemporalCore::withTimeZone` keeps a process-lifetime `LazyNeverDestroyed` LRU of at most 8 open `UCalendar`s (evicted entries are `ucal_close`d), and the `TimeZoneCacheEntry` that owns each one lives in bmalloc memory, which LeakSanitizer does not scan as a root region, so the libc-allocated `UCalendar` is misreported as a direct leak. This PR adds the one `test/leaksan.supp` entry for it with a comment. It is bounded and intentional, not a real leak. ### How did you verify your code works? `test/js/bun/jsc/temporal-global.test.ts` covers the global being present by default and the `BUN_JSC_useTemporal=0` escape hatch. `test/js/web/temporal/temporal.test.ts` covers the spec property attributes, all nine namespaces, `Temporal.Now`, parsing/arithmetic/DST-disambiguation round-trips, `Date.prototype.toTemporalInstant`, `Intl.DateTimeFormat` formatting of Temporal objects, and `structuredClone` rejection. ``` $ USE_SYSTEM_BUN=1 bun test test/js/bun/jsc/temporal-global.test.ts test/js/web/temporal/temporal.test.ts 1 pass 9 fail $ bun bd test test/js/bun/jsc/temporal-global.test.ts test/js/web/temporal/temporal.test.ts 10 pass 0 fail ``` `test/js/web/workers/structured-clone.test.ts` (231 tests) also passes with the flag on. <!-- robobun:evidence:begin --> --- **[review]** gate passed · iteration 4 · 4 files touched <details><summary>fails on main (without fix)</summary> ```console ASAN without fix: 9 FAILED $ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/js/bun/jsc/temporal-global.test.ts test/js/web/temporal/temporal.test.ts bun test v1.4.0 (f2e0cd5) test/js/bun/jsc/temporal-global.test.ts: 9 | cmd: [bunExe(), "-e", `process.stdout.write(typeof Temporal + " " + typeof Temporal.Now.instant)`], 10 | env: { ...bunEnv, BUN_JSC_useTemporal: undefined }, 11 | stderr: "pipe", 12 | }); 13 | const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]); 14 | expect({ stdout, stderr, exitCode }).toEqual({ stdout: "object function", stderr: expect.any(String), exitCode: 0 }); ^ error: expect(received).toEqual(expected) { - "exitCode": 0, - "stderr": Any<String>, - "stdout": "object function", + "exitCode": 1, + "stderr": + "1 | process.stdout.write(typeof Temporal + " " + typeof Temporal.Now.instant) + ^ + ReferenceError: Temporal is not defined + at /workspace/bun/[eval]:1:53 + + Bun v1.4.0-debug+f2e0cd5 ... (truncated) release without fix: all passed bun test v1.4.0-canary.1 (2f503b5) test/js/bun/jsc/temporal-global.test.ts: (pass) Temporal is exposed by default [18.29ms] (pass) BUN_JSC_useTemporal=0 disables Temporal [17.95ms] test/js/web/temporal/temporal.test.ts: (pass) Temporal global > is installed with the spec property attributes [0.03ms] (pass) Temporal global > exposes all nine namespaces [0.05ms] (pass) Temporal core operations > Temporal.Now [5.26ms] (pass) Temporal core operations > parsing, arithmetic, and formatting round-trip [0.17ms] (pass) Temporal core operations > DST disambiguation [0.09ms] (pass) Temporal core operations > Date.prototype.toTemporalInstant [0.04ms] (pass) Temporal core operations > Intl.DateTimeFormat formats Temporal objects [2.06ms] (pass) Temporal core operations > structuredClone rejects Temporal objects [0.12ms] 10 pass 0 fail 27 expect() calls Ran 10 tests across 2 files. [175.00ms] __F:0:S:0 ``` </details> <details><summary>passes on PR (with fix)</summary> ```console ASAN with fix: all passed $ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/js/bun/jsc/temporal-global.test.ts test/js/web/temporal/temporal.test.ts bun test v1.4.0 (f2e0cd5) test/js/bun/jsc/temporal-global.test.ts: (pass) Temporal is exposed by default [1284.32ms] (pass) BUN_JSC_useTemporal=0 disables Temporal [1302.12ms] test/js/web/temporal/temporal.test.ts: (pass) Temporal global > is installed with the spec property attributes [2.15ms] (pass) Temporal global > exposes all nine namespaces [3.39ms] (pass) Temporal core operations > Temporal.Now [168.15ms] (pass) Temporal core operations > parsing, arithmetic, and formatting round-trip [9.26ms] (pass) Temporal core operations > DST disambiguation [6.56ms] (pass) Temporal core operations > Date.prototype.toTemporalInstant [2.74ms] (pass) Temporal core operations > Intl.DateTimeFormat formats Temporal objects [27.37ms] (pass) Temporal core operations > structuredClone rejects Temporal objects [7.59ms] 10 pass 0 fail 27 expect() calls Ran 10 tests across 2 files. [3.65s] __F:0:S:0 release with fix: all passed $ bun scripts/build.ts --profile=release [configured] bun-profile → bun (stripped) in 711ms (unchanged) ninja: Entering directory `/workspace/bun/build/release' [1/7] cxx obj/src/jsc/bindings/ZigGlobalObject.cpp.o [2/7] gen cpp.rs (cppbind) [2/7] cargo bun_bin → libbun_rust.a (--target x86_64-unknown-linux-gnu) nightly-2026-07-20-x86_64-unknown-linux-gnu unchanged - rustc 1.99.0-nightly (9f36de775 2026-07-19) �[1m�[92m Compiling�[0m bun_core v0.0.0 (/workspace/bun/src/bun_core) �[1m�[92m Compiling�[0m bun_errno v0.0.0 (/workspace/bun/src/errno) �[1m�[92m Compiling�[0m bun_ptr v0.0.0 (/workspace/bun/src/ptr) �[1m�[92m Compiling�[0m bun_boringssl_sys v0.0.0 (/workspace/bun/src/boringssl_sys) �[1m�[92m Compiling�[0m bun_safety v0.0.0 (/workspace/bun/src/safety) �[1m�[92m Compiling�[0m bun_zlib_sys v0.0.0 (/workspace/bun/src/zlib_sys) �[1m�[92m Compiling�[0m bun_cares_sys v0.0.0 (/workspace/bun/src/cares_sys) �[1m�[92m Compiling�[0m bun_zstd v0.0.0 (/workspace/bun/src/zstd) �[1m�[92m Compiling�[0m bun_picohttp v0.0.0 (/workspace/bun/src/picohttp) �[1m�[92m Compiling�[0m bun_brotli v0.0.0 (/workspace/bun/src/brotli) �[1m�[92m Compiling�[0m b ... (truncated) ``` </details> <details><summary>diff hotspot</summary> ``` src/jsc/bindings/ZigGlobalObject.cpp | 5 +- test/js/bun/jsc/temporal-global.test.ts | 20 ++++---- test/js/web/temporal/temporal.test.ts | 88 +++++++++++++++++++++++++++++++++ test/leaksan.supp | 9 +++- 4 files changed, 107 insertions(+), 15 deletions(-) ``` </details> **gate history** · 2 passed · 0 rejected · iteration 4 <details><summary>evidence per changed file</summary> ``` file reads edits tests src/jsc/bindings/ZigGlobalObject.cpp 2 1 8 test/js/bun/jsc/temporal-global.test.ts 0 0 0 test/js/web/temporal/temporal.test.ts 0 2 7 test/leaksan.supp 0 0 10 ``` </details> <!-- robobun:evidence:end -->
Upgrades WebKit to upstream
2603e9eb41f0via oven-sh/WebKit#300 (merged as oven-sh/WebKit@a0e65bf298).Binding updates for upstream API changes
DeferredWorkTimer::Ticketrefactor:TicketDatarenamed toTicketand is nowThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr;addPendingWorkreturnsWeakTicket;scheduleWorkSoonbecamescheduleWorkSoonIfActive.JSCTaskSchedulerandBunClientDatahook registration updated to the newRef<Ticket>&&/Ticket&signatures.DateCachetimezone reset:resetIfNecessarySlow()becameclearForTimeZoneChange();lastTimeZoneIDmoved toWTF::lastTimeZoneID()/WTF::timeZoneDidChange(). Callers inZigGlobalObject,JSEnvironmentVariableMap, andBunJSCModulenow bumpWTF::timeZoneDidChange()then clear the per-VM cache.SparseArrayValueMapcompaction: now aHashSet<SparseArrayEntry>; iterator yields the entry directly (.keybecame.index()).ArrayBuffer::isLocked()folded intoisDetachable().WebKit upgrade: upstream range
d81bcc3d833c..2603e9eb41f0(211 commits in JSC/WTF/bmalloc)Notable changes
JIT / DFG / FTL / B3 / Air
6d70d346c664AddLoadMegamorphicGetterIC0d5d36b5f94eAddRegExpExecStickyDFG node23903f1a1cc7Add AtomString Array loop in DFG / FTL082efc20347dHandleString#trim/trimStart/trimEndin DFG / FTLeeb2440ba085InlineStringSlicerope construction in FTL752e7e8b0d05ConvertHasOwnPropertyon current for-in key toEnumeratorHasOwnProperty7f538702bc4eProve resolved values non-thenable forNewResolvedPromisein DFG constant folding338e02c8838aFix DFG strength reduction folding compiler-thread RegExp failure into a definite no-matchd801f1e36011/674917cb5f4d/71208eb12b5eShrinkAir::Argto 16 bytes,Air::Instto 64 bytes0f2107b6d205RemoveAir::lowerMacros;5d5a2e3a036fsingle-passAir::simplifyCFGebe71899e170Adjust JIT tier-up thresholds for Macs with fewer P-coresGC / Heap
5ecce0f050d2/6fddaa00b614Manually pipeline memory fetching for GC marking (SlotVisitor prefetch)f0df03efe38cTweak number of GC threads on Apple platforms904ba5171187Strong<T>is now pointer-sizedb80bcf43bdceSparseArrayValueMap33% more compact usingHashSetRuntime / Promises / Async
d11c8c7ba675/3ac446bb73b3PolymorphicMicrotaskCallCachefor microtask calls, threaded through more functions5f65bd95a4b6Cooperative driving of async generators74cc52330394UseJSSlimPromiseReactionforJSAsyncGeneratorqueue793fd5461d93async-generator fast consume insertsExitOK707b16ac07eaPromiseResolveThenableJobrejects whenSpeciesConstructorthrows8490d02c5dccAsyncFromSyncIteratorcloses correctly on rejected value promise8e15aeeee3bcImprove exception unwinding performance3bd19f0a328eMove object structured-cloning code into JSCStrings / RegExp / YARR
4e93b58dfd8eArray#joinwrites rope elements directly into result buffer485bcf1b176aFast path forArray#concatwith multiple argumentsbef2808f4db2Parse replacement template once inString#replace(global +$substitutions)5031c9001ee2ImplementString.rawin C++7a764d7acc54Yarr collects BM info for fixed-count terms;e13280f56c44rearrange YarrJIT registers forregT3630d6be8962aFix YARR EOL string-list optimization with multiline flagWebAssembly
c7bfc7c0ca52AddB3::eliminateWasmGCAllocationsphase;a2bb3b59f1ccfold WasmGC object comparisons1152f3717e9bImplement Table64 JS API7f065ab4abdbFix streaming instantiation using result promise as import object when imports omitted228685d7d2a3Names inErrorstacktrace forinstantiateStreamingmodulesbccb52eace5b/f854abcc8468BBQ strength-reduce signed div/rem by negative pow2; mask beforeshrfb30bac88bb4Wasm debugger: replace polling STW participation withVMBlockingScopeTemporal / Intl
23eb4f85f358EnableTemporalobject by defaultcfda643c04c0/2fb282a82538/170ee738c6f1/bdd3b71e35c2/d3c7fd25598a/a0433cfeb9ab/1482a7ad4add/75d9be0204db/f9f65c7ff4f6Multiple Temporal spec-alignment & calendar fixes (ZonedDateTime, PlainDateTime, PlainYearMonth, PlainMonthDay, non-ISO calendars, Duration rounding)6ea58a42a909AdduseIntlEraMonthcodeoption, narrowAvailableCalendars824d2b29e233Use modernunit/skeleton inIntl.NumberFormatcde1f2154e51UseIntlCachefor Temporal pattern generation inIntl.DateTimeFormatParser / Bytecode / LLInt
d981384b263dAddTokNumberInt32toLiteralParserto remove number-conversion overhead1994bc0cc3e2Skip unreachable implicit return for arrow function expression bodiesc0e48d007a10LLInt recordsIterationMode::Genericinop_iterator_next/op_async_iterator_next69ab6c6330aaFix CLoop withloadh/storehWTF / bmalloc
3aa0615a5649FixWTF::divideRoundedUpoverflow near type max39dc095e8f0eFixcalculateBase64EncodedSize()truncation for >4 GB inputsb420bd341074FixpairIntHashbit extraction degrading hash distribution6cccd5ef64ee/82b692fc69fc/dce31d0f206flibpas: fix OoB paths in MAR code, segregated-heap race, zeroed-alloc bugBun-relevant API changes
DeferredWorkTimerTicket refactor (15c117a5444a):TicketDatais nowThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr.addPendingWork()returns aWeakTicket(ThreadSafeWeakPtr<TicketData>) instead of a rawTicket.scheduleWorkSoon(Ticket, Task&&)is replaced byscheduleWorkSoonIfActive(WeakTicket&&, Task&&)/mustScheduleWorkSoonIfActive(...), andcancelPendingWork()now takes aWeakTicket&&. Callers that held a rawTicketmust be updated to holdWeakTicketand use the*IfActivevariants.65d36770c7a6,a01ee718ca4d):JSDateMathnow checksWTF::lastTimeZoneID()/WTF::timeZoneDidChange()guarded byUSE(TIME_ZONE_CHANGE_NOTIFICATIONS). Ports without notifications re-read the host zone on each cache reset. Embedders that previously calledDateCache::timeZoneChanged()directly should route through the new WTF hooks.d11c8c7ba675,3ac446bb73b3,5f65bd95a4b6):callMicrotask()inJSMicrotasknow takes an additionalMicrotaskCallCache*parameter.AsyncFunctionResume's body was factored out intoasyncFunctionGeneratorBodyCall()which also threads the cache. Any Bun code callingcallMicrotask/ resuming async functions directly needs the extra argument.PropertyAttribute::LastAttributesentinel (b80bcf43bdce): thePropertyAttributeenum gained aLastAttributesentinel used by the new compactSparseArrayValueMapencoding.static_asserts against attribute bit-width may need updating.JSCWebPreferenceOptions.h(3af9d4073d75): JSC feature flags are now driven byUnifiedWebPreferences.yaml; the build emits a newJSCWebPreferenceOptions.hthat must be on the include path / in generated-sources lists.[decide:webkit] gate passed · iteration 30 · 13 files touched
fails on main (without fix)
passes on PR (with fix)
diff hotspot
gate history · 6 passed · 12 rejected · iteration 30
evidence per changed file