Skip to content

Upgrade to upstream WebKit 23b0720b40 - #814

Merged
sosukesuzuki merged 1019 commits into
mainfrom
bun/upgrade-to-23b0720b40
Oct 15, 2026
Merged

sosukesuzuki merged 1019 commits into
mainfrom
bun/upgrade-to-23b0720b40

Conversation

@sosukesuzuki

@sosukesuzuki sosukesuzuki commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Merges upstream WebKit 23b0720b40 (2026-10-15): 1013 commits since dbdca7545d (#773), 170 of them in Source/JavaScriptCore, Source/WTF or Source/bmalloc.

Please land this as a merge commit, not a squash. The merge records upstream/main as a parent, which is how the next upgrade finds its base.

The commits:

  1. The merge. Its message lists every conflict and every place that merged cleanly but no longer fit; the same list is below.
  2. [JSC] Keep ShadowRealm. Upstream removed ShadowRealm and JSRemoteFunction in 323565@main (d5f13fa851) because WebKit never shipped them. Bun does: it is a documented global, it is in bun-types, and Bun's tests use it. The merge takes the removal as it is, and this commit brings back the JavaScriptCore and JSTests parts, from the fork's versions of the files. This is a decision for the maintainers: it means the fork carries about 1,700 lines of engine code that upstream no longer maintains. To let ShadowRealm go instead, drop or revert this one commit (Bun then has to drop the global, its types, docs and tests, the deriveShadowRealmGlobalObject entries of its method tables, and renumber JSType.rs).
  3. CI: take CombinedDomains.json from JavaScriptCore/Scripts. Upstream generates the file in another directory now, and the tarballs had lost it.
  4. [JSC] Windows: yield once where a collection resumes the mutators, and its follow-up at the head. See below. Also a decision for the maintainers.
  5. A merge of main, for 4556ec7c1c (SourceProvenance). SourceProvider.h conflicted next to lines where upstream had turned SourceTaintedOrigin into SourceTaintedness. What that commit adds takes a SourceTaintedness too now, like its neighbours. The constructor's definition in SourceProvider.cpp had merged cleanly with the old type and would no longer have matched its declaration.

With the second commit, JSType.h, GlobalObjectMethodTable.h, Intrinsic.h, LinkTimeConstant.h, BuiltinNames.h, BytecodeIntrinsicRegistry.h and BytecodeList.rb are what they were before the merge.

The collector's yield on Windows

Collector::resumeThePeriphery() used to end its wait for the parallel visitors with a SpinBackoff::spinOnce(), which ran at least once per call. SpinBackoff has no pause steps on Windows, so there that was a SwitchToThread(); on Linux it is a pause. 1d86f80869 (323742@main) removed the wait, rightly, and the yield went with it.

Bun's test/js/bun/module-graph/module-graph-workers.test.ts then timed out on Windows Server 2019 x64, every time. Its cells wait for 1 ms timers of a sleeping worker while dozens of threads spin on setImmediate() on four cores. Such a loop collects every 14 ms or so, so it used to give up the CPU that often, and without the yield it runs out its quantum. By topology (A to E), in seconds, from oven-sh/bun#45303's CI:

A B C D E sum
before the upgrade 14 36 26 10 4 90
upgraded, without the yield 18 84 78 22 12 214
upgraded, with it 16 34 30 10 4 94

This puts one Thread::yield() back in the same place, under USE(BUN_JSC_ADDITIONS) && OS(WINDOWS). It keeps a side effect on purpose: what Bun did before this upgrade, for that test and for any program with busy threads and workers on a loaded Windows server. The other way is to leave the engine as upstream has it and make the test wait without spinning. Windows 11 aarch64 lost the same yield and is no slower (56 in all three rows), which is not explained.

What needs a careful look

  • OptionsMSVC.cmake. 0a75fded40 sets CMAKE_MSVC_RUNTIME_LIBRARY to MultiThreadedDLL with a plain set(), which overrides what is passed with -D. It merged without a conflict and would have replaced the static CRT that Dockerfile.windows and Bun pass. It is now only the default. Not built locally.
  • Latin1Character is a struct (50a617392b). The fork's own code needed byteCast in jsc.cpp, CachedTypes.cpp and JSDateMath.cpp. Only what Linux x64 compiles has been compiled; the Windows-only templates of URL.cpp were instantiated by hand on Linux and are fine.
  • ScriptFetchParameters::Type::CSS comes after HostDefined, and SourceProviderSourceType::CSS after BunTranspiledModule, unlike upstream's order. HostDefined has to stay 5: Bun's transpiler writes the number into the module info it serializes, and BunAnalyzeTranspiledModule.cpp asserts it.
  • GCIncomingRefCountedSet::sweep() combines upstream's eden sweep of new and dirty ArrayBuffers (91e8fd1b2f) with the fork's accounting of m_bytes after an eden sweep.
  • The Collector serves several heaps upstream now. The fork's begin-phase stamps moved into beginCollectionInEachHeap(), and totalMaxEdenSize() sums effectiveMaxEdenSize().

The merge

66 files conflicted. What was done about them, and about the places where the
two sides merged without a conflict but no longer fit:

NODELETE is now LEGACY_NODELETE (e795d5a, e4be394, b8f13b0):

  • In most of the conflicting files this was the whole conflict: upstream renamed
    the annotation on a line the fork had changed or sat next to. The fork's lines,
    renamed. That is all of the conflicts in yarr/ but one, CachedTypes.{h,cpp},
    JSBigInt.h, JSCell.h, URL.h, URLParser.h, and single lines in many other
    headers.
  • NODELETE is no longer defined under clang, so the 16 uses the fork had added in
    places that did not conflict are renamed too.

Heap / Collector (729712a and the fourteen commits after it let one Collector
serve several heaps):

  • Collector.cpp: there is no m_heap any more. The stamps the fork takes at the
    start of a collection are per heap, so they moved from runBeginPhase() to
    beginCollectionInEachHeap(), still ahead of willStartCollection(); nothing in
    between reads them. GCRequest::didFinishEndPhase still runs where it did;
    didFinishCollection() went to endCollectionInEachHeap() with upstream.
  • The mutator schedulers ask Collector::totalMaxEdenSize(), which sums the fork's
    Heap::effectiveMaxEdenSize() so that the cap under critical memory still holds.
  • GC rate limiting stays reverted (642e225).
  • GCIncomingRefCountedSet (91e8fd1, an eden sweep only looks at new and dirty
    ArrayBuffers): upstream's sweep, with the fork's accounting of m_bytes after an
    eden sweep. What upstream's eden sweep visits is what the fork counted
    separately, and m_oldCount is the fork's m_sizeAfterLastSweep, which is gone.
  • MarkedBlock.cpp: marksConveyLivenessDuringMarking() is now
    staleMarksStillRecordSurvivors() (b8c79b4).
  • VM::shrinkFootprintNow() clears sourceProviderCacheMap itself:
    clearSourceProviderCaches() became pruneUnusedSourceProviderCaches(), which
    keeps the caches used since the last prune (92e99db).

Latin1Character is a struct (50a6173): byteCast where the fork's code passes
bytes for characters or the reverse, in jsc.cpp, CachedTypes.cpp and
JSDateMath.cpp (the V8 date parser takes bytes).

Source taintedness (ac57a2a): SourceTaintedOrigin.h is SourceTaintedness.h.
JSModuleRecord's hasSameObservableSource() compares taintedness().

CSS module scripts (b1913f6):

  • makeModule() and provideFetch() take a JSValue. They stay member functions, and
    the new default-export path passes the loader on.
  • SyntheticModuleRecord::tryCreateDefaultExportSyntheticModule() is public, with
    the fork's JSModuleLoader* parameter.
  • ScriptFetchParameters::Type::CSS comes after HostDefined, which stays 5: Bun's
    transpiler writes that number into the module info it serializes.
    SourceProviderSourceType::CSS comes after BunTranspiledModule likewise.
  • with { type: "css" } stays a HostDefined type with USE(BUN_JSC_ADDITIONS), as
    "text" does: Bun loads it itself.
  • JSModuleLoader::registryEntry() looks under Type::CSS too.

Exception stacks (70896f2, no stack is captured for a throw that a user's
catch clause is certain to handle): Exception visits m_asyncContext and takes
upstream's lock. The fork's createScriptCallStackFromException() reads
stackForReporting().

BigInt (e2ffc55 adds a divide-and-conquer toString): the fork already has one,
on Barrett division and interruptible. The fork's is kept and upstream's tests
run against it.

Yarr:

  • 7a8cc2f (bit tables for Unicode property escapes): the fork has
    matchCharacterClassMatchesAndRanges() inlined in matchCharacterClass(), so
    upstream's new helpers landed inside a function body. They now precede it.
  • 8d2c95e (length checks for an EOL string list): the fork has no
    consumeIndex(). A string list is only made of the whole pattern's body, which
    is matched forward, so it is an add32.
  • stress/regexp-stringlist-eol-length-groups.js expects no match from a lastIndex
    inside a surrogate pair. That is A6 of JSTests/BUN-TEST-DIFFERENCES.md; the
    expectation is updated and the file is listed there.

Others:

  • ExecutableMemoryHandle.h (e2e0869): ENABLE_LIBPAS_JIT_HEAP is defined above
    the includes. The exclusion of ARM64 Windows went with it.
  • pas_thread_local_cache.c (69e1e79): pas_memory_flavor_plain, still
    asymmetric.
  • OptionsMSVC.cmake (0a75fde) set CMAKE_MSVC_RUNTIME_LIBRARY to
    MultiThreadedDLL whatever was passed. It merged cleanly and would have replaced
    the static CRT that Dockerfile.windows and Bun pass. It is now only the default.
  • CMakeLists.txt (e8c36a1): CombinedDomains.json is generated in
    JavaScriptCore_SCRIPTS_DIR, by the fork's command (the output path as an
    argument, no redirect).
  • JSGlobalObject.cpp (733b18f): cachedToLocaleStringNumberFormat() is in;
    exposeDollarVM() stays in JSDollarVM.cpp.
  • Nodes.h (e5f751c): neededConstants() is gone, statements() stays.
  • InjectedScriptSource.js (b0bb30b): upstream's shape, testing for the fork's
    one-line "[native code] }".
  • RuntimeManager.js (f87677d): upstream's parse, with ecmaVersion "latest".
  • Symbol.h, VerifierSlotVisitorScope.h, WasmFunctionIPIntMetadataGenerator.h,
    IntlDateTimeFormat.cpp, SourceProvider.h: both sides' includes.
  • WebCore/page/Viewport.h, ProofOfPossessionProviderInfo.h and
    FindInteractionTester.h are new upstream files that git took for renames of the
    deleted ShadowRealm headers. Upstream's files.

JSType.h loses ShadowRealmType here and gets it back in the next commit. Nothing
else in it changed. .github/ and the Dockerfiles are untouched.

How it was verified

Linux x64 only, with clang 20 (not the LLVM 23 that CI uses), from a machine that could reach neither the pinned toolchain nor the prebuilt releases.

  • jsc builds and links, Debug with assertions, with the flags of scripts/build/deps/webkit.ts in oven-sh/bun and libpas.
  • JavaScriptCore, WTF and bmalloc also build in the configuration Bun ships (USE_MIMALLOC, USE_EXTERNAL_MIMALLOC, -fno-pic), from Bun's own build graph.
  • run-javascriptcore-tests --quick on that Debug jsc, filtered to every test under JSTests/stress and JSTests/wasm/stress that the merge adds or changes, plus the ShadowRealm, remote function, string list, BigInt, ArrayBuffer, WeakMap, import attribute, Unicode property and toLocaleString tests: 440 runs of 125 files pass. One file needed its expectation changed, stress/regexp-stringlist-eol-length-groups.js (A6, see above). The whole suite has not been run; this pull request's test job is the first full run.
  • All 64 tests of test262's built-ins/ShadowRealm pass (default, no JIT, validateExceptionChecks).
  • Of the lines the fork had added to a file that upstream also changed (382 files), 35 are not in the result. Each is one of the rewrites listed above. Counting repeated lines found one more that the ShadowRealm revert had lost, which is back (AllowLazyMaterializationOfImmutableProperties in JSFunction.cpp).
  • Bun's C++ compiles against this tree, with the changes it needs (mostly Latin1Character). No Bun could be linked or run: Bun's Rust needs the pinned nightly.
  • macOS, Windows, FreeBSD, Android, musl, arm64, ASAN, LTO: nothing has been built. CI here is the first build of all of them.

Found on the way, not from this merge, not changed here

In ShadowRealm, in code that is the same as on main; 2 to 4 also happen on Bun 1.4.2:

  1. new ShadowRealm().evaluate("(function (v) { throw v })")(Symbol()) fails ASSERT(!scope.exception()) in sanitizeRemoteFunctionException() (toWTFString() of a Symbol throws). A build without assertions throws a TypeError.
  2. remoteFunctionCallGeneric() wraps its return value for targetGlobalObject, where remoteFunctionCallForJSFunction() has globalObject. A function returned through a wrapped Proxy has the inner realm's Function.prototype.
  3. An error is only replaced when Interpreter::unwind() unwinds the remote function's frame. When C++ calls the wrapped function (Promise.prototype.then, Array.prototype.sort, String.prototype.replace), the inner realm's error object comes out.
  4. f.caller of a sloppy function in the realm skips the remote function's frame and returns the outer realm's function.
  5. stress/remoteFunctionCallForJSFunction-should-placate-overflow-check{,2}.js do not pass --useShadowRealm=1, so all they see is a ReferenceError. They are as upstream had them.

Generated by Claude Code


Generated by Claude Code

rniwa and others added 30 commits October 13, 2026 01:27
…expectations for WebCore

https://bugs.webkit.org/show_bug.cgi?id=327382

Unreviewed. Just removing the unexpectedly passing file from the expectations.

* Source/WebCore/SaferCPPExpectations/UncheckedLocalVarsCheckerExpectations:

Canonical link: https://commits.webkit.org/323554@main
https://bugs.webkit.org/show_bug.cgi?id=327227

Reviewed by Carlos Garcia Campos.

This change makes internals returning frame damage history rectangles
in CSS pixel coordinates rather than device pixel coordinates as the
tests under platform/glib/damage/ assume CSS pixel coordinates.

Canonical link: https://commits.webkit.org/323555@main
…hs that are not performance sensitive

https://bugs.webkit.org/show_bug.cgi?id=327224

Reviewed by Anne van Kesteren.

Fix Safer C++ warnings in Source/WebCore/layout that are in rare feature
branches (SVG text, ruby, selection, pagination, hit testing, initial-letter,
line-box-contain, text-emphasis, block-ellipsis, line-clamp, hyphenation and
vertical-text baselines). Hot inline layout and painting paths are left alone.

This tested as performance neutral on Speedometer and MotionMark.

* Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp:
* Source/WebCore/layout/formattingContexts/inline/InlineFormattingUtils.cpp:
* Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp:
* Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp:
* Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp:
* Source/WebCore/layout/formattingContexts/inline/ruby/RubyFormattingContext.cpp:
* Source/WebCore/layout/integration/inline/InlineIteratorLineBox.cpp:
* Source/WebCore/layout/integration/inline/InlineIteratorLogicalOrderTraversal.cpp:
* Source/WebCore/layout/integration/inline/InlineIteratorSVGTextBox.cpp:
* Source/WebCore/layout/integration/inline/LayoutIntegrationLineLayout.cpp:
* Source/WebCore/layout/integration/inline/LineSelection.h:

Canonical link: https://commits.webkit.org/323556@main
https://bugs.webkit.org/show_bug.cgi?id=327247

Reviewed by Tim Nguyen.

Rename auto to normal for the continue property since at first the WPT tests were expecting this
and recently the spec was synced to match the WPT tests [1].

[1] w3c/csswg-drafts@bf9279e

* LayoutTests/imported/w3c/web-platform-tests/css/css-overflow/inheritance-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-overflow/parsing/continue-invalid-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-overflow/parsing/continue-valid-expected.txt:
* Source/WebCore/css/CSSProperties.json:
* Source/WebCore/css/parser/CSSPropertyParserCustom.h:
(WebCore::CSS::PropertyParserCustom::consumeLineClampShorthand):
* Source/WebCore/rendering/style/RenderStyleConstants.cpp:
(WebCore::operator<<):
* Source/WebCore/rendering/style/RenderStyleConstants.h:
* Source/WebCore/style/StyleAdjuster.cpp:
(WebCore::Style::Adjuster::adjust const):
* Source/WebCore/style/StyleExtractorCustom.h:
(WebCore::Style::ExtractorCustom::extractWebkitLineClampShorthand):
(WebCore::Style::ExtractorCustom::extractWebkitLineClampShorthandSerialization):
* Source/WebCore/style/values/primitives/StyleKeyword+Mappings.h:

Canonical link: https://commits.webkit.org/323557@main
https://bugs.webkit.org/show_bug.cgi?id=327156
rdar://189747796

Reviewed by Youenn Fablet.

whatwg/html#13055 adds the [SameAgentCluster]
extended attribute: serializing or transferring an object implementing
such an interface restricts the result to the agent cluster it came from,
deserializing it in another agent cluster throws a DataCloneError, and
serializing it for storage throws as well. This is what
w3c/webcodecs#717 needs for EncodedVideoChunk,
VideoFrame, EncodedAudioChunk, and AudioData, and what the WebCodecs
crossAgentCluster tests already expect. MediaStreamTrack and
MediaStreamTrackHandle are transferred the same way, so restrict them
too.

The bindings generator now emits isRestrictedToSameAgentCluster for
[Serializable] and [Transferable] interfaces. SerializedScriptValue maps
each serialization tag to the PlatformObjectSerializationTraits of its
interface in one place, platformObjectSerializationTraitsForTag(), which
both the exposure check and the new isTagRestrictedToSameAgentCluster()
use. When CloneSerializer writes a restricted tag it writes the agent
cluster ID after it, as JSC already does for SharedArrayBuffer, and
CloneDeserializer checks that ID before reading the object. All of these
objects already refuse to be serialized for storage, before their tag is
written.

The existing tests only cover the video types, so add tests for
AudioData, EncodedAudioChunk, MediaStreamTrack, and
MediaStreamTrackHandle.

Tests: imported/w3c/web-platform-tests/mediacapture-insertable-streams/MediaStreamTrackHandle-transfer-cross-agent-cluster.https.html
       imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-transfer-cross-agent-cluster.https.html
       imported/w3c/web-platform-tests/webcodecs/audio-serialization.crossAgentCluster.https.html

Canonical link: https://commits.webkit.org/323558@main
https://bugs.webkit.org/show_bug.cgi?id=327317
rdar://189858704

Reviewed by Brent Fulgham.

rebaseline active-quirks-by-domain.html

* LayoutTests/platform/ios/fast/quirks/active-quirks-by-domain-expected.txt:
* LayoutTests/platform/mac-wk2/fast/quirks/active-quirks-by-domain-expected.txt: Removed.

Canonical link: https://commits.webkit.org/323559@main
https://bugs.webkit.org/show_bug.cgi?id=303066
rdar://165656837

Reviewed by Vitor Roriz.

FontCascade::fontForCombiningCharacterSequence on Cocoa and Skia accepts a
font for a combining character cluster only when the font's cmap has every
code point in the cluster. That is the first rule in step 1 of CSS Fonts 4
cluster matching. Neither port implemented the second, canonical-equivalence
rule, so a font missing only a combining mark's glyph was rejected even when
it had the precomposed letter, and the whole cluster fell back to a system
font with a different weight.

The canonical-equivalence check runs before moving on to the next font family,
so a cluster still comes from a single font, as intended by
https://bugs.webkit.org/show_bug.cgi?id=68287.

The new check keeps the cmap-based coverage test from
https://bugs.webkit.org/show_bug.cgi?id=185933, and uses the same test for
the precomposed character.

On Cocoa, choosing the font is not enough, because CoreText does not compose a
decomposed cluster into the precomposed glyph.
fontForCombiningCharacterSequence now reports the precomposed character it
matched, and ComplexTextController::collectComplexTextRuns builds the text to
shape from it while it walks the clusters, the same way it builds
m_smallCapsBuffer. ComplexTextRun maps the shaped indices back to the original
text. With synthesized small caps, a matched cluster is shaped from its
capitalized cluster's precomposed character when the font has one, and
otherwise is not shaped as small caps, because the font has none of the
cluster's combining marks.

On Skia, HarfBuzz already composes the cluster when it shapes, so the shaping
text is not needed. Font selection still reports the precomposed character it
matched, so the synthesized small caps decision above is the same as on Cocoa.

Tests: imported/w3c/web-platform-tests/css/css-fonts/cluster-matching-canonical-equivalence-001.html
       imported/w3c/web-platform-tests/css/css-fonts/cluster-matching-canonical-equivalence-002.html
       imported/w3c/web-platform-tests/css/css-fonts/cluster-matching-canonical-equivalence-003.html
       Tools/TestWebKitAPI/Tests/WTF/StringView.cpp

* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/cluster-matching-canonical-equivalence-001-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/cluster-matching-canonical-equivalence-001-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/cluster-matching-canonical-equivalence-001.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/cluster-matching-canonical-equivalence-002-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/cluster-matching-canonical-equivalence-002-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/cluster-matching-canonical-equivalence-002.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/cluster-matching-canonical-equivalence-003-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/cluster-matching-canonical-equivalence-003-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/cluster-matching-canonical-equivalence-003.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/support/fonts/no-combining-marks.ttf: Added.
A subset of fonts/Lato-Medium.ttf with ASCII, U+01F0 and U+1E96 to U+1E99, and
no combining marks or layout features. It is renamed because Lato has a
Reserved Font Name.
* Source/WTF/wtf/text/StringView.cpp:
(WTF::StringView::precomposedCharacter const):
* Source/WTF/wtf/text/StringView.h:
* Source/WebCore/platform/graphics/ComplexTextController.cpp:
(WebCore::ComplexTextController::collectComplexTextRuns):
* Source/WebCore/platform/graphics/ComplexTextController.h:
(WebCore::ComplexTextController::ComplexTextRun::create):
* Source/WebCore/platform/graphics/FontCascade.cpp:
(WebCore::FontCascade::fontForCombiningCharacterSequence const):
* Source/WebCore/platform/graphics/FontCascade.h:
* Source/WebCore/platform/graphics/cairo/FontCairoHarfbuzzNG.cpp:
(WebCore::FontCascade::fontForCombiningCharacterSequence const):
* Source/WebCore/platform/graphics/coretext/ComplexTextControllerCoreText.mm:
(WebCore::ComplexTextController::ComplexTextRun::ComplexTextRun):
(WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
* Source/WebCore/platform/graphics/coretext/FontCascadeCoreText.cpp:
(WebCore::fontForOrientation):
(WebCore::FontCascade::fontForCombiningCharacterSequence const):
* Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp:
(WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
* Source/WebCore/platform/graphics/skia/ComplexTextControllerSkia.cpp:
(WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
* Source/WebCore/platform/graphics/skia/FontCascadeSkia.cpp:
(WebCore::FontCascade::fontForCombiningCharacterSequence const):
* Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp:
(WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
* Tools/TestWebKitAPI/Tests/WTF/StringView.cpp:
(TestWebKitAPI::TEST(WTF, StringViewPrecomposedCharacter)):
(TestWebKitAPI::TEST(WTF, StringViewPrecomposedCharacterNone)):

Canonical link: https://commits.webkit.org/323560@main
https://bugs.webkit.org/show_bug.cgi?id=327330

Reviewed by Anne van Kesteren.

Make BuilderState::m_style a const CheckedRef instead of a raw reference so that
the generated and custom style builder code calling through BuilderState::style()
is trusted by the static analyzer.

This tested as performance neutral on Speedometer and MotionMark once
PGO profiles are regenerated.

* Source/WebCore/style/StyleBuilderState.cpp:
* Source/WebCore/style/StyleBuilderState.h:
* Source/WebCore/style/StyleBuilderStateInlines.h:

Canonical link: https://commits.webkit.org/323561@main
Unreviewed gardening.

These glib baselines no longer differ from the generic ones, so the tests
failed only because of the stale copies. Remove them together with the
failure expectations; the tests pass against the generic baselines on the
GTK and WPE bots and locally.

* LayoutTests/platform/glib/TestExpectations:
* LayoutTests/platform/glib/fast/text/font-load-data-partitioned-alphabet-expected.txt: Removed.
* LayoutTests/platform/glib/http/tests/websocket/tests/hybi/invalid-continuation-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-self-block-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/css/css-values/attr-pseudo-elem-invalidation-2-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/audioworklet.https.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/element-frame.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/element-iframe.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/element-img.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/element-input-image.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/element-picture.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/element-script.https.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/element-script.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/fetch-via-serviceworker.https.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/fetch.https.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/fetch.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/script-module-import-dynamic.https.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/script-module-import-dynamic.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/script-module-import-static.https.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/script-module-import-static.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/svg-image.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/worker-dedicated-constructor.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/worker-dedicated-importscripts.https.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/worker-dedicated-importscripts.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/browsers/browsing-the-web/back-forward-cache/pushstate.https-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/browsers/browsing-the-web/back-forward-cache/service-worker-clients-matchall.https-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/browsers/browsing-the-web/back-forward-cache/service-worker-controlled-after-restore.https-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/browsers/browsing-the-web/back-forward-cache/storage-events-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.sharedworker-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video.https-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/service-workers/service-worker/registration-script-module.https-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/upgrade-insecure-requests/gen/iframe-blank-inherit.meta/unset/img-tag.https-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/upgrade-insecure-requests/gen/srcdoc-inherit.meta/unset/img-tag.https-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/webrtc/simulcast/getStats.https-expected.txt: Removed.
* LayoutTests/platform/gtk/TestExpectations:
* LayoutTests/platform/wpe/TestExpectations:

Canonical link: https://commits.webkit.org/323562@main
…riding 'visibility: visible'

https://bugs.webkit.org/show_bug.cgi?id=326988

Reviewed by Rob Buis.

Per SVG2, 'visibility: hidden' on <text> / <foreignObject> only hides the
element itself - descendants can override it with 'visibility: visible'.
LBSE skipped the whole subtree, unlike the legacy engine.

Split shouldPaintSVGRenderer() into shouldPaintSVGLeafRenderer() and
shouldPaintSVGContainerRenderer() (used by <g> and <text>). Hidden containers
keep painting the foreground, mask and clipping mask phases, so visible
descendants are still painted, masked and clipped. <foreignObject> skips the
check, as its CSS boxes check their own visibility.

Fixes svg/batik/text/textProperties2.svg - also add new tests to specifically
cover the visibility in all scenarios, as WPT tests.

Tests: imported/w3c/web-platform-tests/svg/extensibility/foreignObject/foreign-object-visibility-hidden-visible-content.html
       imported/w3c/web-platform-tests/svg/render/reftests/visibility-hidden-container-mask-clip.html
       imported/w3c/web-platform-tests/svg/text/reftests/text-visibility-hidden-tspan-visible.html

* LayoutTests/imported/w3c/web-platform-tests/svg/extensibility/foreignObject/foreign-object-visibility-hidden-visible-content-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/extensibility/foreignObject/foreign-object-visibility-hidden-visible-content-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/extensibility/foreignObject/foreign-object-visibility-hidden-visible-content.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/render/reftests/visibility-hidden-container-mask-clip-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/render/reftests/visibility-hidden-container-mask-clip-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/render/reftests/visibility-hidden-container-mask-clip.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/text/reftests/text-visibility-hidden-tspan-visible-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/text/reftests/text-visibility-hidden-tspan-visible-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/text/reftests/text-visibility-hidden-tspan-visible.html: Added.
* LayoutTests/platform/mac-tahoe-wk2-lbse-text/TestExpectations:
* Source/WebCore/rendering/RenderLayerModelObject.cpp:
(WebCore::RenderLayerModelObject::shouldPaintSVGLeafRenderer const):
(WebCore::RenderLayerModelObject::shouldPaintSVGContainerRenderer const):
(WebCore::RenderLayerModelObject::paintSVGClippingMask const):
(WebCore::RenderLayerModelObject::shouldPaintSVGRenderer const): Deleted.
* Source/WebCore/rendering/RenderLayerModelObject.h:
* Source/WebCore/rendering/svg/RenderSVGContainer.cpp:
(WebCore::RenderSVGContainer::paint):
* Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp:
(WebCore::RenderSVGForeignObject::paint):
* Source/WebCore/rendering/svg/RenderSVGImage.cpp:
(WebCore::RenderSVGImage::paint):
* Source/WebCore/rendering/svg/RenderSVGShape.cpp:
(WebCore::RenderSVGShape::paint):
* Source/WebCore/rendering/svg/RenderSVGText.cpp:
(WebCore::RenderSVGText::paint):

Canonical link: https://commits.webkit.org/323563@main
https://bugs.webkit.org/show_bug.cgi?id=288591

Reviewed by Xabier Rodriguez-Calvar.

Ubuntu Jammy ships 1.20 and is supported until April 2025. Debian bullseye ships 1.18 and is no
longer supported. Debian bookworm ships 1.22 and is supported until June 2026.

So we can bump from 1.18 to 1.20.
See also https://docs.webkit.org/Ports/WebKitGTK%20and%20WPE%20WebKit/DependenciesPolicy.html

* Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp:
(WebCore::AudioFileReader::handleNewDeinterleavePad):
* Source/WebCore/platform/audio/gstreamer/AudioSourceProviderGStreamer.cpp:
(WebCore::AudioSourceProviderGStreamer::handleNewDeinterleavePad):
* Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp:
(WebCore::AudioTrackPrivateGStreamer::updateConfigurationFromCaps):
* Source/WebCore/platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp:
(initializeDMABufAvailability):
* Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp:
(WebCore::registerWebKitGStreamerElements):
(gst_buffer_new_memdup): Deleted.
* Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h:
* Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::setupCodecProbe):
* Source/WebCore/platform/graphics/gstreamer/VideoEncoderGStreamer.cpp:
(WebCore::retrieveTemporalIndex):
* Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp:
(WebCore::VideoTrackPrivateGStreamer::updateConfigurationFromCaps):
* Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp:
* Source/WebCore/platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.cpp:
(WebCore::MockRealtimeAudioSourceGStreamer::render):
* Source/WebCore/platform/mediastream/libwebrtc/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp:
(WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData):
* Source/cmake/GStreamerChecks.cmake:

Canonical link: https://commits.webkit.org/323564@main
https://bugs.webkit.org/show_bug.cgi?id=327263
rdar://189822326

Reviewed by Yusuke Suzuki.

It never shipped and keeping it carries ongoing cost well beyond the code
itself, so remove it along with the JSRemoteFunction marshalling machinery
it depends on.

Removing it:

- Stops building a ShadowRealm prototype, object structure, and
  constructor on every JSGlobalObject. These were created eagerly and
  unconditionally in JSGlobalObject::init (not behind the option), so
  every realm paid the allocation and initialization for a disabled
  feature.
- Restores the invariant that every global object is an immutable
  prototype exotic object. ShadowRealm global objects were the sole
  exception (createStructureForShadowRealm cleared the bit), which forced
  a global-object special case into JSObject::setPrototypeWithCycleCheck
  and a hack into the JS bindings generator; both are gone, and the
  assertion is tightened back accordingly.
- Shrinks GlobalObjectMethodTable by one slot
  (deriveShadowRealmGlobalObject) and removes the cross-origin
  parent-document walk it required in WebCore, which has been a recurring
  source of site-isolation bugs. The now-unused
  JSGlobalObject::createWithCustomMethodTable is removed with it.
- Removes JSRemoteFunction and its exception-unwinding, FunctionPrototype,
  InternalFunction, DFG, FTL, thunk, and JIT-operation branches.
- Drops ShadowRealm as a WebIDL global context, so the
  ShadowRealmGlobalScope partial-interface generation, the
  WebAPIsInShadowRealmEnabled plumbing, and the related binding-generator
  special cases go away.

createTypeErrorCopy is retained because JSModuleLoader also uses it.

This deletes the ShadowRealm JSC runtime classes, the WebCore
ShadowRealmGlobalScope wrapper, the ShadowRealmEnabled and
WebAPIsInShadowRealmEnabled preferences, the WebKit-owned ShadowRealm
layout tests, the imported ShadowRealm WPT tests, and the JSTests stress
coverage. The test262 ShadowRealm tests are kept but skipped via
JSTests/test262/config.yaml, since test262 is a vendored upstream suite.

Canonical link: https://commits.webkit.org/323565@main
…element changes

https://bugs.webkit.org/show_bug.cgi?id=327214
rdar://189782941

Reviewed by Tyler Wilcock.

AXObjectCache::createObjectFromRenderer() picks the class of an accessibility object from the
renderer, and for a select and its options from how the select renders. Objects survive renderer
changes, though, so they can end up with a class that no longer fits. A select that switched
between a native and a base appearance dropdown box after assistive technology accessed it, for
instance because a class or media query applies appearance: base-select, kept its objects and
never exposed its base appearance picker. Changing the size or multiple attribute of a native
select had the same problem, and an object created before its element had a renderer kept the
class it got without one.

Factor the class decision out of createObjectFromRenderer(), and replace an object along with the
other deferred renderer changes when its renderer now calls for another class. For a select that
includes the objects of its options and optgroups, whose class depends on the select. When the
replaced object had focus, move the focus to the new object, so that assistive technology is told.

Tests: accessibility/isolated-tree/mac/select-appearance-switch.html
       accessibility/mac/select-appearance-switch.html

Canonical link: https://commits.webkit.org/323566@main
https://bugs.webkit.org/show_bug.cgi?id=327310

Reviewed by Darin Adler.

We can stop using contentRect() in RenderImage when hasNaturalAspectRatio() is false now that replacedContentRect()
works on the natural dimensions and can handle that case just fine. To remove all uses, computePaintRectForObjectViewBox()
also had to be updated to use natural dimensions.

Making everything going through replacedContentRect() also fixes another edge case of an SVG with only a width
using 'object-fit: none' or 'object-fit: scale-down'.

Test: imported/w3c/web-platform-tests/css/css-images/object-fit-none-svg-width-only.html
* LayoutTests/imported/w3c/web-platform-tests/css/css-images/object-fit-none-svg-width-only-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-images/object-fit-none-svg-width-only-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-images/object-fit-none-svg-width-only.html: Added.
* Source/WebCore/rendering/RenderImage.cpp:
* Source/WebCore/rendering/RenderImage.h:
* Source/WebCore/rendering/RenderReplaced.cpp:
* Source/WebCore/rendering/RenderReplaced.h:

Canonical link: https://commits.webkit.org/323567@main
…t preserveAspectRatio as none

https://bugs.webkit.org/show_bug.cgi?id=326836

Reviewed by Nikolas Zimmermann.

SVG2 says:

  "For ‘image’ elements embedding an SVG image, the ‘preserveAspectRatio’ attribute on the root element in the
   referenced SVG image must be ignored, and instead treated as if it had a value of none."

    - https://w3c.github.io/svgwg/svg2-draft/embedded.html#ImageElement

To implement this, we now pass a new flag IgnoreRootPreserveAspectRatio when painting <svg:image> elements
(both RenderSVGImage and LegacyRenderSVGImage) and implement the rest of the placement sizing via new helpers.

In the follow on changes we can add support for `object-fit` and `object-position` in this shared placement code.

Tests: imported/w3c/web-platform-tests/css/css-images/object-fit-fill-svg-with-natural-size-and-viewbox.html
       imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-does-not-affect-img.html
       imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-ignores-svg-root-viewbox.html
       imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-meet-svg-viewbox-only.html
       imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-meet-svg-with-size.html
       imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-none-animated-viewbox.html
       imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-none-shared-document.html
       imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-none-svg-viewbox-only.html
       imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-overrides-svg-root.html
       imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-slice-svg.html

* LayoutTests/imported/w3c/web-platform-tests/css/css-images/object-fit-fill-svg-with-natural-size-and-viewbox-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-images/object-fit-fill-svg-with-natural-size-and-viewbox-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-images/object-fit-fill-svg-with-natural-size-and-viewbox.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-does-not-affect-img-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-does-not-affect-img-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-does-not-affect-img.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-ignores-svg-root-viewbox-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-ignores-svg-root-viewbox-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-ignores-svg-root-viewbox.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-meet-svg-viewbox-only-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-meet-svg-viewbox-only-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-meet-svg-viewbox-only.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-meet-svg-with-size-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-meet-svg-with-size-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-meet-svg-with-size.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-none-animated-viewbox-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-none-animated-viewbox-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-none-animated-viewbox.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-none-shared-document-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-none-shared-document-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-none-shared-document.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-none-svg-viewbox-only-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-none-svg-viewbox-only-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-none-svg-viewbox-only.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-overrides-svg-root-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-overrides-svg-root-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-overrides-svg-root.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-slice-svg-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-slice-svg-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/embedded/image-preserveaspectratio-slice-svg.html: Added.
* Source/WebCore/platform/graphics/ImagePaintingOptions.h:
* Source/WebCore/platform/graphics/ImageTypes.h:
* Source/WebCore/rendering/svg/RenderSVGImage.cpp:
* Source/WebCore/rendering/svg/RenderSVGImage.h:
* Source/WebCore/rendering/svg/SVGImageIntrinsicSizing.cpp:
* Source/WebCore/rendering/svg/SVGImageIntrinsicSizing.h:
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGImage.cpp:
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGImage.h:
* Source/WebCore/svg/SVGSVGElement.cpp:
* Source/WebCore/svg/SVGSVGElement.h:
* Source/WebCore/svg/graphics/SVGImage.cpp:
* Source/WebCore/svg/graphics/SVGImage.h:

Canonical link: https://commits.webkit.org/323568@main
rdar://189797144
https://bugs.webkit.org/show_bug.cgi?id=327236

Reviewed by Jean-Yves Avenard.

We add support for copyTo by reusing the same code path for BGRX as BGRA and RGBX/RGBA.
The WPT test is not fully complete as it should check the copyT X component.
This will be added when the spec is clear about what should be done.

Tests: imported/w3c/web-platform-tests/webcodecs/videoFrame-copyTo-rgbx-padding.any.html
       imported/w3c/web-platform-tests/webcodecs/videoFrame-copyTo-rgbx-padding.any.worker.html

* LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-copyTo-rgbx.any-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-copyTo-rgbx.any.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-copyTo-rgbx.any.js: Added.
(makeData):
(makeFrame):
(string_appeared_here.promise_test.async t):
* LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-copyTo-rgbx.any.worker-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-copyTo-rgbx.any.worker.html: Added.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/webcodecs/videoFrame-copyTo-rgbx.any-expected.txt: Added.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/webcodecs/videoFrame-copyTo-rgbx.any.worker-expected.txt: Added.
* Source/WebCore/platform/graphics/cv/VideoFrameCV.mm:
(WebCore::VideoFrame::copyTo):

Canonical link: https://commits.webkit.org/323569@main
Unreviewed gardening.

GTK and WPE produce output identical to an existing Mac or iOS baseline for
these tests, while the generic baseline is stale. Where every port that runs
the test agrees, promote that baseline to the generic file, or to platform/wk2
when WK1 and Windows keep the generic result, and delete the copies made
redundant. Where the match is a version-specific override, add a copy under
platform/glib instead.

Promoted to the generic baseline:
* LayoutTests/accessibility/parent-delete-expected.txt:
* LayoutTests/compositing/geometry/ancestor-overflow-change-expected.txt:
* LayoutTests/compositing/geometry/fixed-position-composited-switch-expected.txt:
* LayoutTests/compositing/overflow/overflow-auto-with-touch-toggle-expected.txt:
* LayoutTests/compositing/repaint/invalidations-on-composited-layers-expected.txt:
* LayoutTests/compositing/tiling/huge-layer-img-expected.txt:
* LayoutTests/fast/forms/focus-selection-textarea-expected.txt:
* LayoutTests/fast/forms/range/slider-mouse-events-expected.txt:
* LayoutTests/fast/repaint/selection-gap-flipped-fixed-child-expected.txt:
* LayoutTests/http/tests/blink/sendbeacon/beacon-same-origin-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/content-security-policy/img-src/img-src-port-wildcard-allowed.sub-expected.txt:

Promoted to platform/wk2:
* LayoutTests/platform/wk2/http/tests/websocket/tests/hybi/handshake-fail-by-no-cr-expected.txt: Added.
* LayoutTests/platform/wk2/imported/w3c/web-platform-tests/media-source/mediasource-addsourcebuffer-expected.txt: Added.

Copied to platform/glib:
* LayoutTests/platform/glib/compositing/fixed-image-loading-expected.txt: Added.
* LayoutTests/platform/glib/compositing/rtl/rtl-fixed-expected.txt: Added.
* LayoutTests/platform/glib/compositing/rtl/rtl-fixed-overflow-expected.txt: Added.
* LayoutTests/platform/glib/compositing/rtl/rtl-fixed-overflow-scrolled-expected.txt: Added.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.scaleddashes-expected.txt: Added.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.scaleddashes.worker-expected.txt: Added.

Copies made redundant by the promotion:
* LayoutTests/platform/ios/compositing/geometry/ancestor-overflow-change-expected.txt: Removed.
* LayoutTests/platform/ios/http/tests/blink/sendbeacon/beacon-same-origin-expected.txt: Removed.
* LayoutTests/platform/ios/http/tests/websocket/tests/hybi/handshake-fail-by-no-cr-expected.txt: Removed.
* LayoutTests/platform/ios/imported/w3c/web-platform-tests/content-security-policy/img-src/img-src-port-wildcard-allowed.sub-expected.txt: Removed.
* LayoutTests/platform/mac-wk2/http/tests/websocket/tests/hybi/handshake-fail-by-no-cr-expected.txt: Removed.
* LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/media-source/mediasource-addsourcebuffer-expected.txt: Removed.
* LayoutTests/platform/mac/accessibility/parent-delete-expected.txt: Removed.
* LayoutTests/platform/mac/compositing/geometry/ancestor-overflow-change-expected.txt: Removed.
* LayoutTests/platform/mac/compositing/geometry/fixed-position-composited-switch-expected.txt: Removed.
* LayoutTests/platform/mac/compositing/overflow/overflow-auto-with-touch-toggle-expected.txt: Removed.
* LayoutTests/platform/mac/compositing/repaint/invalidations-on-composited-layers-expected.txt: Removed.
* LayoutTests/platform/mac/compositing/tiling/huge-layer-img-expected.txt: Removed.
* LayoutTests/platform/mac/fast/forms/focus-selection-textarea-expected.txt: Removed.
* LayoutTests/platform/mac/fast/forms/range/slider-mouse-events-expected.txt: Removed.
* LayoutTests/platform/mac/fast/repaint/selection-gap-flipped-fixed-child-expected.txt: Removed.
* LayoutTests/platform/mac/http/tests/blink/sendbeacon/beacon-same-origin-expected.txt: Removed.
* LayoutTests/platform/mac/imported/w3c/web-platform-tests/content-security-policy/img-src/img-src-port-wildcard-allowed.sub-expected.txt: Removed.

Expectations:
* LayoutTests/platform/glib/TestExpectations:

Canonical link: https://commits.webkit.org/323570@main
https://bugs.webkit.org/show_bug.cgi?id=327298
rdar://189846138

Reviewed by Kimmo Kinnunen.

Tools/Scripts/update-angle has produced an invalid changes.diff since 315732@main. git
rejects it and it won't apply to the corresponding upstream ANGLE checkout, because:
- trailing whitespace is stripped, which removes the diff's last line
- the zlib files (compression_utils_portable.{cc,h}) show up as new files and fail to
  apply to a synced checkout

Fix by not stripping the whitespace and by treating the zlib files as vendored. Add a
check to update-angle that fails if the produced changes.diff can't be parsed by git.

Regenerate changes.diff for the current revision (322989@main):
"Update ANGLE to 2026-09-28 (7d496316db8acd84887dae75231c5ddb4729e0a6)"

* Source/ThirdParty/ANGLE/changes.diff:
* Tools/Scripts/update-angle:
(phase_bookkeep):

Canonical link: https://commits.webkit.org/323571@main
…record

Unreviewed gardening.

The GTK and WPE bots produce the same output for these tests, and it differs
from the baselines in use only in subtests that moved from FAIL to PASS.
Where no other port evaluates the generic baseline (results.webkit.org shows
no port running the test with it), the generic file takes the new output and
the platform/glib override goes away; otherwise the output goes under
platform/glib.

Generic baselines updated, no other port evaluates them:
* LayoutTests/fast/events/touch/gesture/pad-gesture-cancel-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/fetch/metadata/generated/element-a.sub-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/fetch/metadata/generated/element-area.sub-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/fetch/metadata/generated/element-meta-refresh.optional.sub-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/fetch/metadata/generated/form-submission.sub-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/fetch/metadata/generated/window-location.sub-expected.txt:

Rebaselined under platform/glib:
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/mixed-content/tentative/autoupgrades/mixed-content-cors.https.sub-expected.txt:

Added under platform/glib:
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/css/selectors/old-tests/css3-modsel-20-expected.txt: Added.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/rendering/widgets/the-select-element/select-as-listbox-default-styles.tentative-expected.txt: Added.

Overrides made redundant:
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/element-a.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/element-area.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/element-meta-refresh.optional.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/form-submission.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/fetch/metadata/generated/window-location.sub-expected.txt: Removed.

Expectations:
* LayoutTests/platform/glib/TestExpectations:

Canonical link: https://commits.webkit.org/323572@main
… moduleset

https://bugs.webkit.org/show_bug.cgi?id=327392

Reviewed by Adrian Perez de Castro.

319107@main removed `libwpe` and `wpebackend-fdo` from the minimal
jhbuild moduleset, assuming every supported distribution provides them.
That is no longer true. Debian is the only one of the major
distributions that still packages them.

Ubuntu removed both packages during the 24.04 (noble) development cycle,
and 22.04 was the last release to ship them. Fedora has retired both
packages. Arch Linux has dropped them from its official repositories.

With `ENABLE_WPE_LEGACY_API` enabled by default on WPE, CMake requires
`libwpe` and `wpebackend-fdo`.

As a result, on Ubuntu 24.04 or 26.04, Fedora or Arch, the documented
build steps fail at configure time:
- Tools/wpe/install-dependencies
- Tools/Scripts/update-webkitwpe-libs
- Tools/Scripts/build-webkit --wpe --debug

The minimal moduleset should provide `libwpe` and `wpebackend-fdo`
again. Both entries should include a `<pkg-config>` line, so the system
copy is used where one exists (e.g. Debian) and jhbuild builds them only
where it doesn't.

* Tools/jhbuild/jhbuild-minimal.modules:

Canonical link: https://commits.webkit.org/323573@main
…tepDirection

https://bugs.webkit.org/show_bug.cgi?id=324299
rdar://187531041

Reviewed by Ryosuke Niwa.

The "FromRenderer" suffix was misleading: it implied the step is
triggered with a RenderObject on the call stack, where dispatching a
DOM event would be unsafe. In practice the function is invoked from the
spin-button step handlers in the input element's shadow DOM (a DOM
event), so dispatching beforeinput/input from it is fine. Rename it to
stepUpOrDown() to describe what it does.

The function is only ever called with 1 or -1, so replace the int
argument with enum class StepDirection : bool { Up, Down }, and remove
the now-unreachable multi-step handling (n == 0 early return and the
n > 1 / n < -1 applyStep() follow-ups).

No change in behavior.

* LayoutTests/fast/forms/number/number-stepup-stepdown-from-renderer.html:
* Source/WebCore/html/InputType.cpp:
(WebCore::InputType::stepUpOrDown):
(WebCore::InputType::stepUpFromRenderer): Deleted.
* Source/WebCore/html/InputType.h:
* Source/WebCore/html/TextFieldInputType.cpp:
(WebCore::TextFieldInputType::spinButtonStepDown):
(WebCore::TextFieldInputType::spinButtonStepUp):

Canonical link: https://commits.webkit.org/323574@main
…in text metrics

Unreviewed gardening.

The GTK and WPE bots produce the same output for these render tree dumps,
and the diff against the baseline in use is limited to text run widths, line
heights and the layer geometry that follows from them. Where no other port
evaluates the generic baseline, the generic file takes the output; otherwise
it goes under platform/glib, replacing the gtk-only override where one
existed.

compositing/repaint/become-overlay-composited-layer.html keeps a Pass Failure
line: its box is moved by 0.2s transitions sampled with 250ms timers, and on
the EWS workers the dump sometimes runs before the box has moved back.

Generic baselines updated, no other port evaluates them:
* LayoutTests/compositing/repaint/become-overlay-composited-layer-expected.txt: Added.

Added under platform/glib:
* LayoutTests/platform/glib/compositing/geometry/limit-layer-bounds-overflow-root-expected.txt: Added.
* LayoutTests/platform/glib/compositing/geometry/preserve-3d-switching-expected.txt: Added.
* LayoutTests/platform/glib/compositing/overflow/textarea-scroll-touch-expected.txt: Added.
* LayoutTests/platform/glib/css3/blending/blend-mode-isolation-turn-off-self-painting-layer-expected.txt: Added.
* LayoutTests/platform/glib/css3/blending/blend-mode-isolation-turn-off-self-painting-layer1-expected.txt: Added.
* LayoutTests/platform/glib/css3/blending/blend-mode-isolation-turn-off-self-painting-layer2-expected.txt: Added.
* LayoutTests/platform/glib/css3/blending/blend-mode-isolation-turn-on-self-painting-layer-expected.txt: Added.
* LayoutTests/platform/glib/fast/block/basic/child-block-level-box-with-height-percent-expected.txt: Added.
* LayoutTests/platform/glib/fast/block/basic/inline-content-with-floating-images2-expected.txt: Added.
* LayoutTests/platform/glib/fast/block/basic/quirk-mode-percent-height-expected.txt: Added.
* LayoutTests/platform/glib/fast/inline/simple-inline-inflow-positioned-expected.txt: Added.
* LayoutTests/platform/glib/fast/inline/simple-inline-with-out-of-flow-descendant-expected.txt: Added.
* LayoutTests/platform/glib/fast/inline/simple-inline-with-out-of-flow-descendant2-expected.txt: Added.
* LayoutTests/platform/glib/fast/text/emphasis-overlap-expected.txt: Added.
* LayoutTests/platform/glib/http/tests/contentextensions/allowlist-expected.txt: Added.
* LayoutTests/platform/glib/http/tests/contentextensions/basic-filter-expected.txt: Added.
* LayoutTests/platform/glib/http/tests/contentextensions/css-display-none-expected.txt: Added.
* LayoutTests/platform/glib/http/tests/contentextensions/domain-rules-expected.txt: Added.
* LayoutTests/platform/glib/http/tests/contentextensions/filters-with-quantifiers-combined-expected.txt: Added.
* LayoutTests/platform/glib/http/tests/contentextensions/media-filtered-expected.txt: Added.
* LayoutTests/platform/glib/http/tests/contentextensions/subresource-redirect-blocked-expected.txt: Added.
* LayoutTests/platform/glib/http/tests/contentextensions/top-url-expected.txt: Added.

Overrides made redundant:
* LayoutTests/platform/glib/compositing/repaint/become-overlay-composited-layer-expected.txt: Removed.
* LayoutTests/platform/gtk/compositing/overflow/textarea-scroll-touch-expected.txt: Removed.

Expectations:
* LayoutTests/platform/glib/TestExpectations:

Canonical link: https://commits.webkit.org/323575@main
https://bugs.webkit.org/show_bug.cgi?id=327358
rdar://189877347

Reviewed by Alan Baradlay.

m_gridLanesContentSizeForWebInspectorOverlay is a 4-byte LayoutUnit that sits
directly before m_resolvedTrackList, which is 8-byte aligned, so it leaves 4
bytes of padding. The trailing std::optional<bool> and bool members then need
another 4 bytes of tail padding.

Move the LayoutUnit down next to those small members so that all three pack
into a single 8-byte slot. This shrinks RenderGrid by 8 bytes
(120 -> 112 in a mock of the member layout; the same on Clang, GCC and
Clang with the MSVC ABI).

* Source/WebCore/rendering/RenderGrid.h:

Canonical link: https://commits.webkit.org/323576@main
… factor

https://bugs.webkit.org/show_bug.cgi?id=327205
rdar://189779826

Reviewed by Sam Weinig.

This patch aligns WebKit with Gecko / Firefox and Blink / Chromium.

When a Negate node's child is a Product whose children are all numeric,
simplify(Negate&) negated every child of the product. That is only
correct when the product has an odd number of factors, since
-(a * b) = (-a) * b, not (-a) * (-b). With typed arithmetic, a product
such as `2px * 3px` (type length^2) cannot be resolved on its own and so
survives simplification. Subtracting it then produced the wrong sign:
`calc((0px * 0px - 2px * 3px) / 1px)` resolved to 6px instead of -6px.

Negate only the first factor of the product instead.

Test: imported/w3c/web-platform-tests/css/css-values/typed-arithmetic-negated-product.html

* LayoutTests/imported/w3c/web-platform-tests/css/css-values/typed-arithmetic-negated-product-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-values/typed-arithmetic-negated-product.html: Added.
* Source/WebCore/css/calc/CSSCalcTree+Simplification.cpp:
(WebCore::CSSCalc::simplify):

Canonical link: https://commits.webkit.org/323577@main
https://bugs.webkit.org/show_bug.cgi?id=327289
rdar://problem/189838099

Reviewed by Tyler Wilcock.

RenderListItem::markerText returned nothing for a ::marker with `content`, so the list item's line was read
without it. Return the text the marker's content renderers hold, or the content's alternative text when it
has one.

Test: accessibility/list-marker-content-text.html

* LayoutTests/accessibility/list-marker-content-text-expected.txt: Added.
* LayoutTests/accessibility/list-marker-content-text.html: Added.
* Source/WebCore/rendering/RenderListItem.cpp:
(WebCore::RenderListItem::markerText const):
* LayoutTests/platform/glib/TestExpectations:

Canonical link: https://commits.webkit.org/323578@main
… implement input.releaseActions

https://bugs.webkit.org/show_bug.cgi?id=326372
rdar://189205046

Reviewed by BJ Burg.

Dispatch validated input actions for none and key input sources through the existing
`SimulatedInputDispatcher`, and implement `input.releaseActions` with the WebDriver input
cancel list.

Each top-level browsing context now has its own WebDriver input state (`BidiInputState`):
input sources, the input cancel list, and an actions queue (`BidiInputActionsQueue`).
`input.performActions` and `input.releaseActions` for the same top-level context run strictly
in order through that queue. Commands for different top-level contexts don't block each
other. The input sources are owned by the BiDi input state, separate from the session-global
sources used by Classic WebDriver.

Validated ticks are translated to `SimulatedInputKeyFrames`. `keyDown` adds the key to the
source's pressed keys and appends a matching `keyUp` to the input cancel list; `keyUp` of a
key that isn't pressed dispatches nothing; pause and none sources only contribute to the
tick duration, which is the maximum duration in the tick. WebDriver key values in the
U+E000-U+E05D range map to Automation virtual keys; other values are character keys.
`input.releaseActions` dispatches the input cancel list in reverse order, one keyframe per
undo action, then resets the input state. A command queued behind a reset re-registers
its input sources, so it dispatches against the reset state.

Actions from pointer and wheel input sources, including pause actions, report "unsupported
operation", as do key sources on ports without keyboard interactions, so unsupported source
types never reach the input dispatcher.

If the page closes while actions are being dispatched, or before a queued command runs,
the command reports "no such frame". The BiDi input state of a closing page is dropped
before pending event callbacks are failed.

* Source/WebKit/UIProcess/Automation/BidiInputAgent.cpp:
(WebKit::Automation::simulatedSourceType):
(WebKit::Automation::BidiInputState::simulatedSource):
(WebKit::Automation::BidiInputState::reset):
Add the dispatcher input sources and the input cancel list to the input state.

(WebKit::Automation::BidiInputActionsQueue::enqueue):
(WebKit::Automation::BidiInputActionsQueue::runNextCommand):
Add the WebDriver actions queue.

(WebKit::Automation::virtualKeyForKeyValue):
(WebKit::Automation::translateTicksToKeyFrames):
(WebKit::Automation::keyFramesForActions):
(WebKit::Automation::keyFramesForUndoActions):
Translate action ticks and undo actions to simulated input keyframes.

(WebKit::dispatchKeyFrames):
(WebKit::BidiInputAgent::inputStateForTopLevelContext):
(WebKit::BidiInputAgent::willClosePage):
(WebKit::BidiInputAgent::performActions):
(WebKit::BidiInputAgent::releaseActions):
* Source/WebKit/UIProcess/Automation/BidiInputAgent.h:
Rename the `BidiInput` namespace to `Automation`, and `State` to `BidiInputState`.

* Source/WebKit/UIProcess/Automation/SimulatedInputDispatcher.cpp:
(WebKit::normalizedVirtualKey):
(WebKit::pressedCharKey):
Moved from WebAutomationSession.cpp so the BiDi input agent can share them.

* Source/WebKit/UIProcess/Automation/SimulatedInputDispatcher.h:
* Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp:
(WebKit::WebAutomationSession::willClosePage):
Drop the page's BiDi input state.

(WebKit::WebAutomationSession::runInteractionSequence): Added.
(WebKit::WebAutomationSession::performInteractionSequence):
Factor the dispatch to SimulatedInputDispatcher out of performInteractionSequence so
WebDriver BiDi can share it with its own input sources.

* Source/WebKit/UIProcess/Automation/WebAutomationSession.h:
Make webFrameIDForHandle() public so the BiDi input agent can resolve frame handles.

Canonical link: https://commits.webkit.org/323579@main
https://bugs.webkit.org/show_bug.cgi?id=327374

Reviewed by Rupin Mittal.

Replace the instances of NODELETE with LEGACY_NODELETE to prepare for
a migration to new annotation which works on constructor/destructor.

Canonical link: https://commits.webkit.org/323580@main
…t copies of the drop shadow

https://bugs.webkit.org/show_bug.cgi?id=317995
rdar://180783813

Reviewed by Kimmo Kinnunen.

hasBlurredDropShadow() and hasDropShadow() each called the public
dropShadow() accessor once or twice per query. That accessor returns
std::optional<GraphicsDropShadow> by value, so every call copied the
whole optional, including the GraphicsDropShadow's Color member, only to
read a single field.

Have the two helpers read GraphicsContextState::dropShadow() directly,
which already hands back a const reference. This removes all of those
copies with no change to the public API.

The public dropShadow() keeps returning by value rather than by const
reference: a reference would alias m_state and could be left dangling by
a subsequent save()/restore() or setDropShadow() that mutates the state
stack, and LIFETIME_BOUND does not catch that misuse.

No change in behavior, so no new tests.

* Source/WebCore/platform/graphics/GraphicsContext.h:
(WebCore::GraphicsContext::hasBlurredDropShadow const):
(WebCore::GraphicsContext::hasDropShadow const):

Canonical link: https://commits.webkit.org/323581@main
https://bugs.webkit.org/show_bug.cgi?id=327402
<rdar://problem/189912173>

Reviewed by Antti Koivisto.

Only text from a DOM node could become a RenderCombineText, and a marker's text has no node, so it was always
plain text. Now marker text (from list-style-type or content) becomes combined text, and gets rebuilt when
text-combine-upright changes.

Tests: imported/w3c/web-platform-tests/css/css-pseudo/marker-text-combine-upright-002-ref.html
       imported/w3c/web-platform-tests/css/css-pseudo/marker-text-combine-upright-002.html
       imported/w3c/web-platform-tests/css/css-pseudo/marker-text-combine-upright-dynamic.html

* LayoutTests/TestExpectations:
* LayoutTests/imported/w3c/web-platform-tests/css/css-pseudo/marker-text-combine-upright-002-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-pseudo/marker-text-combine-upright-002-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-pseudo/marker-text-combine-upright-002.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-pseudo/marker-text-combine-upright-dynamic-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-pseudo/marker-text-combine-upright-dynamic.html: Added.
* Source/WebCore/rendering/RenderCombineText.cpp:
(WebCore::RenderCombineText::RenderCombineText):
* Source/WebCore/rendering/RenderCombineText.h:
* Source/WebCore/rendering/updating/RenderTreeBuilderList.cpp:
(WebCore::RenderTreeBuilder::List::updateItemMarker):
(WebCore::createMarkerTextRenderer):
(WebCore::RenderTreeBuilder::List::buildInlineMarker):
(WebCore::RenderTreeBuilder::List::buildMarkerContentRenderers):
* Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp:
(WebCore::createContentRenderer):
* LayoutTests/imported/w3c/web-platform-tests/css/css-pseudo/marker-text-combine-upright.html:

Canonical link: https://commits.webkit.org/323582@main
…frame of `none` as the element's own `translate`

https://bugs.webkit.org/show_bug.cgi?id=327193
rdar://189882533

Reviewed by Simon Fraser.

If a keyframe held an explicit value of `none` for an individual transform property (`rotate`, `scale`
and `translate`), then this would be represented as `nullptr` on the `AcceleratedEffectValues` struct
representing this keyframe's values. This made an implicit and explicit `none` value indistinguishable.

We now pass a list of explicit properties to the `AcceleratedEffectValues` constructor and if one of
the individual properties is found, we ensure we create an identity value.

Test: webanimations/threaded-animations/transform-individual-properties.html

* LayoutTests/webanimations/threaded-animations/transform-individual-properties-expected.txt: Added.
* LayoutTests/webanimations/threaded-animations/transform-individual-properties.html: Added.
* Source/WebCore/platform/animation/AcceleratedEffect.cpp:
(WebCore::m_timelineIdentifier):
* Source/WebCore/platform/animation/AcceleratedEffectValues.cpp:
(WebCore::AcceleratedEffectValues::AcceleratedEffectValues):
* Source/WebCore/platform/animation/AcceleratedEffectValues.h:
(WebCore::AcceleratedEffectValues::AcceleratedEffectValues):
* Source/WebCore/platform/graphics/transforms/RotateTransformOperation.h:
* Source/WebCore/platform/graphics/transforms/ScaleTransformOperation.h:
* Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.h:

Canonical link: https://commits.webkit.org/323583@main
szewai and others added 15 commits October 14, 2026 17:18
https://bugs.webkit.org/show_bug.cgi?id=327600
rdar://190060653

Unreviewed test gardening. Skipped tests never run, so we cannot tell whether a failure is specific to Site Isolation or
not. Stop skipping them and record their actual results under Site Isolation instead.

* LayoutTests/platform/mac-site-isolation/TestExpectations:

Canonical link: https://commits.webkit.org/323786@main
… on Mac

https://bugs.webkit.org/show_bug.cgi?id=327618
rdar://190068678

Reviewed by Sihui Liu.

This snippet should only be compiled in for Mac.

No new tests needed.

* Source/WebCore/platform/cocoa/ParentalControlsURLFilter.mm:
(WebCore::ParentalControlsURLFilter::requestPermissionForURL):

Canonical link: https://commits.webkit.org/323787@main
…derer across a style and layout update that can destroy it

https://bugs.webkit.org/show_bug.cgi?id=327570
rdar://188692696

Reviewed by Ryosuke Niwa.

The CheckedPtr to the owner's renderer is only needed to decide whether
to update style and layout, but it stays in scope to the end of the
function, where the style update, the layout, and startAnimations() can
all destroy the renderer out from under it. Reduce its scope to the
condition that uses it.

Test: fast/frames/iframe-owner-renderer-destroyed-during-implicit-close.html

* LayoutTests/fast/frames/iframe-owner-renderer-destroyed-during-implicit-close-expected.txt: Added.
* LayoutTests/fast/frames/iframe-owner-renderer-destroyed-during-implicit-close.html: Added.
* Source/WebCore/dom/Document.cpp:
(WebCore::Document::implicitClose):
* LayoutTests/fast/frames/resources/subframe-smil-animation-forces-owner-layout.html: Added.

Canonical link: https://commits.webkit.org/323788@main
https://bugs.webkit.org/show_bug.cgi?id=327594
rdar://190057233

Reviewed by Simon Fraser.

Outlines are painted outside the border box, over the surface beneath the element, but
their color is resolved from the element itself rather than from that surface. Let
WebKitAdditions choose the outline color so it can suit the surface it is painted on.

* Source/WebCore/rendering/BorderEdge.cpp:
(WebCore::borderEdgesForOutline):
* Source/WebCore/rendering/BorderEdge.h:
* Source/WebCore/rendering/OutlinePainter.cpp:
(WebCore::outlineColor):
(WebCore::OutlinePainter::paintOutline const):

Canonical link: https://commits.webkit.org/323789@main
…L declares long

https://bugs.webkit.org/show_bug.cgi?id=327149
rdar://189740041

Reviewed by Chris Dumez.

SVGTextContentElement interface declares `long getNumberOfChars()` as per
SVG 2 specification [1], but the C++ implementation returned `unsigned`. Make the
C++ signature match the IDL by returning `int`, clamping the character count
to the `int` range.

The C++ method is renamed to numberOfCharsForBindings() and the IDL uses
ImplementedAs=numberOfCharsForBindings, following the existing *ForBindings
convention.

The internal callers compare the count against unsigned `charnum` arguments,
so they now use a new private `unsigned numberOfChars()` helper instead, to
avoid signed / unsigned comparisons.

No new tests, no behavior change; covered by existing tests.

[1] https://w3c.github.io/svgwg/svg2-draft/text.html#InterfaceSVGTextContentElement

* Source/WebCore/svg/SVGTextContentElement.cpp:
(WebCore::SVGTextContentElement::numberOfCharsForBindings):
(WebCore::SVGTextContentElement::numberOfChars):
(WebCore::SVGTextContentElement::getSubStringLength):
(WebCore::SVGTextContentElement::getStartPositionOfChar):
(WebCore::SVGTextContentElement::getEndPositionOfChar):
(WebCore::SVGTextContentElement::getExtentOfChar):
(WebCore::SVGTextContentElement::getRotationOfChar):
(WebCore::SVGTextContentElement::selectSubString):
* Source/WebCore/svg/SVGTextContentElement.h:
* Source/WebCore/svg/SVGTextContentElement.idl:

Canonical link: https://commits.webkit.org/323790@main
…Layout panel is open don't list their grids and flex containers

https://bugs.webkit.org/show_bug.cgi?id=327031
rdar://189647875

Reviewed by Qianlang Chen.

CSSManager applied `layoutContextTypeChangedMode` only to the targets that existed when the mode was set.
Under Site Isolation, frame targets come and go with iframe navigations, so a frame target created while the
Layout panel was open stayed in `Observed` mode. Its grids and flex containers were not reported until the
panel was hidden and shown again.

Applying the mode to the new target is not enough. Each committed load resets FrameDOMAgent's bindings, so
FrameCSSAgent cannot push a grid that is laid out before the frontend requests the new document, and it never
retries. A new frame target hits this reliably: its first document is the initial empty one, and the frontend
asks for the loaded one only after the provisional target commits.

CSSManager now remembers the mode and applies it to each new frame target in `initializeTarget`, after `CSS.enable`.
Page targets are left alone: they request their document later, and InspectorCSSAgent does not push nodes once it arrives.
It sends nothing for the default `Observed` mode, so targets that exist at startup get no extra command.

In `All` mode, FrameDOMAgent::getDocument now has FrameCSSAgent push every layout context node again, once the
reply has been sent.

The main frame's FrameTarget now also gets `All`. Its DOM tree is never spliced into the page tree, and FrameCSSAgent
pushing grid paths into it binds the main document's `<iframe>` elements there. A cross-origin iframe's document could
then splice into that hidden `<iframe>` instead of the one in the page tree. FrameCSSAgent now skips the push when
the page's CSS agent reports the document, which `documentIsReportedByPageCSSAgent` already tells it.

The test covers a new iframe and a reload in the same frame target. It keeps a node list the way
LayoutDetailsSidebarPanel keeps its node sets, rebuilds that list as the frame document is spliced, before the
grids arrive, and checks that the grids still reach it. They do through `LayoutFlagsChanged`, which each new
WI.DOMNode sends, so DOMManager needs no change. The reload case holds the frontend's request for the new
document until the frame has loaded, so the grids are always laid out first.

A second test navigates the main frame cross-site and checks that the iframe's document ends up in the page tree.

Tests: http/tests/site-isolation/inspector/css/layout-context-type-changed-mode-cross-site-navigation-splice.html
       http/tests/site-isolation/inspector/css/layout-context-type-changed-mode-new-frame-target.html

* LayoutTests/http/tests/site-isolation/inspector/css/layout-context-type-changed-mode-cross-site-navigation-splice-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/css/layout-context-type-changed-mode-cross-site-navigation-splice.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/css/layout-context-type-changed-mode-new-frame-target-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/css/layout-context-type-changed-mode-new-frame-target.html: Added.
* Source/WebCore/inspector/agents/frame/FrameCSSAgent.cpp:
(WebCore::FrameCSSAgent::setLayoutContextTypeChangedMode):
(WebCore::FrameCSSAgent::pushLayoutContextNodesToFrontend): Extracted from `setLayoutContextTypeChangedMode`. Skips a
document that the page's CSS agent reports.
(WebCore::FrameCSSAgent::didBindDocument): Defers the push to the dispatch timer, because the frontend drops
nodes that arrive before the `DOM.getDocument` reply.
(WebCore::FrameCSSAgent::nodesWithPendingLayoutFlagsChangeDispatchTimerFired): Likewise for a node whose flags changed.
(WebCore::FrameCSSAgent::reset):
* Source/WebCore/inspector/agents/frame/FrameCSSAgent.h:
* Source/WebCore/inspector/agents/frame/FrameDOMAgent.cpp:
(WebCore::FrameDOMAgent::getDocument):
* Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js:
(WI.CSSManager): Stores the current mode.
(WI.CSSManager.prototype.initializeTarget):
(WI.CSSManager.prototype.set layoutContextTypeChangedMode):
(WI.CSSManager.prototype._setLayoutContextTypeChangedModeForTarget): Shared by the setter and `initializeTarget`.

Canonical link: https://commits.webkit.org/323791@main
https://bugs.webkit.org/show_bug.cgi?id=327625
rdar://190074699

Build fix

No new tests needed.

* Source/WebCore/platform/cocoa/ParentalControlsURLFilter.mm:
(WebCore::ParentalControlsURLFilter::requestPermissionForURL):

Canonical link: https://commits.webkit.org/323792@main
…oller nested in another composited scroller

https://bugs.webkit.org/show_bug.cgi?id=326183
rdar://189067776

Reviewed by Matt Woodrow.

This patch aligns WebKit with Gecko / Firefox and Blink / Chromium.

OverlapMapContainer::ensureClippingScopeForLayers() walks the enclosing clipping
layers from root to leaf. When a child scope is missing, it creates that one
scope and stops. If more than one scope is missing, the rect ends up in an
ancestor scope instead of the leaf. findClippingScopeForLayers() then can't
find the leaf scope for later layers, so they are never tested against that
rect.

This happens when a composited scroller is a stacking context nested inside
another composited scroller. Its paint-order children start with an empty
overlap container, so the first layer added there is missing both the outer
and inner scroller scopes. Later overlapping siblings don't composite and
paint underneath the composited layer.

Fix this by creating every missing scope along the chain.

Test: compositing/layer-creation/clipping-scope/nested-scroller-overlap-inside-inner-scroller.html

* LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap-inside-inner-scroller-expected.txt: Added.
* LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap-inside-inner-scroller.html: Added.
* LayoutTests/platform/ios/compositing/layer-creation/clipping-scope/nested-scroller-overlap-inside-inner-scroller-expected.txt: Added.
* Source/WebCore/rendering/LayerOverlapMap.cpp:
(WebCore::OverlapMapContainer::ensureClippingScopeForLayers):

Canonical link: https://commits.webkit.org/323793@main
https://bugs.webkit.org/show_bug.cgi?id=327586
rdar://190052525

Reviewed by Abrar Rahman Protyasha and Mike Wyrzykowski.

* Configurations/CommonBase.xcconfig:
* Source/WebCore/Configurations/WebCore.xcconfig:
* Source/WebGPU/Configurations/WebGPU.xcconfig:

Canonical link: https://commits.webkit.org/323794@main
…t> outlives its shadow root

https://bugs.webkit.org/show_bug.cgi?id=327621
rdar://189806062

Reviewed by Ryosuke Niwa.

The observer registers with the element's TreeScope, which for a link in a shadow tree is the
ShadowRoot — and a node keeps its Document alive but not its ShadowRoot. Destroying the observer
in removingSteps runs it while that scope is still alive, so it can no longer outlive its registry

Test: fast/dom/HTMLLinkElement/link-expect-in-shadow-tree-removed-crash.html

* LayoutTests/fast/dom/HTMLLinkElement/link-expect-in-shadow-tree-removed-crash-expected.txt: Added.
* LayoutTests/fast/dom/HTMLLinkElement/link-expect-in-shadow-tree-removed-crash.html: Added.
* Source/WebCore/html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::processInternalResourceLink):
(WebCore::HTMLLinkElement::removingSteps):
* Source/WebCore/html/HTMLLinkElement.h:

Canonical link: https://commits.webkit.org/323795@main
…e `IntlNumberFormat` when only a locale string is given

https://bugs.webkit.org/show_bug.cgi?id=327503

Reviewed by Yusuke Suzuki.

`n.toLocaleString("en-US")` created an IntlNumberFormat on every call, and
a new ICU number formatter is slow for its first few uses. This patch caches
one IntlNumberFormat per JSGlobalObject, keyed by the locale string, in the
same way as the collator cache of String#localeCompare.

The cache is used only when locales is a string and options is undefined,
where creating the formatter runs no user code.

This patch also makes this cache and the collator cache miss while a
language change is pending, so that a change in the middle of a VM entry
is not ignored until the next entry.

Tests: JSTests/microbenchmarks/number-to-locale-string-with-locales.js
       JSTests/stress/number-to-locale-string-locales-cache-language-change.js
       JSTests/stress/number-to-locale-string-locales-cache.js

* JSTests/microbenchmarks/number-to-locale-string-with-locales.js: Added.
(test):
* JSTests/stress/number-to-locale-string-locales-cache-language-change.js: Added.
(shouldBe):
(setTimeout):
* JSTests/stress/number-to-locale-string-locales-cache.js: Added.
(shouldBe):
(Intl.NumberFormat):
* JSTests/stress/string-locale-compare-locales-cache-language-change.js:
(setTimeout):
* Source/JavaScriptCore/runtime/BigIntPrototype.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::visitChildrenImpl):
(JSC::JSGlobalObject::cachedLocaleCompareCollator):
(JSC::JSGlobalObject::cachedToLocaleStringNumberFormat):
* Source/JavaScriptCore/runtime/JSGlobalObject.h:
* Source/JavaScriptCore/runtime/NumberPrototype.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):

Canonical link: https://commits.webkit.org/323796@main
…ing them

https://bugs.webkit.org/show_bug.cgi?id=327581
rdar://190050490

Reviewed by Wenson Hsieh and Ryosuke Niwa.

Previous behavior invoked completion handlers by iterating a Vector in
place. Our new Borrow<T> rules forbid that approach.

New behavior: Move out all handlers we're going to call before we call the
first one.

Out of an abundance of caution, I'm landing this change separately because
there's a small chance it will change behavior if previous code re-entrantly
registered duplicate completion handlers without crashing in practice.

* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::requestTextRecognition):

Canonical link: https://commits.webkit.org/323797@main
1013 upstream commits since dbdca75 (the previous upgrade, #773), 170 of them
in Source/JavaScriptCore, Source/WTF or Source/bmalloc.

Upstream removed ShadowRealm (d5f13fa, 323565@main). This merge takes the
removal as it is. The next commit brings the JavaScriptCore part back, because
Bun ships ShadowRealm, so Bun does not build against this commit by itself.

66 files conflicted. What was done about them, and about the places where the
two sides merged without a conflict but no longer fit:

NODELETE is now LEGACY_NODELETE (e795d5a, e4be394, b8f13b0):
- In most of the conflicting files this was the whole conflict: upstream renamed
  the annotation on a line the fork had changed or sat next to. The fork's lines,
  renamed. That is all of the conflicts in yarr/ but one, CachedTypes.{h,cpp},
  JSBigInt.h, JSCell.h, URL.h, URLParser.h, and single lines in many other
  headers.
- NODELETE is no longer defined under clang, so the 16 uses the fork had added in
  places that did not conflict are renamed too.

Heap / Collector (729712a and the fourteen commits after it let one Collector
serve several heaps):
- Collector.cpp: there is no m_heap any more. The stamps the fork takes at the
  start of a collection are per heap, so they moved from runBeginPhase() to
  beginCollectionInEachHeap(), still ahead of willStartCollection(); nothing in
  between reads them. GCRequest::didFinishEndPhase still runs where it did;
  didFinishCollection() went to endCollectionInEachHeap() with upstream.
- The mutator schedulers ask Collector::totalMaxEdenSize(), which sums the fork's
  Heap::effectiveMaxEdenSize() so that the cap under critical memory still holds.
- GC rate limiting stays reverted (642e225).
- GCIncomingRefCountedSet (91e8fd1, an eden sweep only looks at new and dirty
  ArrayBuffers): upstream's sweep, with the fork's accounting of m_bytes after an
  eden sweep. What upstream's eden sweep visits is what the fork counted
  separately, and m_oldCount is the fork's m_sizeAfterLastSweep, which is gone.
- MarkedBlock.cpp: marksConveyLivenessDuringMarking() is now
  staleMarksStillRecordSurvivors() (b8c79b4).
- VM::shrinkFootprintNow() clears sourceProviderCacheMap itself:
  clearSourceProviderCaches() became pruneUnusedSourceProviderCaches(), which
  keeps the caches used since the last prune (92e99db).

Latin1Character is a struct (50a6173): byteCast where the fork's code passes
bytes for characters or the reverse, in jsc.cpp, CachedTypes.cpp and
JSDateMath.cpp (the V8 date parser takes bytes).

Source taintedness (ac57a2a): SourceTaintedOrigin.h is SourceTaintedness.h.
JSModuleRecord's hasSameObservableSource() compares taintedness().

CSS module scripts (b1913f6):
- makeModule() and provideFetch() take a JSValue. They stay member functions, and
  the new default-export path passes the loader on.
- SyntheticModuleRecord::tryCreateDefaultExportSyntheticModule() is public, with
  the fork's JSModuleLoader* parameter.
- ScriptFetchParameters::Type::CSS comes after HostDefined, which stays 5: Bun's
  transpiler writes that number into the module info it serializes.
  SourceProviderSourceType::CSS comes after BunTranspiledModule likewise.
- `with { type: "css" }` stays a HostDefined type with USE(BUN_JSC_ADDITIONS), as
  "text" does: Bun loads it itself.
- JSModuleLoader::registryEntry() looks under Type::CSS too.

Exception stacks (70896f2, no stack is captured for a throw that a user's
catch clause is certain to handle): Exception visits m_asyncContext and takes
upstream's lock. The fork's createScriptCallStackFromException() reads
stackForReporting().

BigInt (e2ffc55 adds a divide-and-conquer toString): the fork already has one,
on Barrett division and interruptible. The fork's is kept and upstream's tests
run against it.

Yarr:
- 7a8cc2f (bit tables for Unicode property escapes): the fork has
  matchCharacterClassMatchesAndRanges() inlined in matchCharacterClass(), so
  upstream's new helpers landed inside a function body. They now precede it.
- 8d2c95e (length checks for an EOL string list): the fork has no
  consumeIndex(). A string list is only made of the whole pattern's body, which
  is matched forward, so it is an add32.
- stress/regexp-stringlist-eol-length-groups.js expects no match from a lastIndex
  inside a surrogate pair. That is A6 of JSTests/BUN-TEST-DIFFERENCES.md; the
  expectation is updated and the file is listed there.

Others:
- ExecutableMemoryHandle.h (e2e0869): ENABLE_LIBPAS_JIT_HEAP is defined above
  the includes. The exclusion of ARM64 Windows went with it.
- pas_thread_local_cache.c (69e1e79): pas_memory_flavor_plain, still
  asymmetric.
- OptionsMSVC.cmake (0a75fde) set CMAKE_MSVC_RUNTIME_LIBRARY to
  MultiThreadedDLL whatever was passed. It merged cleanly and would have replaced
  the static CRT that Dockerfile.windows and Bun pass. It is now only the default.
- CMakeLists.txt (e8c36a1): CombinedDomains.json is generated in
  JavaScriptCore_SCRIPTS_DIR, by the fork's command (the output path as an
  argument, no redirect).
- JSGlobalObject.cpp (733b18f): cachedToLocaleStringNumberFormat() is in;
  exposeDollarVM() stays in JSDollarVM.cpp.
- Nodes.h (e5f751c): neededConstants() is gone, statements() stays.
- InjectedScriptSource.js (b0bb30b): upstream's shape, testing for the fork's
  one-line "[native code] }".
- RuntimeManager.js (f87677d): upstream's parse, with ecmaVersion "latest".
- Symbol.h, VerifierSlotVisitorScope.h, WasmFunctionIPIntMetadataGenerator.h,
  IntlDateTimeFormat.cpp, SourceProvider.h: both sides' includes.
- WebCore/page/Viewport.h, ProofOfPossessionProviderInfo.h and
  FindInteractionTester.h are new upstream files that git took for renames of the
  deleted ShadowRealm headers. Upstream's files.

JSType.h loses ShadowRealmType here and gets it back in the next commit. Nothing
else in it changed. .github/ and the Dockerfiles are untouched.
Upstream removed ShadowRealm and JSRemoteFunction in 323565@main (d5f13fa)
because WebKit never shipped them. Bun does: ShadowRealm is a documented global,
it is in bun-types, and Bun's tests use it.

This reverts the parts of that commit under Source/JavaScriptCore and JSTests,
and the ShadowRealmEnabled entry of UnifiedWebPreferences.yaml, which is where
Options::useShadowRealm comes from. The WebCore part (the ShadowRealmGlobalScope
wrapper, the bindings generator's global context, the
WebAPIsInShadowRealmEnabled preference) and the layout tests, which need a
browser, stay removed.

What comes back is the fork's code, not upstream's last version of it:
- Each deleted file is the fork's file merged with what upstream did to it up to
  the removal (the LEGACY_NODELETE rename, SourceTaintedness).
- JSFunction.cpp has the one-line "[native code]" text and
  AllowLazyMaterializationOfImmutableProperties in the JSRemoteFunction branches.
- BunV8HeapSnapshotBuilder.cpp has its ShadowRealmType case.

One line is new to the fork: Interpreter::isExceptionCaughtByUserCatchClause()
(323523@main) stops at a remote function, as it did upstream until the removal.

With this, JSType.h, GlobalObjectMethodTable.h, Intrinsic.h, LinkTimeConstant.h,
BuiltinNames.h and BytecodeIntrinsicRegistry.h are what they were before the
merge, so Bun's mirror of JSType and its method tables need no change.

WebCore's method tables have no entry for the deriveShadowRealmGlobalObject slot
any more, so WebCore does not build with this. The fork only builds JSCOnly.

To let ShadowRealm go later, revert this commit.
e8c36a1 (323155@main) generates it there, and no longer in DerivedSources.

Dockerfile.windows copied DerivedSources/*.json, which matches nothing now, so
every Windows lane failed once it had built everything. The Linux, musl, Android
and FreeBSD Dockerfiles looked for it with find, which copies nothing and
succeeds: those lanes were green and their tarballs had lost the file.
generate-protocol.ts of bun-inspector-protocol reads it from the tarball.

All five name the file now, so a lane fails when it is not there.

Co-authored-by: sosuke <sosuke@anthropic.com>
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Preview build of 2ef4a7a: autobuild-preview-pr-814-2ef4a7ab

Comment thread LayoutTests/css3/color-filters/color-filter-scrollbar-color.html

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nothing blocking. The comments below are optional suggestions. There is no need to push a fix for them before merging.

Beyond the inline findings (both in upstream WebCore code pulled in by the merge), I also checked the two fork-specific commits: the new hard-coded JavaScriptCore/Scripts/CombinedDomains.json path in the five Dockerfiles matches where Source/cmake/WebKitFS.cmake sets JavaScriptCore_SCRIPTS_DIR for every non-Apple build, and the arm64 Linux un-skip of type-index-abstract-heap-types-subtype-validation.js and the .wkdev-sdk-version bump are expectation/toolchain changes only.

Extended reasoning...

This is an upstream WebKit sync of roughly 100 commits (13k files) into the Bun fork plus two fork-specific commits: keeping ShadowRealm and pointing the Dockerfiles at the new CombinedDomains.json location. The two inline findings are in upstream WebCore rendering code and a layout test, not in fork-authored code. The Dockerfile path change was verified against the CMake variable definition; it only falls back to the PrivateHeaders location on Apple non-Bun builds, which these Dockerfiles do not cover. No security-sensitive surface is touched by the fork-specific commits; the sheer size of the upstream merge and the incomplete conversation history mean a human look is still warranted.

Additional findings (outside the current diff — GitHub can't attach inline comments there):

  • 🟡 Source/WebCore/rendering/RenderBox.cpp:515 — Pages that change -apple-color-filter at runtime now get scrollbar thumb and track colors filtered with the old filter until scrollbar-color itself changes. The push in RenderBox::styleDidChange at Source/WebCore/rendering/RenderBox.cpp:508 only fires when oldStyle->scrollbarColor() != newStyle.scrollbarColor(), yet the value it pushes now depends on appleColorFilter() (lines 514-515). Fix: recompute and push the scrollbar color whenever either scrollbar-color or -apple-color-filter changes (and ideally the currentColor source), for both the document element path at line 520 and the overflow path at line 522. On the base branch the pushed value ignored the filter, so a filter change never left it stale.

    Why this was flagged

    A page sets scrollbar-color: blue green and later toggles a class that changes -apple-color-filter (for example adding or removing invert(1)), the common way apps implement a smart-invert mode. Style resolution runs RenderBox::styleDidChange (Source/WebCore/rendering/RenderBox.cpp:508); the guard compares only scrollbarColor(), which is unchanged, so no ScrollbarColor is pushed through frameView().scrollbarColorDidChange (line 520) or scrollableArea->scrollbarColorDidChange (line 522). The value pushed earlier was computed with colorResolvingCurrentColorApplyingColorFilter (lines 514-515) using the previous filter. The page content repaints with the new filter while the scrollbar keeps the colors derived from the old filter. On the base branch the pushed colors never depended on the filter (colorResolvingCurrentColor), so there was no stale state; the diff makes the value filter-dependent without widening the change guard. The new tests in LayoutTests/css3/color-filters only change scrollbar-color, never the filter, so they do not exercise this path.

    Verification: Source/WebCore/rendering/RenderBox.cpp:508 gates the push on oldStyle->scrollbarColor() != newStyle.scrollbarColor() only, while the value pushed at lines 514-515 is now colorResolver.colorResolvingCurrentColorApplyingColorFilter (new in this diff; base used colorResolvingCurrentColor). A color-filter change is only a repaint-level difference, so nothing else re-pushes the color.

claude and others added 2 commits October 15, 2026 08:01
An experiment, to be dropped again if the measurement says it is not the cause.

Collector::resumeThePeriphery() used to end its wait for the parallel visitors
with a SpinBackoff::spinOnce(), which ran at least once per call. On Windows
SpinBackoff has no pause steps, so that was a SwitchToThread(). 323742@main
(1d86f80) removed the wait, rightly, and the yield went with it.

With this upgrade test/js/bun/module-graph/module-graph-workers.test.ts of
oven-sh/bun takes 230 seconds on Windows Server 2019 x64 where it took 90, and
nothing else measured there, or on another platform, moved. Its cells wait for
1 ms timers of a sleeping worker while some sixty threads spin on setImmediate()
on four cores. Such a loop collects every 14 ms or so, so it used to give up the
CPU that often, and now runs out its quantum.

This puts the yield back where it was, on Windows only.

Co-authored-by: sosuke <sosuke@anthropic.com>
Brings in 4556ec7, SourceProvenance and Options::disallowNonStaticCode.

SourceProvider.h conflicted twice, next to lines where ac57a2a had turned
SourceTaintedOrigin into SourceTaintedness. Both sides are kept.

What that commit adds takes a SourceTaintedness too, like the functions it stands
next to: the SourceProvider constructor (whose definition in SourceProvider.cpp
merged cleanly with the old type, and would no longer have matched its
declaration), StringSourceProvider::create() and its constructor, and
makeSource(). A SourceTaintedOrigin still converts, so their callers are as they
were.

makeModule()'s "every type but these four is parsed as JavaScript below" still
holds with SourceProviderSourceType::CSS: the switch has no case for it, and a CSS
module does not come as a JSSourceCode.

Co-authored-by: sosuke <sosuke@anthropic.com>

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code review found no issues

No high-confidence issues detected in this change.

This review covers commit 9aec710, which is no longer the latest commit on this pull request; later commits are not covered by it.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nothing blocking. The comments below are optional suggestions. There is no need to push a fix for them before merging.

Additional findings (outside the current diff — GitHub can't attach inline comments there):

  • 🟡 Source/JavaScriptCore/runtime/JSModuleLoader.cpp:851 — Hosts that fulfil a module fetch with a non-JSSourceCode value (the new makeModule contract) now crash on the require(esm) sync-replay path while the async path accepts it. JSModuleLoader.cpp:851 still casts fetchPromise->result() with uncheckedDowncast before passing it to makeModule, which since this merge takes a JSValue and handles non-JSSourceCode data itself (JSModuleLoader.cpp:1467). Fix: pass fetchPromise->result() straight to makeModule, as moduleRegistryFetchSettled does at JSMicrotask.cpp:1026, so both paths honour the same contract. Conditional on a host (Bun's loader lives outside this tree) resolving a fetch with a non-JSSourceCode value.

    Why this was flagged

    Trigger: vm.m_synchronousModuleQueue is set (require(esm)), a dependency's fetch promise was already fulfilled by the host, and its result is not a JSSourceCode; hostLoadImportedModule reaches the BUN_JSC_ADDITIONS replay block at JSModuleLoader.cpp:844-851. This merge changed makeModule to take JSValue and to turn any non-JSSourceCode moduleData into a default-export SyntheticModuleRecord (JSModuleLoader.cpp:1467-1474), and the async reaction now forwards the raw value (call at JSMicrotask.cpp:1026). The replay at JSModuleLoader.cpp:851 was not updated: uncheckedDowncast(fetchPromise->result()) (JSCast.h:348-356) calls reportZappedCellAndCrash for a non-JSSourceCode cell under ASSERT_ENABLED or ENABLE(SECURITY_ASSERTIONS) on x86_64, and for a primitive result asCell() yields a garbage pointer that makeModule's dynamicDowncast then dereferences in every build. On the base branch both paths required a JSSourceCode, so the two paths agreed; now only the sync path rejects the value the contract allows. No safeguard applies: makeModule's own dynamicDowncast runs only after the unchecked cast has already produced the bad pointer.

    Verification: nit. Trigger: a host that drives require(esm) through JSModuleLoader::loadModuleSync fulfils a dependency's fetch promise with a non-JSSourceCode value, and the replay block at Source/JavaScriptCore/runtime/JSModuleLoader.cpp:844-851 runs in an ASSERT_ENABLED or ASAN build. JSModuleLoader.cpp:851 is unchanged by the diff and still reads makeModule(globalObject, resolved, uncheckedDowncast<JSSourceCode>(fetchPromise->result())).

  • 🟡 Source/JavaScriptCore/heap/Collector.cpp:378 — If Bun's idle-GC completion callback must run to finish something, an embedder whose VM shuts down with that collection still queued now never gets it. Heap::shutDown at Source/JavaScriptCore/heap/Heap.cpp:471 only requests a Leave, and runNotRunningPhase at Collector.cpp:375-378 clears every pending request once the heap set is empty, so a GCRequest::didFinishEndPhase set by JSC__VM__collectAsyncIdle is dropped instead of reaching Collector.cpp:650. On the base branch shutDown called waitForAllCollections() first, which ran the collection and the callback. Fix: before leaving the collector, serve or explicitly complete pending requests that carry didFinishEndPhase (for example wait for them in shutDown as the base did, or run the callback when the request is discarded).

    Why this was flagged

    The trigger is Heap::collectAsync with a GCRequest whose didFinishEndPhase is set (GCRequest.h:57-58 says Bun sets it from JSC__VM__collectAsyncIdle) followed by VM destruction before the next GC poll; the request cannot be subsumed (GCRequest.cpp:34-35) so it stays queued. Heap::shutDown (Heap.cpp:470-473) no longer waits for pending collections; it queues a Leave membership change and waits only for that. The collector enters runNotRunningPhase (Collector.cpp:367-388): applyAllMembershipChangesWithLock removes the heap, then because m_heaps.isEmpty() it does m_requests.clear() and advances m_lastServedTicket, so the End phase at Collector.cpp:649-651 that runs didFinishEndPhase never happens for that request. On the base branch Heap::shutDown called waitForAllCollections() before stopping the thread, so the queued collection ran and the callback fired. Whether the dropped callback matters depends on what Bun's callback does, which is outside this checkout.

    Verification: runNotRunningPhase (Collector.cpp:367-388) applies the Leave first (line 373), then m_requests.clear() (lines 375-378), so the m_currentRequest.didFinishEndPhase->run() at Collector.cpp:650-651 never executes. On the base commit, Heap::shutDown called waitForAllCollections() when m_collector->hasOutstandingRequest() (base Heap.cpp:470-472), so the callback was guaranteed to run before teardown.

…what it gave

The yield of 9aec710 was an experiment. It is what was missing.
test/js/bun/module-graph/module-graph-workers.test.ts of oven-sh/bun on Windows
Server 2019 x64, by topology (A to E), in seconds:

    before the upgrade        14 36 26 10  4    90
    upgraded, without it      18 84 78 22 12   214
    upgraded, with it         16 34 30 10  4    94

Windows 11 aarch64 takes 56 in all three, and Linux about 15. Its comment now says
what it is for rather than where it came from.

hostLoadImportedModule(), where it replays a fetch that settled before the
synchronous load began, still cast the result to a JSSourceCode. makeModule() takes
a JSValue since b1913f6 and sorts that out itself, and
moduleRegistryFetchSettled(), which this stands in for, passes the value as it is.
Bun's loader only ever gives a JSSourceCode, so nothing changes for it.

Co-authored-by: sosuke <sosuke@anthropic.com>

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code review found no issues

No high-confidence issues detected in this change.

@sosukesuzuki
sosukesuzuki merged commit b1e30d0 into main Oct 15, 2026
52 checks passed
sosukesuzuki added a commit to oven-sh/bun that referenced this pull request Oct 15, 2026
oven-sh/WebKit#814 has landed as b1e30d08cb, and its release has all 45 tarballs.
The merge commit has the same tree as 2ef4a7abd3, the head the preview build was
made from, so this is the same source as before under its lasting name.

Co-authored-by: sosuke <sosuke@anthropic.com>
sosukesuzuki added a commit to oven-sh/bun that referenced this pull request Oct 16, 2026
### What does this PR do?

Upgrades the WebKit fork to upstream WebKit `23b0720b40` (2026-10-15):
1013 upstream commits since `dbdca7545d` (#44615), 170 of them in
JavaScriptCore, WTF or bmalloc. Fork PR: oven-sh/WebKit#814, merged.

### Pin

- `WEBKIT_VERSION` is `b1e30d08cb1428688c5f24109fe4f534096ee2ad`, the
commit oven-sh/WebKit#814 was merged with. Its release,
`autobuild-b1e30d08cb…`, has all 45 tarballs. Until that landed, CI here
ran on preview builds of the fork PR. The last of them was made from
`2ef4a7abd3`, which has the same tree as the merge commit.

### ShadowRealm

Upstream removed `ShadowRealm` and `JSRemoteFunction` (`d5f13fa851`,
323565@main) because WebKit never shipped them. Bun does: it is in
`docs/runtime/globals.mdx` and `bun-types`, and more than a dozen tests
use it. **The fork keeps it**, in a commit of its own on top of the
merge, so nothing changes for Bun's users. The price is about 1,700
lines of engine code that upstream no longer maintains. Whether to go on
paying it is for the maintainers to decide; reverting that one fork
commit lets it go.

### What changed in Bun

- `Latin1Character` is a `struct` upstream now, no longer `unsigned
char` (`50a617392b`), so a span or pointer of one no longer converts to
the other. Where bytes become characters or the reverse there is a
`byteCast`: `helpers.h` (the `EncodedSlice` conversions),
`bindings.cpp`, `BunString.cpp`, `JSBuffer.cpp`, `V8String.cpp`,
`WebSocket.cpp`, `SerializedScriptValue.cpp`, `SubtleCrypto.cpp`,
`KeyObject.cpp`, `CryptoPrimes.cpp`, `JSSQLStatement.cpp`,
`HTTPHeaderMap.cpp`, `LintReport.cpp`, `ZigException.cpp`,
`ZigGlobalObject.cpp`, `wtf-bindings.cpp`, `decodeURIComponentSIMD.cpp`,
`BakeSourceProvider.cpp`. Size and alignment are still 1, so nothing
changes across the FFI boundary.
- `Bun__encoding__writeLatin1`, `Bun__encoding__byteLengthLatin1AsUTF8`
and `Bun__encoding__constructFromLatin1` are declared with `const
Latin1Character*`, which is what nearly every caller has.
- `StringBuilder__appendLChar` takes a `uint8_t`, the `u8` that Rust
declares, and not a struct by value.
  - `ChromeBackend.h` asks `charactersAreAllASCII()`.
- An `Exception` has no stack when a `catch` clause further up is
certain to handle the throw (`70896f26ff`). The search for that clause
stops at a VM entry frame, so native code that called into JS still gets
a stack. Native code that catches what was thrown natively under it does
not: `node:vm` does that for a `SyntaxError` of the script, and takes
the position for its `evalmachine.<anonymous>:2` header from that stack.
`NodeVM::handleException`, `JSC__Exception__getStackTrace` and
`ZigException__collectSourceLines` read `stackForReporting()`, which
falls back on the error's own stack. `handleException` has to ask before
it materializes the `stack` property, which frees that one. The
reference it keeps across that stays good: `stackForReporting()` [copies
the error's frames into the `Exception`'s own `m_stack` and returns
that](https://github.com/oven-sh/WebKit/blob/2ef4a7abd380ec4dba21d6edcda803ae6425e215/Source/JavaScriptCore/runtime/Exception.cpp#L105-L121),
not a reference into the `ErrorInstance`.
- `VM::clearSourceProviderCaches()` is gone (`92e99db5ad`): a full
collection now keeps the parser caches that were used since the one
before it. `JSC__VM__runGC` clears `sourceProviderCacheMap` itself, for
both values of its `sync` argument, so `Bun.gc(true)` and the
collections at the end of `bun run` and of a worker still drop all of
them. `Bun.gc(false)` does not come through there: it asks for an
asynchronous collection without saying that it be a full one, and is
like any other collection in this. **A collection that Bun did not ask
for keeps a `SourceProvider`, and its source text, for one full
collection longer than before.** That is upstream's intent, but it can
move the numbers of a memory test.
- `SourceProvider::sourceTaintedOrigin()` takes a kind;
`JSCommonJSModule.cpp` passes `taintedness()` on (`ac57a2af8c`).
`SourceTaintedOrigin::Untainted` still converts where a
`SourceTaintedness` is wanted, so the other 28 uses stay.
- `ScriptFetchParameters::Type` has a `CSS` (`b1913f6615`), and the
`switch` in `NodeVM.cpp` has a case for it. It cannot be reached: the
fork keeps `with { type: "css" }` a `HostDefined` type, like `"text"`,
so Bun goes on loading it itself. The fork puts `CSS` after
`HostDefined`, which stays 5, the number
`to_script_fetch_parameters_type()` writes.
- `test/bundler/bundler_bytecode_portable.test.ts` has new snapshots. It
pins hashes of encoded bytecode, and failed on all eleven test lanes at
once, which its header says is the case to update. The opcodes and the
cache format did not change, but what the bytecode generator emits did
(the unary plus that is no longer dropped, when `arguments` is captured,
the handler type of an async function without `await`, constant array
literals). 23 of the 27 entries move, by at most 1712 bytes out of 21
MB, and no `js` hash does.
- `src/jsc/JSType.rs` needs no change. With ShadowRealm kept,
`JSType.h`, `GlobalObjectMethodTable.h`, `Intrinsic.h`,
`LinkTimeConstant.h`, `BuiltinNames.h`, `BytecodeIntrinsicRegistry.h`
and `BytecodeList.rb` are the same as before.

### The collector's yield on Windows

With the upgrade as upstream has it,
`test/js/bun/module-graph/module-graph-workers.test.ts` timed out on
Windows 2019 x64, every time and on no other lane: 214 seconds where it
had taken 90, against a limit of 180. Nothing hangs; it is slower only
when the CPU is oversubscribed.

- `Collector::resumeThePeriphery()` used to end in one
`SpinBackoff::spinOnce()` per call. `SpinBackoff` has no pause steps on
Windows, so there that was a `SwitchToThread()`; on Linux it is a
`pause`. `1d86f80869` (323742@main) removed the loop it was part of,
rightly, and the yield went with it.
- The test's cells wait for 1 ms timers of a sleeping worker, 25 ticks
or more each, while dozens of threads spin on `setImmediate()` on four
cores. Such a loop collects every 14 ms or so, so it used to give up the
CPU that often. Without the yield it runs out its quantum, which is long
on Windows Server, while the worker that just woke stands in line.
- **The fork yields once in the same place again, on Windows only.**
That keeps what Bun did before this upgrade, for the test and for any
program with busy threads and workers on a loaded Windows server. It is
a side effect kept on purpose, so it is for the maintainers to say
whether they want it. The other way is to make the test wait without
spinning.

By topology (A to E), in seconds, on Windows 2019 x64, measured on CI
with probes that are no longer in this branch:

| | A | B | C | D | E | sum |
|---|---|---|---|---|---|---|
| before the upgrade | 14 | 36 | 26 | 10 | 4 | 90 |
| upgraded, without the yield | 18 | 84 | 78 | 22 | 12 | 214 |
| upgraded, with it | 16 | 34 | 30 | 10 | 4 | 94 |
| upgraded, without it, the cells calling `Sleep(0)` once in 5000 turns
of their wait loop | | 14 | 14 | 4 | 0 | |

Windows 11 aarch64 (56) and Linux (about 15) are the same in the first
three rows, and so is every measurement of one process or one worker on
its own. Why Windows 11 aarch64, which lost the same yield, is no slower
is not explained.

### How did you verify your code works?

CI is the real check: the machine this was prepared on could reach
neither the pinned LLVM 23 nor the pinned Rust nightly. In the first run
(#125713) every lane built, and two test files failed: the bytecode
snapshots, updated since, and the Windows timeout described above.

Locally, on Linux x64:

- A debug Bun was built against the new WebKit tree, from Bun's own
build graph with its own flags (`-Werror` included), with clang 20 and
rustc 1.98.1 standing in for the pinned toolchain. That took four
changes to Rust code that are not in this pull request, for standard
library API that 1.98.1 lacks (`AllocatorClone`, `type_info::of`,
`FieldId::offset`/`name`, `Default for Once`).
- `bun-debug -p 42` prints 42, and `process.versions.webkit` is the
preview build of that time.
- `test/js/bun/jsc/webkit-upgrade-23b0720b40.test.ts` (new, 11 cases)
passes on it. On Bun 1.4.2 (`USE_SYSTEM_BUN=1 bun test`), 9 of them
fail. The other two pin what had to stay the same: the header `node:vm`
gives an error, and an error leaving a ShadowRealm.
- The bytecode snapshots are the values CI received. That build produces
the same ones for the 22 entries whose packages it could install, and
the same as before for the 4 that did not move.
- The fork's CI for oven-sh/WebKit#814: all 45 lanes build (Linux glibc
and musl, macOS, Windows, FreeBSD, Android; x64 and arm64; release, LTO,
debug, ASAN), and its run of the whole JavaScriptCore test suite passes
on Linux x64 and arm64. Its first run caught that the tarballs had lost
`CombinedDomains.json`, which upstream now generates in another
directory; that is fixed there.
- The merge was read again by area (GC, ShadowRealm, module loader,
exceptions, Yarr, `Latin1Character`) for places where the two sides
merged cleanly and no longer fit. Yarr's JIT was fuzzed against its
interpreter: about 4.7 million results for string lists, 5.2 million for
large character classes, and 312 patterns over every code point, with no
mismatch. test262's 64 `built-ins/ShadowRealm` tests and the 149 of
`JSTests/modules` pass.

---

## Upstream WebKit changes

What follows describes upstream. Where the fork does something else, it
says so.

Upstream range: `dbdca7545da8` (2026-10-05) -> `23b0720b409a`
(2026-10-15), 322785@main through 323796@main for the commits listed
here. 1013 upstream commits in total, 170 of which touch
`Source/JavaScriptCore`, `Source/WTF` or `Source/bmalloc`. 38 of those
170 only touch web preferences, `PlatformEnable*` / `PlatformHave.h`,
static-analysis expectation files or browser-only Inspector protocol
JSON and have no effect on a JSCOnly build.

### Highlights

- **ShadowRealm and `JSRemoteFunction` are removed upstream**
(`d5f13fa851`, 323565@main). This drops a `JSType` entry, a
`GlobalObjectMethodTable` slot,
`JSGlobalObject::createWithCustomMethodTable`,
`Options::useShadowRealm`, builtins, thunks and JIT operations. Bun
ships `ShadowRealm`, so **the fork keeps all of it**; the section below
lists what that is.
- **`Latin1Character` is now a distinct `struct`, no longer `unsigned
char`** (`50a617392b`, 323550@main). `std::span<const Latin1Character>`
and `std::span<const uint8_t>` are different types; every place that
mixes `span8()` with `uint8_t*`/`unsigned char*` needs an explicit cast.
- **`NODELETE` is renamed to `LEGACY_NODELETE`** across WTF, JSC and
WebCore and the alias is removed (`e795d5a2ba`, `e4be3948da`,
`b8f13b0bdb`). About 570 files of purely mechanical churn in WTF and JSC
alone.
- **`SourceTaintedOrigin.h` is replaced by `SourceTaintedness.h`**
(`ac57a2af8c`, 323174@main). `SourceProvider`, `makeSource`,
`StringSourceProvider::create` and the function-constructor helpers now
take a `SourceTaintedness` (implicitly constructible from
`SourceTaintedOrigin`).
- **`JSC::Exception` no longer captures a stack when the throw is
certainly caught by a user `catch` clause** (`70896f26ff`, 323523@main).
`Exception::stack()` can be empty in that case;
`Exception::stackForReporting(VM&)` falls back to the `ErrorInstance`
stack.
- **Module loader: hosts may resolve a fetch with an arbitrary
`JSValue`** that becomes the default export of a synthetic module, and
`type: "css"` is a recognised (default-off) import attribute
(`b1913f6615`, 322887@main). `provideFetch` / `makeModule` signatures
changed.
- **GC: groundwork for one `Collector` covering several heaps** (15
commits). Behaviour is unchanged with the default options, but `Heap`,
`Collector`, `SlotVisitor` and `AbstractSlotVisitor` internals moved
around. Real wins in the same area: Eden collections only sweep new or
dirtied `ArrayBuffer`s (`91e8fd1b2f`), `SourceProviderCache` entries
survive a full GC if they were used since the previous one
(`92e99db5ad`), and `WeakMap`/`WeakSet` get an inline 4-entry buffer
(`54a3720b4e`).
- **Wasm BBQ allocates registers for locals** (`ab081a2baf`,
323294@main), with two follow-up miscompile fixes in the same range
(`691f57b972`, `f0525ca5fa`).
- **RegExp: large Unicode property classes use bit tables in the Yarr
JIT** (`7a8cc2f8bf`, 323543@main): `/\p{L}/u` code size drops from 13.8
KB to 664 B on ARM64 and the microbenchmark is 1.5x faster.
- **`BigInt.prototype.toString` is divide-and-conquer** (`e2ffc55c56`,
323232@main): 16384 digits go from 664 ms to 34 ms. The fork already had
its own, which it keeps.
- **Parser fast path for large literal arrays** (`81026ad583`, reland of
`a4bf1d39d6`) plus single-pass constant array bytecode generation
(`b7161cda17`).
- **`Number`/`BigInt.prototype.toLocaleString("locale")` caches its
`IntlNumberFormat`** per global object (`733b18f696`, 323796@main).
- **A batch of DFG/FTL miscompile fixes**: backwards propagation
(`13714a5887`, `3785004bc4`, `96115d8717`), FTL `ToIntegerOrInfinity`
returning `-0` (`0e08d48004`), FTL `CheckJSCast` always exiting
(`f9dcd0ee93`), `RegExp.call` turned into `new RegExp` (`4681ea866a`),
unused `new Uint8Array(-1)` not throwing (`78c68289ca`).
- **Eleven parser / runtime spec-conformance fixes**, several of which
turn previously accepted code into early `SyntaxError`s (see below).
- **`downcast` / `dynamicDowncast` / `uncheckedDowncast` on an lvalue
`Ref`/`RefPtr` now return a raw reference/pointer** (`2edaa07117`,
323226@main).

### Language features & spec conformance

- **Unary `+` changes evaluation order** (`b985a89bbd`, 322817@main):
the parser no longer strips unary plus from operands of `*`, `/`, `%`,
`-`. `+a * b()` now calls `a.valueOf()` first, and `+1n * 2n` throws a
`TypeError` instead of returning `2n`.
- **`using` allowed in a function nested in a switch clause**
(`e694d1c0c3`, 323061@main): `case 0: (() => { using x = null; })()` no
longer throws a `SyntaxError`.
- **`await a ** b` and `await` as an identifier in a module are
SyntaxErrors** (`e33864764e`, 323662@main).
- **Labelled function declarations are declared in the enclosing scope**
(`29e6343215`, 323675@main): sloppy-mode `label: function f() {}` is
hoisted like an unlabelled one, and `let f; label: function f() {}` is
now an early error.
- **Strict-mode reserved words rejected as parameter and function names
by a `"use strict"` directive** (`9f543645c4`, 323677@main): `function
foo(implements) { "use strict"; }` and `function static() { "use
strict"; }` are early errors.
- **`instanceof` of a primitive through a bound function does not read
`prototype`** (`d02369b1de`, 322956@main).
- **`Array.fromAsync` reads the async iterator's `next` before
constructing `this`** (`d59de52c72`, 322967@main).
- **`Object.defineProperty` reads descriptor fields after
`ToPropertyKey` in DFG/FTL** (`4dab012045`, 322982@main): the inlined
fast path is kept only for keys proven to be string, symbol, int32 or
number.
- **`for-in` no longer skips indexed properties of functions**
(`21b684a378`, 323086@main).
- **`GetPrototypeFromConstructor` reads `prototype` before
`GetFunctionRealm`** (`6fba1aeeb7`, 323408@main): fixes revoked-proxy
ordering for built-in constructors; adds `tryGetFunctionRealm()`.
- **Cross-realm check centralised when the DFG inlines intrinsics**
(`eb79fa320b`, 323152@main): cross-realm inlining is opt-in per
intrinsic; when only the executable is known the DFG speculates
same-realm with a runtime check and a new `BadRealm` exit kind.

### Runtime & builtins

- **Divide-and-conquer `JSBigInt::toString`** (`e2ffc55c56`,
323232@main): port of V8's algorithm on top of the existing
Burnikel-Ziegler division; used from 12 digits upwards.
- **RegExp `String#replace` and `JSON.stringify` do not resolve
substring ropes** (`5ca1f041c3`, 323545@main): characters are read
through a `StringView`; adds `JSString::tryGetView()`. 1.35x to 1.55x on
the new microbenchmarks.
- **Do not capture `Exception` stack when a user handler definitely
catches it** (`70896f26ff`, 323523@main):
`VM::throwException(JSGlobalObject*, JSValue)` walks the bytecode
handler tables and passes `DoNotCaptureStack` when no debugger is
attached and the innermost catching handler is a non-builtin `catch`.
The walk stops at VM entry frames, so native callers never count as
catchers. The wrapper handler of await-less async functions changes from
`Finally` to `SynthesizedCatch`.
- **`JSWeakMap` / `JSWeakSet` inline buffer** (`54a3720b4e`,
323380@main): the initial capacity of 4 is stored inside the cell, so
most instances never allocate an out-of-line buffer. The cells get
larger.
- **`Symbol::privateName()` does not copy `PrivateName`** (`59f9ffb4cd`,
323079@main) and **`putByValMegamorphic` / `inByValMegamorphic` do not
create an `Identifier`** (`9b61fb4887`, 323381@main): removes atomic
ref/deref from by-val slow paths.
- **Don't capture `arguments` just because another binding is captured**
(`1c9b58a9ae`, 323504@main): `arguments` stays out of the activation
unless eval, `with`, the debugger, an inner arrow function or a separate
generator/async body can resolve it.
- **Prevalent-domain taint kind** (`ac57a2af8c`, 323174@main):
`SourceTaintedness` holds one `SourceTaintedOrigin` per
`SourceTaintKind` (`ScriptTrackingPrivacy`, `PrevalentDomain`). The
bytecode cache still stores only the `ScriptTrackingPrivacy` origin, so
the `CachedTypes` layout is unchanged.
- **Release exception scope in asyncFromSync iterator functions**
(`eee3738376`, 322945@main): exception-check validator fixes only.
- **Remove use of `JSGlobalObjectAdditions.h`** (`ad70712c67`,
323755@main): drops the `JS_GLOBAL_OBJECT_ADDITIONS_*` hooks.

### Parser & bytecode generator

- **Scan large data arrays fast** (`a4bf1d39d6` 322915@main, reverted by
`5366788462` 322991@main, relanded as `81026ad583` 323063@main):
`parseArrayElement` short-circuits primitive elements followed by `,`,
and a dedicated lexer routine scans runs of simple numeric elements.
- **Evaluate constant array literal elements once in
`ArrayNode::emitBytecode`** (`b7161cda17`, 322943@main): avoids walking
the element linked list twice.
- **Use `Vector<JSValue>` in the parser since GC is deferred**
(`e5f751c78b`, 323287@main): also removes `m_numConstants` /
`ScopeNode::neededConstants()`.
- **Proactively merge back used-variable sets** (`e36036d0ef`,
323334@main): the number of sets is bounded by parenthesis nesting depth
rather than the count of parenthesised expressions in a scope, which
could overflow the `Vector` limit.

### Performance (LLInt / Baseline / DFG / FTL / B3)

- **`for-of` over strings**: the `FastString` path of `op_iterator_next`
is inlined in LLInt and Baseline for 8-bit strings (`23ff891340`,
322928@main) and for Latin-1 characters in 16-bit strings (`316c1ac309`,
323369@main); DFG/FTL `StringIteratorNext` gets the same 16-bit
treatment, 2.2x on the microbenchmark (`459880fdd4`, 323062@main).
- **Inline the double case of `Number.isNaN` / `isFinite` /
`isSafeInteger`** in DFG and FTL (`4cce27133e`, 323211@main): 2.0x to
2.3x on untyped inputs.
- **JIT array butterfly allocation follows the C++ sizing rule**
(`0c5333c36c`, 323411@main): JIT and C++ now pick the same size class
for tiny arrays; `array-map-tiny` 1.6x, `new-array-variable-size-tiny`
2.2x.
- **Use `DirectCall` when polymorphic inlining fails** (`48d5655a67`,
323496@main): one non-inlinable variant no longer disables inlining of
the others.
- **Branch on `op_instanceof` result in each arm when `jtrue`/`jfalse`
follows** (`5009fc2116`, 323664@main): keeps `MatchStructure` type
information so the later `CheckStructure` can be eliminated.
- **TypeCheckHoisting does not hoist a monomorphic `CheckStructure` over
a polymorphic access** (`57c6380045`, 323371@main): avoids over-narrow
hoisted checks and the resulting OSR exits.
- **MovHint removal applies the block-terminal liveness rule only to
phantom allocations** (`ed1ea24585`, 323212@main): three-level liveness
lattice, more MovHints removed.
- **FTL lowering clean-ups**: strings (`3e286ac0a3`, 323214@main),
Map/Set lookup and iteration (`2ee637ac01`, 323315@main), object and
array access (`7fbbbd1f45`, 323372@main), arithmetic and comparisons
(`114fe57867`, 323647@main), `Math.pow(1, x)` fast path (`37413df14c`,
323743@main), two stores per iteration when filling new arrays
(`3acfa863de`, 323519@main).
- **Compile-time**: `BackwardsPropagationPhase` revisits only affected
blocks (`4ab3c0e99e`, 323541@main); `PutStackSinkingPhase` computes
reaching defs in one dominator-tree walk (`819db6a41c`, 323542@main); B3
`ReduceStrength` folds Phis during the main walk and drops its second
walk (`b2a5db1e51`, 323635@main).
- **Install approximate FTL bytecode cost sooner** (`ea0feabee8`,
323741@main): recorded on `BaselineJITCode` before B3 compilation
finishes, so inlining heuristics see it earlier.
- **Remove `CodeBlock::m_shouldAlwaysBeInlined`** (`2d92bb7ea6`,
322790@main): the flag had been ignored by `operationOptimize` for
years; no behaviour change.
- **MacroAssembler bit-op micro-optimisations** on ARM64 and x86-64
(`c5cb0e0f45`, 322841@main) and **Air prologue generators can emit late
paths** (`6ccecb6246`, 323494@main, no behaviour change).

### JIT correctness fixes

- **FTL `CheckJSCast` always OSR-exited for classes with a `JSType`
range** (`f9dcd0ee93`, 323102@main): `bitNot` was used on a 0/1 value;
hit for example by `for await` over async generators.
- **DFG backwards propagation**: non-integer constants are no longer
treated as "within power of two", so `(x + y + 0.5) | 0` is right on
overflow (`13714a5887`, 323383@main); right shifts are bounded by the
masked shift count (`3785004bc4`, 323595@main); `LogicalNot` no longer
forwards its own use flags to its operand (`96115d8717`, 323639@main).
- **FTL `ToIntegerOrInfinity`** returned `-0` for inputs in (-1, 0)
(`0e08d48004`, 323624@main).
- **DFG should not turn a call to `RegExp` into `NewRegExpUntyped`**
(`4681ea866a`, 323678@main): the lowering is restricted to construct
sites.
- **TypedArray / ArrayBuffer construction throws `RangeError` for
negative length** (`78c68289ca`, 323740@main): the nodes stay
`MustGenerate` unless the length is a known valid constant, so an unused
`new Uint8Array(-1)` still throws.

### GC & memory

- **Eden GC sweeps only new and dirty ArrayBuffers** (`91e8fd1b2f`,
323384@main): `GCIncomingRefCountedSet::sweep()` no longer filters every
live `ArrayBuffer` on each Eden collection. An unknown collection scope
is now treated as Full.
- **Keep `SourceProviderCache` if it was touched in the last full GC
cycle** (`92e99db5ad`, 323676@main): full collections prune only unused
caches instead of clearing all of them.
- **Remove `optimizeParallelSlotVisitorsForStoppedMutator` and its
protocol** (`1d86f80869`, 323742@main): the option was off since 2016
and racy. Removes the per-visitor `rightToRun` lock;
`mutatorIsStopped()` becomes `mutatorsAreStopped()`.
- **Multi-heap `Collector` series** (no behaviour change with default
options; `useGlobalGC` already existed, stays `false`, and is explicitly
not usable yet):
- Group per-heap work of Begin/End (`729712aa49`, 322785@main); read the
heap through `heap()` (`e2eefa65e8`, 322849@main); replace `Heap&` with
a vector of heaps (`f488eac0e0`, 322984@main).
- Assert that `Heap` methods only receive that heap's cells: `isMarked`,
`addToRememberedSet`, `reportExtraMemoryAllocated`, `addReference`,
`addFinalizer`, `protect`/`unprotect` (`5fa36a13d4`, 322980@main).
- Logging and signposts summed over heaps (`b68bb7b7c0`, 323109@main);
compiler-thread suspension (`ef6ad2a4ee`, 323111@main); own visitor in
`rememberExecutingAndCompilingCodeBlocks()` (`34832d663f`, 323112@main);
GC verifier moved from `Heap` to `Collector` (`75a1e77857`,
323113@main); mutator scheduler (`192fd94f17`, 323250@main).
- Heap analysis: visitors store `isAnalyzingHeap` and hand each cell to
its own VM's analyzer (`ddc9c7fbc6`, 323477@main).
- Heaps join and leave a `Collector`; `Heap::m_localCollector` vs. the
shared global collector; each `MarkingConstraint` records its heap
(`5e4ff7aa73`, 323479@main).
- Collection-scope decision and visitor checks (`47697fd0eb`,
323482@main); per-heap bytes-marked and extra-memory accounting
(`94bf250671`, 323597@main).
- Renames and documentation only: bytes "visited" to bytes "marked" /
old-generation cell bytes (`5b292fffd7`, 323735@main); `MarkedBlock`
mark and newly-allocated bit helpers (`b8c79b4438`, 323785@main).

### WebAssembly

- **Allocate registers for locals in BBQ** (`ab081a2baf`, 323294@main):
expression-stack entries reference locals instead of copying them, and
the busiest locals (ranked by IPInt) are pinned to callee-save registers
for the whole function body.
- **`and64` / `or64` / `xor64` with a blinded `Imm64` should read
`src`** (`691f57b972`, 323522@main): x86-64-only random miscompile of
`i64.and/or/xor` with a constant, exposed by the change above.
- **BBQ should flush only the block's results at the end of a block**
(`f0525ca5fa`, 323660@main): multi-value block results could be mixed
up, also exposed by the change above.
- **Report `OMGOSREntryCallee` pending with its BBQ owner**
(`9ed2bcd5bc`, 322903@main): closes a window where a frame still running
in a retired OSR-entry callee was not seen as live.
- **One-type rec groups match the shorthand form** (`8cbe7ed174`,
323455@main): `(rec (type ...))` with a single self-referential type now
canonicalises to the same type as the shorthand, fixing `ref.test`.
- **Wasm debugger: a continue after `Hc<thread>` resumed the wrong VM**
(`7c3fb01227`, 323333@main).

### RegExp (Yarr)

- **Bit tables instead of inlined compares for Unicode property
escapes** (`7a8cc2f8bf`, 323543@main): for 16-bit subjects, classes with
128 or more entries below U+20000 use a heap-allocated, deduplicated bit
table owned by the `YarrCodeBlock`.
- **EOL StringList does better length checks** (`8d2c95ee3b`,
322803@main): `/^(?:aaaa|bbbb|dd|ee|g)$/` dispatches on the input length
once per group of equal-length alternatives.

### Intl / ICU

- **`toLocaleString` reuses `IntlNumberFormat` when only a locale string
is given** (`733b18f696`, 323796@main): one cached formatter per
`JSGlobalObject`, keyed by locale. This cache and the `localeCompare`
collator cache now miss while a language change is pending.
- **Typed-string wrappers for ICU functions that take a locale**
(`9626df6128`, 323410@main): `ubrkOpen`, `ucalOpen`, `ucolOpen`,
`udatOpen`, `udatpgOpen`, `unumOpen`, `usearchOpen`,
`uStrToLower/Upper/Title` in `wtf/text/icu/UnicodeExtras.h`. No
behaviour change.
- No Temporal behaviour changes in this range (only include edits, the
`ucalOpen` wrapper and the annotation rename under `runtime/temporal/`).

### Module loader

- **CSS module scripts** (`b1913f6615`, 322887@main): adds
`ScriptFetchParameters::Type::CSS`, `SourceProviderSourceType::CSS` and
`Options::useCSSModuleScripts` (default `false`). When a fetch resolves
with something that is not a `JSSourceCode`,
`JSModuleLoader::makeModule` wraps it with
`SyntheticModuleRecord::tryCreateDefaultExportSyntheticModule` (now
public).
- **A module worker evaluates its entry script once** (`47b1bf884e`,
323507@main): new `JSC::loadModule(JSGlobalObject*, const Identifier&
moduleKey, SourceCode&&, RefPtr<ScriptFetcher>)` registers provided
source under a caller-chosen key instead of a private entrypoint key.
- **`createTypeErrorCopy` comment clean-up** (`3fcb0d2aec`,
323692@main): the function is retained because `JSModuleLoader` uses it.

### Inspector & debugging

- **Async command errors are sent with the right request id**
(`2cb4a4edf3`, 323091@main): adds
`BackendDispatcher::sendErrorResponse(requestId, code, message)`;
`CallbackBase::sendFailure()` and the generated async handlers use it.
- **`toString` is no longer called twice by `console.log`**
(`432718f701`, 323668@main): the stringified first argument is reused as
the `RemoteObject` description, so having an inspector attached is not
observable this way.
- **Don't automatically invoke native getters on functions and prototype
objects** (`b0bb30bdd4`, 323271@main):
`Runtime.getDisplayableProperties` keeps them as accessors.
- **`Debugger::exception()` honours a pause blocked by another
debugger** (`7899962151`, 322901@main).
- Protocol JSON changes are limited to browser-only domains (CSS,
Canvas, DOM, DOMDebugger, DOMStorage, IndexedDB, Page): `a3243e0fce`,
`6ed1f44d53`, `4424ae9f33`, `15fea1ee0f`, `e86e35f4d9`, `fe7b1ac8b3`,
`427feb8178`, `41d4de49d3`, `64611e1e3f`, `44dcf77e60`, `ec3d95f1d7`,
`614cfd229d`. Runtime, Debugger, Console, Heap, ScriptProfiler and
Target are untouched.

### WTF

- **`Latin1Character` is a distinct type** (`50a617392b`, 323550@main):
details below.
- **Smart-pointer casts return a smart pointer only for an rvalue**:
`Ref`/`RefPtr` (`2edaa07117`, 323226@main), `CheckedPtr`/`CheckedRef`
(`277305bef9`, 323119@main), `WeakPtr`/`WeakRef` (`8e7db40c16`,
322963@main).
- **Reduce stack use and code size of `Vector` append slow paths**
(`22f00b355a`, 323213@main): small trivially copyable arguments are
passed by value to out-of-line slow paths; about 104 KB less `__text`
across the macOS frameworks.
- **Static `Vector::map(range, fn)`** (`60582f61a4`, 322862@main).
- **Remove most uses of `ASCIILiteral::fromLiteralUnsafe()`**
(`dc95362184`, 322902@main): adds a `consteval` constructor from
`std::array<char, N>`. `fromLiteralUnsafe` itself still exists.
- **`SAFE_*` logging macros** (`0d3626899f`, 323050@main):
`SAFE_PRINTSTREAM_PRINTF`, `SAFE_WTFLOG`, `SAFE_ANDROID_LOG_PRINT`, and
others.
- **[Linux] Do not set high priority for non-utility threads**
(`f030129a85`, 323095@main): `Thread::setCurrentThreadQOS()` is forced
to the default QOS on Linux.
- **[Android] Log channel property was read after it became invalid**
(`38c980e8e8`, 323116@main).
- Small additions: `StringView::precomposedCharacter()` (`9719fea3ee`,
323560@main), `URL::protocolIsInHTTPFamilyOrBlob()` (`d90a67d5c7`,
323757@main), `tuple_zip` zips references instead of copies
(`183405b4b6`, 323690@main), `Borrow<T>` range-for and subscripting
(`9b55d50c13`, 323531@main), `SWIFT_SHARED_REFERENCE` on
`DeferrableRefCounted` (`61a1e863f2`, 323771@main).
- Port-specific string/span wrappers: GLib (`7c3395d795`, 322837@main;
`8ef26af51d`, 323768@main), Darwin (`7af5c57acd`, 323210@main).

### bmalloc / libpas

- **Introduce `pas_memory_flavor`; `pas_page_malloc` is flavor-aware**
(`69e1e79b26`, 323533@main): every `pas_heap_config` carries a memory
flavor in place of `pas_page_flags` (`pas_page_flags.h` removed,
`pas_memory_flavor.h` added). Only the MTE flavor is a real alternative
today.
- **Round up compact SystemHeap allocation sizes** (`f1b6790127`,
323646@main): Darwin `malloc_zone_malloc_with_options_np` requires the
size to be a multiple of the alignment.
- **MTE tag-policy tests** (`c1f2f38f01`, 323491@main).

### Build system & ports

- **`CombinedDomains.json` is generated into
`JavaScriptCore_SCRIPTS_DIR`** instead of the derived-sources directory,
on every CMake port (`e8c36a19c9`, 323155@main).
- **Vendored ICU headers in `Source/WTF/icu/unicode` are marked `#pragma
clang system_header`** (`76b650f4f5`, 323059@main).
- **More `JS_EXPORT_PRIVATE` on functions reachable from inline code**
(`4a1f084b9c`, 322927@main; `ef268b071f`, 322930@main): `Watchpoint`,
`SlotVisitor::didRace`, `CallFrame::topOfFrameInternal`,
`JSFunction::allocateRareData`, `Structure(VM&, CreatingEarlyCellTag)`
and others.
- **`heap/HeapProfiler.h` becomes a private framework header**
(`12c9964c28`, 323069@main).
- **[Win] `OptionsMSVC.cmake` sets `CMAKE_MSVC_RUNTIME_LIBRARY` to
`MultiThreadedDLL` unconditionally** (`0a75fded40`, 323106@main; outside
the three directories but relevant to a static-CRT build).
- Other: `-Wmissing-designated-field-initializers` fix (`dd14326b38`,
323122@main), Cocoa dev presets bake in `DYLD_FRAMEWORK_PATH`
(`ecf6e18b11`, 323760@main), `ENABLE_FUTURE_API_VERSION` for GLib ports
(`f4d6497564`, 323586@main), `check-xcfilelists` in EWS (`1538f2b2a2`,
322789@main).

### Removed features

- **ShadowRealm / `JSRemoteFunction`** (`d5f13fa851`, 323565@main), see
below.
- **`Options::optimizeParallelSlotVisitorsForStoppedMutator`**
(`1d86f80869`, 323742@main).
- **`CodeBlock::m_shouldAlwaysBeInlined`, `DFG::mightInlineFunction()`**
(`2d92bb7ea6`, 322790@main).

### Safer CPP (static-analysis annotations, no intended behaviour
change)

- WTF headers (`e2e0869eaa`, 322839@main): also defines
`ENABLE_LIBPAS_JIT_HEAP` before the conditional include in
`ExecutableMemoryHandle.h`, so `MetaAllocatorHandle.h` is no longer
pulled in when the libpas JIT heap is used.
- WebCore bindings and code generator (`12c9964c28`, 323069@main), see
the code-generator notes below.
- WTF after the analyzer update (`163c1963d4`, 323368@main): adds
`SPECIALIZE_TYPE_TRAITS` for `ExternalStringImpl` and
`RegisteredSymbolImpl`.
- `5cce878453`, `917c91dde1`, `e95978e65e`, `0b23dd248f`, `386e25e9d4`:
suppressions and expectation files.
- `NODELETE` -> `LEGACY_NODELETE`: `e795d5a2ba` (WTF, 323505@main),
`e4be3948da` (JSC, 461 files, 323540@main), `b8f13b0bdb` (alias removed,
323593@main).

### No effect on JSCOnly (preferences, platform flags, test noise)

`9b7886d864`, `b4363b9b36`, `bcb4d683f0`, `472401fb42`, `e049f5845b`,
`7ed4288b58`, `9fdd2604ed`, `38f193ec53`, `8e822d6010`, `97090661c8`,
`7dfcda9d52`, `ff6999b2c6`, `b6260a6063`, `5b23cbc369`, `d7cc8ac53c`,
`83f810390d`, `ba2293363a`, `53d8d953c7`, `7275e58ccc`, `16838cede3`,
`dcbc3580c4`, `9e5059ee07`, `8de1c7b476`, `f199f49af2`, `ad9093ff9b`
(web preferences and `PlatformEnable*` / `PlatformHave.h` / Cocoa
runtime checks only); `11a7ffdb0e` (removes debug logging from the LOL
JIT).

### ShadowRealm removal in detail (`d5f13fa851`, 323565@main)

Upstream's rationale: the feature never shipped in Safari, yet its
prototype, structure and constructor were created eagerly on every
`JSGlobalObject`. What the commit removes from JavaScriptCore:

- **Files**:
`runtime/ShadowRealm{Constructor,Object,Prototype}{.cpp,.h,Inlines.h}`,
`runtime/JSRemoteFunction{.cpp,.h,Inlines.h}`,
`builtins/ShadowRealmPrototype.js`, with their entries in
`CMakeLists.txt` (LUT sources, builtins, private headers) and
`Sources.txt`.
- **`JSType`**: `ShadowRealmType` (value 71), together with its
`JSCast.h` fast-cast entry and `JSType.cpp` printer case.
- **`GlobalObjectMethodTable`**: the `deriveShadowRealmGlobalObject`
slot (between `instantiateStreaming` and `codeForEval`).
- **`JSGlobalObject`**: `createWithCustomMethodTable()`,
`deriveShadowRealmGlobalObject()`, `createStructureForShadowRealm()`,
`shadowRealmPrototype()`, `shadowRealmStructure()`,
`remoteFunctionStructure()`, and the members `m_shadowRealmConstructor`,
`m_shadowRealmPrototype`, `m_shadowRealmObjectStructure`,
`m_remoteFunctionStructure`.
- **Option**: `Options::useShadowRealm`. It was not in `OptionsList.h`;
it is generated into `JSCWebPreferenceOptions.h` from the
`ShadowRealmEnabled` entry (`jscOptionName`) of
`UnifiedWebPreferences.yaml`, which is deleted along with
`WebAPIsInShadowRealmEnabled`.
- **Builtin plumbing**: bytecode intrinsic `@isShadowRealm`
(`BytecodeIntrinsicRegistry.h`, `emitIsShadowRealm`, the
`NodesCodegen.cpp` brand check); link-time constants and private names
`importInRealm`, `evalInRealm`, `moveFunctionToRealm`,
`createRemoteFunction`, `isRemoteFunction`; the `ShadowRealm` common
identifier and builtin name.
- **Heap**: iso subspaces `shadowRealmSpace` and `remoteFunctionSpace`.
- **VM**: `getRemoteFunction(bool)`, `m_fastRemoteFunctionExecutable`,
`m_slowRemoteFunctionExecutable`, and the `RemoteFunctionCallIntrinsic`
thunk mapping.
- **JIT**: `Intrinsic::RemoteFunctionCallIntrinsic`, thunk
`remoteFunctionCallGenerator` (about 200 lines of
`ThunkGenerators.cpp`), operations `operationGetWrappedValueForCaller`,
`operationGetWrappedValueForTarget`,
`operationMaterializeRemoteFunctionTargetCode`,
`operationThrowRemoteFunctionException`.
- **DFG / FTL**: no dedicated node types existed (`DFGNodeType.h` is
untouched). Only the `JSRemoteFunction::info()` slow-path branch in
`compileFunctionToString` is removed from both tiers.
- **Interpreter**: `UnwindFunctor`'s `seenRemoteFunction` tracking and
`sanitizeRemoteFunctionException()`, which rewrote exceptions crossing
the realm boundary into a `TypeError`; also the remote-function stop
condition in the new `isExceptionCaughtByUserCatchClause()`.
- **Other runtime branches**: `JSFunction::isRemoteFunction()`,
`JSC::isRemoteFunction(JSValue)`, name/length/`toString` handling in
`JSFunction.cpp` and `JSFunctionInlines.h`, `getFunctionRealm()`
unwrapping in `InternalFunction.cpp`, the
`RetrieveCallerFunctionFunctor` check in `FunctionPrototype.cpp`, the
`targetFunction` internal property in `JSInjectedScriptHost.cpp`, and
`$.isRemoteFunction` in the `jsc` shell.
- **Invariant tightened**: every global object is again an
immutable-prototype exotic object; the `isGlobalObject()` escape hatch
in the `JSObject::setPrototypeWithCycleCheck` assertion is gone.
- **Kept**: `createTypeErrorCopy` (used by `JSModuleLoader`). The
test262 ShadowRealm tests stay in the tree but are skipped through
`JSTests/test262/config.yaml`; JSC stress tests for the feature are
deleted.

### Things embedders need to react to

**a. `runtime/JSType.h`** (does not reach Bun: the fork keeps
`ShadowRealmType`, and its `JSType.h` is unchanged)
- The only change is the removal of `ShadowRealmType` (`d5f13fa851`).
Everything after it shifts down by one: `RegExpObjectType` 72 -> 71
through `DerivedStringObjectType` 96 -> 95, and therefore
`LastJSCObjectType` 96 -> 95. Any mirror of the enum and any embedder
types numbered from `LastJSCObjectType + 1` move with it.

**b. `GlobalObjectMethodTable`** (`runtime/GlobalObjectMethodTable.h`;
does not reach Bun: the fork keeps the slot)
- The only change is the removal of `JSGlobalObject*
(*deriveShadowRealmGlobalObject)(JSGlobalObject*)` (`d5f13fa851`).
Positional initialisers must drop that entry: `...,
instantiateStreaming, codeForEval, canCompileStrings,
trustedScriptStructure`.
- `moduleLoaderFetch`'s type is unchanged, but its promise may now
resolve to a non-`JSSourceCode` value (`b1913f6615`).

**c. Options**
- `OptionsList.h`: removed
`optimizeParallelSlotVisitorsForStoppedMutator` (`1d86f80869`). Nothing
added, no default changed.
- Generated from `UnifiedWebPreferences.yaml`: removed `useShadowRealm`
(`d5f13fa851`; the fork keeps it); added `useCSSModuleScripts`, default
`false` (`b1913f6615`).

**d. WebCore bindings code generator**
(`Source/WebCore/bindings/scripts`, `bindings/js`,
`bindings/IDLTypes.h`)
- `12c9964c28` (323069@main): `IDLInterface<T>::ConversionResultType` is
`Ref<T>` (was `T&`) and `NullableConversionResultType` is `RefPtr<T>`
(was `T*`); `Converter<IDLInterface<T>>` returns
`object.releaseNonNull()`. Generated code appends `.get()` when passing
interface arguments to the implementation. Interface and buffer-source
results are wrapped in a functor, `toJS<IDLInterface<X>>(...,
throwScope, [&] -> decltype(auto) { return impl.foo(); })`. Union
attribute setters pass the conversion functor inline to `convert<>()`
instead of through a named `valueFunctor`. Many `SUPPRESS_UNCOUNTED_*` /
`SUPPRESS_UNCHECKED_*` / `protect(...)` annotations are emitted, and
`getPtrOrRef` / `extractValueFromNullable` gain
`CLANG_POINTER_CONVERSION`.
- `86d0164f83` (322966@main) and `942f69a02d` (323558@main):
`[Serializable]` / `[Transferable]` interfaces get `static bool
isExposedInGlobalObject(JSDOMGlobalObject&)` and `static constexpr bool
isRestrictedToSameAgentCluster`; new `[SameAgentCluster]` attribute.
- `0e684f1df5` (322993@main): new `[QuirksCanChangeAtRuntime]` attribute
emitting `reevaluateQuirkDependentPrototypeProperties()`.
- `e427188d73` (323551@main): generated headers say `LEGACY_NODELETE`.
`214d23390e` (323718@main): no `wrapped()` override for
`[JSLegacyParent]` interfaces.
- `d5f13fa851`: `ShadowRealm` dropped as a global context;
`preprocess-idls.pl` loses `--shadowRealmGlobalScopeConstructorsFile`;
the `StructureFlags` special case is gone.
- JSC's `builtins_generate_separate_header.py` adds a
`FunctionExecutable.h` include to the separate builtin headers it
generates for WebCore (`12c9964c28`).

**e. JSC headers**
- `parser/SourceTaintedOrigin.h` -> `parser/SourceTaintedness.h`
(`ac57a2af8c`). `SourceProvider::sourceTaintedOrigin()` ->
`sourceTaintedOrigin(SourceTaintKind)` or `taintedness()`;
`setSourceTaintedOrigin(origin)` -> `setSourceTaintedOrigin(kind,
origin)`; `computeNewSourceTaintedOriginFromStack()` ->
`computeNewSourceTaintednessFromStack()`. Parameters of `SourceProvider`
/ `StringSourceProvider` constructors, `makeSource`,
`constructFunction*`, `FunctionExecutable::fromGlobalCode` and
`tryGetCachedFunctionExecutableForFunctionConstructor` are
`SourceTaintedness`; passing `SourceTaintedOrigin::Untainted` still
compiles through the implicit constructor.
- `VM.h`: `clearSourceProviderCaches()` ->
`pruneUnusedSourceProviderCaches()`, which only drops caches not used
since the last prune (`92e99db5ad`); `getRemoteFunction()` removed;
`mightHavePrevalentDomainTaintedCode()` added.
- `Exception.h`: `stackForReporting(VM&)` added; `stack()` may be empty
for exceptions caught by user code (`70896f26ff`).
- `JSModuleLoader.h`, `ModuleRegistryEntry.h`: `provideFetch(...,
JSSourceCode*)` -> `provideFetch(..., JSValue)`; `makeModule(...,
JSSourceCode*)` -> `makeModule(..., JSValue moduleData)` (`b1913f6615`).
New enumerators `ScriptFetchParameters::Type::CSS` and
`SourceProviderSourceType::CSS` affect exhaustive `switch` statements.
In the fork they come last, after `HostDefined` and
`BunTranspiledModule`, which keep their values.
- `Completion.h`: `loadModule` overload taking a module key
(`47b1bf884e`).
- `Symbol.h`: `privateName()` returns `GCOwnedDataScope<const
PrivateName&>` instead of `PrivateName` (`59f9ffb4cd`).
- `InternalFunction.h`: `tryGetFunctionRealm(JSObject*)` added;
`JSC_GET_DERIVED_STRUCTURE` uses it and falls back to the current realm
instead of throwing (`6fba1aeeb7`).
- `JSString.h`: `tryGetView()` added (`5ca1f041c3`). `IndexingType.h`:
`leastUpperBoundOfIndexingTypes` is inline, `...AndValue` moved to
`IndexingTypeInlines.h` (`b7161cda17`).
- `JSFunctionInlines.h` no longer includes `JSRemoteFunction.h`, so its
transitive includes are gone (`d5f13fa851`; not in the fork).
- `heap/AbstractSlotVisitor.h`: `heapAnalyzer()` -> `isAnalyzingHeap()`
(`ddc9c7fbc6`); pure virtual `mutatorIsStopped()` ->
`mutatorsAreStopped()` (`1d86f80869`).
- `heap/Heap.h`: removed `isSafeToCollect()`,
`isMarkingForGCVerifier()`, `setKeepVerifierSlotVisitor()`,
`clearVerifierSlotVisitor()`, `dumpVerifierMarkerData()` (the verifier
lives on `Collector`); the signature of
`addMarkingConstraint(std::unique_ptr<MarkingConstraint>)` is unchanged,
but it is now a no-op with `useGC=false`, asserts that
`notifyIsSafeToCollect()` already ran, and waits for a running
collection before returning (`5e4ff7aa73`). `MarkingConstraintSet::add`
takes a `Heap&`.
- `heap/SlotVisitor.h`: `bytesVisited()` -> `bytesMarked()`;
`rightToRun()`, `updateMutatorIsStopped()`,
`optimizeForStoppedMutator()` removed. `heap/MarkedBlock.h`:
`aboutToMarkSlow` -> `resetStaleMarks`, `resetMarks` ->
`resetMarksForVersionWrap`, `resetAllocated` ->
`resetNewlyAllocatedForVersionWrap`, `marksConveyLivenessDuringMarking`
-> `staleMarksStillRecordSurvivors`.
- `inspector/InjectedScript.h`: `wrapObject` gains a trailing `const
String& descriptionHint = { }`;
`ConsoleMessage::setMessageIsFirstArgument(bool)` added (`432718f701`).
`InspectorBackendDispatcher.h`: `sendErrorResponse` added
(`2cb4a4edf3`).
- `bytecode/ExitKind.h`: `BadRealm` inserted (`eb79fa320b`).
`runtime/Intrinsic.h`: `RemoteFunctionCallIntrinsic` removed, later
intrinsics renumber (not in the fork).
- No changes (other than the `LEGACY_NODELETE` rename) to `JSCell.h`,
`JSCellInlines.h`, `JSObject.h`, `JSMicrotask.h`, `Microtask.h`,
`MicrotaskQueue.h`. `bytecode/BytecodeList.rb` and `dfg/DFGNodeType.h`
are unchanged. The `LinkTimeConstant` enum does lose five entries from
its middle upstream; the fork keeps them. Bun keys its bytecode cache on
`BUN_WEBKIT_VERSION`, so caches written by an older Bun are rejected and
rebuilt either way.
- No change of include style in this range; JSC headers keep
`<JavaScriptCore/...>` includes.

**f. WTF**
- `Latin1Character` (`50a617392b`): `struct WTF::Latin1Character {
uint8_t value; }` with implicit conversions to and from integral types
and the usual arithmetic/comparison operators. Consequences:
`std::span<const Latin1Character>` no longer converts to or from
`std::span<const uint8_t>`; `const unsigned char* p =
string.span8().data()` no longer compiles (use `byteCast` /
`spanReinterpretCast` / `reinterpret_cast`); templates instantiated with
`uint8_t` on `span8()` data (for example `parseInteger<T, uint8_t>`)
need `Latin1Character`; mixed ternaries need an explicit `char16_t { ...
}`. `String::span<T>()`, `StringImpl::tryCreateUninitialized<T>()` and
`adopt()` are constrained by the new `IsStringStorageCharacter` concept.
`StringBuilder::append(uint8_t)` is deleted. New `std::span<const
uint8_t>` overloads of `String::fromUTF8`,
`fromUTF8ReplacingInvalidSequences` and `fromUTF8WithLatin1Fallback`.
Size and alignment stay 1, so passing pointers across an FFI boundary is
unaffected.
- `NODELETE` is no longer defined on the Clang path of `wtf/Compiler.h`;
use `LEGACY_NODELETE` (`b8f13b0bdb`).
- `downcast<T>(ref)`, `dynamicDowncast<T>(ref)`,
`uncheckedDowncast<T>(ref)` on an lvalue `Ref` / `RefPtr` / `CheckedRef`
/ `CheckedPtr` / `WeakRef` / `WeakPtr` return `T&` / `T*`; only rvalues
return a smart pointer, and a failed `dynamicDowncast` leaves the source
intact (`2edaa07117`, `277305bef9`, `8e7db40c16`). `auto x =
dynamicDowncast<T>(refPtr)` therefore no longer holds a reference, and
`->` on the result of `downcast<T>(ref)` becomes `.`.
- `tuple_zip` returns tuples of references (`183405b4b6`).
- No API changes to `Lock`, `RunLoop`, `URL` (apart from the added
helper), `Vector` (apart from the static `map`) or `RefPtr` itself
beyond annotations.

**g. Build**
- `OptionsMSVC.cmake` forces
`CMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL` with a plain `set()`,
overriding a static-CRT value passed on the command line or by a
toolchain file (`0a75fded40`). In the fork it is only the default, so
the static CRT that Bun passes still wins.
- `bmalloc` public header list: `pas_page_flags.h` removed,
`pas_memory_flavor.h` added (`69e1e79b26`).
- `CombinedDomains.json` moved to `JavaScriptCore_SCRIPTS_DIR`
(`e8c36a19c9`). The prebuilt tarballs still have it at their top level.


---
_Generated by [Claude Code](https://claude.ai/code)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.