Skip to content

Upgrade to upstream WebKit 51cc3feb7298#248

Merged
sosukesuzuki merged 881 commits into
mainfrom
bun/upgrade-to-51cc3feb7298
Jun 4, 2026
Merged

Upgrade to upstream WebKit 51cc3feb7298#248
sosukesuzuki merged 881 commits into
mainfrom
bun/upgrade-to-51cc3feb7298

Conversation

@sosukesuzuki

Copy link
Copy Markdown

Merges upstream WebKit/WebKit main (51cc3fe, 880 commits since 39d4ce1) into the fork.

Conflict resolutions preserve the fork's additions while adopting upstream's changes:

  • JSPromise cross-realm fix (webkit.org/b/316187): rejectPromise/fulfillPromise/performPromiseThenWithInternalMicrotask/reject/fulfill/rejectAsHandled/rejectWithCaughtException dropped their JSGlobalObject* parameter; promise jobs now queue on the promise's own realm. The fork's async-context capture/restore and synchronous module queue logic were re-applied on top of the new signatures.
  • OrderedHashTable.h/OrderedHashTableHelper.h renamed to JSOrderedHashTable.h/JSOrderedHashTableHelper.h upstream; JSMap/JSSet includes updated.
  • queueMicrotask fast/slow path split (queueMicrotaskSlow); the fork's 4-argument overload is kept and routes through the new path.
  • createUndefinedVariableError keeps the fork's "X is not defined" message, now using upstream's OOM-safe tryMakeString structure.
  • JSModuleLoader::innerModuleLoading keeps the fork's iterative worklist implementation with upstream's mechanical signature updates applied.

Note: JSType.h gained SentinelType before ObjectType, shifting all object JSType values by +1. The Bun-side mirror is updated in the corresponding bun PR.

Verified locally: JSC debug build succeeds; full Bun debug build against this tree passes promise/async-context/module smoke tests.

Ahmad-S792 and others added 30 commits June 1, 2026 01:37
… instead of the font-style range

https://bugs.webkit.org/show_bug.cgi?id=315912
rdar://178324521

Reviewed by Vitor Roriz, Brandon Stewart, and Tim Nguyen.

In UnrealizedCoreTextFont::modifyFromContext() the oblique angle was clamped
against the @font-face weight capabilities instead of the slope capabilities,
a copy-paste error. Since the affected faces declare an oblique range but no
weight, the clamp was skipped and the angle was never constrained to the
declared font-style range.

Clamp m_slope against fontFaceCapabilities().slope, matching weight and width.

* LayoutTests/TestExpectations: Progressions
* LayoutTests/platform/glib/TestExpectations: Platform Specific Expectation
* Source/WebCore/platform/graphics/cocoa/UnrealizedCoreTextFont.cpp:
(WebCore::UnrealizedCoreTextFont::modifyFromContext):

Canonical link: https://commits.webkit.org/314280@main
…y crashing

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

Reviewed by Xabier Rodriguez-Calvar.

Make sure the m_frameRate GStreamerIncomingTrackProcessor member variable is initialized. This is a
prospective fix for a flaky crash I cannot reproduce, where the stats collector would attempt to
create a -nan double to an IDLDouble.

* LayoutTests/platform/glib/TestExpectations:
* Source/WebCore/platform/mediastream/gstreamer/GStreamerIncomingTrackProcessor.h:

Canonical link: https://commits.webkit.org/314281@main
https://bugs.webkit.org/show_bug.cgi?id=315751
rdar://178139405

Reviewed by Dan Glastonbury.

This is useful to for example with the test skip added here,
a simulator + debug layers bug.

* Source/ThirdParty/ANGLE/src/common/platform_helpers.h:
(angle::IsIOSSimulator):
* Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests_expectations.txt:
* Source/ThirdParty/ANGLE/src/tests/test_expectations/GPUTestConfig.cpp:
(angle::GPUTestConfig::GPUTestConfig):
* Source/ThirdParty/ANGLE/src/tests/test_expectations/GPUTestConfig.h:
* Source/ThirdParty/ANGLE/src/tests/test_expectations/GPUTestExpectationsParser.cpp:
(angle::GPUTestExpectationsParser::parseLine):

Canonical link: https://commits.webkit.org/314282@main
…-per-second value

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

Reviewed by Xabier Rodriguez-Calvar.

The stats collector expects this caps field to be a double, not unsigned.

* Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp:

Canonical link: https://commits.webkit.org/314283@main
…media-source/mediasource-getvideoplaybackquality.html fails

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

Reviewed by Xabier Rodriguez-Calvar.

Since that commit the video sink GRefPtr is cleared along with the pipeline, so at EOS
updateVideoSinkStatistics() was returning false and no playback quality metrics were reported
anymore. We now attempt to update the stats only if playback hasn't ended yet.

* Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::videoPlaybackQualityMetrics):

Canonical link: https://commits.webkit.org/314284@main
…consistently times out

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

Reviewed by Xabier Rodriguez-Calvar.

The timeout was happening in the penultimate sub-test that calls replaceTrack before generating an
offer. In that situation the outgoing media track bin isn't fully linked and doesn't have a
transceiver yet. The transceiver codec-preferences were not updated so the attempt to link outgoing
sources in the end-point after creating the offer left an unlinked outgoing media track bin, because
the msid SDP attribute wasn't matched properly.

The proposed fix is to iterate over the webrtcbin transceivers after the replaceTrack call and
update a-msid attributes on their codec-preferences caps when appropriate.

* LayoutTests/platform/glib/TestExpectations:
* Source/WebCore/Modules/mediastream/gstreamer/GStreamerMediaEndpoint.cpp:
(WebCore::GStreamerMediaEndpoint::linkOutgoingSources):
(WebCore::GStreamerMediaEndpoint::trackWasReplaced):
* Source/WebCore/Modules/mediastream/gstreamer/GStreamerMediaEndpoint.h:
* Source/WebCore/Modules/mediastream/gstreamer/GStreamerPeerConnectionBackend.cpp:
(WebCore::GStreamerPeerConnectionBackend::trackWasReplaced):
* Source/WebCore/Modules/mediastream/gstreamer/GStreamerPeerConnectionBackend.h:
* Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpSenderBackend.cpp:
(WebCore::GStreamerRtpSenderBackend::replaceTrack):
* Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingMediaSourceGStreamer.cpp:
(WebCore::RealtimeOutgoingMediaSourceGStreamer::replaceTrack):
* Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingMediaSourceGStreamer.h:

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

Reviewed by Nikolas Zimmermann.

When clipping not rounded rects, SkCanvas::clipRect is more efficient.

* Source/WebCore/platform/graphics/skia/SkiaCompositingLayer.cpp:
(WebCore::SkiaCompositingLayer::clipRect):
(WebCore::SkiaCompositingLayer::paintSelf):
(WebCore::SkiaCompositingLayer::paintSelfAndChildren):
(WebCore::SkiaCompositingLayer::paintBackdrop):
* Source/WebCore/platform/graphics/skia/SkiaCompositingLayer.h:

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

Reviewed by Taher Ali.

MathML <a> will have to wait until we support MathMLAnchorElement.

Upstream commit: web-platform-tests/wpt@34637df

Canonical link: https://commits.webkit.org/314287@main
…n in Safari

https://bugs.webkit.org/show_bug.cgi?id=315876
rdar://178277160

Reviewed by Dan Glastonbury.

Mostly mechanical changes so webgpu.github.io/webgpu-samples/?sample=primitivePicking
works in Safari.

Test: fast/webgpu/primitive-index.html

* LayoutTests/fast/webgpu/primitive-index-expected.txt: Added.
* LayoutTests/fast/webgpu/primitive-index.html: Added.
* Source/WebCore/Modules/WebGPU/GPUAdapter.cpp:
(WebCore::convertFeatureNameToEnum):
* Source/WebCore/Modules/WebGPU/GPUFeatureName.h:
(WebCore::convertToBacking):
* Source/WebCore/Modules/WebGPU/GPUFeatureName.idl:
* Source/WebCore/Modules/WebGPU/Implementation/WebGPUConvertToBackingContext.cpp:
(WebCore::WebGPU::ConvertToBackingContext::convertToBacking):
* Source/WebCore/Modules/WebGPU/InternalAPI/WebGPUFeatureName.h:
* Source/WebGPU/WGSL/IOValidator.cpp:
(WGSL::IOValidator::validateBuiltinIO):
* Source/WebGPU/WGSL/Metal/MetalFunctionWriter.cpp:
(WGSL::Metal::FunctionDefinitionWriter::visit):
* Source/WebGPU/WGSL/Parser.cpp:
(WGSL::Parser<Lexer>::parseEnableDirective):
(WGSL::Parser<Lexer>::parseAttribute):
* Source/WebGPU/WGSL/WGSL.cpp:
(WGSL::wgslExtensionToWebGPUFeatureName):
* Source/WebGPU/WGSL/WGSLEnums.h:
* Source/WebGPU/WebGPU/HardwareCapabilities.mm:
(WebGPU::baseFeatures):
* Source/WebGPU/WebGPU/RenderPipeline.mm:
(WebGPU::errorValidatingInterstageShaderInterfaces):
* Source/WebGPU/WebGPU/ShaderModule.h:
* Source/WebGPU/WebGPU/ShaderModule.mm:
(WebGPU::ShaderModule::usesPrimitiveIndexInInput const):
(WebGPU::ShaderModule::populateFragmentInputs):
(wgpuAdapterFeatureName):
* Source/WebGPU/WebGPU/WebGPU.h:
* Source/WebKit/Shared/WebGPU/WebGPUFeatureName.serialization.in:

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

Reviewed by Patrick Griffis.

* Source/WebKit/WPEPlatform/wpe/WPEBufferDMABuf.cpp:
* Source/WebKit/WPEPlatform/wpe/WPEBufferSHM.cpp:
* Source/WebKit/WPEPlatform/wpe/WPEClipboard.cpp:
* Source/WebKit/WPEPlatform/wpe/WPEDisplay.cpp:
* Source/WebKit/WPEPlatform/wpe/WPEEvent.cpp:
* Source/WebKit/WPEPlatform/wpe/WPEGamepadManager.cpp:
(wpe_gamepad_manager_class_init):
* Source/WebKit/WPEPlatform/wpe/WPEGestureController.cpp:
* Source/WebKit/WPEPlatform/wpe/WPEKeymap.h:
* Source/WebKit/WPEPlatform/wpe/WPEScreen.cpp:
* Source/WebKit/WPEPlatform/wpe/WPESettings.h:
* Source/WebKit/WPEPlatform/wpe/WPEToplevel.cpp:
* Source/WebKit/WPEPlatform/wpe/WPEView.cpp:
(wpe_view_class_init):

Canonical link: https://commits.webkit.org/314289@main
…tIndicatorWithAnimation()

<https://bugs.webkit.org/show_bug.cgi?id=309108>
<rdar://167427221>

Reviewed by Anne van Kesteren.

Crashes occur when a `WebPageProxy` object is destroyed when a `WeakPtr`
is used to make a method call since it doesn't keep the object alive.

Promote unsafe `WeakPtr<WebPageProxy>` usage to `RefPtr<WebPageProxy` to
ensure the object stays alive for the duration of the method call.  Also
promote `WeakPtr<WebProcessProxy>` in completion callbacks where the
process object could be destroyed during sandbox extension processing.

* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::loadSimulatedRequest):
(WebKit::WebPageProxy::loadAlternateHTML):
(WebKit::WebPageProxy::reload):
(WebKit::WebPageProxy::executeEditCommand):
(WebKit::WebPageProxy::contextMenuItemSelected):
* Source/WebKit/UIProcess/mac/WebPageProxyMac.mm:
(WebKit::WebPageProxy::didPerformDictionaryLookup):
(WebKit::WebPageProxy::scheduleSetObscuredContentInsetsDispatch):

Originally-landed-as: 305413.397@rapid/safari-7624.2.5.110-branch (79f65b1). rdar://176067210
Canonical link: https://commits.webkit.org/314290@main
rdar://178276637
https://bugs.webkit.org/show_bug.cgi?id=315885

Reviewed by Abrar Rahman Protyasha and Tim Horton.

WebsiteDataStore::soAuthorizationCoordinator() RELEASE_ASSERTs that Extensible
SSO is enabled, but trySOAuthorization() in NavigationState only checked
NavigationAction::shouldPerformSOAuthorization() and the URL scheme handler
before calling it.

That flag is cleared up front in WebPageProxy::decidePolicyForNavigationActionShared()
when the preference is disabled, but the policy decision is resolved asynchronously by
the client, so a client that disables Extensible SSO on a web view after the decision
has begun leaves the flag set from when SSO was still on. trySOAuthorization() then reached
the coordinator and hit the assertion. Re-check the preference at the point of use, matching
the existing WebPageProxy variant.

Test: Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SOAuthorizationTests.mm

* Source/WebKit/UIProcess/Cocoa/NavigationState.mm:
(WebKit::trySOAuthorization):
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SOAuthorizationTests.mm:
(-[TestSOAuthorizationDelegate init]):
(-[TestSOAuthorizationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
(TestWebKitAPI::TEST(SOAuthorizationRedirect, DisableSSODuringPolicyDecision)):

Canonical link: https://commits.webkit.org/314291@main
https://bugs.webkit.org/show_bug.cgi?id=315853
rdar://178251443

Reviewed by Darin Adler.

font: <system-font> (e.g. menu) stamps every font-variant longhand with a
system-font sentinel keyword, for example, font-variant-numeric: menu.

ShorthandSerializer::serializeFontVariant currently returns
the empty string whenever any longhand held that sentinel, so an explicitly-set
longhand such as font-variant-numeric: tabular-nums was dropped from the
shorthand. Therefore only return empty when all longhands are system-font
sentinels, otherwise omit the sentinels and serialize the rest.

This is what the font-variant-serialization WPT asserts and and other
major engines follow.

* Source/WebCore/css/ShorthandSerializer.cpp:
(WebCore::ShorthandSerializer::serializeFontVariant const):
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/parsing/font-variant-serialization-expected.txt:

Canonical link: https://commits.webkit.org/314292@main
…animations/svgpointlist-animation-invalid-value-1.html is a flaky text failure.

https://bugs.webkit.org/show_bug.cgi?id=316006
rdar://178437435

Unreviewed test gardening.

* LayoutTests/platform/mac-wk2/TestExpectations:

Canonical link: https://commits.webkit.org/314293@main
https://bugs.webkit.org/show_bug.cgi?id=316005
rdar://178436125

Reviewed by Yijia Huang.

WasmGC Array and Struct are no longer using cell-types. Remove them.

* Source/JavaScriptCore/heap/Heap.cpp:
(JSC::Heap::Heap):
* Source/JavaScriptCore/heap/Heap.h:

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

Reviewed by Ryosuke Niwa.

createHTMLDocument() used to populate the document with a write() call
without a corresponding close() call. This meant that IsParsingChildren
did not get unset, impacting :last-child and friends. A subtest of
shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-009.html
caught this.

So we re-implement createHTMLDocument() the way the specification
requires. This also impacts readyState (it's now "complete" instead of
"loading") and we take this opportunity to upstream the local tests.

Upstream: web-platform-tests/wpt#60293
Canonical link: https://commits.webkit.org/314295@main
…ests/html/semantics/embedded-content/the-img-element/sizes/sizes-auto-resize-observer-removes-auto.html is a flaky text failure

https://bugs.webkit.org/show_bug.cgi?id=316012
rdar://178442127

Unreviewed test gardening.

* LayoutTests/platform/mac-wk2/TestExpectations:

Canonical link: https://commits.webkit.org/314296@main
… instead of the font-style range in the Skia path

https://bugs.webkit.org/show_bug.cgi?id=315912
rdar://178324521

Reviewed by Tim Nguyen.

FontCustomPlatformData::fontPlatformData() in the Skia port has the same
copy-paste error fixed for the CoreText path in https://commits.webkit.org/314280@main:
the oblique slope was clamped against fontFaceCapabilities().weight instead of
.slope. That fix progressed font-slant-2a and font-slant-2c on cocoa but worked
around the still-broken Skia path by marking both as ImageOnlyFailure in the glib
TestExpectations. Applying the same fix to Skia lets us remove those expectations.

* LayoutTests/platform/glib/TestExpectations:
* Source/WebCore/platform/graphics/skia/FontCustomPlatformDataSkia.cpp:
(WebCore::FontCustomPlatformData::fontPlatformData):

Canonical link: https://commits.webkit.org/314297@main
…sing again

https://bugs.webkit.org/show_bug.cgi?id=315962
rdar://178384586

Reviewed by Tim Horton.

314244@main added some source files to WebCore, but re-serialized the
entire project file in the process. Xcode's serializer likely dropped
the `xros` token from the `platformFilters` of all 33 iOS-family entries
in the "Copy Modern Media Controls Images" build phase.

This re-introduced the visionOS portion of the regression originally
fixed in 314200@main: WebCore.framework on visionOS is once again
missing modern media controls images.

To fix this, we restore `xros` to the platform filters of the affected
entries.

* Source/WebCore/WebCore.xcodeproj/project.pbxproj:

Canonical link: https://commits.webkit.org/314298@main
… flaky text failure.

https://bugs.webkit.org/show_bug.cgi?id=316014
rdar://178443412

Unreviewed test gardening.

* LayoutTests/platform/ios/TestExpectations:
* LayoutTests/platform/mac-wk2/TestExpectations:

Canonical link: https://commits.webkit.org/314299@main
…DFPluginAnnotation, PDFPluginPasswordForm

https://bugs.webkit.org/show_bug.cgi?id=315894
rdar://178298727

Reviewed by Anne van Kesteren.

Use protect(foo) instead of RefPtr {foo } to align with WebKit's transition from
brace-initialized smart pointer temporaries.

No new tests needed.

* Source/WebCore/platform/mediarecorder/MediaRecorderPrivateEncoder.cpp:
(WebCore::MediaRecorderPrivateEncoder::encodePendingVideoFrames):
* Source/WebKit/WebProcess/Plugins/PDF/PDFPluginAnnotation.mm:
(WebKit::PDFPluginAnnotation::attach):
* Source/WebKit/WebProcess/Plugins/PDF/PDFPluginPasswordForm.mm:
(WebKit::PDFPluginPasswordForm::unlockFailed):

Canonical link: https://commits.webkit.org/314300@main
…ml is a flaky crash.

https://bugs.webkit.org/show_bug.cgi?id=316016
rdar://178444089

Unreviewed test gardening.

* LayoutTests/platform/mac-wk2/TestExpectations:

Canonical link: https://commits.webkit.org/314301@main
https://bugs.webkit.org/show_bug.cgi?id=249265
rdar://103573160

Reviewed by Simon Fraser.

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

Merge (Test) & Inspired by: https://chromium.googlesource.com/chromium/blink/+/dd578478d0d2affea98eb5cf59f9f6f525cfd890

When drawing line caps for zero-length subpaths, the path-derived
geometry is the position of the linecap, and not the generated shape.
Hence the non-scaling-stroke transform should be applied to the position
where the line cap shape should be drawn, and not the shape itself.
Previously the transform was applied to the whole cap shape, so a
non-uniform transform (e.g. scale(2,1)) would distort the cap itself -
turning a round cap into an ellipse and a square cap into a rectangle -
which is exactly what vector-effect: non-scaling-stroke should prevent.

This also lets us simplify the code by calling fillRect/fillEllipse
directly instead of going through a temporary Path object, so the
zeroLengthLinecapPath() helper is removed.

NOTE: This patch fixes the bug in both Legacy and Layer based SVG engine.

* Source/WebCore/rendering/svg/RenderSVGPath.cpp:
(WebCore::RenderSVGPath::strokeZeroLengthSubpaths const):
(WebCore::RenderSVGPath::zeroLengthLinecapPath const): Deleted.
* Source/WebCore/rendering/svg/RenderSVGPath.h:
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGPath.cpp:
(WebCore::LegacyRenderSVGPath::strokeZeroLengthSubpaths const):
(WebCore::LegacyRenderSVGPath::zeroLengthLinecapPath const): Deleted.
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGPath.h:
* LayoutTests/svg/custom/non-scaling-stroke-zero-length-subpath-linecaps-expected.html: Added.
* LayoutTests/svg/custom/non-scaling-stroke-zero-length-subpath-linecaps.html: Added.

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

Reviewed by Adrian Perez de Castro.

* Source/WebKit/WPEPlatform/wpe/WPEBufferFormats.cpp:
* Source/WebKit/WPEPlatform/wpe/WPEBufferFormats.h:
* Source/WebKit/WPEPlatform/wpe/WPEInputMethodContext.cpp:
(wpe_input_method_context_class_init):
* Source/WebKit/WPEPlatform/wpe/WPEKeymap.cpp:
* Source/WebKit/WPEPlatform/wpe/WPEToplevel.cpp:
* Source/WebKit/WPEPlatform/wpe/WPEVersion.cpp:
* Source/WebKit/WPEPlatform/wpe/WPEView.cpp:
* Source/WebKit/WPEPlatform/wpe/wayland/WPEViewWayland.cpp:

Canonical link: https://commits.webkit.org/314303@main
…landV3.cpp

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

Reviewed by Adrian Perez de Castro.

Silence missing-field-initializers clang warnings by providing explicit initializers for the action,
language and preedit_hint callbacks.

* Source/WebKit/WPEPlatform/wpe/wayland/WPEInputMethodContextWaylandV3.cpp:

Canonical link: https://commits.webkit.org/314304@main
…Unicode ranges

https://bugs.webkit.org/show_bug.cgi?id=315926
rdar://178330634

Reviewed by Yijia Huang.

Yarr was splitting m_matches / m_ranges / m_matchesUnicode / m_rangesUnicode ranges
previously with ASCII v.s. non-ASCII. But given that we are having Char8
/ Char16, it is more efficient and natural to split them with Latin1
v.s. non-Latin1. This patch changes this. Also we improve addSorted /
addSortedRange for edge cases: we carefully avoid adding singleton range
(only one element) for boundary char code. Also, based on the above
boundary, we rename them to m_matches8, m_ranges8, m_matches32, m_ranges32.

Test: JSTests/stress/regexp-character-class-latin1-boundary.js

* JSTests/stress/regexp-character-class-latin1-boundary.js: Added.
(shouldBe):
(repeat):
* Source/JavaScriptCore/yarr/YarrInterpreter.cpp:
(JSC::Yarr::Interpreter::testCharacterClass):
* Source/JavaScriptCore/yarr/YarrJIT.cpp:
(JSC::Yarr::MaskedAlternativeInfo::computeMaskForCharacterClass):
* Source/JavaScriptCore/yarr/YarrPattern.cpp:
(JSC::Yarr::CharacterClassConstructor::reset):
(JSC::Yarr::CharacterClassConstructor::append):
(JSC::Yarr::CharacterClassConstructor::appendInverted):
(JSC::Yarr::CharacterClassConstructor::putChar):
(JSC::Yarr::CharacterClassConstructor::putCharNonUnion):
(JSC::Yarr::CharacterClassConstructor::putRange):
(JSC::Yarr::CharacterClassConstructor::atomClassStringDisjunction):
(JSC::Yarr::CharacterClassConstructor::invertMatches):
(JSC::Yarr::CharacterClassConstructor::performSetOpWith):
(JSC::Yarr::CharacterClassConstructor::performSetOpWithMatches):
(JSC::Yarr::CharacterClassConstructor::charClass):
(JSC::Yarr::CharacterClassConstructor::addSorted):
(JSC::Yarr::CharacterClassConstructor::addSortedRange):
(JSC::Yarr::CharacterClassConstructor::latin1Op):
(JSC::Yarr::CharacterClassConstructor::latin1Invert):
(JSC::Yarr::CharacterClassConstructor::nonLatin1OpSorted):
(JSC::Yarr::CharacterClassConstructor::nonLatin1Invert):
(JSC::Yarr::CharacterClassConstructor::coalesceTables):
(JSC::Yarr::dumpCharacterClass):
(JSC::Yarr::anycharCreate):
(JSC::Yarr::CharacterClass::hasSharedLeadSurrogate const):
(JSC::Yarr::CharacterClassConstructor::asciiOp): Deleted.
(JSC::Yarr::CharacterClassConstructor::asciiInvert): Deleted.
(JSC::Yarr::CharacterClassConstructor::unicodeOpSorted): Deleted.
(JSC::Yarr::CharacterClassConstructor::unicodeInvert): Deleted.
(JSC::Yarr::CharacterClass::copyOnly8BitCharacterData): Deleted.
* Source/JavaScriptCore/yarr/YarrPattern.h:
(JSC::Yarr::CharacterClass::CharacterClass):
(JSC::Yarr::CharacterClass::hasSingleCharacters const):
(JSC::Yarr::ClassSet::ClassSet):
* Source/JavaScriptCore/yarr/create_regex_tables:
(in):
* Source/JavaScriptCore/yarr/generateYarrUnicodePropertyTables.py:
(PropertyData.addMatch):
(PropertyData.addRange):
(PropertyData.addMatchUnordered):
(PropertyData.addRangeUnordered):
(PropertyData.removeMatch):

Canonical link: https://commits.webkit.org/314305@main
https://bugs.webkit.org/show_bug.cgi?id=316021
rdar://178452080

REGRESSION (314080@main): iOS layout tests failing due to RuntimeError raised: No initialized devices for testing

Reverted change:

    Reduce run-webkit-tests startup overhead for faster iteration
    https://bugs.webkit.org/show_bug.cgi?id=314459
    rdar://176618242
    314080@main (7d4b9ad)

Canonical link: https://commits.webkit.org/314306@main
…ts/css/css-images tests are failing with image diffs

https://bugs.webkit.org/show_bug.cgi?id=316018
rdar://178450586

Unreviewed test gardening

* LayoutTests/platform/ios/TestExpectations:

Canonical link: https://commits.webkit.org/314307@main
https://bugs.webkit.org/show_bug.cgi?id=315988
rdar://178402222

Reviewed by Abrar Rahman Protyasha, Megan Gardner, and Pascoe.

fast/forms/ios/drag-range-track.html is failing on EWS since
touch events are disabled.

Move the test to a more appropriate location where the
test expectations are correct, and rename to the test to
more accurately describe the behavior in question.

* LayoutTests/fast/events/touch/ios/slider-touch-drag-small-thumb-expected.txt: Renamed from LayoutTests/fast/forms/ios/drag-range-track-expected.txt.
* LayoutTests/fast/events/touch/ios/slider-touch-drag-small-thumb.html: Renamed from LayoutTests/fast/forms/ios/drag-range-track.html.

Canonical link: https://commits.webkit.org/314308@main
https://bugs.webkit.org/show_bug.cgi?id=316013
rdar://176988227

Reviewed by Abrar Rahman Protyasha.

This was happening because the mouse tracking gesture recognizer was being recognized when it should
not have been, resulting in a mouse press happening which then clears the selection.

Fix this by blocking the mouse tracking gesture recognizer on the pan gesture recognizer.
Consequently, the pan gesture recognizer needs to be changed to make its activation conditions more
limited.

This also requires special handling of elements such as range inputs to ensure that they still receive
the proper events instead of scrolling happening instead.

This also fixes a latent issue in WKTextSelectionController that was revealed incidentally with the above
changes; the selection should be considered changed if one of the previous or new visual data's is nil.

Tests: Tools/TestWebKitAPI/Tests/WebKit/WebPage/AppKitGesturesTests.swift

* Source/WebCore/html/HTMLInputElement.h:
* Source/WebKit/Shared/Cocoa/InteractionInformationAtPosition.h:
* Source/WebKit/Shared/Cocoa/InteractionInformationAtPosition.mm:
(WebKit::InteractionInformationAtPosition::InteractionInformationAtPosition):
* Source/WebKit/Shared/Cocoa/InteractionInformationAtPosition.serialization.in:
* Source/WebKit/UIProcess/mac/WKAppKitGestureController.mm:
(-[WKAppKitGestureController _dragPressShouldBeginAtLocation:]):
(-[WKAppKitGestureController _panShouldBeginAtLocation:]):
(-[WKAppKitGestureController gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):
(-[WKAppKitGestureController gestureRecognizer:shouldRequireFailureOfGestureRecognizer:]):
(-[WKAppKitGestureController gestureRecognizerShouldBegin:]):
* Source/WebKit/UIProcess/mac/WKTextSelectionController.swift:
(WKTextSelectionController.moveInsertionCursor(to:placeAtWordBoundary:)):
* Source/WebKit/WebProcess/WebPage/Cocoa/PositionInformationForWebPage.mm:
(WebKit::selectionPositionInformation):
* Tools/TestWebKitAPI/Helpers/cocoa/WebPage+JavaScriptExpression.swift:
* Tools/TestWebKitAPI/Resources/cocoa/custom-slider.html: Added.
* Tools/TestWebKitAPI/Tests/WebKit/WebPage/AppKitGesturesTests.swift:
(AppKitGesturesTests.singleClickFiresPointerMouseAndClickEvents(_:)):
(AppKitGesturesTests.scrollingDoesNotRemoveTextSelection):
(AppKitGesturesTests.pressDragOverRangeInputChangesInputValue(_:)):
(AppKitGesturesTests.pressDragOnImageInitiatesDragAndDrop):
(AppKitGesturesTests.pressDragOverRangeInputChangesInputValue): Deleted.

Canonical link: https://commits.webkit.org/314309@main
basuke and others added 23 commits June 3, 2026 16:33
…he crashes the iframe process

https://bugs.webkit.org/show_bug.cgi?id=316114
rdar://178543188

Reviewed by Sihui Liu.

When a cross-site Site Isolation page is held in the back/forward cache via a
SuspendedPageProxy, evicting that cache entry never cleared the cached page in the
iframe processes. WebBackForwardCacheEntry only sent ClearCachedPage to the main
process and to the iframe processes tracked in m_cachedChildren, which is empty for
the cross-site SuspendedPageProxy path. The SuspendedPageProxy teardown then sent a
plain Close to the iframe process, so it ran WebPage::close() with its document still
in the back/forward cache and Page::~Page() asserted (m_rootFrames was not empty).

The cached subframe processes live in one of two places depending on the path: the
in-process cache path records them on WebBackForwardCacheEntry::m_cachedChildren, while
the cross-site path leaves them in the frozen frame tree of the SuspendedPageProxy.
Unify both into a single accessor: SuspendedPageProxy now records the frame item it was
suspended under (suspendedFrameItemID) and exposes its iframe processes, and
WebBackForwardCacheEntry::iframeProcesses() folds those into the m_cachedChildren set.
A new WebBackForwardCacheEntry::allProcesses() adds the main frame process, so the
destructor clears every relevant process through one path.

The destructor sends ClearCachedPage to allProcesses() before m_suspendedPage is
released at the end of the destructor; ~SuspendedPageProxy then sends Close, and IPC is
FIFO per connection, so ClearCachedPage arrives first and the iframe leaves the
back/forward cache cleanly. A SuspendedPageProxy can be shared across same-process
entries, so its frame id may differ from ours; only the entry the page was actually
suspended under (suspendedFrameItemID() == m_backForwardFrameItemID) contributes the
suspended page's iframe processes, other entries do nothing.

This crash is only reachable once MultiProcessBackForwardCacheEnabled is on under Site
Isolation, so the new test enables the preference explicitly.

* Source/WebKit/UIProcess/SuspendedPageProxy.cpp:
(WebKit::SuspendedPageProxy::startSuspension):
(WebKit::SuspendedPageProxy::iframeProcesses):
* Source/WebKit/UIProcess/SuspendedPageProxy.h:
(WebKit::SuspendedPageProxy::suspendedFrameItemID const):
* Source/WebKit/UIProcess/WebBackForwardCacheEntry.cpp:
(WebKit::WebBackForwardCacheEntry::~WebBackForwardCacheEntry):
(WebKit::WebBackForwardCacheEntry::iframeProcesses const):
(WebKit::WebBackForwardCacheEntry::allProcesses const):
* Source/WebKit/UIProcess/WebBackForwardCacheEntry.h:
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm:
(TEST(SiteIsolation, MultiProcessBFCacheCrossSiteEvictionDoesNotCrashIframe)):

Canonical link: https://commits.webkit.org/314507@main
https://bugs.webkit.org/show_bug.cgi?id=257907
rdar://problem/110915794

Reviewed by Nikolas Zimmermann.

Partial Merge: https://chromium.googlesource.com/chromium/src/+/7f43c0d43ff1b00697461a588118d69e8d86238a

<animateMotion> animations specified use the 'path' attribute (or an
<mpath> etc) are not special in any way with respect to the 'rotate'
attribute and its effects.

Refactor SVGAnimateMotionElement::calculateAnimatedValue() so that said
attribute is also applied in the non-path animation case as well.

In addition, this made `RotateMode` as enum class and used it throughout
code and removed `default` handling of RotateMode, since all cases are
handled properly.

* Source/WebCore/svg/SVGAnimateMotionElement.cpp:
(WebCore::SVGAnimateMotionElement::rotateMode const):
(WebCore::SVGAnimateMotionElement::calculateAnimatedValue):
* Source/WebCore/svg/SVGAnimateMotionElement.h:
* LayoutTests/imported/w3c/web-platform-tests/svg/animations/animateMotion-from-to-rotate-auto-expected.txt: Progression

Also added tests covering the degenerate <animateMotion> cases where the
from/to points share a coordinate (fromPoint.y == toPoint.y) or are
identical (zero delta), guarding against a NaN angle out of atan2.

* LayoutTests/imported/w3c/web-platform-tests/svg/animations/animateMotion-from-to-rotate-auto-horizontal-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/animations/animateMotion-from-to-rotate-auto-horizontal.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/animations/animateMotion-from-to-rotate-auto-no-motion-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/animations/animateMotion-from-to-rotate-auto-no-motion.html: Added.

Canonical link: https://commits.webkit.org/314508@main
…form-tests/css/selectors/invalidation/has-complexity.html is a constant TIMEOUT

https://bugs.webkit.org/show_bug.cgi?id=315668
rdar://178056302

Reviewed by Alan Baradlay.

311870@main fixed a part of invalidation code that had not worked at all because an overflowing bitfield.
That exposed a O(n^2) performance issue with sibling combinator style invalidation.

Fix by expanding the existing hasAlreadyMatchedAndMutationIsIrrelevant optimization in ChildChangeInvalidation
to cover sibling combinator visits. Order-insensitive :has() arguments are skipped there entirely since the
changed element's own traversal already covers them. Arguments using only sibling combinators (+/~) are
short-circuited when the mutation is at the end of the element list, where a pre-existing sibling's match is
provably unaffected by it (which also makes the end-of-list removal case linear).

Test: fast/selectors/has-complexity-traversal-count.html
* LayoutTests/fast/selectors/has-complexity-traversal-count-expected.txt: Added.
* LayoutTests/fast/selectors/has-complexity-traversal-count.html: Added.

Add a test that records invalidation traversal counts for the cases tested by has-complexity.html.

* LayoutTests/platform/glib/TestExpectations:
* LayoutTests/platform/mac-wk2/TestExpectations:
* Source/WebCore/style/ChildChangeInvalidation.cpp:
(WebCore::Style::ChildChangeInvalidation::invalidateForChangedElement):
(WebCore::Style::ChildChangeInvalidation::invalidateForHasSiblings):
* Source/WebCore/style/ChildChangeInvalidation.h:
* Source/WebCore/style/StyleScopeRuleSets.cpp:
(WebCore::Style::HasArgumentSiblingInfo::isOrderSensitive const):
(WebCore::Style::HasArgumentSiblingInfo::isStructuralSibling const):
(WebCore::Style::scanHasArgument):
(WebCore::Style::hasArgumentSiblingInfo):
(WebCore::Style::ensureInvalidationRuleSets):
* Source/WebCore/style/StyleScopeRuleSets.h:

Canonical link: https://commits.webkit.org/314509@main
https://bugs.webkit.org/show_bug.cgi?id=316129
rdar://178557623

Reviewed by Pascoe.

The Cocoa CMake build globally suppressed -Wunused-parameter via
-Wno-unused-parameter in OptionsCocoa.cmake, even though -Wall -Wextra
already enables it. Xcode enables the warning everywhere (-Wextra in
CommonBase.xcconfig, treated as an error) and opts specific projects out
per-target via WK_FIXME_WARNING_CFLAGS.

Drop the blanket suppression so WTF, JavaScriptCore, WebCore, and PAL
warn like they do under Xcode, and add per-target opt-outs mirroring the
projects Xcode still exempts: WebKit (already present), WebKitLegacy,
DumpRenderTree, ImageDiff, and MiniBrowser. TestWebKitAPI and
WebKitTestRunner already opt out; the third-party targets build with -w.

WebKitLegacy's existing opt-out used add_compile_options(), which runs
after WEBKIT_FRAMEWORK_DECLARE creates the target and so never applied;
switch it to the target-scoped WEBKIT_ADD_TARGET_CXX_FLAGS form.

* Source/WebKitLegacy/PlatformCocoa.cmake:
* Source/cmake/OptionsCocoa.cmake:
* Tools/DumpRenderTree/PlatformMac.cmake:
* Tools/ImageDiff/PlatformMac.cmake:
* Tools/MiniBrowser/mac/CMakeLists.txt:

Canonical link: https://commits.webkit.org/314510@main
https://bugs.webkit.org/show_bug.cgi?id=315253
rdar://177581560

Reviewed by Wenson Hsieh.

Adds a test-only SPI to inject a UITextAutofillSuggestion into the
focused input, mirroring how a user would pick an autofill credential
from the iOS keyboard. This unblocks layout-test coverage of any code
path that depends on -[WKContentView insertTextSuggestion:]
including autofill IPC routing for cross-origin iframes under site
isolation.

* LayoutTests/fast/forms/ios/insert-autofill-suggestion-expected.txt: Added.
* LayoutTests/fast/forms/ios/insert-autofill-suggestion.html: Added.
* LayoutTests/resources/ui-helper.js:
(window.UIHelper.insertAutofillSuggestion):
* Tools/DumpRenderTree/mac/UIScriptControllerMac.h:
* Tools/DumpRenderTree/mac/UIScriptControllerMac.mm:
(WTR::UIScriptControllerMac::insertAutofillSuggestion):
* Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* Tools/TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::insertAutofillSuggestion):
* Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h:
* Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::insertAutofillSuggestion):

Canonical link: https://commits.webkit.org/314511@main
https://bugs.webkit.org/show_bug.cgi?id=316261
rdar://178664808

Reviewed by Geoffrey Garen.

Use Helpers/ and Helpers/cocoa/ qualified paths for test helper imports
so they resolve under CMake, where (unlike Xcode's hmap) those directories
aren't on the basename search path.

* Tools/TestWebKitAPI/Resources/cocoa/MessagePortSecurity.mm:

Canonical link: https://commits.webkit.org/314512@main
https://bugs.webkit.org/show_bug.cgi?id=316163
rdar://178579821

Reviewed by Yusuke Suzuki and Dan Hecht.

This patch optimizes the layout of InlineCacheHandler to place hot fields within the same
cache line and reduce padding.

Key changes:

- m_next is grouped with other hot fields and the class is made CACHE_LINE_ALIGNED to
ensure hot fields land on one cache line.

- m_structureID is placed as the first field. The instance begins with a hidden 4-byte
refcount, and placing m_structureID first uses the 4 bytes between the refcount and the
first pointer-size field instead of wasting them on padding. Also, m_cacheType and
m_makesJSCalls are placed after the 4-byte m_offset, to use 2 out of 4 bytes of padding
between m_offset and m_uid.

- CACHE_LINE_ALIGNED is moved from Lexer.h to a reusable header CPU.h.

Testing: covered by existing tests.
Canonical link: https://commits.webkit.org/314513@main
…en Site Isolation is active

https://bugs.webkit.org/show_bug.cgi?id=314699
rdar://176944362

Reviewed by Sihui Liu.

The MultiProcessBackForwardCacheEnabled preference has been off-by-default and required to be
toggled on independently from SiteIsolationEnabled. In practice the two features are meant to be
used together: under Site Isolation, BFCache relies on the UIProcess coordination this flag
unlocks (BackForwardCache::addIfCacheable refuses any SI page when the flag is off, per the guard
from bug 313657).

Flip the preference on automatically at page creation time whenever SiteIsolationEnabled is on,
mirroring the existing pattern for UseUIProcessForBackForwardItemLoading in WebProcessPool.

Drop the now-redundant `enableFeature(configuration, @"MultiProcessBackForwardCacheEnabled")`
calls from the SiteIsolation.mm API tests (including GoBackToPageWithIframeBFCache) — every
affected test goes through siteIsolatedViewAndDelegate, which sets up SI, so the preference is
auto-enabled by the new code path.

Adjust SiteIsolation.mm tests whose pre-conditions changed because of the auto-enable:
- DrawAfterNavigateToDomainAgain, IframeRedirectCrossSite: extend the expected frame trees to
  include the cached iframe-process tree that now stays alive through the cross-site nav.
- NavigationWithIFrames: replace waitForDidFinishLoadInSubframe (which doesn't fire on BFCache
  restore) with a frameTreesMatch spin pattern.
- ShutDownFrameProcessesAfterNavigation, GoBackToPageWithIframe, ProcessReuse: turn BFCache off
  via the process pool config (pageCacheEnabled = NO) — the assertions in these tests are about
  pre-BFCache semantics (process teardown, reload-style goBack tree, WebProcessCache reuse
  counted via WebPages) that BFCache deliberately changes.
- siteIsolatedViewWithSharedProcess: disable BFCache on the WebProcessCache process pool
  (EnableProcessCache::Yes) for the same reason — those tests assert process-reuse semantics that
  BFCache would otherwise perturb.
- PostMessageWithMessagePorts: disable BFCache; the test exercises MessagePort delivery across
  site-isolated processes, not BFCache, and the same-site navigation must not cache the page
  holding the port.

Covered by existing SiteIsolation.MultiProcessBFCache* tests plus the adjusted tests above.

* Source/WebKit/UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::createWebPage):
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm:
(siteIsolatedViewWithSharedProcess):
(TEST(SiteIsolation, PostMessageWithMessagePorts)):
(TEST(SiteIsolation, IframeRedirectCrossSite)):
(TEST(SiteIsolation, NavigationWithIFrames)):
(TEST(SiteIsolation, ShutDownFrameProcessesAfterNavigation)):
(TEST(SiteIsolation, DrawAfterNavigateToDomainAgain)):
(TEST(SiteIsolation, GoBackToPageWithIframe)):
(TEST(SiteIsolation, GoBackToPageWithIframeBFCache)):
(TEST(SiteIsolation, ProcessReuse)):

Canonical link: https://commits.webkit.org/314514@main
… 314363@main

https://bugs.webkit.org/show_bug.cgi?id=316226
rdar://178649065

Reviewed by Sihui Liu.

314363@main introduced changes to fix layout test window-open-local-after-network-scheme.sub.html under
site isolation. The !m_shouldReuseMainFrame removal in ProvisionalPageProxy and the coreLocalFrame()
change in WebFrame::commitProvisionalFrame are not needed.

The CommitTiming::Immediately fix handles the about:blank case on its own, and the second call to
takeWindowProxyAndOpenerFrom in commitProvisionalFrame transfers the WindowProxy from remoteFrame to
localFrame unconditionally, and when the frame ID is non-null it is always a different frame, so the
original coreFrame() code was already correct.

* Source/WebKit/UIProcess/ProvisionalPageProxy.cpp:
(WebKit::ProvisionalPageProxy::initializeWebPage):
* Source/WebKit/WebProcess/WebPage/WebFrame.cpp:
(WebKit::WebFrame::commitProvisionalFrame):

Canonical link: https://commits.webkit.org/314515@main
https://bugs.webkit.org/show_bug.cgi?id=316184
rdar://175469152

Reviewed by Jer Noble.

When WebKit's fullscreen video layer is hosted in another process, the UI process and
auxiliary processes should be considered visible for the duration of the fullscreen
presentation. The existing mechanism for visibility propagation (WKVisibilityPropagationView)
relies on the web view being in a visible scene, and while the app hosting the video layer does
propagate a visibility endowment to the UI process, WKVisibilityPropagationView does not further
propagate visibility to the auxiliary processes if the web view itself is not visible.

To address this, introduced LayerHostingVisibilityPropagator. It propagates a hereditary visibility
endowment grant to each auxiliary process for every visibility endowment granted to the UI process.
It also takes a MediaPlayback process assertion on the UI process for the duration of the fullscreen
layer presentation (to account for the lack of a visible scene assertion).

To detect which source environments currently hold the endowment, EndowmentStateTracker now
requests RBSProcessStateValueEndowmentInfos and walks RBSProcessEndowmentInfo entries instead of
just namespaces, allowing it to record the source environment per visibility grant and notify
clients via a new visibilityEndowmentEnvironmentsChanged() callback.

VideoPresentationManagerProxy creates a propagator during fullscreen setup, attaches it to the
VideoPresentationModel, and removes it during cleanup. WKContentView keeps a WeakHashSet of active
propagators and updates them alongside the existing WKVisibilityPropagationViews as auxiliary
processes launch and exit.

* Source/WebKit/Platform/spi/ios/BaseBoardSPI.h:
* Source/WebKit/Platform/spi/ios/RunningBoardServicesSPI.h:
(+[RBSProcessPredicate predicateMatchingHandle:]):
* Source/WebKit/SourcesCocoa.txt:
* Source/WebKit/UIProcess/Cocoa/VideoPresentationManagerProxy.h:
* Source/WebKit/UIProcess/Cocoa/VideoPresentationManagerProxy.mm:
(WebKit::VideoPresentationModelContext::setLayerHostingVisibilityPropagator):
(WebKit::VideoPresentationManagerProxy::setupFullscreenWithID):
(WebKit::VideoPresentationManagerProxy::didCleanupFullscreen):
* Source/WebKit/UIProcess/EndowmentStateTracker.h:
(WebKit::EndowmentStateTrackerClient::visibilityEndowmentEnvironmentsChanged):
(WebKit::EndowmentStateTracker::visibilityEndowmentEnvironments const):
* Source/WebKit/UIProcess/EndowmentStateTracker.mm:
(WebKit::handleForPID):
(WebKit::EndowmentStateTracker::stateFromProcessState):
(WebKit::EndowmentStateTracker::isApplicationForeground):
(WebKit::EndowmentStateTracker::stateForHandle):
(WebKit::EndowmentStateTracker::registerMonitorIfNecessary):
(WebKit::EndowmentStateTracker::ensureState const const):
(WebKit::EndowmentStateTracker::setState):
(): Deleted.
(WebKit::EndowmentStateTracker::stateFromEndowments): Deleted.
* Source/WebKit/UIProcess/PageClient.h:
(WebKit::PageClient::createLayerHostingVisibilityPropagator):
* Source/WebKit/UIProcess/ios/LayerHostingVisibilityPropagator.h: Added.
* Source/WebKit/UIProcess/ios/LayerHostingVisibilityPropagator.mm: Added.
(WebKit::invalidateInjectors):
(WebKit::LayerHostingVisibilityPropagator::create):
(WebKit::LayerHostingVisibilityPropagator::LayerHostingVisibilityPropagator):
(WebKit::LayerHostingVisibilityPropagator::~LayerHostingVisibilityPropagator):
(WebKit::LayerHostingVisibilityPropagator::propagateVisibilityToProcess):
(WebKit::LayerHostingVisibilityPropagator::stopPropagatingVisibilityToProcess):
(WebKit::LayerHostingVisibilityPropagator::clear):
(WebKit::LayerHostingVisibilityPropagator::visibilityEndowmentEnvironmentsChanged):
(WebKit::LayerHostingVisibilityPropagator::refreshInjectorsAtIndex):
* Source/WebKit/UIProcess/ios/PageClientImplIOS.h:
* Source/WebKit/UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::createLayerHostingVisibilityPropagator):
* Source/WebKit/UIProcess/ios/WKContentView.h:
* Source/WebKit/UIProcess/ios/WKContentView.mm:
(-[WKContentView _setupVisibilityPropagationForWebProcess:contextID:]):
(-[WKContentView _removeVisibilityPropagationForWebProcess:]):
(-[WKContentView _setupVisibilityPropagationForGPUProcess]):
(-[WKContentView _setupVisibilityPropagationForModelProcess]):
(-[WKContentView _removeVisibilityPropagationViewForGPUProcess]):
(-[WKContentView _removeVisibilityPropagationViewForModelProcess]):
(-[WKContentView _resetVisibilityPropagation]):
(-[WKContentView _createLayerHostingVisibilityPropagator]):
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:

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

Reviewed by Wenson Hsieh.

When typing Korean 2-Set (두벌식) in modeless mode, the input source uses insertText: with replacementRange:
rather than setMarkedText:. Mail sets _markedTextInputEnabled = YES, which enables inline predictions via
allowsInlinePredictions(). The inline predictions pipeline (NSSpellChecker -> IPC -> showCompletionForCandidate:)
can call setMarkedText: on the main thread while 2-Set Korean's handleEventByInputMethod: XPC round-trip is in
flight - a window where m_collectedKeypressCommands is non-empty.

When setMarkedText: is called during that window, WebViewImpl queues it and sets m_stagedMarkedRange.
2-Set Korean then polls selectedRangeWithCompletionHandler to verify its cursor position. That handler captured
m_stagedMarkedRange and computed: `compositionRange.location + stagedSelectedRange->location` but because only
modeless insertText: had been used so far, the web process has no composition - compositionRange.location is
notFound (SIZE_MAX). Adding any value to SIZE_MAX overflows, producing NSNotFound. The Korean IME interprets
NSNotFound as "cursor unknown" and abandons modeless mode for the rest of the session, causing "셔ㄷ" to be typed
instead of "셛".

This PR fixes the bug by adding compositionRange.location != notFound guard in selectedRangeWithCompletionHandler.

Test: Tools/TestWebKitAPI/Tests/WebKit/WKWebView/mac/WKWebViewMacEditingTests.mm

* Source/WebKit/UIProcess/mac/WebViewImpl.mm:
(WebKit::WebViewImpl::selectedRangeWithCompletionHandler):
* Tools/Scripts/webkitpy/api_tests/allowlist.txt:
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/mac/WKWebViewMacEditingTests.mm:
(TestWebKitAPI::TEST(WKWebViewMacEditingTests, ModelessInputMethodStagingReportsPostKeystrokeCursorAndContent)):
(TestWebKitAPI::TEST(WKWebViewMacEditingTests, ModelessInputMethodStagingToleratesExternalSetMarkedText)):

Canonical link: https://commits.webkit.org/314517@main
…on the new process, and tighten BrowsingContextGroup processMap invariants

https://bugs.webkit.org/show_bug.cgi?id=315787
rdar://178185140

Reviewed by Sihui Liu.

Two related fixes uncovered by the same set of layout tests.

1. File URL approval gap across process swap.
When continueNavigationInNewProcess swaps to a fresh WebContent process, the
new process inherits the page's back/forward list. Once it commits, it can
surface child-frame history items via BackForwardUpdateItem IPC. The per-
process file URL approval gate at WebBackForwardList.cpp:768 then trips
because the new process was only seeded with the top-level navigation URL,
not with iframe URLs in the target back/forward item's frame-state tree.

Add WebProcessProxy::addPreviouslyApprovedFileURLsFromFrameStateTree, which
recursively approves both urlString and originalURLString file URLs in a
FrameState tree on the process. continueNavigationInNewProcess calls it for
navigation.targetItem() (assembled via copyMainFrameStateWithChildren(), since
FrameState::children is cleared by WebBackForwardListFrameItem::setFrameState),
before the new process can send any IPC referencing those URLs.

2. BrowsingContextGroup processMap conflict on data:/empty-site replacement.
A history navigation that swaps to a data: page (which carries an empty
registrable domain) followed by history.back() registers a fresh FrameProcess
for the data: site in a BrowsingContextGroup that already has one. The old
ASSERT in addFrameProcessWithoutInjectingPageContext insisted the existing
entry be terminated; for empty-domain sites that is not the case, and the
ASSERT trips. The same constraint in removeFrameProcess silently overwrote
the wrong entry in Release.

Replace m_processMap.remove with a guarded removal that only fires when the
process is still the current entry for its site, and gate both ASSERTs on a
shared canReplaceFrameProcessInProcessMap helper that recognises terminated
processes and empty-site keys as legitimate replacements.

Tests: Site Isolation copies of existing back/forward navigation layout tests
that use file:// iframes. Each enables SiteIsolationEnabled +
MultiProcessBackForwardCacheEnabled and crashes the UI process via the
WebBackForwardList.cpp MESSAGE_CHECK before this change; each passes after it.
history-back-initial-vs-final-url.html additionally exercises the data: process
swap that triggers the BCG processMap conflict and asserts in Debug builds.

* Source/WebKit/UIProcess/BrowsingContextGroup.cpp:
(WebKit::canReplaceFrameProcessInProcessMap): Added. Returns true when the
existing entry is terminated or its site has an empty registrable domain.
(WebKit::BrowsingContextGroup::addFrameProcessWithoutInjectingPageContext):
ASSERT via the new helper; allow replacement when the helper accepts.
(WebKit::BrowsingContextGroup::removeFrameProcess): ASSERT via the new helper
and only remove the m_processMap entry when this process is still current.
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::continueNavigationInNewProcess): Approve file URLs from
the back-forward target item on newProcess via the new WebProcessProxy helper.
* Source/WebKit/UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::addPreviouslyApprovedFileURLsFromFrameStateTree):
Added. Recursively approve file URLs in a FrameState tree.
* Source/WebKit/UIProcess/WebProcessProxy.h:
* LayoutTests/fast/history/site-isolation/go-back-then-navigate-subframe.html: Added.
* LayoutTests/fast/history/site-isolation/go-back-then-navigate-subframe-expected.txt: Added.
* LayoutTests/fast/history/site-isolation/history-back-initial-vs-final-url.html: Added.
* LayoutTests/fast/history/site-isolation/history-back-initial-vs-final-url-expected.txt: Added.
* LayoutTests/fast/loader/site-isolation/form-state-restore-with-frames.html: Added.
* LayoutTests/fast/loader/site-isolation/form-state-restore-with-frames-expected.txt: Added.

Canonical link: https://commits.webkit.org/314518@main
…l is a flaky text failure

https://bugs.webkit.org/show_bug.cgi?id=316020
rdar://178452109

Reviewed by Tim Horton and Megan Gardner.

This test checked the media control icons after a single rAF, but since
the icons were loaded into `blob: URL` <img>s, they were only committed in
some future rendering update.

To address the flakiness, we wait until at least one icon has committed
a `blob:` mask-image. We bound the wait till 120 frames so as to not
time out in the failing case. To support this test change, we add an
optional maximumFrames argument to the waitForCondition methods in
UIHelper.

* LayoutTests/media/modern-media-controls/icon-service/icon-service-bundle-load.html:
* LayoutTests/platform/mac-wk2/TestExpectations:
* LayoutTests/resources/ui-helper.js:
(window.UIHelper.async waitForCondition):
(window.UIHelper.async waitForConditionAsync):

Canonical link: https://commits.webkit.org/314519@main
…line decode overhead

https://bugs.webkit.org/show_bug.cgi?id=315554
rdar://177927925

Reviewed by Simon Fraser and Kimmo Kinnunen.

The canvas-lines subtest sends any many StrokeLineWithColorAndThickness IPC
messages per frame as possible. Each message incurs stream decode/dispatch
overhead and, on the GPU side, constructs a full Path object only to immediately
detect it's a single line segment and call CGContextStrokeLineSegments. The Path
construction and destruction per message is pure waste.

Buffer up to 64 consecutive single-line strokes in RemoteGraphicsContextProxy
and flush them as a single StrokeLinesWithColorAndThickness batch message. On
the GPU side, the batch handler iterates directly over the lines calling
CGContextStrokeLineSegments without constructing any Path objects, skipping
redundant color/thickness state changes between consecutive lines with matching
attributes.

The existing single-line strokeLine handler is also optimized to call
CGContextStrokeLineSegments directly, bypassing Path construction. To preserve
correctness when stroke state involves a pattern or gradient,
GraphicsContextCG::strokeLine applies the pattern before stroking, and falls
back through GraphicsContext::strokeLine (which routes through strokePath)
when a gradient is set, mirroring the single-line fast path inside strokePath.

Buffering only works if pending lines are flushed before anything observes the
canvas contents. RemoteGraphicsContextProxy::send() always flushes pending
lines first; a private sendRaw() helper performs the IPC without flushing and
is what flushPendingLines() calls, eliminating recursion. RemoteImageBufferProxy::
send/sendSync flush before image-buffer-targeted messages (PutPixelBuffer,
FlushContextSync, CopyNativeImage, etc.). getPixelBuffer flushes explicitly
because its non-mappable branch routes through RemoteRenderingBackendProxy's
connection, bypassing the proxy's own send hooks. recordResourceUse(ImageBuffer&)
flushes the source buffer's pending lines after isCached() confirms the buffer
is one of our proxies, so cross-buffer draws (drawImageBuffer, drawPattern,
clipToImageBuffer, drawFilteredImageBuffer) see its up-to-date contents.

* Source/WebCore/platform/graphics/ColorTypes.h:
(WebCore::PackedColor::RGBA::operator ==):
* Source/WebCore/platform/graphics/PathSegmentData.cpp:
(WebCore::operator<<):
* Source/WebCore/platform/graphics/PathSegmentData.h:
* Source/WebKit/GPUProcess/graphics/PathSegment.serialization.in:
* Source/WebKit/GPUProcess/graphics/RemoteGraphicsContext.cpp:
(WebKit::RemoteGraphicsContext::strokeLinesWithColorAndThickness):
(WebKit::RemoteGraphicsContext::strokeLineWithColorAndThickness): Deleted.
* Source/WebKit/GPUProcess/graphics/RemoteGraphicsContext.h:
* Source/WebKit/GPUProcess/graphics/RemoteGraphicsContext.messages.in:
* Source/WebKit/Scripts/webkit/messages.py:
(types_that_cannot_be_forward_declared):
(headers_for_type):
* Source/WebKit/WebProcess/GPU/graphics/RemoteGraphicsContextProxy.cpp:
(WebKit::RemoteGraphicsContextProxy::send):
(WebKit::RemoteGraphicsContextProxy::save):
(WebKit::RemoteGraphicsContextProxy::restore):
(WebKit::RemoteGraphicsContextProxy::translate):
(WebKit::RemoteGraphicsContextProxy::rotate):
(WebKit::RemoteGraphicsContextProxy::scale):
(WebKit::RemoteGraphicsContextProxy::setCTM):
(WebKit::RemoteGraphicsContextProxy::concatCTM):
(WebKit::RemoteGraphicsContextProxy::setLineCap):
(WebKit::RemoteGraphicsContextProxy::setLineDash):
(WebKit::RemoteGraphicsContextProxy::setLineJoin):
(WebKit::RemoteGraphicsContextProxy::setMiterLimit):
(WebKit::RemoteGraphicsContextProxy::clip):
(WebKit::RemoteGraphicsContextProxy::clipRoundedRect):
(WebKit::RemoteGraphicsContextProxy::clipOut):
(WebKit::RemoteGraphicsContextProxy::clipOutRoundedRect):
(WebKit::RemoteGraphicsContextProxy::clipToImageBuffer):
(WebKit::RemoteGraphicsContextProxy::clipPath):
(WebKit::RemoteGraphicsContextProxy::resetClip):
(WebKit::RemoteGraphicsContextProxy::drawFilteredImageBuffer):
(WebKit::RemoteGraphicsContextProxy::drawGlyphsImmediate):
(WebKit::RemoteGraphicsContextProxy::drawDisplayList):
(WebKit::RemoteGraphicsContextProxy::drawImageBuffer):
(WebKit::RemoteGraphicsContextProxy::drawNativeImage):
(WebKit::RemoteGraphicsContextProxy::drawSystemImage):
(WebKit::RemoteGraphicsContextProxy::drawPattern):
(WebKit::RemoteGraphicsContextProxy::beginTransparencyLayer):
(WebKit::RemoteGraphicsContextProxy::endTransparencyLayer):
(WebKit::RemoteGraphicsContextProxy::drawRect):
(WebKit::RemoteGraphicsContextProxy::drawLine):
(WebKit::RemoteGraphicsContextProxy::drawLinesForText):
(WebKit::RemoteGraphicsContextProxy::drawDotsForDocumentMarker):
(WebKit::RemoteGraphicsContextProxy::drawEllipse):
(WebKit::RemoteGraphicsContextProxy::drawPath):
(WebKit::RemoteGraphicsContextProxy::drawFocusRing):
(WebKit::RemoteGraphicsContextProxy::fillPath):
(WebKit::RemoteGraphicsContextProxy::fillRect):
(WebKit::RemoteGraphicsContextProxy::fillRoundedRect):
(WebKit::RemoteGraphicsContextProxy::fillRectWithRoundedHole):
(WebKit::RemoteGraphicsContextProxy::fillEllipse):
(WebKit::RemoteGraphicsContextProxy::drawVideoFrame):
(WebKit::RemoteGraphicsContextProxy::strokePath):
(WebKit::RemoteGraphicsContextProxy::strokeRect):
(WebKit::RemoteGraphicsContextProxy::strokeEllipse):
(WebKit::RemoteGraphicsContextProxy::bufferLine):
(WebKit::RemoteGraphicsContextProxy::sendPendingDraws):
(WebKit::RemoteGraphicsContextProxy::clearRect):
(WebKit::RemoteGraphicsContextProxy::drawControlPart):
(WebKit::RemoteGraphicsContextProxy::applyStrokePattern):
(WebKit::RemoteGraphicsContextProxy::applyFillPattern):
(WebKit::RemoteGraphicsContextProxy::applyDeviceScaleFactor):
(WebKit::RemoteGraphicsContextProxy::beginPage):
(WebKit::RemoteGraphicsContextProxy::endPage):
(WebKit::RemoteGraphicsContextProxy::setURLForRect):
(WebKit::RemoteGraphicsContextProxy::recordResourceUse):
(WebKit::RemoteGraphicsContextProxy::inlineStrokeStateIfBatchable):
(WebKit::RemoteGraphicsContextProxy::appendStateChangeItemForInlineStrokeIfNecessary): Deleted.
* Source/WebKit/WebProcess/GPU/graphics/RemoteGraphicsContextProxy.h:
(WebKit::RemoteGraphicsContextProxy::sendPendingDrawsIfNecessary):
(WebKit::RemoteGraphicsContextProxy::consumeHasDrawn):
* Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.cpp:
(WebKit::RemoteImageBufferProxy::copyNativeImage const):
(WebKit::RemoteImageBufferProxy::filteredNativeImage):
(WebKit::RemoteImageBufferProxy::getPixelBuffer const):
(WebKit::RemoteImageBufferProxy::putPixelBuffer):
(WebKit::RemoteImageBufferProxy::convertToLuminanceMask):
(WebKit::RemoteImageBufferProxy::transformToColorSpace):
* Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
* Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp:
(WebKit::RemoteRenderingBackendProxy::cachedImageBuffer const):
(WebKit::RemoteRenderingBackendProxy::isCached const): Deleted.
* Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h:
* Source/WebKit/WebProcess/GPU/graphics/RemoteSnapshotRecorderProxy.cpp:
(WebKit::RemoteSnapshotRecorderProxy::drawSnapshotFrame):

Canonical link: https://commits.webkit.org/314520@main
* LayoutTests/TestExpectations:
* LayoutTests/platform/glib/TestExpectations:
* LayoutTests/platform/wpe/TestExpectations:

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

Reviewed by Antti Koivisto.

  <canvas id=c width=300 height=200></canvas>
  <script>
    let ctx = c.getContext("2d");
    ctx.font = "152px serif";
    ctx.textAlign = "center";
    ctx.fillText("\u0BB5", 150, 100);
  </script>

The Tamil glyph (U+0BB5) should be centered horizontally on x=150.
Instead it was left-aligned at x=150 - canvas treated the text as zero
width.

The canvas shaped-text cache reads result.width from
FontCascade::layoutComplexText. That function computed the segment width
as controller.totalAdvance().width() before and after advancing the
ComplexTextController, but totalAdvance() is the full run total - it is
populated up front in the controller's constructor and does not change
across advance() calls. So the difference was always zero for any run
that took the complex shaping path. Pre-cache callers only consumed the
glyph buffer and ignored result.width, so the defect was latent.

The fix mirrors layoutSimpleText: use controller.runWidthSoFar() (the
running tally that grows with each advance() call) instead of
totalAdvance().width(). The simple path already did this correctly via
WidthIterator::runWidthSoFar(), which is why Latin text centered
correctly while Tamil/Devanagari/Arabic/emoji did not.

* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/text/2d.text.draw.align.center.complex-shaping-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/text/2d.text.draw.align.center.complex-shaping.html: Added.
* Source/WebCore/platform/graphics/FontCascade.cpp:
(WebCore::FontCascade::layoutComplexText const):

Canonical link: https://commits.webkit.org/314522@main
…rame-to-top navigations

https://bugs.webkit.org/show_bug.cgi?id=316182
rdar://178591146

Reviewed by Sihui Liu.

When a cross-origin sandboxed iframe with upgrade-insecure-requests does
window.top.location = "http://...", the URL should get upgraded to https but doesn't. The
upgrade logic looks at the target frame's CSP origin set, which only knows about the target
frame's own origin. Since the URL points to the iframe's origin (not the top frame's),
nothing matches.

Check the requesting document's CSP for non-site isolation config. For site isolation, look
up the originating frame's CSP origin set in the UIProcess.

* LayoutTests/imported/w3c/web-platform-tests/upgrade-insecure-requests/link-upgrade.sub.https-expected.txt:
* LayoutTests/platform/ios-site-isolation/TestExpectations:
* Source/WebCore/loader/FrameLoader.cpp:
(WebCore::FrameLoader::changeLocation):
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::receivedNavigationActionPolicyDecision):

Canonical link: https://commits.webkit.org/314523@main
https://bugs.webkit.org/show_bug.cgi?id=316271
rdar://176466427

Reviewed by Abrar Rahman Protyasha.

For some situations we would like to simplify the
proofreading underlines. Use the same styling that
we use for autocorrection.

* Source/WebCore/rendering/TextBoxPainter.cpp:
(WebCore::TextBoxPainter::paintPlatformDocumentMarker):

Canonical link: https://commits.webkit.org/314524@main
https://bugs.webkit.org/show_bug.cgi?id=316282
rdar://178689729

REGRESSION(314513@main): static assertion failed due to requirement 'InlineCacheHandler::offsetOfUid() == 40'

Reverted change:

    [JSC] Optimize the layout of InlineCacheHandler
    https://bugs.webkit.org/show_bug.cgi?id=316163
    rdar://178579821
    314513@main (de82270)

Canonical link: https://commits.webkit.org/314525@main
…d content inset area

rdar://177728093
https://bugs.webkit.org/show_bug.cgi?id=316078

Reviewed by Lily Spiniolas and Simon Fraser.

LocalFrameView::insetClipLayerRect treats the top/left obscured content insets as expanding
the content area outwards, which is correct, and it should treat the bottom/right insets
similarly. Instead it treats them as narrowing the visible content area. This leads to the
clip layer clipping out the bottom/right obscured content inset area.

When Safari is in RTL mode with its sidebar opened from the right, there's a right obscured
content inset for it. If the page can scroll horizontally, part of the page should be shown
under the partially transparent side bar. But the clip layer clips out the right obscured
content inset area (area under the side bar) and nothing gets shown.

Fix this by treating the bottom/right insets as expanding the content area outwards
like top/left insets.

Test: compositing/geometry/frame-clipping-layer-with-bottom-right-inset.html
      compositing/geometry/frame-clipping-layer-with-top-left-inset.html

* LayoutTests/compositing/geometry/frame-clipping-layer-with-bottom-right-inset-expected.txt:
* LayoutTests/compositing/geometry/frame-clipping-layer-with-bottom-right-inset.html:
    - Give bottom/right insets different values to ensure we don't mix them up.
    - Add more cases at different scroll positions (top left, top right, bottom left,
      bottom right.) Print out the layer tree at each position.

* LayoutTests/compositing/geometry/frame-clipping-layer-with-top-left-inset-expected.txt:
* LayoutTests/compositing/geometry/frame-clipping-layer-with-top-left-inset.html:
    - Same changes as compositing/geometry/frame-clipping-layer-with-bottom-right-inset.html.

* Source/WebCore/page/LocalFrameView.cpp:
(WebCore::LocalFrameView::insetClipLayerRect):
* Source/WebCore/page/LocalFrameView.h:
* Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::reconcileScrollingState):
* Source/WebCore/page/scrolling/coordinated/ScrollingTreeFrameScrollingNodeCoordinated.cpp:
(WebCore::ScrollingTreeFrameScrollingNodeCoordinated::repositionRelatedLayers):
* Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
(WebCore::ScrollingTreeFrameScrollingNodeMac::repositionRelatedLayers):
* Source/WebCore/rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::insetClipLayerRect const):

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

Reviewed by Geoffrey Garen.

CMake rules for the Mac currently hard-code an option HAVE_MATERIAL_HOSTING.
They should not hard-code any such options; instead the options to be passed to
the Swift compiler should be worked out the same way as on Xcode builds, which
is by preprocessing Platform* and noting the resulting list of definitions.
That's what this change does. This will ensure the list of HAVE and USE symbols
is appropriate for each different platform.

This also deduplicates the way that -Xcc -D options are passed to Swift based
on the CMake configuration variables.

* Source/WTF/Scripts/generate-platform-args:
(platform_defines_from_dM):
(run_xcode_mode):
(run_cmake_mode):
(main):
* Source/WebKit/CMakeLists.txt:
* Source/WebKit/PlatformIOS.cmake:
* Source/WebKit/PlatformMac.cmake:
* Source/cmake/WebKitMacros.cmake:
* Tools/Scripts/swift/swiftc-wrapper.sh:

Canonical link: https://commits.webkit.org/314527@main
…e site

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

Reviewed by Yusuke Suzuki.

In a VM with multiple JSGlobalObjects, two defects let a foreign realm leak
into observable objects (e.g. the resolving functions passed to an awaited
thenable's then(f, j)):

1. The await fast paths in resolveWithInternalMicrotaskForAsyncAwait and
   resolveWithInternalMicrotask adopted cross-realm vanilla promises directly,
   skipping the intermediate promise that PromiseResolve[1] requires for them.
   Now they require the promise's realm to match the current globalObject, so
   cross-realm promises take the thenable path, whose resolving functions
   re-anchor the realm; cross-realm await now costs one extra microtask,
   matching V8. resolvePromise has no such check in the spec and keeps its
   fast path, but enqueues the thenable job with the promise's realm.

2. Internal microtask handlers used the queue entry's globalObject, which is
   the settle site's realm and can be foreign (e.g. then/catch/finally called
   on a cross-realm promise). Per spec, each job's realm is fixed at creation
   (e.g. Await[2] step 4), so runInternalMicrotask now derives the realm from
   the object each job drives (the generator, the result promise, or the
   module) and passes it to the handlers, following the precedent of
   JSPromise::pipeFrom. fulfillPromise, rejectPromise, and
   performPromiseThenWithInternalMicrotask now anchor on the promise's realm
   instead of taking a globalObject.

V8 behaves correctly in all of these cases. Same-realm fast paths only pay
one extra pointer comparison; same-realm microtask ordering is unchanged and
async/promise microbenchmarks are neutral.

    const other = createGlobalObject();
    other.MainFunction = Function;
    other.subject = somePendingMainRealmPromise;
    new other.Function(`
        (async () => {
            await subject;
            await { then(f) {
                // f.constructor must be this realm's Function,
                // but was MainFunction before this patch.
            } };
        })();
    `)();

[1]: https://tc39.es/ecma262/#sec-promise-resolve
[2]: https://tc39.es/ecma262/#await

Tests: JSTests/stress/cross-realm-await-thenable-resolve-realm.js
       JSTests/stress/cross-realm-promise-internal-reaction-realm.js

* JSTests/stress/cross-realm-await-thenable-resolve-realm.js: Added.
(shouldBe):
(async return):
* JSTests/stress/cross-realm-promise-internal-reaction-realm.js: Added.
(shouldBe):
(makePending):
(makePendingRejection):
(async settles):
(async return):
* Source/JavaScriptCore/runtime/JSMicrotask.cpp:
(JSC::asyncFromSyncIteratorContinueOrDone):
(JSC::promiseFinallyReactionJob):
(JSC::asyncModuleExecutionDone):
(JSC::asyncModuleExecutionResume):
(JSC::promiseResolveWithoutHandlerJob):
(JSC::runInternalMicrotask):
* Source/JavaScriptCore/runtime/JSPromise.cpp:
(JSC::JSPromise::resolvePromise):
(JSC::JSPromise::resolveWithInternalMicrotaskForAsyncAwait):
(JSC::JSPromise::resolveWithInternalMicrotask):

Canonical link: https://commits.webkit.org/314528@main
…3feb7298

# Conflicts:
#	Source/JavaScriptCore/CMakeLists.txt
#	Source/JavaScriptCore/heap/CellContainerInlines.h
#	Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
#	Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.cpp
#	Source/JavaScriptCore/runtime/JSGlobalObject.cpp
#	Source/JavaScriptCore/runtime/JSGlobalObject.h
#	Source/JavaScriptCore/runtime/JSMap.h
#	Source/JavaScriptCore/runtime/JSMicrotask.cpp
#	Source/JavaScriptCore/runtime/JSModuleLoader.cpp
#	Source/JavaScriptCore/runtime/JSOrderedHashTable.h
#	Source/JavaScriptCore/runtime/JSOrderedHashTableHelper.h
#	Source/JavaScriptCore/runtime/JSPromise.cpp
#	Source/JavaScriptCore/runtime/JSPromise.h
#	Source/JavaScriptCore/runtime/JSPromisePrototype.cpp
#	Source/JavaScriptCore/runtime/JSSet.h
#	Source/WebCore/page/QuirksData.h
@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Walkthrough

This PR updates repository and Apple build configuration, adds many JSTests microbenchmarks and stress tests across engine subsystems, and expands Test262 harness and conformance coverage for ArrayBuffer, Atomics, Error stack accessors, and iterator zip behavior.

Changes

Repository and Apple build configuration

Layer / File(s) Summary
Repository metadata and ownership
.gitattributes, .github/CODEOWNERS, .wkdev-sdk-version
Test-file attribution is narrowed, CODEOWNERS mappings are revised for payment, pointer capture, sandbox, and Apple Pay paths, and the wkdev SDK version is bumped.
Apple build and toolchain configuration
CMakeLists.txt, CMakePresets.json, Configurations/CommonBase.xcconfig
iOS sysroot and Swift compiler setup are refactored, the mac preset uses Source/cmake/ninja-wrapper, and shared Apple xcconfig flags add build script fusion and another Swift warning policy.

JSTests microbenchmarks and stress coverage

Layer / File(s) Summary
New microbenchmarks
JSTests/microbenchmarks/*
New microbenchmarks cover array, map, set, regexp, string, typed array, weak collection, BigInt, Intl, and related operations.
Iterator and collection stress tests
JSTests/stress/array-*, JSTests/stress/map-*, JSTests/stress/set-*, JSTests/stress/iterator-*, JSTests/stress/weak-*
Stress tests expand iterator fast-path, mid-iteration, cross-realm, invalidation, helper, weak collection, and collection cloning coverage.
Runtime and JIT regression tests
JSTests/stress/bigint-*, JSTests/stress/dfg-*, JSTests/stress/ftl-*, JSTests/stress/osr-*, JSTests/stress/*
Additional stress coverage targets promises, JIT and GC regressions, array join behavior, property access edge cases, numeric conversion, WebAssembly table growth, and related runtime paths.
Regexp, string, locale, and Temporal tests
JSTests/stress/regexp-*, JSTests/stress/string-*, JSTests/stress/intl-*, JSTests/stress/temporal-*, JSTests/stress/to-locale-*
String, regexp, Intl, locale-casing, and Temporal tests are expanded or adjusted, including many new regexp regression suites and updated Temporal Stage 4 expectations.

Test262 harness and ArrayBuffer or Atomics conformance

Layer / File(s) Summary
Test262 configuration and harness helpers
JSTests/test262/config.yaml, JSTests/test262/harness/*, JSTests/test262/latest-changes-summary.txt
Feature-level skips and harness helpers are updated, including new error-constructor utilities, accessor-property verification helpers, typed-array argument factories, and summary regeneration.
ArrayBuffer immutable and transferToImmutable coverage
JSTests/test262/test/built-ins/ArrayBuffer/...
ArrayBuffer isView coverage is rewired through all typed-array constructors, and new immutable, sliceToImmutable, and transferToImmutable tests cover descriptors, coercion, detachment, resizing, and result contents.
TypedArray and Atomics conformance updates
JSTests/test262/test/built-ins/ArrayIteratorPrototype/..., JSTests/test262/test/built-ins/Atomics/...
Typed-array constructor-argument wiring is updated, immutable-buffer Atomics cases are added, and many non-shared buffer tests switch to typed-array argument factories and revised harness options.

Test262 Error.stack and Iterator zip coverage

Layer / File(s) Summary
Error.stack getter coverage
JSTests/test262/test/built-ins/Error/prototype/stack/getter-*, .../instance-*, .../prop-desc.js
Getter behavior is covered for instances, prototypes, subclasses, proxies, cross-realm receivers, foreign newTarget, and receivers without [[ErrorData]], along with descriptor and enumerability checks.
Error.stack setter coverage
JSTests/test262/test/built-ins/Error/prototype/stack/setter-*
Setter behavior is covered for creation, overwrite, delete round-trips, non-string values, non-extensible and prototype receivers, proxy interactions, cross-realm behavior, and assignment through inherited accessors.
Iterator.zip and zipKeyed tests
JSTests/test262/test/built-ins/Iterator/zip/*, .../zipKeyed/*
Strict completion checks and fresh result container checks are added for Iterator.zip and Iterator.zipKeyed.

Possibly related PRs

  • oven-sh/WebKit#236: Overlaps with the CMakeLists.txt refactor around Swift wrapper selection and iOS sysroot handling.
  • oven-sh/WebKit#231: Touches the same iOS Swift and sysroot configuration areas updated here in CMakeLists.txt and shared Apple build settings.

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

Actionable comments posted: 18

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
JSTests/stress/dataview-bytelength-ic-stub-stack-desync.js (1)

42-45: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a post-transfer assertion to make the regression detectable.

Line 44 computes r after ab.transfer(), but the test never validates the detached-path output. That weakens regression detection for the byteLength IC desync case.

✅ Suggested patch
 ab.transfer();
 
 let r = hot(dv, A, objs);
+if (r[0] !== -1)
+    throw new Error("Expected detached DataView byteLength read to be caught and mapped to -1");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@JSTests/stress/dataview-bytelength-ic-stub-stack-desync.js` around lines 42 -
45, After calling ab.transfer() and computing r with hot(dv, A, objs), add an
explicit assertion that verifies the detached-path output (the value in r) so
the byteLength IC desync regression is detectable; locate the code around
ab.transfer() and the hot(dv, A, objs) call and insert an assertion using the
existing test helpers (e.g., assertEq or assert) to compare r to the expected
result (or expected detached/null value) and fail the test if it differs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@JSTests/stress/checkpoint-exception-handler-during-osr-exit.js`:
- Around line 36-37: The exception assertion condition using exn?.constructor
!== TypeError && exn?.message.indexOf("instanceof") < 0 is wrong and should use
logical OR and safer message access; update the check so it throws when the
exception is not a TypeError OR its message does not include "instanceof"
(change && to ||) and make the message lookup fully optional-chained (e.g., use
exn?.message?.indexOf("instanceof") < 0) while keeping the thrown Error text
("expected TypeError in instanceof") and referring to the same exn and TypeError
identifiers.

In
`@JSTests/stress/ftl-osr-exit-phantom-new-array-with-butterfly-having-a-bad-time-double-hole.js`:
- Around line 7-13: The test mutates Array.prototype[3] inside cb without
guaranteeing restoration; capture the original descriptor via
Object.getOwnPropertyDescriptor(Array.prototype, 3) before defining the custom
getter/setter in cb, wrap the mutation and test body in a try/finally, and in
the finally restore the original descriptor (using Object.defineProperty if
descriptor exists or delete Array.prototype[3] if it was undefined) so
getterCalls/setterCalls cleanup is always performed; apply the same pattern to
the other sites that modify Array.prototype[3] (the other places that define a
custom getter/setter).

In `@JSTests/stress/generator-expression-info-multiwide-remap.js`:
- Around line 16-21: The test currently swallows runtime failures by catching
exceptions from eval(code) and only printing them; change the catch(e) handler
so the exception is rethrown (or the test process terminated) after printing to
ensure failures fail the test — e.g., in the catch(e) for eval(code) call, keep
the print("Error: " + e) but add throw e (or call quit(1)) so runtime errors
don't get silently ignored.

In `@JSTests/stress/intl-canonical-iana-time-zone.js`:
- Around line 90-110: Uncomment and re-enable the Temporal check by replacing
the commented block with a runtime guard: wrap the legacy↔primary pairs test in
an if (typeof Temporal !== "undefined") { ... } so it only runs when Temporal is
available; inside, define the pairs array and iterate over it calling
shouldBeTrue(new Temporal.ZonedDateTime(0n, legacy).equals(new
Temporal.ZonedDateTime(0n, primary))) to exercise ZonedDateTime.prototype.equals
(which uses TimeZoneEquals) and ensure legacy aliases are accepted. Ensure you
reference Temporal.ZonedDateTime, ZonedDateTime.prototype.equals, and the pairs
list exactly as in the diff so the test logic matches the intended assertions.

In `@JSTests/stress/intl-datetimeformat-temporal-formatter-cache.js`:
- Around line 117-120: Replace the current boolean throw-check around
fmtDS.format(plainTime) with a try/catch that captures the thrown exception
(e.g., let err = null; try { fmtDS.format(plainTime); } catch (e) { err = e; })
and then assert the error is a TypeError using the existing test helpers (for
example: shouldBe(err instanceof TypeError, true, "dateStyle + PlainTime must
throw TypeError") or shouldBe(err.name, "TypeError", "...")). Ensure you
reference fmtDS.format and plainTime in the changed block and remove the old
threw boolean-only assertion.

In `@JSTests/stress/map-iterator-fully-packed-table.js`:
- Around line 60-63: The post-done iterator checks currently only assert done
=== true but must also assert value === undefined; update the assertions after
calling it.next() (the variable named after from the iterator it) to include
assert(after.value === undefined, "post-done iterator value") and do the same
for the other iterator's post-done check (the second iterator's after/it pair
around lines 80-82) so both iterators verify value is undefined when done.

In `@JSTests/stress/out-of-memory-while-creating-undefined-variable-error.js`:
- Around line 13-14: The test currently asserts exception.message == "Can't find
variable" which doesn't match this fork's createUndefinedVariableError wording;
update the check on exception.message (in the failing block that throws "FAILED:
" + exception.message) to assert the message contains or ends with "is not
defined" (e.g., use a substring or regex check against "is not defined") so it
matches the fork's createUndefinedVariableError output instead of the upstream
phrase.

In `@JSTests/stress/regexp-alternative-heavy.js`:
- Around line 9-12: The catch blocks that currently do `print(\`    BUILD ERROR:
${e.message}\`); return;` (and the similar prints at the other two catch sites)
swallow failures; replace each caught-error handling by rethrowing the error
(e.g., `throw e;`) or terminating the process with a non-zero status (e.g.,
`quit(1)`), so that the test fails hard on build/compile/runtime errors instead
of silently returning; locate the catch blocks that print "BUILD ERROR:
${e.message}" and change them to rethrow/quit accordingly.

In `@JSTests/stress/regexp-duplicate-named-captures-indices.js`:
- Around line 3-5: The test uses exec on /(?<x>a){2}z|(?<x>b){2}y|c/d with the
input "aac" which doesn't match so m is null; fix by using a matching input such
as "aaz" (or "bby") in the call to exec so m is non-null (i.e. change the
literal passed to exec from "aac" to "aaz") so the subsequent access to
m.indices.groups and the check for "x" will not dereference null.

In `@JSTests/stress/regress-171780137.js`:
- Line 10: Replace the weak negated assertion with two explicit checks: assert
that parsed[sym] === 42 and assert that parsed.foo === undefined. Locate the
current assertion using the symbols parsed and sym and change it to two
assertions (e.g., assert.eq(parsed[sym], 42) and assert.eq(parsed.foo,
undefined) or equivalent assert calls) so the test verifies the exact expected
state.

In `@JSTests/stress/temporal-calendar.js`:
- Around line 2-3: The test file is being unconditionally skipped by the "//@
skip" directive which prevents the new Temporal calendar assertions from
running; remove the "//@ skip" line (or replace it with a conditional skip that
only triggers when IntlDateTimeFormat Temporal support is actually missing) so
the Temporal calendar checks (e.g., the Stage‑4 calendar assertions referencing
toLocaleString) execute during test runs.

In `@JSTests/stress/temporal-duration.js`:
- Around line 2-3: Remove the global test skip (the line containing "//@ skip")
so the Temporal.Duration stress suite runs; instead isolate only the unsupported
toLocaleString assertions by removing or guarding the specific assertions that
call Duration.prototype.toLocaleString (the assertions noted around the
toLocaleString checks previously at lines ~286-288) so those three assertions
are skipped/disabled while keeping the rest of the suite active. Ensure the
global skip remains removed and only the toLocaleString calls
(Temporal.Duration.prototype.toLocaleString assertions) are the ones excluded or
wrapped with a conditional/skip helper.

In `@JSTests/stress/temporal-timezone.js`:
- Around line 2-3: Remove the file-level skip so the Temporal assertions
execute: delete or comment out the literal line "//@ skip" at the top of
JSTests/stress/temporal-timezone.js (the file-level skip that prevents the whole
test from running), leaving the FIXME comment intact so the file runs and the
new Temporal toLocaleString checks are executed.

In `@JSTests/stress/typedarray-forEach-transition.js`:
- Around line 12-14: The failure message drops the index because the Error
constructor is called with two arguments; update the throw in the if (v !==
0xDEAD) branch so the index variable i is included in the error message (e.g.
build a single string by concatenating or using a template literal) so the
thrown Error includes "read stale value at index <i>" for easier debugging.

In
`@JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/argument-coercion.js`:
- Line 246: The typeof comparisons for Symbol are using the bare undefined
instead of the string "undefined", causing the checks around Symbol.toPrimitive
to always be incorrect; update the two conditions that read `typeof Symbol ===
undefined` and `typeof Symbol !== undefined` to use string comparisons (`typeof
Symbol === "undefined"` and `typeof Symbol !== "undefined"`) so the guards
around Symbol.toPrimitive (referenced in the loop that checks
Symbol.toPrimitive) behave correctly.

In
`@JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/this-is-not-object.js`:
- Around line 39-46: The loop over badReceivers indexes entries that can be
undefined when optional features are absent; before accessing badReceivers[i][0]
and [1] (the label/value), guard the lookup by first retrieving the entry (e.g.,
var entry = badReceivers[i]) and skip it if undefined (continue) or only then
extract var label = entry[0]; var value = entry[1]; This ensures
Symbol/BigInt-placeholder undefined entries don't get indexed and the intended
assert.throws path still runs.

In
`@JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToImmutable/this-is-not-object.js`:
- Around line 29-43: The test builds badReceivers with conditional entries that
may be undefined when Symbol/BigInt are missing and then dereferences them in
the loop; filter out those undefined entries before iterating (e.g. replace
iteration over badReceivers with badReceivers =
badReceivers.filter(function(e){return e !== undefined;}) or similar) so the
for-loop that uses label and value (variables from badReceivers[i]) never tries
to access properties of undefined; update the code around the badReceivers
declaration/for loop to perform this filter prior to using label/value.

In `@JSTests/test262/test/built-ins/Atomics/xor/immutable-buffer.js`:
- Around line 32-52: The test currently iterates over all typed array
constructors with testWithAllTypedArrayConstructors which can include
non-Atomics-compatible types; change the iteration to use the helper that
restricts to Atomics-compatible integer typed arrays (e.g.
testWithAtomicsTypedArrayConstructors or testWithIntegerTypedArrayConstructors)
so that TA (the typed array under test) and the Atomics.xor(ta, index, value)
call exercise immutable-buffer write validation specifically; keep the rest of
the test (index/value objects and assertions) unchanged.

---

Outside diff comments:
In `@JSTests/stress/dataview-bytelength-ic-stub-stack-desync.js`:
- Around line 42-45: After calling ab.transfer() and computing r with hot(dv, A,
objs), add an explicit assertion that verifies the detached-path output (the
value in r) so the byteLength IC desync regression is detectable; locate the
code around ab.transfer() and the hot(dv, A, objs) call and insert an assertion
using the existing test helpers (e.g., assertEq or assert) to compare r to the
expected result (or expected detached/null value) and fail the test if it
differs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: fce9a711-f4bf-40b1-bdc5-95664c884be7

📥 Commits

Reviewing files that changed from the base of the PR and between 6d586e2 and cf78490.

📒 Files selected for processing (300)
  • .gitattributes
  • .github/CODEOWNERS
  • .wkdev-sdk-version
  • CMakeLists.txt
  • CMakePresets.json
  • Configurations/CommonBase.xcconfig
  • JSTests/microbenchmarks/array-iterator-fast-entries.js
  • JSTests/microbenchmarks/array-iterator-fast-keys.js
  • JSTests/microbenchmarks/array-iterator-fast-values.js
  • JSTests/microbenchmarks/array-prototype-lastIndexOf-double-large.js
  • JSTests/microbenchmarks/bigint-heap-dec.js
  • JSTests/microbenchmarks/bigint-heap-inc.js
  • JSTests/microbenchmarks/intl-string-tolocalelowercase.js
  • JSTests/microbenchmarks/intl-string-tolocaleuppercase.js
  • JSTests/microbenchmarks/map-clone-large.js
  • JSTests/microbenchmarks/map-clone.js
  • JSTests/microbenchmarks/map-iterator-fast-entries.js
  • JSTests/microbenchmarks/map-iterator-fast-keys.js
  • JSTests/microbenchmarks/map-iterator-fast-values.js
  • JSTests/microbenchmarks/regexp-matchall-digit-cached.js
  • JSTests/microbenchmarks/regexp-matchall-digit-literal.js
  • JSTests/microbenchmarks/regexp-search-digit-cached.js
  • JSTests/microbenchmarks/regexp-search-digit-literal.js
  • JSTests/microbenchmarks/set-clone-large.js
  • JSTests/microbenchmarks/set-clone.js
  • JSTests/microbenchmarks/set-iterator-fast-entries.js
  • JSTests/microbenchmarks/set-iterator-fast-keys.js
  • JSTests/microbenchmarks/set-iterator-fast-values.js
  • JSTests/microbenchmarks/string-from-code-point.js
  • JSTests/microbenchmarks/string-iterator-for-of-ascii.js
  • JSTests/microbenchmarks/string-iterator-for-of-surrogate-pairs.js
  • JSTests/microbenchmarks/string-iterator-spread-surrogate-pairs.js
  • JSTests/microbenchmarks/string-matchall-digit-short.js
  • JSTests/microbenchmarks/string-matchall-letter-short.js
  • JSTests/microbenchmarks/string-search-digit-short.js
  • JSTests/microbenchmarks/typed-array-allocate-float64-variable-length.js
  • JSTests/microbenchmarks/typed-array-allocate-int32-constant-512.js
  • JSTests/microbenchmarks/typed-array-allocate-uint8-variable-length.js
  • JSTests/microbenchmarks/weak-map-constructor-empty.js
  • JSTests/microbenchmarks/weak-set-constructor-empty.js
  • JSTests/stress/array-iterator-fast-cross-realm.js
  • JSTests/stress/array-iterator-fast-ftl.js
  • JSTests/stress/array-iterator-fast-iterator-proto-symbol-iterator-overridden.js
  • JSTests/stress/array-iterator-fast-keys-values-entries.js
  • JSTests/stress/array-iterator-fast-mid-iteration.js
  • JSTests/stress/array-iterator-fast-multi-mode-cross-realm-prototype.js
  • JSTests/stress/array-iterator-fast-non-array-iterated-object.js
  • JSTests/stress/array-iterator-fast-own-symbol-iterator-on-instance.js
  • JSTests/stress/array-iterator-fast-watchpoint-invalidate-next.js
  • JSTests/stress/array-iterator-fast-watchpoint-invalidate-symbol-iterator.js
  • JSTests/stress/array-join-dfg-empty-separator.js
  • JSTests/stress/array-join-dfg-object-separator-tostring-once.js
  • JSTests/stress/array-join-dfg-string-separator.js
  • JSTests/stress/array-join-dfg-tostring-mutation.js
  • JSTests/stress/array-join-dfg-undefined-separator.js
  • JSTests/stress/array-join-dfg-untyped-separator.js
  • JSTests/stress/array-join-tostring-adds-indexed-prototype-property.js
  • JSTests/stress/array-prototype-valueOf-override-should-not-break-toPrimitive.js
  • JSTests/stress/b3cppi-ssa-dominance.js
  • JSTests/stress/baseline-op-del-by-id-write-barrier.js
  • JSTests/stress/baseline-op-del-by-val-write-barrier.js
  • JSTests/stress/bigint-in-place-thresholds.js
  • JSTests/stress/bigint-inc-dec-in-place.js
  • JSTests/stress/checkpoint-exception-handler-during-osr-exit.js
  • JSTests/stress/create-many-realms.js
  • JSTests/stress/cross-realm-await-thenable-resolve-realm.js
  • JSTests/stress/cross-realm-promise-internal-reaction-realm.js
  • JSTests/stress/cross-realm-promise-microtask-ordering.js
  • JSTests/stress/dataview-bytelength-ic-stub-stack-desync.js
  • JSTests/stress/decouple-calllinkinfo-from-access-case.js
  • JSTests/stress/dfg-boolean-to-number-known-boolean-use-via-iterator-fast-path.js
  • JSTests/stress/dfg-ensure-absence-dictionary-then-property.js
  • JSTests/stress/dfg-ensure-absence-own-then-property.js
  • JSTests/stress/dfg-new-typed-array-with-size-zero-fill.js
  • JSTests/stress/direct-eval-cache-rope.js
  • JSTests/stress/fixobviousspills-earlydefs.js
  • JSTests/stress/ftl-materialize-new-array-with-butterfly.js
  • JSTests/stress/ftl-osr-exit-phantom-new-array-with-butterfly-having-a-bad-time-double-hole.js
  • JSTests/stress/ftl-osr-exit-phantom-new-array-with-butterfly-having-a-bad-time-int32-hole.js
  • JSTests/stress/ftl-osr-exit-phantom-new-array-with-butterfly-having-a-bad-time.js
  • JSTests/stress/generator-expression-info-multiwide-remap.js
  • JSTests/stress/get-by-id-constant-fold-dictionary-head-shadow-property.js
  • JSTests/stress/get-by-val-double-subscript-out-of-uint32-range.js
  • JSTests/stress/growable-sharedarraybuffer-parallel-grow-during-prototype-methods.js
  • JSTests/stress/intl-canonical-iana-time-zone.js
  • JSTests/stress/intl-datetimeformat-temporal-formatter-cache.js
  • JSTests/stress/iterator-fast-path-mode-mixing.js
  • JSTests/stress/iterator-helpers-fast-path-drain-and-reentrancy.js
  • JSTests/stress/iterator-helpers-set-entries-exception-check.js
  • JSTests/stress/iterator-prototype-forEach-map-set-iterator-close.js
  • JSTests/stress/iterator-prototype-includes.js
  • JSTests/stress/jsonp-large-array-index.js
  • JSTests/stress/map-iterator-fast-cross-realm.js
  • JSTests/stress/map-iterator-fast-ftl.js
  • JSTests/stress/map-iterator-fast-iterator-proto-symbol-iterator-overridden.js
  • JSTests/stress/map-iterator-fast-keys-values-entries.js
  • JSTests/stress/map-iterator-fast-mid-iteration.js
  • JSTests/stress/map-iterator-fast-watchpoint-invalidate-next.js
  • JSTests/stress/map-iterator-fast-watchpoint-invalidate-symbol-iterator.js
  • JSTests/stress/map-iterator-fully-packed-table.js
  • JSTests/stress/map-set-clone-large-table.js
  • JSTests/stress/map-set-for-of-fast-iterator-storage.js
  • JSTests/stress/new-weak-map-weak-set-dfg.js
  • JSTests/stress/number-tostring-methods-out-of-range-arguments.js
  • JSTests/stress/osr-exit-scratch-buffer-gc.js
  • JSTests/stress/out-of-memory-while-creating-undefined-variable-error.js
  • JSTests/stress/parseint-large-result-int32-boxing.js
  • JSTests/stress/proxy-revoke.js
  • JSTests/stress/regexp-alternative-heavy.js
  • JSTests/stress/regexp-bol-optimize-out-of-stack.js
  • JSTests/stress/regexp-character-class-latin1-boundary.js
  • JSTests/stress/regexp-combined-large.js
  • JSTests/stress/regexp-deep-nested.js
  • JSTests/stress/regexp-duplicate-named-captures-indices.js
  • JSTests/stress/regexp-fixedcount-zero-length-content-backtrack.js
  • JSTests/stress/regexp-greedy-nested-quantifier-backtrack.js
  • JSTests/stress/regexp-greedy-varcount-minfail.js
  • JSTests/stress/regexp-greedy-varcount-multialt.js
  • JSTests/stress/regexp-heavy-mixed.js
  • JSTests/stress/regexp-large-quantifier.js
  • JSTests/stress/regexp-lookahead-heavy.js
  • JSTests/stress/regexp-multialt-content-backtracking.js
  • JSTests/stress/regexp-nongreedy-varcount-content-backtrack.js
  • JSTests/stress/regexp-quantify-atom-copy-term-out-of-stack.js
  • JSTests/stress/regexp-unicode-case-insensitive-ascii-range-canonical-set.js
  • JSTests/stress/regexp-variable-count-native.js
  • JSTests/stress/regexp-variable-counted-parentheses-with-min.js
  • JSTests/stress/regress-159954.js
  • JSTests/stress/regress-168411205.js
  • JSTests/stress/regress-171780137.js
  • JSTests/stress/set-iterator-fast-cross-realm.js
  • JSTests/stress/set-iterator-fast-ftl.js
  • JSTests/stress/set-iterator-fast-iterator-proto-symbol-iterator-overridden.js
  • JSTests/stress/set-iterator-fast-keys-values-entries.js
  • JSTests/stress/set-iterator-fast-mid-iteration.js
  • JSTests/stress/set-iterator-fast-watchpoint-invalidate-next.js
  • JSTests/stress/set-iterator-fast-watchpoint-invalidate-symbol-iterator.js
  • JSTests/stress/stack-overflow-regexp.js
  • JSTests/stress/string-at-cse-array-mode.js
  • JSTests/stress/string-from-code-point-intrinsic.js
  • JSTests/stress/string-from-code-point-out-of-range.js
  • JSTests/stress/string-iterator-fast-path.js
  • JSTests/stress/string-iterator-surrogate-pairs.js
  • JSTests/stress/string-prototype-matchall-edge-cases.js
  • JSTests/stress/string-prototype-matchall-species-constructor.js
  • JSTests/stress/string-prototype-matchall-tostring-once.js
  • JSTests/stress/string-prototype-matchall-tostring-recompiles-regexp.js
  • JSTests/stress/string-prototype-matchall-watchpoint-invalidation.js
  • JSTests/stress/string-prototype-search-edge-cases.js
  • JSTests/stress/string-prototype-search-strength-reduction.js
  • JSTests/stress/string-prototype-search-watchpoint-invalidation.js
  • JSTests/stress/temporal-calendar.js
  • JSTests/stress/temporal-duration.js
  • JSTests/stress/temporal-plaindate.js
  • JSTests/stress/temporal-plaindatetime.js
  • JSTests/stress/temporal-plainmonthday.js
  • JSTests/stress/temporal-plaintime.js
  • JSTests/stress/temporal-plainyearmonth.js
  • JSTests/stress/temporal-timezone.js
  • JSTests/stress/to-locale-case-root-fast-path.js
  • JSTests/stress/typedarray-forEach-transition.js
  • JSTests/stress/wasm-funcref-table-grow-gc-marking-gap.js
  • JSTests/stress/weak-map-weak-set-lazy-buffer.js
  • JSTests/stress/yarr-jit-shared-lead-prefilter.js
  • JSTests/test262/config.yaml
  • JSTests/test262/expectations.yaml
  • JSTests/test262/harness/assert.js
  • JSTests/test262/harness/nativeErrors.js
  • JSTests/test262/harness/propertyHelper.js
  • JSTests/test262/harness/proxyTrapsHelper.js
  • JSTests/test262/harness/sta.js
  • JSTests/test262/harness/temporalHelpers.js
  • JSTests/test262/harness/testTypedArray.js
  • JSTests/test262/latest-changes-summary.txt
  • JSTests/test262/test/built-ins/ArrayBuffer/isView/arg-is-typedarray-buffer.js
  • JSTests/test262/test/built-ins/ArrayBuffer/isView/arg-is-typedarray-constructor.js
  • JSTests/test262/test/built-ins/ArrayBuffer/isView/arg-is-typedarray-subclass-instance.js
  • JSTests/test262/test/built-ins/ArrayBuffer/isView/arg-is-typedarray.js
  • JSTests/test262/test/built-ins/ArrayBuffer/isView/invoked-as-a-fn.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/immutable/prop-desc.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/immutable/return-immutable.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/immutable/this-has-no-arraybufferdata-internal.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/immutable/this-is-not-object.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/immutable/this-is-sharedarraybuffer.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/argument-coercion.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/modify-source-after-return.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/not-a-constructor.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/prop-desc.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/this-becomes-detached.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/this-grows.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/this-has-no-arraybufferdata-internal.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/this-is-not-detached.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/this-is-not-object.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/this-is-sharedarraybuffer.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/this-shrinks.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToImmutable/new-length-coercion.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToImmutable/not-a-constructor.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToImmutable/prop-desc.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToImmutable/this-has-no-arraybufferdata-internal.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToImmutable/this-is-not-detachable.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToImmutable/this-is-not-object.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToImmutable/this-is-sharedarraybuffer.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToImmutable/to-larger.js
  • JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToImmutable/to-same-or-smaller.js
  • JSTests/test262/test/built-ins/ArrayIteratorPrototype/next/detach-typedarray-in-progress.js
  • JSTests/test262/test/built-ins/Atomics/add/bad-range.js
  • JSTests/test262/test/built-ins/Atomics/add/bigint/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/add/good-views.js
  • JSTests/test262/test/built-ins/Atomics/add/immutable-buffer.js
  • JSTests/test262/test/built-ins/Atomics/add/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/add/non-shared-int-views-throws.js
  • JSTests/test262/test/built-ins/Atomics/and/bad-range.js
  • JSTests/test262/test/built-ins/Atomics/and/bigint/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/and/good-views.js
  • JSTests/test262/test/built-ins/Atomics/and/immutable-buffer.js
  • JSTests/test262/test/built-ins/Atomics/and/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/and/non-shared-int-views-throws.js
  • JSTests/test262/test/built-ins/Atomics/compareExchange/bad-range.js
  • JSTests/test262/test/built-ins/Atomics/compareExchange/bigint/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/compareExchange/good-views.js
  • JSTests/test262/test/built-ins/Atomics/compareExchange/immutable-buffer.js
  • JSTests/test262/test/built-ins/Atomics/compareExchange/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/compareExchange/non-shared-int-views-throws.js
  • JSTests/test262/test/built-ins/Atomics/exchange/bad-range.js
  • JSTests/test262/test/built-ins/Atomics/exchange/bigint/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/exchange/good-views.js
  • JSTests/test262/test/built-ins/Atomics/exchange/immutable-buffer.js
  • JSTests/test262/test/built-ins/Atomics/exchange/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/exchange/non-shared-int-views-throws.js
  • JSTests/test262/test/built-ins/Atomics/exchange/nonshared-int-views.js
  • JSTests/test262/test/built-ins/Atomics/isLockFree/bigint/expected-return-value.js
  • JSTests/test262/test/built-ins/Atomics/load/bad-range.js
  • JSTests/test262/test/built-ins/Atomics/load/bigint/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/load/good-views.js
  • JSTests/test262/test/built-ins/Atomics/load/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/load/non-shared-int-views-throws.js
  • JSTests/test262/test/built-ins/Atomics/notify/immutable-buffer-returns-0.js
  • JSTests/test262/test/built-ins/Atomics/or/bad-range.js
  • JSTests/test262/test/built-ins/Atomics/or/bigint/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/or/good-views.js
  • JSTests/test262/test/built-ins/Atomics/or/immutable-buffer.js
  • JSTests/test262/test/built-ins/Atomics/or/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/or/non-shared-int-views-throws.js
  • JSTests/test262/test/built-ins/Atomics/store/bad-range.js
  • JSTests/test262/test/built-ins/Atomics/store/bigint/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/store/good-views.js
  • JSTests/test262/test/built-ins/Atomics/store/immutable-buffer.js
  • JSTests/test262/test/built-ins/Atomics/store/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/store/non-shared-int-views-throws.js
  • JSTests/test262/test/built-ins/Atomics/sub/bad-range.js
  • JSTests/test262/test/built-ins/Atomics/sub/bigint/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/sub/good-views.js
  • JSTests/test262/test/built-ins/Atomics/sub/immutable-buffer.js
  • JSTests/test262/test/built-ins/Atomics/sub/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/sub/non-shared-int-views-throws.js
  • JSTests/test262/test/built-ins/Atomics/xor/bad-range.js
  • JSTests/test262/test/built-ins/Atomics/xor/bigint/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/xor/good-views.js
  • JSTests/test262/test/built-ins/Atomics/xor/immutable-buffer.js
  • JSTests/test262/test/built-ins/Atomics/xor/non-shared-bufferdata.js
  • JSTests/test262/test/built-ins/Atomics/xor/non-shared-int-views-throws.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/getter-cross-realm.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/getter-data-property-shadows.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/getter-error-as-prototype.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/getter-error-instance.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/getter-error-prototype.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/getter-foreign-new-target.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/getter-no-error-data.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/getter-not-a-constructor.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/getter-receiver-is-proxy.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/getter-subclass.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/getter-this-not-object.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/instance-no-own-stack.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/instance-not-enumerable.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/prop-desc.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-creates-own-property.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-cross-realm.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-delete-round-trip.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-empty-string.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-existing-own-property.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-no-argument.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-non-error-receiver.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-non-extensible-receiver.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-non-string-value.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-non-writable-stack.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-not-a-constructor.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-own-accessor.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-proxy-trap-rejects.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-proxy-trap-throws.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-proxy-wrapping-prototype.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-receiver-is-null-proto.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-receiver-is-other-prototype.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-receiver-is-prototype.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-receiver-is-proxy.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-this-not-object.js
  • JSTests/test262/test/built-ins/Error/prototype/stack/setter-via-assignment.js
  • JSTests/test262/test/built-ins/Iterator/zip/iterator-zip-iteration-strict-checks-remaining-done.js
  • JSTests/test262/test/built-ins/Iterator/zip/result-arrays-are-fresh.js
  • JSTests/test262/test/built-ins/Iterator/zipKeyed/iterator-zip-iteration-strict-checks-remaining-done.js
  • JSTests/test262/test/built-ins/Iterator/zipKeyed/result-objects-are-fresh.js
💤 Files with no reviewable changes (3)
  • JSTests/test262/test/built-ins/Atomics/isLockFree/bigint/expected-return-value.js
  • JSTests/test262/test/built-ins/Atomics/exchange/nonshared-int-views.js
  • JSTests/stress/proxy-revoke.js

Comment on lines +36 to +37
if (exn?.constructor !== TypeError && exn?.message.indexOf("instanceof") < 0) {
throw new Error("expected TypeError in instanceof");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix exception assertion logic (&& should be ||) and guard message access.

This condition currently accepts wrong exceptions when either side happens to pass. It should fail if the exception is not a TypeError or the message does not mention instanceof. Also make message access fully optional-chained.

Suggested patch
-if (exn?.constructor !== TypeError && exn?.message.indexOf("instanceof") < 0) {
+if (exn?.constructor !== TypeError || exn?.message?.indexOf("instanceof") < 0) {
     throw new Error("expected TypeError in instanceof");
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (exn?.constructor !== TypeError && exn?.message.indexOf("instanceof") < 0) {
throw new Error("expected TypeError in instanceof");
if (exn?.constructor !== TypeError || exn?.message?.indexOf("instanceof") < 0) {
throw new Error("expected TypeError in instanceof");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@JSTests/stress/checkpoint-exception-handler-during-osr-exit.js` around lines
36 - 37, The exception assertion condition using exn?.constructor !== TypeError
&& exn?.message.indexOf("instanceof") < 0 is wrong and should use logical OR and
safer message access; update the check so it throws when the exception is not a
TypeError OR its message does not include "instanceof" (change && to ||) and
make the message lookup fully optional-chained (e.g., use
exn?.message?.indexOf("instanceof") < 0) while keeping the thrown Error text
("expected TypeError in instanceof") and referring to the same exn and TypeError
identifiers.

Comment on lines +7 to +13
function cb() {
if (trigger) {
Object.defineProperty(Array.prototype, 3, {
get() { getterCalls++; return 42; },
set(value) { setterCalls++; },
configurable: true
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Ensure Array.prototype[3] is always cleaned up.

This test mutates Array.prototype but never guarantees restoration. If a run aborts mid-file, prototype pollution can affect later tests in the same process.

Suggested fix
 trigger = true;
-let a = opt(true);
+let a;
+try {
+    a = opt(true);

 // After having a bad time, the rematerialized Array uses SlowPutArrayStorage and index 3 must be
 // a hole at the OSR exit. The subsequent a[3] = 4.4 store in baseline code must therefore be
 // forwarded to the Array.prototype setter instead of creating an own property.
 if (a.hasOwnProperty(3))
@@
 if (a.hasOwnProperty(3) || a[3] !== 42)
     throw new Error("after reverse, index 3 should still be a hole reading 42 from the getter, got: " + a[3]);
-gc();
+    gc();
+} finally {
+    delete Array.prototype[3];
+}

Also applies to: 42-44, 70-70

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@JSTests/stress/ftl-osr-exit-phantom-new-array-with-butterfly-having-a-bad-time-double-hole.js`
around lines 7 - 13, The test mutates Array.prototype[3] inside cb without
guaranteeing restoration; capture the original descriptor via
Object.getOwnPropertyDescriptor(Array.prototype, 3) before defining the custom
getter/setter in cb, wrap the mutation and test body in a try/finally, and in
the finally restore the original descriptor (using Object.defineProperty if
descriptor exists or delete Array.prototype[3] if it was undefined) so
getterCalls/setterCalls cleanup is always performed; apply the same pattern to
the other sites that modify Array.prototype[3] (the other places that define a
custom getter/setter).

Comment on lines +16 to +21
try {
eval(code);
print("Done");
} catch(e) {
print("Error: " + e);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Do not swallow runtime failures in this regression test.

The catch block only prints, so eval(code) failures won’t fail the test and regressions can slip through.

Suggested fix
-try {
-    eval(code);
-    print("Done");
-} catch(e) {
-    print("Error: " + e);
-}
+eval(code);
+print("Done");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
eval(code);
print("Done");
} catch(e) {
print("Error: " + e);
}
eval(code);
print("Done");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@JSTests/stress/generator-expression-info-multiwide-remap.js` around lines 16
- 21, The test currently swallows runtime failures by catching exceptions from
eval(code) and only printing them; change the catch(e) handler so the exception
is rethrown (or the test process terminated) after printing to ensure failures
fail the test — e.g., in the catch(e) for eval(code) call, keep the
print("Error: " + e) but add throw e (or call quit(1)) so runtime errors don't
get silently ignored.

Comment on lines +90 to +110
// Temporal.ZonedDateTime uses the same hashmap-backed TimeZoneID lookup as Intl, so
// legacy aliases must also be accepted there. ZonedDateTime.prototype.equals() uses
// TimeZoneEquals internally, which recognises legacy ↔ primary as the same timezone.
// FIXME: ZonedDateTime — test via Temporal.ZonedDateTime once implemented.
// if (typeof Temporal !== "undefined") {
// const pairs = [
// ["Asia/Calcutta", "Asia/Kolkata"],
// ["America/Buenos_Aires", "America/Argentina/Buenos_Aires"],
// ["Europe/Kiev", "Europe/Kyiv"],
// ["Asia/Katmandu", "Asia/Kathmandu"],
// ["US/Pacific", "America/Los_Angeles"],
// ["GB", "Europe/London"],
// ["Brazil/East", "America/Sao_Paulo"],
// ["UCT", "UTC"],
// ["Etc/UTC", "UTC"],
// ["Zulu", "UTC"],
// ];
// for (const [legacy, primary] of pairs) {
// shouldBeTrue(new Temporal.ZonedDateTime(0n, legacy).equals(new Temporal.ZonedDateTime(0n, primary)));
// }
// }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Re-enable the Temporal behavior check with a runtime guard instead of commented code.

This block is currently inert, so the claimed Temporal.ZonedDateTime.prototype.equals() observability is not tested and regressions can slip through.

Proposed fix
-// FIXME: ZonedDateTime — test via Temporal.ZonedDateTime once implemented.
-// if (typeof Temporal !== "undefined") {
-//     const pairs = [
-//         ["Asia/Calcutta",          "Asia/Kolkata"],
-//         ["America/Buenos_Aires",   "America/Argentina/Buenos_Aires"],
-//         ["Europe/Kiev",            "Europe/Kyiv"],
-//         ["Asia/Katmandu",          "Asia/Kathmandu"],
-//         ["US/Pacific",             "America/Los_Angeles"],
-//         ["GB",                     "Europe/London"],
-//         ["Brazil/East",            "America/Sao_Paulo"],
-//         ["UCT",                    "UTC"],
-//         ["Etc/UTC",                "UTC"],
-//         ["Zulu",                   "UTC"],
-//     ];
-//     for (const [legacy, primary] of pairs) {
-//         shouldBeTrue(new Temporal.ZonedDateTime(0n, legacy).equals(new Temporal.ZonedDateTime(0n, primary)));
-//     }
-// }
+if (typeof Temporal !== "undefined"
+    && Temporal.ZonedDateTime
+    && typeof Temporal.ZonedDateTime.prototype.equals === "function") {
+    const pairs = [
+        ["Asia/Calcutta", "Asia/Kolkata"],
+        ["America/Buenos_Aires", "America/Argentina/Buenos_Aires"],
+        ["Europe/Kiev", "Europe/Kyiv"],
+        ["Asia/Katmandu", "Asia/Kathmandu"],
+        ["US/Pacific", "America/Los_Angeles"],
+        ["GB", "Europe/London"],
+        ["Brazil/East", "America/Sao_Paulo"],
+        ["UCT", "UTC"],
+        ["Etc/UTC", "UTC"],
+        ["Zulu", "UTC"],
+    ];
+    for (const [legacy, primary] of pairs)
+        shouldBeTrue(new Temporal.ZonedDateTime(0n, legacy).equals(new Temporal.ZonedDateTime(0n, primary)));
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Temporal.ZonedDateTime uses the same hashmap-backed TimeZoneID lookup as Intl, so
// legacy aliases must also be accepted there. ZonedDateTime.prototype.equals() uses
// TimeZoneEquals internally, which recognises legacy ↔ primary as the same timezone.
// FIXME: ZonedDateTime — test via Temporal.ZonedDateTime once implemented.
// if (typeof Temporal !== "undefined") {
// const pairs = [
// ["Asia/Calcutta", "Asia/Kolkata"],
// ["America/Buenos_Aires", "America/Argentina/Buenos_Aires"],
// ["Europe/Kiev", "Europe/Kyiv"],
// ["Asia/Katmandu", "Asia/Kathmandu"],
// ["US/Pacific", "America/Los_Angeles"],
// ["GB", "Europe/London"],
// ["Brazil/East", "America/Sao_Paulo"],
// ["UCT", "UTC"],
// ["Etc/UTC", "UTC"],
// ["Zulu", "UTC"],
// ];
// for (const [legacy, primary] of pairs) {
// shouldBeTrue(new Temporal.ZonedDateTime(0n, legacy).equals(new Temporal.ZonedDateTime(0n, primary)));
// }
// }
if (typeof Temporal !== "undefined"
&& Temporal.ZonedDateTime
&& typeof Temporal.ZonedDateTime.prototype.equals === "function") {
const pairs = [
["Asia/Calcutta", "Asia/Kolkata"],
["America/Buenos_Aires", "America/Argentina/Buenos_Aires"],
["Europe/Kiev", "Europe/Kyiv"],
["Asia/Katmandu", "Asia/Kathmandu"],
["US/Pacific", "America/Los_Angeles"],
["GB", "Europe/London"],
["Brazil/East", "America/Sao_Paulo"],
["UCT", "UTC"],
["Etc/UTC", "UTC"],
["Zulu", "UTC"],
];
for (const [legacy, primary] of pairs)
shouldBeTrue(new Temporal.ZonedDateTime(0n, legacy).equals(new Temporal.ZonedDateTime(0n, primary)));
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@JSTests/stress/intl-canonical-iana-time-zone.js` around lines 90 - 110,
Uncomment and re-enable the Temporal check by replacing the commented block with
a runtime guard: wrap the legacy↔primary pairs test in an if (typeof Temporal
!== "undefined") { ... } so it only runs when Temporal is available; inside,
define the pairs array and iterate over it calling shouldBeTrue(new
Temporal.ZonedDateTime(0n, legacy).equals(new Temporal.ZonedDateTime(0n,
primary))) to exercise ZonedDateTime.prototype.equals (which uses
TimeZoneEquals) and ensure legacy aliases are accepted. Ensure you reference
Temporal.ZonedDateTime, ZonedDateTime.prototype.equals, and the pairs list
exactly as in the diff so the test logic matches the intended assertions.

Comment on lines +117 to +120
// dateStyle + PlainTime must throw (no overlap).
let threw = false;
try { fmtDS.format(plainTime); } catch (e) { threw = true; }
shouldBe(threw, true, "dateStyle + PlainTime must throw TypeError");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Per current Intl.DateTimeFormat + Temporal behavior, should new Intl.DateTimeFormat("en-US", { dateStyle: "short" }).format(new Temporal.PlainTime(...))throwTypeError?

💡 Result:

Yes, calling new Intl.DateTimeFormat("en-US", { dateStyle: "short" }).format(new Temporal.PlainTime(...)) should throw a TypeError [1]. According to the Intl.DateTimeFormat specification regarding Temporal types, the options provided must be compatible with the object being formatted [2][3]. Specifically, when the dateStyle option is specified, the DateTimeFormat instance is restricted to formatting objects that contain date components, such as Temporal.PlainDate, Temporal.PlainYearMonth, or Temporal.PlainMonthDay [2][3]. Conversely, to format a Temporal.PlainTime object, the instance must be configured with timeStyle or relevant time component options [2][3]. Because Temporal.PlainTime does not contain date information, attempting to format it using an Intl.DateTimeFormat instance configured with dateStyle (which implicitly requires date components) results in an error [1]. Technical documentation and TC39 discussions confirm that this mismatch between the formatting options and the Temporal type's available data leads to a TypeError [1].

Citations:


Assert TypeError explicitly for dateStyle + PlainTime.

dateStyle config is incompatible with Temporal.PlainTime (no date fields), so formatting should throw a TypeError—the test should capture the error and assert its type instead of only checking that something threw.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@JSTests/stress/intl-datetimeformat-temporal-formatter-cache.js` around lines
117 - 120, Replace the current boolean throw-check around
fmtDS.format(plainTime) with a try/catch that captures the thrown exception
(e.g., let err = null; try { fmtDS.format(plainTime); } catch (e) { err = e; })
and then assert the error is a TypeError using the existing test helpers (for
example: shouldBe(err instanceof TypeError, true, "dateStyle + PlainTime must
throw TypeError") or shouldBe(err.name, "TypeError", "...")). Ensure you
reference fmtDS.format and plainTime in the changed block and remove the old
threw boolean-only assertion.

Comment on lines +12 to +14
if (v !== 0xDEAD) {
throw new Error("read stale value at index ", i);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix dropped index in failure message.

At Line 13, new Error("read stale value at index ", i) drops i, so failures lose the index context.

Suggested patch
-            throw new Error("read stale value at index ", i);
+            throw new Error(`read stale value at index ${i}`);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (v !== 0xDEAD) {
throw new Error("read stale value at index ", i);
}
if (v !== 0xDEAD) {
throw new Error(`read stale value at index ${i}`);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@JSTests/stress/typedarray-forEach-transition.js` around lines 12 - 14, The
failure message drops the index because the Error constructor is called with two
arguments; update the throw in the if (v !== 0xDEAD) branch so the index
variable i is included in the error message (e.g. build a single string by
concatenating or using a template literal) so the thrown Error includes "read
stale value at index <i>" for easier debugging.

"sliceToImmutable" + reprArgs("toString", "toString") + " calls");

badEndToString = true;
if (typeof Symbol === undefined || !Symbol.toPrimitive) continue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Incorrect typeof comparison with undefined.

Lines 246 and 361 compare the result of typeof Symbol (which is a string) directly with undefined (not a string). This will never work as intended.

Line 246: typeof Symbol === undefined should be typeof Symbol === "undefined"
Line 361: typeof Symbol !== undefined should be typeof Symbol !== "undefined"

The current code at line 246 will always be false, potentially skipping Symbol.toPrimitive tests even when Symbol is available.

🔧 Proposed fix
-    if (typeof Symbol === undefined || !Symbol.toPrimitive) continue;
+    if (typeof Symbol === "undefined" || !Symbol.toPrimitive) continue;
-  if (typeof Symbol !== undefined && Symbol.toPrimitive) {
+  if (typeof Symbol !== "undefined" && Symbol.toPrimitive) {

Also applies to: 361-361

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/argument-coercion.js`
at line 246, The typeof comparisons for Symbol are using the bare undefined
instead of the string "undefined", causing the checks around Symbol.toPrimitive
to always be incorrect; update the two conditions that read `typeof Symbol ===
undefined` and `typeof Symbol !== undefined` to use string comparisons (`typeof
Symbol === "undefined"` and `typeof Symbol !== "undefined"`) so the guards
around Symbol.toPrimitive (referenced in the loop that checks
Symbol.toPrimitive) behave correctly.

Comment on lines +39 to +46
typeof Symbol === "undefined" ? undefined : ["unique symbol", Symbol("1")],
typeof Symbol === "undefined" || !Symbol.for ? undefined : ["registered symbol", Symbol.for("1")],
typeof BigInt === "undefined" ? undefined : ["bigint", BigInt(1)]
];

for (var i = 0; i < badReceivers.length; i++) {
var label = badReceivers[i][0];
var value = badReceivers[i][1];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Guard optional-feature placeholders before indexing.

When Symbol or BigInt is unavailable, entries become undefined, but Line 45/Line 46 index them unconditionally. That throws before the intended assert.throws path.

Suggested fix
 for (var i = 0; i < badReceivers.length; i++) {
+  if (!badReceivers[i]) continue;
   var label = badReceivers[i][0];
   var value = badReceivers[i][1];
   calls = [];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@JSTests/test262/test/built-ins/ArrayBuffer/prototype/sliceToImmutable/this-is-not-object.js`
around lines 39 - 46, The loop over badReceivers indexes entries that can be
undefined when optional features are absent; before accessing badReceivers[i][0]
and [1] (the label/value), guard the lookup by first retrieving the entry (e.g.,
var entry = badReceivers[i]) and skip it if undefined (continue) or only then
extract var label = entry[0]; var value = entry[1]; This ensures
Symbol/BigInt-placeholder undefined entries don't get indexed and the intended
assert.throws path still runs.

Comment on lines +29 to +43
var badReceivers = [
["undefined", undefined],
["null", null],
["number", 42],
["string", "1"],
["true", true],
["false", false],
typeof Symbol === "undefined" ? undefined : ["unique symbol", Symbol("1")],
typeof Symbol === "undefined" || !Symbol.for ? undefined : ["registered symbol", Symbol.for("1")],
typeof BigInt === "undefined" ? undefined : ["bigint", BigInt(1)]
];

for (var i = 0; i < badReceivers.length; i++) {
var label = badReceivers[i][0];
var value = badReceivers[i][1];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Filter optional receiver entries before iterating.

Line 42/Line 43 can dereference undefined when Symbol or BigInt is unavailable, causing this test to fail for the wrong reason.

Suggested fix
 var badReceivers = [
   ["undefined", undefined],
   ["null", null],
   ["number", 42],
   ["string", "1"],
   ["true", true],
   ["false", false],
   typeof Symbol === "undefined" ? undefined : ["unique symbol", Symbol("1")],
   typeof Symbol === "undefined" || !Symbol.for ? undefined : ["registered symbol", Symbol.for("1")],
   typeof BigInt === "undefined" ? undefined : ["bigint", BigInt(1)]
-];
+].filter(Boolean);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var badReceivers = [
["undefined", undefined],
["null", null],
["number", 42],
["string", "1"],
["true", true],
["false", false],
typeof Symbol === "undefined" ? undefined : ["unique symbol", Symbol("1")],
typeof Symbol === "undefined" || !Symbol.for ? undefined : ["registered symbol", Symbol.for("1")],
typeof BigInt === "undefined" ? undefined : ["bigint", BigInt(1)]
];
for (var i = 0; i < badReceivers.length; i++) {
var label = badReceivers[i][0];
var value = badReceivers[i][1];
var badReceivers = [
["undefined", undefined],
["null", null],
["number", 42],
["string", "1"],
["true", true],
["false", false],
typeof Symbol === "undefined" ? undefined : ["unique symbol", Symbol("1")],
typeof Symbol === "undefined" || !Symbol.for ? undefined : ["registered symbol", Symbol.for("1")],
typeof BigInt === "undefined" ? undefined : ["bigint", BigInt(1)]
].filter(Boolean);
for (var i = 0; i < badReceivers.length; i++) {
var label = badReceivers[i][0];
var value = badReceivers[i][1];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToImmutable/this-is-not-object.js`
around lines 29 - 43, The test builds badReceivers with conditional entries that
may be undefined when Symbol/BigInt are missing and then dereferences them in
the loop; filter out those undefined entries before iterating (e.g. replace
iteration over badReceivers with badReceivers =
badReceivers.filter(function(e){return e !== undefined;}) or similar) so the
for-loop that uses label and value (variables from badReceivers[i]) never tries
to access properties of undefined; update the code around the badReceivers
declaration/for loop to perform this filter prior to using label/value.

Comment on lines +32 to +52
testWithAllTypedArrayConstructors(function(TA, makeCtorArg) {
var calls = [];
var index = {
valueOf() {
calls.push("index.valueOf");
return 0;
}
};
var value = {
valueOf() {
calls.push("value.valueOf");
return 1;
}
};

var ta = new TA(makeCtorArg(8));
assert.throws(TypeError, function() {
Atomics.xor(ta, index, value);
});
assert.compareArray(calls, []);
}, null, ["immutable"]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Constrain constructor coverage to Atomics-compatible typed arrays.

At Line 32, testWithAllTypedArrayConstructors can include non-integer typed arrays, which may throw TypeError for the wrong reason and dilute this immutable-buffer assertion. Use an Atomics-compatible constructor helper/set so the failure specifically exercises immutable buffer write validation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@JSTests/test262/test/built-ins/Atomics/xor/immutable-buffer.js` around lines
32 - 52, The test currently iterates over all typed array constructors with
testWithAllTypedArrayConstructors which can include non-Atomics-compatible
types; change the iteration to use the helper that restricts to
Atomics-compatible integer typed arrays (e.g.
testWithAtomicsTypedArrayConstructors or testWithIntegerTypedArrayConstructors)
so that TA (the typed array under test) and the Atomics.xor(ta, index, value)
call exercise immutable-buffer write validation specifically; keep the rest of
the test (index/value objects and assertions) unchanged.

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

Preview Builds

Commit Release Date
cf784902 autobuild-preview-pr-248-cf784902 2026-06-04 08:39:54 UTC

@sosukesuzuki sosukesuzuki merged commit 5851d47 into main Jun 4, 2026
48 checks passed
Jarred-Sumner pushed a commit to oven-sh/bun that referenced this pull request Jun 16, 2026
> [!NOTE]
> [oven-sh/WebKit#248](oven-sh/WebKit#248) is
merged and `WEBKIT_VERSION` now points at the release
`autobuild-5851d4722e461bae1eb5537b091f4103e192a94a`. Ready to merge
once CI is green.

## Bun-side changes

- `src/jsc/JSType.rs`: added `Sentinel` and shifted all object JSType
values by +1 (upstream added `SentinelType` before `ObjectType`)
- C++ bindings: dropped the `JSGlobalObject*` argument from
`JSPromise::reject`/`fulfill`/`rejectAsHandled`/`rejectWithCaughtException`
call sites (upstream cross-realm fix changed the signatures)
- `bindings.cpp`: `OrderedHashTableHelper.h` →
`JSOrderedHashTableHelper.h` (upstream header rename)

# WebKit upgrade: `39d4ce1f12ea` → `51cc3feb7298`

155 commits touching `Source/JavaScriptCore`, `Source/WTF`, and
`Source/bmalloc`.

## Highlights (Bun-relevant)

- **`JSType.h` changed — `src/jsc/JSType.rs` must be updated.** "[JSC]
Add foundation of handling builtin iterators in fast-iteration-protocol"
(`3d1bebd7930d`,
[315933](https://bugs.webkit.org/show_bug.cgi?id=315933)) adds
`SentinelType` immediately before `ObjectType`, shifting the numeric
value of `ObjectType` and every JSType after it by one.
- **JSPromise API signature changes.** "[JSC] Promise jobs must not run
with the realm of a cross-realm settle site" (`51cc3feb7298`,
[316187](https://bugs.webkit.org/show_bug.cgi?id=316187)):
`rejectPromise`, `fulfillPromise`,
`performPromiseThenWithInternalMicrotask`, `reject`, `fulfill`, and
`rejectWithCaughtException` no longer take a `JSGlobalObject*` — promise
jobs are now queued on the promise's own realm via `JSPromise::realm()`.
Any embedder code calling these APIs needs the `globalObject` argument
dropped.
- **Header rename: `OrderedHashTable.h` → `JSOrderedHashTable.h`** (and
`OrderedHashTableHelper.h` → `JSOrderedHashTableHelper.h`), "Unreviewed,
just making JSC::OrderedHashTable => JSC::JSOrderedHashTable"
(`54982d6c532d`,
[315420](https://bugs.webkit.org/show_bug.cgi?id=315420)).
- **`queueMicrotask` fast/slow path split.** "[JSC] Fold microtask
queueing slow path condition to m_canFastQueueMicrotask"
(`e88edb51fd50`,
[315743](https://bugs.webkit.org/show_bug.cgi?id=315743)) introduces
`JSGlobalObject::queueMicrotaskSlow`; the fast path checks a single
`m_canFastQueueMicrotask` flag.
- **Undefined-variable error message OOM hardening** (`69ec4dddc261`,
[315603](https://bugs.webkit.org/show_bug.cgi?id=315603)) —
`createUndefinedVariableError` now uses `tryMakeString` (interacts with
Bun's custom "X is not defined" message).
- **Module loader cleanup**: `ModuleRegistryEntry` error fields merged
(`198caec02193`,
[315001](https://bugs.webkit.org/show_bug.cgi?id=315001)) — touches the
module registry that Bun's synchronous module loading builds on.

## New language / runtime features

- Temporal: `Intl.DateTimeFormat` Temporal support and `toLocaleString`
(`5745eb4c8ff1`,
[315637](https://bugs.webkit.org/show_bug.cgi?id=315637));
`Temporal.Calendar` object removed, JS layer updated to Stage 4 spec
(`b35d67a6fdad`,
[315608](https://bugs.webkit.org/show_bug.cgi?id=315608));
`TemporalTimeZone` made destructible (`4f41ed450183`); third-party
license files for `temporal_rs` / `icu4x` (`3555ec26edc7`).
- `Iterator.prototype.includes` throws RangeError when `skippedElements
> Number.MAX_SAFE_INTEGER` (`40a1acb199d9`,
[315920](https://bugs.webkit.org/show_bug.cgi?id=315920)).

## Performance

- Fast iteration protocol for builtin iterators: foundation
(`3d1bebd7930d`), String fast iteration (`4a781308731b`,
[315330](https://bugs.webkit.org/show_bug.cgi?id=315330)), Map/Set
iterators handled in DFG (`300fd8c35ee7`,
[316074](https://bugs.webkit.org/show_bug.cgi?id=316074)), iterator
storage set at creation in DFG/FTL (`0206365a0d08`).
- `String#matchAll` (`31e38187aad2`) and `String#search`
(`c800622bab89`) moved to C++.
- New DFG nodes: `ArrayJoin` (`26b192b1d624`), `String.fromCodePoint`
(`93a4fbeda183`), `NewWeakMap`/`NewWeakSet` (`d61d43e680e1`) with inline
cell allocation (`8317f5c80ed4`).
- BigInt: in-place `JSBigInt` for inc/dec (`9923753ca3b3`) and
small-size calculations (`c60baa450f96`).
- Map/Set: `gcSafeMemcpy` fast path for cloning large Maps/Sets
(`253bd0c20582`); `JSOrderedHashTable` over-allocation fix
(`f72ea56abf5c`); Set prototype cleanup via `forEachInSetStorage`
(`6d826ae9d949`).
- Intl: per-unit number formatter cache in `Intl.DurationFormat`
(`7e34b0157828`); language-tag canonicalization cache in `IntlCache`
(`99cab5c03916`); root-locale fast path for
`toLocaleLowerCase`/`toLocaleUpperCase` (`e14189a28e4c`).
- Strings: improved rope-string comparison (`e8eb62b22193`);
`WTF::reverseFindDouble` for `Array#lastIndexOf` (`9a9fa471589e`).
- FTL stack overflow check moved to prologue (`1b422914d55f`,
[172456](https://bugs.webkit.org/show_bug.cgi?id=172456)).
- `ownPropertyKeys` returns CoW arrays in the common case
(`a5760beba07c`).
- YARR: variable-count parentheses in YarrJIT (`6646c49f2a7b`,
[307145](https://bugs.webkit.org/show_bug.cgi?id=307145)); shared
lead-surrogate optimization (`6eff2e74e048`).
- `NewTypedArrayWithSize` zero-fills 8 bytes at a time (`dcc2aea406e0`).

## Correctness / security fixes

- Cross-realm promise realm fix (`51cc3feb7298`, see Highlights).
- YARR: NonGreedy backtracking fix (`95d80761e676`,
[316180](https://bugs.webkit.org/show_bug.cgi?id=316180)); `putRange()`
missing Unicode canonical equivalents U+017F/U+212A (`faf717c136d1`);
named group omitted from `indices.groups` on backtrack (`e1cdfab158f3`,
[312688](https://bugs.webkit.org/show_bug.cgi?id=312688)).
- DFG: `GetByStatus::computeFor` must not constant-fold prototype loads
on dictionary structures (`73689f543082`); dictionary structures
rejected in `tryEnsureAbsence` (`177d2cad35bf`, `78c04ea7a1bc`); object
allocation sinking `PutByVal` fix (`cdfa73fdc391`); `StringAt` CSE
arrayMode fix (`1f4e4caab01b`); no bytecode advance when reifying inline
frames at a checkpoint (`4e802a14cac6`).
- Array: `Array.prototype.join` skipping prototype elements added during
`toString` (`f181acea4464`); rematerialization preserving double-array
holes when "having a bad time" (`a82eb9dd7fab`, `eba64ef44de3`);
`ClonedArguments::copyToArguments` loop condition with non-zero offset
(`5099a4a8958e`); Array `ToPrimitive` fast path ignoring `valueOf`
override (`8a7e39c2bf81`).
- `matchAll` fast path must not skip `SpeciesConstructor` when the
species watchpoint is invalidated (`66b61320dbd7`); missing exception in
`replaceAllWithCacheUsingRegExpSearchThreeArguments` (`18a2c9a10033`).
- Map/Set iterator fast path: `IteratorClose` on callback throw
(`87547f94b76e`); missing exception check in Set fast path
(`b67282ad890b`).
- Proxy construct trap throws `TypeError` from the current realm per
spec (`26cc47d853a8`).
- UB fix in double-to-int conversions (`3825a1a93bbf`).
- Concurrency: `WaiterListManager::unregister` data race
(`21ab50e40f06`); `JSLock m_hasOwnerThread` concurrency issue
(`aed1fddc0be2`); `RegExp::byteCodeCompileIfNecessary` made threadsafe
(`dcf25ed3c992`).
- Wasm: `Table.grow` with default value (`36a3e59badd1`); missing
exception check after rope resolution (`57df341619ed`);
`WebAssemblyCompileOptions::tryCreate` OOM throw (`d8b63073f0c5`);
`Wasm::InstanceAnchor` unregistration order (`76b34686210f`).
- B3/Air: `AirFixObviousSpills` early-def modeling (`fa0214fe9a50`);
dominance analysis in `B3CanonicalizePrePostIncrements`
(`81aa535db3c9`).
- Baseline write barrier handling in `OpDelBy{Id,Val}` (`1cdc540e6ebe`).

## GC / memory

- OSR exits' `ScratchBuffer`s are now scanned (`87b4375777a3`,
[309599](https://bugs.webkit.org/show_bug.cgi?id=309599)).
- GC safety for sunk contiguous array materialization in FTL
(`e638840dd2cd`).
- GC deferred while using the direct-eval `CacheLookupKey`
(`32f1bfb84129`).
- Structure-heap reservation scales with physical memory
(`cffeaa6ccbf4`).
- libpas: guard page in front of the compact-heap reservation
(`ba26b5242151`); `pas_enumerator_create` validity check
(`ed57dc0915ee`).
- Removed unused WasmGC cell-types (`b9019a00056e`).

## WTF / build

- `WTF::Variant` GCC 15 build fix (`3917eb489bf7`); `std::to_array()` →
`WTF::toArray()` (`f1df550f3723`).
- Unified/jumbo build work: larger bundles (`8916f524a78a`), @cost
weighting (`9816b1440ae4`), prefix-header tuning (`9238babac42c`) —
source of many `#include`-style churn conflicts.
- "Apply C-preprocessor to JS builtin files" landed (`17e27ee7cfd3`)
then was reverted (`8ed5bbe28206`); JS builtins for `next()` restored
(`0047d9699435`).
- JIT helper threads get `QOS_UTILITY` on less powerful devices
(`371f7ad0ed89`).
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.