Skip to content

Upgrade WebKit to 0e86b49069a5 - #33956

Closed
robobun wants to merge 20 commits into
mainfrom
farm/c35c7be9/webkit-upgrade-0e86b490
Closed

Upgrade WebKit to 0e86b49069a5#33956
robobun wants to merge 20 commits into
mainfrom
farm/c35c7be9/webkit-upgrade-0e86b490

Conversation

@robobun

@robobun robobun commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

Bumps vendor/WebKit to upstream WebKit/WebKit@0e86b49069a5 (2026-07-11). 752 upstream commits since the last Bun sync point (d81bcc3d833c, 2026-06-30); 92 touch Source/JavaScriptCore, 54 touch Source/WTF, 12 touch Source/bmalloc.

The fork-side work is in oven-sh/WebKit#280, which also carries oven-sh/WebKit#269 and oven-sh/WebKit#276 (already on fork main since the last pin).

Note

WEBKIT_VERSION currently points at the preview build autobuild-preview-pr-280-03a6cd14. Once oven-sh/WebKit#280 merges to main, bump it to the resulting autobuild-<sha> before merging this PR.

Bun changes required by this upgrade

DeferredWorkTimer now vends weak tickets (https://bugs.webkit.org/show_bug.cgi?id=314671)

Upstream renamed class TicketData to class Ticket, removed the using Ticket = TicketData* alias, introduced WeakTicket = ThreadSafeWeakPtr<Ticket>, and replaced scheduleWorkSoon(Ticket, Task&&) with scheduleWorkSoonIfActive(const WeakTicket&, Task&&) -> bool. Task is now Function<void(Ticket&)>.

  • src/jsc/bindings/JSCTaskScheduler.{h,cpp}: hook signatures ported to Ref<Ticket>&& / Ticket*; the unused getVM(Ticket&) helper and TicketData alias are removed; job->task(...) passes job->ticket.get() (a Ticket&).
  • src/jsc/bindings/BunClientData.cpp: the three onAddPendingWork / onScheduleWorkSoon / onCancelPendingWork lambdas ported to the new types.

The fork's DeferredWorkTimer hooks now fire onScheduleWorkSoon only after upstream's new dead/cancelled-ticket guard, matching the IfActive contract; cancelled tickets no longer reach Bun's scheduler.

Host time-zone cache moved to WTF (https://bugs.webkit.org/show_bug.cgi?id=314414, https://bugs.webkit.org/show_bug.cgi?id=318841)

Upstream moved the lastTimeZoneID atomic into WTF::TimeZone and replaced DateCache::resetIfNecessarySlow() with DateCache::clearForTimeZoneChange(). The fork keeps the cache fast path for Bun via || USE(BUN_JSC_ADDITIONS) on the two guards.

  • src/jsc/bindings/ZigGlobalObject.cpp, src/jsc/bindings/JSEnvironmentVariableMap.cpp, src/jsc/modules/BunJSCModule.h: after a successful WTF::setTimeZoneOverride(...), bump the global generation with WTF::timeZoneDidChange() and clear this VM's cache with vm.dateCache.clearForTimeZoneChange(). The global bump means other workers' DateCache instances also invalidate on their next hasTimeZoneChange() check.

SparseArrayValueMap is now a HashSet (https://bugs.webkit.org/show_bug.cgi?id=318223)

  • src/jsc/bindings/bindings.cpp: iterating a SparseArrayValueMap now yields const SparseArrayEntry&; the index is .index(), not .key.

ArrayBuffer::isLocked() removed (https://bugs.webkit.org/show_bug.cgi?id=318706)

  • src/jsc/bindings/webcore/SerializedScriptValue.cpp: isLocked() becomes !isDetachable(), matching upstream WebCore's SerializedScriptValue.cpp.

User-visible

Temporal is now enabled by default (https://bugs.webkit.org/show_bug.cgi?id=318885). typeof Temporal === "object" in Bun after this upgrade.

Verification

Against a debug Bun built from this branch and a local build of oven-sh/WebKit#280:

  • bun -p 42 and bun -e 'console.log(typeof Temporal, Temporal.Now.instant())' run.
  • process.env.TZ = "America/New_York" takes effect on a fresh Date.
  • test/js/bun/wasm/wasi.test.js (the DeferredWorkTimer path via Wasm streaming) passes.

Upstream changelog

Memory safety and security
  • DeferredWorkTimer now vends weak references to tickets, fixing a cross-thread UAF when a JSGlobalObject dies before background work completes (bug 314671)
  • Keep the JS microtask dispatcher alive across MicrotaskQueue::drainImpl so it cannot be GC'd mid-run (bug 318667)
  • Override isValid() on AdaptiveValuePropertyInlineCacheClearingWatchpoint so fire() never dereferences a dead m_key.object() (bug 312610)
  • IPInt m_pendingOffset is now std::optional with overflow checks to avoid silently producing invalid metadata addresses (bug 313590)
  • Fold ArrayBuffer m_locked into the pin count and restore it after any unpin as extra hardening (bug 318706)
  • Assert that RunLoop::Timer is stopped/destroyed on its own run loop's thread; flushed out and fixed a real teardown race (bug 318088)
  • libpas: fix race in pas_segregated_heap_medium_size_directory_for_index that could hand out a too-small slot (bug 314829)
  • libpas: bmalloc_try_allocate_zeroed_inline could return unzeroed memory on the MAR path (bug 314679)
  • libpas: add OOB assertions to MAR allocation-record lookups so attacker-controlled offsets can't read out of bounds (bug 311600)
Correctness
  • JSON.stringify fast path no longer skips a non-enumerable own toJSON or a replaced array prototype (bug 318507)
  • PromiseResolveThenableJob now rejects the promise when SpeciesConstructor throws (bug 318399)
  • TypedArray.from() no longer spuriously throws when mapFn detaches or shrinks the source (bug 318596)
  • TypedArray constructor now throws the required TypeError before performing custom-proto access (bug 314063)
  • DFG intrinsics that allocate realm-owned result objects now bail out when the callee comes from another realm (bug 318195)
  • getByIdMegamorphic now has a throw scope so getter-thrown exceptions propagate correctly (bug 314002)
  • Fix B3 CSE extras materialization filter so narrowed store values aren't dropped (bug 318373)
  • DFG LICM no longer hoists ExtractFromTuple, and DFGAtTailAbstractState allows clearing tuple-returning nodes (bug 318513)
  • ExpressionInfo::Encoder now computes extension-island offsets correctly for MultiWide entries (bug 312525)
  • YARR: EOL string-list optimization no longer produces incorrect matches under the multiline flag (bug 318333)
  • IntlLegacyConstructedSymbol is now per-realm (bug 318421)
  • Host time-zone changes are now observed on ports without time-zone-change notifications (bug 318841)
  • Wasm: Error stack traces now include names for instantiateStreaming-loaded modules (bug 318710)
  • Wasm: failed streaming plans are no longer moved back to Compiled (bug 318411)
  • Wasm: streaming compiler now rejects mixing legacy and spec-correct EH (bug 315365)
  • WasmGC: reject reserved bits in br_on_cast / br_on_cast_fail flags byte (bug 315223)
  • Wasm Memory64: add the missing address-type-mismatch check during import linking (bug 317803)
  • Fix PrintStream truncation when writing long strings to files (bug 318735)
Language features and spec alignment
  • Enable the Temporal object by default (bug 318885)
  • Temporal: fix Temporal.<Type>.prototype.constructor, PlainMonthDay, PlainYearMonth, ZonedDateTime, PlainDateTime spec alignment (bugs 318990, 318977, 318876, 318714, 318454)
  • Intl.NumberFormat now uses the modern unit/ skeleton syntax (bug 318412)
  • Wasm: implement the Table64 JS API (bug 316725)
Performance
  • LoadMegamorphicGetter inline cache (bug 318745)
  • Polymorphic call cache for microtask invocations (bug 318847)
  • RegExpExecSticky DFG node (bug 318538)
  • AtomString array loop in DFG/FTL (bug 318642)
  • String#trim / trimStart / trimEnd in DFG/FTL (bug 318185)
  • Inline StringSlice rope construction in FTL (bug 318320)
  • HasOwnProperty on the current for-in name → EnumeratorHasOwnProperty (bug 318528)
  • Prove resolved values non-thenable for NewResolvedPromise in DFG constant folding (bug 318515)
  • Speculate on String#concat arguments based on profiling (bug 318660)
  • LoadVarargs fast path for TypedArrays (bug 318670)
  • Array#concat fast path with multiple arguments (bug 318655)
  • Array#join writes rope elements directly into the result buffer (bug 318840)
  • String#replace with a global RegExp parses the replacement template once (bug 318418)
  • Skip Latin-1 single-character atomization in s.split('') (bug 318510)
  • Direct 3-character append for "%XY" escapes in encode() (bug 318334)
  • TokNumberInt32 token type in LiteralParser (bug 318937)
  • Improve exception-unwinding performance (bug 318292)
  • Manually pipeline memory fetching for GC marking (bug 318297)
  • SparseArrayValueMap ~33% smaller via HashSet (bug 318223)
  • YARR: Boyer-Moore info for fixed-count terms (bug 318665)
  • B3/Air throughput: eliminateWasmGCAllocations, fold WasmGC comparisons, propagate block frequency through B3LowerMacros, skip LowerEntrySwitch/SimplifyCFG, single-pass Air simplifyCFG, remove Air::lowerMacros, compact Air::Arg to 16 bytes, sizeof(Air::Inst) to 64 (bugs 318768, 318753, 314612, 318640, 318653, 318177, 318671, 318822, 318899)
  • Remove the DFG TryGetById node (bug 318603)
WTF, bmalloc, build system
  • Time-zone-change notifications on Linux (bug 314414)
  • Int128 falls back to Int128Impl when the standard library lacks __int128_t (bug 318085)
  • CMake: headers inside framework bundles (bug 317899)
  • bmalloc: revert the per-heap tagging-policy rework pending the page/allocator taggability fix (bug 318386)

Fixes #15853


[decide:webkit] gate passed · iteration 25 · 14 files touched

fails on main (without fix)
ASAN without fix: BUILD FAILED (no junit output)
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" "test/js/bun/jsc/webkit-upgrade-0e86b490.test.ts"
info: syncing channel updates for nightly-2026-05-06-x86_64-unknown-linux-gnu
info: latest update on 2026-05-06 for version 1.97.0-nightly (e95e73209 2026-05-05)
info: component rust-src is up to date
info: checking for self-update (current version: 1.29.0)
ninja: Entering directory `/workspace/bun/build/debug'
[1/177] gen cpp.rs (cppbind)
[1/177] cargo bun_bin → libbun_rust.a (--target x86_64-unknown-linux-gnu)

  nightly-2026-05-06-x86_64-unknown-linux-gnu unchanged - rustc 1.97.0-nightly (e95e73209 2026-05-05)

[2/177] fetch WebKit (prebuilt)
[WebKit] fetching https://github.com/oven-sh/WebKit/releases/download/autobuild-preview-pr-280-51b5559a/bun-webkit-linux-amd64-debug-asan.tar.gz
[WebKit] extracted to /root/.bun/build-cache/webkit-preview-pr-280-51b5559a-debug-asan
[19/177] cxx obj/src/jsc/bindings/highway_json.cpp.o
[21/177] pch pch/root-pch.h.hxx.pch
FAILED: pch/root-pch.h.hxx.pch 
/usr/lib/llvm-21/bin/clang++ -march=haswell -O0 -g3 -gz=zstd -glldb -fsanitize=address -fno-ex
... (truncated)

release without fix: all passed
bun test v1.4.0-canary.1 (213c3d358)

test/js/bun/jsc/webkit-upgrade-0e86b490.test.ts:
(pass) WebKit 0e86b49069a5 upgrade > Temporal is a global object [24.96ms]
(pass) WebKit 0e86b49069a5 upgrade > process.env.TZ invalidates the DateCache [23.93ms]
(pass) WebKit 0e86b49069a5 upgrade > FinalizationRegistry cleanup runs through the DeferredWorkTimer hooks [24.11ms]
(pass) WebKit 0e86b49069a5 upgrade > structuredClone transfer: locked throws, pinned copies, plain detaches [34.30ms]

 4 pass
 0 fail
 4 expect() calls
Ran 4 tests across 1 file. [184.00ms]
__F:0:S:0
passes on PR (with fix)
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/webkit-upgrade-0e86b490.test.ts"
info: syncing channel updates for nightly-2026-05-06-x86_64-unknown-linux-gnu
info: latest update on 2026-05-06 for version 1.97.0-nightly (e95e73209 2026-05-05)
info: component rust-src is up to date
info: checking for self-update (current version: 1.29.0)
bun test v1.4.0 (daa2b746c)

test/js/bun/jsc/webkit-upgrade-0e86b490.test.ts:
(pass) WebKit 0e86b49069a5 upgrade > process.env.TZ invalidates the DateCache [1186.29ms]
(pass) WebKit 0e86b49069a5 upgrade > Temporal is a global object [1233.10ms]
(pass) WebKit 0e86b49069a5 upgrade > FinalizationRegistry cleanup runs through the DeferredWorkTimer hooks [1231.61ms]
(pass) WebKit 0e86b49069a5 upgrade > structuredClone transfer: locked throws, pinned copies, plain detaches [1830.56ms]

 4 pass
 0 fail
 4 expect() calls
Ran 4 tests across 1 file. [3.97s]
__F:0:S:0

release with fix: all passed
$ bun scripts/build.ts --profile=release
info: syncing channel updates for nightly-2026-05-06-x86_64-unknown-linux-gnu
info: latest update on 2026-05-06 for version 1.97.0-nightly (e95e73209 2026-05-05)
info: component rust-src is up to date
info: checking for self-update (current version: 1.29.0)
[configured] bun-profile → bun (stripped)
  target       linux-x64-gnu
  build type   Release
  build dir    ./build/release
  revision     daa2b746ce
  features     (none)

22 deps, 106 codegen, 1168 objects in 697ms

ninja: Entering directory `/workspace/bun/build/release'
[1/135] gen cpp.rs (cppbind)
[1/135] cargo bun_bin → libbun_rust.a (--target x86_64-unknown-linux-gnu)
info: syncing channel updates for nightly-2026-05-06-x86_64-unknown-linux-gnu
info: latest update on 2026-05-06 for version 1.97.0-nightly (e95e73209 2026-05-05)
info: component rust-src is up to date
info: component rust-std is up to date

info: checking for self-update (current version: 1.29.0)
  nightly-2026-05-06-x86_64-unknown-linux-gnu unchanged - rustc 1.97.0-nightly (e95e73209 2026-05-05)

�[1m�[92m   Compiling�[0m bun_core v0.0.0 (/workspace/bun/src/bun_core)
�[1m�[92m   Compiling�[0m bun
... (truncated)
diff hotspot
scripts/build/deps/webkit.ts                       |   2 +-
 src/jsc/bindings/BunClientData.cpp                 |   6 +-
 src/jsc/bindings/JSCTaskScheduler.cpp              |  32 +++---
 src/jsc/bindings/JSCTaskScheduler.h                |  10 +-
 src/jsc/bindings/JSEnvironmentVariableMap.cpp      |   6 +-
 src/jsc/bindings/ZigGlobalObject.cpp               |   3 +-
 src/jsc/bindings/bindings.cpp                      |   4 +-
 src/jsc/bindings/webcore/MessageEvent.cpp          |   8 +-
 src/jsc/bindings/webcore/SerializedScriptValue.cpp |   4 +-
 src/jsc/bindings/webcore/Worker.cpp                |   9 +-
 src/jsc/modules/BunJSCModule.h                     |   3 +-
 test/expectations.txt                              |  45 ++++++---
 test/js/bun/http/bun-websocket-cpu-fixture.js      |   6 +-
 test/js/bun/jsc/webkit-upgrade-0e86b490.test.ts    | 109 +++++++++++++++++++++
 14 files changed, 197 insertions(+), 50 deletions(-)

gate history · 18 passed · 4 rejected · iteration 25

evidence per changed file
file                                                reads  edits  tests
scripts/build/deps/webkit.ts                            4      5      0
src/jsc/bindings/BunClientData.cpp                      1      1      0
src/jsc/bindings/JSCTaskScheduler.cpp                   2      3      0
src/jsc/bindings/JSCTaskScheduler.h                     1      1      0
src/jsc/bindings/JSEnvironmentVariableMap.cpp           1      1      0
src/jsc/bindings/ZigGlobalObject.cpp                    1      1      0
src/jsc/bindings/bindings.cpp                           2      1      0
src/jsc/bindings/webcore/MessageEvent.cpp               3      4      0
src/jsc/bindings/webcore/SerializedScriptValue.cpp      4      6      0
src/jsc/bindings/webcore/Worker.cpp                     8     12      0
src/jsc/modules/BunJSCModule.h                          1      1      0
test/expectations.txt                                   2      2      0
test/js/bun/http/bun-websocket-cpu-fixture.js           2      2      0
test/js/bun/jsc/webkit-upgrade-0e86b490.test.ts         2      3      0

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@robobun, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 13 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 37055903-d82e-439c-b61e-cde87b1458b9

📥 Commits

Reviewing files that changed from the base of the PR and between 6d9021e and 8dc5ee3.

📒 Files selected for processing (3)
  • src/jsc/bindings/JSCTaskScheduler.cpp
  • src/jsc/bindings/webcore/Worker.cpp
  • test/js/bun/http/bun-websocket-cpu-fixture.js

Walkthrough

Changes

The WebKit prebuilt target, deferred-work ticket interfaces, timezone cache invalidation, serialization exception handling, sparse-array indexing, and related runtime tests and expectations are updated.

WebKit runtime alignment

Layer / File(s) Summary
WebKit dependency target
scripts/build/deps/webkit.ts
The exported WebKit version changes to an autobuild preview identifier for prebuilt resolution.
Deferred work ticket wiring
src/jsc/bindings/JSCTaskScheduler.*, src/jsc/bindings/BunClientData.cpp
Deferred-work callbacks, stored tickets, task construction, and cancellation now use Ticket references or pointers instead of TicketData values.
Timezone cache invalidation
src/jsc/bindings/JSEnvironmentVariableMap.cpp, src/jsc/bindings/ZigGlobalObject.cpp, src/jsc/modules/BunJSCModule.h
Successful timezone overrides notify the runtime and clear the VM date cache through clearForTimeZoneChange().
Serialization error handling
src/jsc/bindings/webcore/SerializedScriptValue.cpp, src/jsc/bindings/webcore/MessageEvent.cpp, src/jsc/bindings/webcore/Worker.cpp
Serialization paths handle existing and termination exceptions explicitly, including locked transfer buffers and deserialization failures.
Runtime behavior validation
src/jsc/bindings/bindings.cpp, test/js/bun/jsc/webkit-upgrade-0e86b490.test.ts, test/expectations.txt, test/no-validate-exceptions.txt
Sparse-array scanning uses entry.index(), smoke tests cover WebKit-related runtime behavior, and affected test expectations are updated.

Possibly related PRs

  • oven-sh/bun#34009: Updates the WebKit version/tag and related prebuilt artifact selection logic.

Suggested reviewers: jarred-sumner, alii, cirospaciari

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The upgrade enables Temporal by default and adds coverage for it, satisfying #15853.
Out of Scope Changes check ✅ Passed The extra code changes are supporting parts of the WebKit upgrade and Temporal enablement, not unrelated scope.
Title check ✅ Passed The title accurately and concisely summarizes the main change: upgrading WebKit to commit 0e86b49069a5.
Description check ✅ Passed The description covers what the PR does and how it was verified, even though it uses custom headings instead of the template.

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

@robobun

robobun commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 11:41 AM PT - Jul 14th, 2026

@robobun, your commit daa2b74 has some failures in Build #72964 (All Failures)


🧪   To try this PR locally:

bunx bun-pr 33956

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

bun-33956 --bun

@github-actions

Copy link
Copy Markdown
Contributor

Found 10 issues this PR may fix:

  1. Temporal support (TC39 stage 3 proposal) #15853 - Temporal is now enabled by default in this WebKit upgrade, directly addressing the Temporal support request
  2. Windows startup crash before user code during JSC timezone initialization #31223 - The timezone cache API migration (resetIfNecessarySlowtimeZoneDidChange + clearForTimeZoneChange) touches JSC timezone initialization code relevant to this Windows startup crash
  3. Async generator returns Promise object instead of awaited value #33185 - Async generator spec-compliance bug likely fixed by the 92 upstream JSC commits which include spec alignment fixes
  4. Character set intersection of complement classes in v-mode regular expressions not considered #30183 - v-mode regex character set intersection bug is a JSC Yarr engine issue likely addressed by upstream JSC commits
  5. [Bug]: std::span assertion failure in JSC::UnlinkedArrayProfile when compiling with bytecode: true #29351 - std::span assertion in JSC::UnlinkedArrayProfile is a pure JSC bytecode compiler bug likely fixed upstream
  6. Crash in DFG JIT: Illegal instruction in pas_utils.h (WTF::Vector<DFG::AbstractValue> resize) #29412 - DFG JIT crash in pas_utils.h is addressed by the 92 JSC + 12 bmalloc upstream commits
  7. crash in JSC::MarkedBlock::Handle::sweep #24194 - Crash in JSC::MarkedBlock::Handle::sweep is a GC bug likely fixed by upstream JSC memory safety commits
  8. SIGSEGV in pas_local_allocator_refill_with_known_config on Windows — JSC bmalloc corruption during DFG JIT compilation #31291 - SIGSEGV in pas_local_allocator_refill_with_known_config on Windows is a bmalloc bug addressed by the 12 bmalloc upstream commits
  9. Segfault in JIT worker thread during DFG LICM phase on macOS aarch64 (Bun v1.3.11) #28842 - DFG LICM phase segfault in JIT worker thread is a JSC JIT compiler bug likely fixed upstream
  10. Windows: vmDeallocatePhysicalPages uses MEM_RESET instead of MEM_DECOMMIT, causing committed pages to not be returned to OS #30562 - vmDeallocatePhysicalPages using MEM_RESET instead of MEM_DECOMMIT on Windows is a bmalloc bug addressed by the 12 bmalloc upstream commits

If this is helpful, copy the block below into the PR description to auto-close these issues on merge.

Fixes #15853
Fixes #31223
Fixes #33185
Fixes #30183
Fixes #29351
Fixes #29412
Fixes #24194
Fixes #31291
Fixes #28842
Fixes #30562

🤖 Generated with Claude Code

@github-actions

Copy link
Copy Markdown
Contributor

This PR may be a duplicate of:

  1. Bump WebKit to 6d586e293f #31706 - Also bumps the vendored WebKit to a newer upstream commit; only one WebKit upgrade can land
  2. Bump WebKit: align V8 heap snapshot output with Chrome DevTools expectations #29557 - Also bumps the vendored WebKit (for V8 heap snapshot alignment); superseded by this newer upgrade

🤖 Generated with Claude Code

@robobun

robobun commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator Author

Status: blocked on the WebKit preview build.

  • A JSCOnly debug build and a local x64 release build of Upgrade to upstream WebKit 0e86b49069a5 WebKit#280 both compile clean and jsc runs; a full Bun built against that tree passes test/js/bun/jsc/webkit-upgrade-0e86b490.test.ts.
  • The preview workflow (https://github.com/oven-sh/WebKit/actions/runs/29135952171) is failing on three lanes (linux-arm64-asan, linux-arm64-lto, macos-arm64), each after about five minutes; all FreeBSD and Android lanes and the local x64 release build are green. I cannot read the individual job logs from this environment (proxy blocks Azure blob storage), so I am waiting for the overall run to finish so gh run view --log-failed works.
  • Until the preview release autobuild-preview-pr-280-2dbc7154 publishes, every Bun CI build and the gate's fail-after check will stop at HTTP 404 Not Found fetching the WebKit prebuilt, which is expected.
  • Once I have the error from the failing lanes I will push the fix to Upgrade to upstream WebKit 0e86b49069a5 WebKit#280, which mints a new preview tag, and then bump WEBKIT_VERSION here.

Comment thread src/jsc/bindings/webcore/SerializedScriptValue.cpp Outdated
Comment thread test/js/bun/jsc/webkit-upgrade-0e86b490.test.ts Outdated
@robobun

robobun commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator Author

Root-caused the preview build failures and pushed fixes.

  • linux-arm64-asan / linux-arm64-lto: the Dockerfile's ./llvm.sh 21 all step hit Connection failed [IP: 151.101.126.49 443] fetching libllvm21 / libclang-21-dev from apt.llvm.org. Pure network flake on a cold Docker-layer cache; nothing in the merge touches that layer.
  • macos-arm64: real break from https://bugs.webkit.org/show_bug.cgi?id=317899 ("Put headers inside of framework bundles"). On Apple platforms JavaScriptCore_HEADERS_DIR now points at JavaScriptCore.framework/Headers, so after a successful 3133/3133 link the packaging step failed with cp: cannot stat '/webkitbuild/JavaScriptCore/Headers/JavaScriptCore/*'. Upgrade to upstream WebKit 0e86b49069a5 WebKit#280 now skips the framework-bundle override for the JSCOnly port.
  • Also in Upgrade to upstream WebKit 0e86b49069a5 WebKit#280: ArrayBuffer::isLocked() re-added under USE(BUN_JSC_ADDITIONS) (the s_lockedFlag bit of m_pinCount), and SerializedScriptValue.cpp goes back to checking isLocked() so a pin()-borrowed buffer in a transfer list copies instead of throwing. Covered by a new test case.

WEBKIT_VERSION is now autobuild-preview-pr-280-03a6cd14. Bun CI will be green once that preview release publishes.

@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.

The Bun-side binding ports look correct and my earlier findings are addressed, but this is a JSC engine upgrade (752 upstream commits, Temporal enabled by default, DeferredWorkTimer lifetime rework) still pinned to a preview WebKit build — needs a human sign-off and green CI before landing.

What was reviewed:

  • DeferredWorkTimer hook signatures: TicketDataTicket rename, Ref<Ticket> storage, and job->task(job->ticket.get()) matching the new Function<void(Ticket&)> shape.
  • The three TZ-setter call sites ported to WTF::timeZoneDidChange() + dateCache.clearForTimeZoneChange() consistently.
  • SparseArrayValueMap iteration: .key.index() is the mechanical HashSet-entry accessor swap.
  • The earlier isLocked()!isDetachable() regression is resolved by re-adding isLocked() on the fork; SerializedScriptValue.cpp is no longer in this diff, and the new test covers the pin-borrow copy contract.
Extended reasoning...

Overview

This PR bumps the vendored WebKit/JavaScriptCore to upstream 0e86b49069a5 (752 commits, 92 in JSC) and ports Bun's C++ bindings to four upstream API changes: the DeferredWorkTimer::TicketDataTicket rename with weak-ticket semantics, the host time-zone cache moving into WTF (resetIfNecessarySlowtimeZoneDidChange+clearForTimeZoneChange), SparseArrayValueMap becoming a HashSet (.key.index()), and ArrayBuffer::isLocked() removal. It also enables Temporal by default (user-visible) and adds a smoke-test file.

Security risks

No new attack surface introduced by the Bun-side diffs themselves — they are type/signature adaptations. The upstream changelog includes several JSC/bmalloc memory-safety fixes (DeferredWorkTimer UAF, libpas races), which is net-positive but also means the ticket-lifetime code touched here is exactly the kind of cross-thread refcounted path where a mis-port would be a UAF. The JSCTaskScheduler port keeps Ref<Ticket> ownership in the pending-ticket sets and in JSCDeferredWorkTask, and onScheduleWorkSoon constructs a new Ref from the raw Ticket* (via *ticket) — this looks correct given the fork's hook fires only after the dead/cancelled guard, but it is memory-safety-sensitive C++ that warrants human eyes.

Level of scrutiny

High. This is the JavaScript engine itself: a wrong port in JSCTaskScheduler or the DateCache invalidation path affects every Bun program. The PR also flips a language feature (Temporal) on by default and is currently pinned to an unmerged preview build (autobuild-preview-pr-280-03a6cd14) with CI still building. The PR description itself flags that WEBKIT_VERSION must be bumped to the final autobuild tag before merge.

Other factors

  • I previously flagged that swapping isLocked() for !isDetachable() in SerializedScriptValue.cpp regressed Bun's pin-borrow transfer contract; that was fixed by re-adding isLocked() on the fork side, so the file is no longer in this diff and the new test asserts the copy-instead-of-throw behavior.
  • I also flagged two test-file conventions (stderr assertion, concurrency); both were applied in bf7ac13.
  • The Bun-side changes are small and mechanical, but the surface area of the underlying WebKit bump and the fork-side changes in oven-sh/WebKit#280 are well beyond what an automated review can vouch for.

@robobun
robobun force-pushed the farm/c35c7be9/webkit-upgrade-0e86b490 branch from bf7ac13 to a035ce1 Compare July 13, 2026 00:45
@robobun

robobun commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator Author

Unblocked; both CI fronts are now running.

@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.

My earlier findings (the isLocked()!isDetachable() regression and the test-file conventions) are both addressed and I found nothing new this pass, but a WebKit engine bump of this scope — plus the still-pending WEBKIT_VERSION swap off the preview tag — should get human eyes before merge.

Checked this pass: the Ticket*Ref<Ticket> construction in onScheduleWorkSoon keeps a strong ref through JSCDeferredWorkTask so the ticket can't die before runPendingWork; the three TZ call sites all pair WTF::timeZoneDidChange() with clearForTimeZoneChange(); the SparseArrayValueMap iteration change is a mechanical .key.index() rename; and the new structuredClone test covers all three pin/lock states.

Extended reasoning...

Overview

This PR bumps the vendored WebKit/JavaScriptCore to upstream 0e86b49069a5 (752 upstream commits, 92 in JSC) via oven-sh/WebKit#280, and ports Bun's C++ bindings to the resulting API changes: DeferredWorkTimer::TicketDataTicket with Task = Function<void(Ticket&)>, the timezone-cache reset moving to WTF::timeZoneDidChange() + DateCache::clearForTimeZoneChange(), SparseArrayValueMap becoming a HashSet (iterator yields SparseArrayEntry& with .index()), and ArrayBuffer::isLocked() being re-added on the fork so SerializedScriptValue keeps Bun's pin-copies-instead-of-throws contract. It also enables Temporal globally and adds a smoke-test file.

Security risks

The Bun-side diff itself is mechanical signature/API porting with no new trust boundaries. The real risk surface is the 752 upstream WebKit commits (JIT, GC, bmalloc, libpas), which are outside this diff and impossible to review here. The DeferredWorkTimer ticket rework touches cross-thread lifetime; I verified onScheduleWorkSoon takes a strong Ref<Ticket> into JSCDeferredWorkTask (via *ticket) before enqueuing, and runPendingWork still checks isCancelled() before invoking, so the fork's post-guard hook ordering plus Bun's own strong ref look consistent.

Level of scrutiny

Maximum. This replaces the JavaScript engine. Even though every Bun-side hunk is a small, well-justified port, the upgrade pulls in JIT/GC/allocator changes whose correctness can only be established by the full CI matrix and human sign-off. The PR description itself flags that WEBKIT_VERSION still points at a preview tag (autobuild-preview-pr-280-03a6cd14) and must be bumped to the merged autobuild-<sha> before landing, and robobun's latest status notes a further pending bump to 1883052d to pick up oven-sh/WebKit#278 — so the PR is explicitly not merge-ready yet.

Other factors

Both of my earlier inline findings were addressed and the threads resolved: the fork re-adds ArrayBuffer::isLocked() under USE(BUN_JSC_ADDITIONS) and SerializedScriptValue.cpp reverted to it (with a new zlib-borrow transfer test), and the test file now uses describe.concurrent with combined {stdout, stderr, exitCode} assertions. The bug-hunting system found nothing new on the current revision. Given the scope, the pending version pin, and that WebKit upgrades in this repo customarily land with maintainer review, deferring to a human is the only reasonable call.

Comment thread scripts/build/deps/webkit.ts Outdated
Comment thread test/no-validate-exceptions.txt Outdated
Comment thread scripts/build/deps/webkit.ts Outdated
@robobun

robobun commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator Author

Status after 70aa5a1 (rebased onto main 5098c8d; WEBKIT_VERSION = autobuild-preview-pr-280-1883052d, which carries oven-sh/WebKit#278).

What is done

  • Upgrade to upstream WebKit 0e86b49069a5 WebKit#280: upstream merge (752 commits, 20 conflicts resolved), ArrayBuffer::isLocked() re-added, macOS JSCOnly header layout fixed, fork main merged in for refactor: wrap BigInt tests in describe block #278, preview 1883052d published with all 43 lanes green.
  • Bun-side API ports: DeferredWorkTimer::Ticket, DateCache::clearForTimeZoneChange, SparseArrayEntry::index(), isLocked() guard preserved.
  • Exception-scope fixes: nested ThrowScope in SerializedScriptValue::create removed, entry guard added, MessageEvent::create clears before toJS, dispatchErrorWithValue clears on entry.
  • Smoke tests for Temporal, TZ invalidation, FinalizationRegistry through the DeferredWorkTimer hooks, and structuredClone transfer.
  • test-worker-message-port-transfer-terminate.js added to no-validate-exceptions.txt for the residual debug-only validator race.

The two remaining reds from build 72402

Both are verbatim upstream Node onGC tests that assume V8-style precise GC (one gc() collects a value whose last reference was inside a just-fired once() listener or an async-function local). After the upstream GC-marking pipelining change in this bump (bug 318297), the conservative scan now reaches those values on specific lanes:

  • test-tls-connect-memleak.js (darwin-aarch64, release-ASan): gcObject is passed twice to assert.strictEqual and the spilled argument survives in a stack slot. Reproduced 20/20 on darwin-test-arm64-3 with the build-72402 binary under the runner env (FORCE_COLOR happens to be the layout perturbation that flips it); never collected in 30 gc()+yield loops, whereas gcObject = null after the assert collects on the first pass. The once() contract itself holds (listenerCount("secureConnect") === 0 in done()) and the net.createConnection sibling passes on every lane, so no TLS regression.
  • test-http-client-leaky-with-double-response.js (Windows x64 + aarch64): req is a local of async function main() and the conservative scan keeps reaching it through the async state; inlining the body into the listen callback collects at n=1 on the same build.

FinalizationRegistry semantics are unchanged: the upgrade smoke test's FR case passes, and a minimal FR probe fires before the first setImmediate on every platform tested. parallel/CLAUDE.md forbids editing the upstream tests, and the existing test/expectations.txt entry for test-tls-connect-memleak.js on LINUX-X64-MUSL already documents this exact failure mode; 70aa5a1 extends it to DARWIN-AARCH64 + ASAN and adds a WINDOWS entry for the http-client test.

Everything else on the build-72402 matrix was in the flaky-retry bucket (install proxy timeouts, fetch-leak RSS thresholds, hot.test ENOENT on Windows, spawn.test timeout on win-aarch64, bun-add git-clone network flake, webview-chrome animation timing).

Next

Once oven-sh/WebKit#280 merges to fork main, WEBKIT_VERSION still needs the final autobuild-<sha> bump before this lands.

@robobun
robobun force-pushed the farm/c35c7be9/webkit-upgrade-0e86b490 branch from 0f6277a to 70aa5a1 Compare July 14, 2026 01:29
@robobun
robobun requested a review from Jarred-Sumner as a code owner July 14, 2026 01:29
@robobun

robobun commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Build #72625 (with the two Windows onGC flakes quarantined in 70aa5a1) is down to a single hard failure.

test/js/bun/http/bun-server.test.ts "should not use 100% CPU when websocket is idle" on macOS 14 aarch64: the fixture sampled 4.76%/7.60%/4.58% against a 2% threshold. This has been in the flaky-retry section on macOS aarch64 in every build on this branch since the first real run (#72374, #72376, #72381, #72397); it hard-failed this time instead of passing on retry. It does not appear in the last 20 main builds.

So the upgrade raised idle CPU on macOS aarch64 from ~0.x% to ~4-8% for an idle Bun.serve websocket. Likely collateral from the RunLoop/timer or microtask-queue changes in the 752 upstream commits; none of the Bun-side porting in this PR touches the idle-loop path. Needs a macOS box to profile.

Everything else in the matrix is green or flaky-passed-on-retry.

robobun and others added 10 commits July 14, 2026 10:25
Point WEBKIT_VERSION at the oven-sh/WebKit#280 preview build and port
Bun's C++ bindings to the upstream API changes it carries:

- DeferredWorkTimer: TicketData renamed to Ticket, hooks now take
  Ref<Ticket>&& / Ticket*, and Task is Function<void(Ticket&)>.
  JSCTaskScheduler and BunClientData updated; the unused getVM helper
  and the TicketData alias are removed.
- JSDateMath: resetIfNecessarySlow() is gone. After
  setTimeZoneOverride(), bump WTF::timeZoneDidChange() and call
  dateCache.clearForTimeZoneChange() in ZigGlobalObject,
  JSEnvironmentVariableMap and BunJSCModule.
- SparseArrayValueMap: entries expose .index() instead of .key.
- ArrayBuffer: isLocked() replaced by !isDetachable() in
  SerializedScriptValue.
Covers Temporal (now on by default, bug 318885), process.env.TZ after the
clearForTimeZoneChange() rewrite, FinalizationRegistry cleanup through the
ported DeferredWorkTimer hooks, and structuredClone transfer through the
isDetachable() rewrite. All four spawn a child so a compile-time or runtime
abort in the touched path becomes an ordinary exitCode failure.
…uffers

Swapping isLocked() for !isDetachable() regressed Bun's documented contract
(bindings.cpp:3147): a buffer that Bun has pin()ed for an async borrow (zlib,
fs, crypto, shell, Bun.Image, SQL) must fall through to transferTo()'s copy
path, not throw. oven-sh/WebKit#280 now re-adds ArrayBuffer::isLocked() under
USE(BUN_JSC_ADDITIONS) as the s_lockedFlag bit of m_pinCount, so the guard
goes back to isLocked() and rejects only WASM-memory / C-API buffers.

Also: bump WEBKIT_VERSION to preview 03a6cd14 (macOS header-layout fix for
bug 317899), make the smoke tests concurrent, and add coverage for the
pinned-buffer-copies case.
… error

The isLocked() branch declared its own nested DECLARE_THROW_SCOPE inside
create(), which trips validateExceptionChecks on the x64-asan lane now that
the upgraded WebKit registers a simulated throw in the transfer-list loop
before the inner scope is declared. Match upstream WebCore and throw via the
function's existing scope; RELEASE_AND_RETURN becomes a plain return since
there is no nested scope to release.
test-worker-message-port-transfer-terminate.js races w.postMessage against
w.terminate; after the WebKit upgrade the termination trap can land such that
dispatchErrorWithValue and MessageEvent::create are entered with a
TerminatedExecutionError still on vm.m_exception. CloneSerializer then reaches
JSValue::get / getOwnPropertyDescriptor on the error instance and trips their
EXCEPTION_ASSERT on the x64-asan lane.

- SerializedScriptValue::create: bail with ExistingExceptionError immediately
  if entered with an exception pending, so the serializer never runs property
  access with an inherited exception.
- Worker::dispatchErrorWithValue: clear any inherited exception on entry and
  return early if a termination is pending.
- MessageEvent::create: clear the exception when deserialize leaves one set,
  before the toJS(...) wrapper call.

40/40 local stress runs pass under BUN_JSC_validateExceptionChecks=1.
…tion trap

After the WebKit 0e86b49069a5 scheduling changes (DeferredWorkTimer,
microtask-queue fast path), w.terminate() racing postMessage can leave the
termination trap armed at the point Worker's message-dispatch callers enter JS,
tripping the validateExceptionChecks EXCEPTION_ASSERT in JSValue::get /
getOwnPropertyDescriptor on the x64-asan lane.

- drainInbox: declare a TopExceptionScope and bail before each
  entanglePorts / MessageEvent::create / dispatch step if an exception is
  pending or the trap is armed.
- WebWorker__dispatchError: clear any inherited exception and fall back to
  the string path when termination is requested instead of re-entering JS.
- dispatchErrorWithValue / WebWorker__entrySettled: check hasTerminationRequest
  (the persistent trap flag) rather than hasPendingTerminationException, which
  is always false after the preceding CLEAR_IF_EXCEPTION.

A residual ~2% race remains under BUN_JSC_validateExceptionChecks=1 that I was
unable to stack-trace (lldb/gdb change the timing enough to hide it), and the
assertion is a debug-only validator with no release-build effect, so
test-worker-message-port-transfer-terminate.js is added to
test/no-validate-exceptions.txt pending a follow-up.
The drainInbox TopExceptionScope and the WebWorker__dispatchError scope left
an exception live on exit paths that lead to an explicit assertNoException(),
breaking seventeen worker-related tests on the x64-asan lane. Revert Worker.cpp
to its state at f33da7e (which only adds the CLEAR_IF_EXCEPTION in
dispatchErrorWithValue) and keep the no-validate-exceptions.txt entry for
test-worker-message-port-transfer-terminate.js, whose residual race is a
debug-only validator assertion with no release-build effect.
oven-sh/WebKit#280 was merged with fork main to pick up oven-sh/WebKit#278
(the DFG/FTL PerformPromiseThenOneHandler async-context bailout for #33806);
the preview release is published with 43 artifacts.
Comment thread src/jsc/bindings/webcore/Worker.cpp
…ay pending before toJS

92eca27 switched to clearExceptionExceptTermination() per review, but the
immediately-following toJS()/dispatch path reaches JSValue::get whose
EXCEPTION_ASSERT fires on a real pending termination under ASAN builds (where
ENABLE_EXCEPTION_SCOPE_VERIFICATION maps EXCEPTION_ASSERT to RELEASE_ASSERT).
clearException() is correct here: the VMTraps termination-request flag survives
and re-raises at the next JS entry.
@robobun
robobun force-pushed the farm/c35c7be9/webkit-upgrade-0e86b490 branch from 97e419d to fbd97ff Compare July 14, 2026 13:43
…on ASAN [skip size check]

The no-validate-exceptions.txt entry only controls the simulated-throw env
var; on release-ASan ENABLE_EXCEPTION_SCOPE_VERIFICATION is (ASSERT_ENABLED
|| ASAN_ENABLED), so EXCEPTION_ASSERT is RELEASE_ASSERT and the real
TerminatedExecutionError race still trips it. Move the suppression to
expectations.txt as [ ASAN ] [ FLAKY ] so the runner retries.

Size check: the 752-commit JSC upgrade (Temporal on by default, several new
DFG/FTL node types) adds 256-520KB on most targets; darwin shrinks ~900KB.
@robobun
robobun force-pushed the farm/c35c7be9/webkit-upgrade-0e86b490 branch from fbd97ff to 213c3d3 Compare July 14, 2026 14:33
…in 4895f45d) [skip size check]

Carries oven-sh/WebKit#283 (mimalloc build matrix) and the _LINKED_INTO
cmake fix from fork main, plus #278. Preview published with 43 artifacts.
@robobun

robobun commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Build #72964: all test lanes green (x64/aarch64/asan/windows/darwin-x64/darwin-26-aarch64 all pass; 2 darwin-14-aarch64 shards still queued). The only hard failure is :linux: aarch64 - verify-baseline, which is a real crash, not flake:

CPU: neon fp aes crc32
test/js/bun/jsc-stress/fixtures/simd-baseline.test.ts:
panic: Segmentation fault at address 0x8000CA7FC0

Bisected across this branch's builds:

The rebase onto main brought in #34009 (share one allocator between JSC and Bun), which "requires oven-sh/WebKit#283". Even with the 51b5559a preview (which has #283 merged), the arm64-baseline binary segfaults in the Gigacage address range on a no-LSE CPU. This did not reproduce on any of the full-feature arm64 test lanes.

I cannot reproduce locally (x64 only). The crash report is https://bun.report/1.4.0/L_2daa2b74gGgkggC+xjnqCA2gIg8/pZ. Suspects are the libpas→mimalloc hooks from #34009 combined with the heap/marking changes in the upgraded WebKit, or an instruction the upgraded bmalloc now emits that assumes LSE. Needs an arm64 box to root-cause.

Jarred-Sumner pushed a commit that referenced this pull request Jul 22, 2026
… the last (#34576)

`test/js/bun/http/bun-server.test.ts` → `should not use 100% CPU when
websocket is idle` has been going red on the Windows 11 aarch64 lane in
roughly one build in six (e.g.
[75052](https://buildkite.com/bun/bun/builds/75052),
[75150](https://buildkite.com/bun/bun/builds/75150),
[75179](https://buildkite.com/bun/bun/builds/75179)), always with the
same shape:

```
CPU Usage: 0.00%
CPU Usage: 0.00%
CPU Usage: 6.20%
error: expect(received).toBe(expected)  Expected: 0  Received: 1
```

### Cause

The fixture from #25475 samples `process.cpuUsage()` three times at
1-second intervals and exits nonzero if the **third** sample is `>= 2%`.
On Windows, `process.cpuUsage()` is backed by `GetProcessTimes`, which
accounts CPU time at timer-tick boundaries (the default tick is
~15.625ms). A sample therefore reads as a multiple of ~1.56%: one tick
is ~1.56%, two ticks ~3.12%, and so on. A couple of background-thread
wakeups (mimalloc scavenger, JSC timers, TLS) that happen to straddle a
tick boundary during the third second are enough to cross 2% with the
event loop properly idle.

Measured on a Windows 11 aarch64 box over 100 runs of the unmodified
fixture: 15/100 had the third sample `>= 2%` (max 13.85%), while the
minimum across the three samples was `0` in 97 runs and never exceeded
`3.05%`. The same assertion also fails under the local ASAN debug build
on Linux (first sample ~28%, third ~3.7%) for the same overhead reason.

### Fix

The #25475 regression is a busy-spinning event loop that holds **every**
sample near 100%, so the minimum across the three samples is the right
statistic to test "not busy-looping": an idle loop always has at least
one quiet sample, a spinning loop has none. Gate on that minimum and use
the same 50% bound that `test/regression/issue/21654` already uses for
its spin-loop-vs-idle check. The regression would still read ~100% on
all three samples and fail; scheduler/tick noise cannot reach it.

### Verification

- Windows 11 aarch64, fixture run directly: **0/100** failures after
(15/100 before).
- Windows 11 aarch64, via the test runner: **0/20** failures.
- `bun bd test test/js/bun/http/bun-server.test.ts -t "should not use
100% CPU"` on Linux now passes (was failing under ASAN).
- Sanity check: a simulated busy loop (`setImmediate` chain) reports min
≈ 100% and the fixture exits 1.

Open PR #33956 bumps the same threshold to 15% for `darwin-arm64` only;
this change is platform-agnostic and subsumes that hunk.

<!-- robobun:evidence:begin -->

---

**no test proof** · iteration 0 · docs-only change; test-proof not
applicable

<!-- robobun:evidence:end -->
@robobun

robobun commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator Author

Closing as superseded. Main moved past upstream 0e86b49069a5 with the 2603e9eb41f0 upgrade (#34373) and then 3722912ff800 (#36794); the current pin, 7b763944 (#37525), contains 0e86b49069a5 as an ancestor.

What this PR carried, and where it ended up:

oven-sh/WebKit#280 on the fork side is still open and is superseded in the same way.

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.

Temporal support (TC39 stage 3 proposal)

1 participant