Skip to content

Upgrade to WebKit 39d4ce1f12ea#236

Merged
sosukesuzuki merged 425 commits into
mainfrom
bun/upgrade-to-39d4ce1f12ea
May 22, 2026
Merged

Upgrade to WebKit 39d4ce1f12ea#236
sosukesuzuki merged 425 commits into
mainfrom
bun/upgrade-to-39d4ce1f12ea

Conversation

@sosukesuzuki
Copy link
Copy Markdown

Merge upstream WebKit 39d4ce1f12ea into the Bun fork (~422 commits since 49d2e914a4cc).

Notable JSC changes from upstream

  • JSAsyncFunctionGenerator split out of JSGenerator (e0704d3127d5) — async functions now use a dedicated generator class with the Context field; sizeof(JSGenerator) shrinks from 64 to 48 bytes. Adds JSAsyncFunctionGeneratorType to the JSType enum.
  • JSPromise::performPromiseThenWithInternalMicrotask signature changed (8f742098b444): the JSValue promise argument became JSCell* cell; the inline-microtask reaction now stores the cell in m_packed separately from the context in m_slot.
  • import.defer() semantics (7f062965e945): JSModuleLoader::loadModule takes OptionSet<ModuleLoadFlag> instead of three bool arguments; the moduleLoaderImportModule host hook gained a bool deferred parameter.
  • JSHeapInt32 / JSHeapDouble removed (3bb4fc93fb37); HeapDoubleType / HeapInt32Type removed from the JSType enum.
  • Symbol::description() now takes VM& and returns a (cached) JSString*; Symbol::toString(JSGlobalObject*) added.
  • Promise.all / Promise.allSettled / Promise.any no longer allocate a per-element JSPromiseCombinatorsContext (0f6a35669fa8).

Fork-side fixups

  • BunV8HeapSnapshotBuilder reads SymbolImpl directly instead of Symbol::description(VM&) so heap snapshot traversal does not allocate.
  • AbstractModuleRecord::estimatedSize approximates from OrderedHashMap::capacity() since byteSize() is gone.
  • JSModuleLoader::loadModuleSync (Bun's require(esm) path) now passes { ModuleLoadFlag::Evaluate }.
  • runInternalMicrotask's AsyncFunctionResume BUN_JSC_ADDITIONS branch unwraps JSAsyncFunctionGenerator from the InternalFieldTuple async-context wrapper.
  • JSAsyncFunctionGenerator.h exported as a forwarding header so embedders can include it.

Constellation and others added 30 commits May 18, 2026 02:50
https://bugs.webkit.org/show_bug.cgi?id=314921
rdar://177200730

Reviewed by Sosuke Suzuki.

As String#substr is still frequently used, we add StringSubstr DFG node
and optimize it. Mostly mimicking StringSlice implementation, but index
/ length handling is different.

Test: JSTests/stress/string-substr.js

* JSTests/stress/string-substr-strength-reduction.js: Added.
(shouldBe):
* JSTests/stress/string-substr.js: Added.
(shouldBe):
* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::propagate):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
* Source/JavaScriptCore/dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* Source/JavaScriptCore/dfg/DFGCloneHelper.h:
* Source/JavaScriptCore/dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* Source/JavaScriptCore/dfg/DFGNodeType.h:
* Source/JavaScriptCore/dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/dfg/DFGOperations.h:
* Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:
* Source/JavaScriptCore/dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileStringSubstr):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
* Source/JavaScriptCore/ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/runtime/Intrinsic.h:
* Source/JavaScriptCore/runtime/StringPrototype.cpp:
(JSC::StringPrototype::finishCreation):
* Source/JavaScriptCore/runtime/StringPrototypeInlines.h:
(JSC::extractSubstrOffsets):

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

Reviewed by Youenn Fablet.

This also changes the call for the Cookie Store API, but this does not
impact anything as we never look at the query of that URL. And
therefore that can not be tested.

Tests: imported/w3c/web-platform-tests/beacon/beacon-url-encoding-euc-kr.https.html
       imported/w3c/web-platform-tests/mediasession/artwork-url-encoding-euc-kr.html

Upstream: web-platform-tests/wpt#59851
Canonical link: https://commits.webkit.org/313403@main
https://bugs.webkit.org/show_bug.cgi?id=314933
rdar://177219737

Reviewed by Sosuke Suzuki.

JSGenerator's context field is used only when we are using it for async
function. Let's split them. We introduce JSAsyncFunctionGenerator, which is
different class from JSGenerator. It still has context field, but we
no longer has context field in JSGenerator. We implement all the things
of JSAsyncFunctionGenerator, aligned to previous JSGenerator. And start
using JSAsyncFunctionGenerator for async function. As a result, sizeof(JSgenerator)
becomes 48-byte from 64-byte. This reduces GC pressure and memory cache
hit rate.

* Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj:
* Source/JavaScriptCore/Sources.txt:
* Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp:
(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
* Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h:
* Source/JavaScriptCore/bytecode/BytecodeList.rb:
* Source/JavaScriptCore/bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitNewAsyncFunctionGenerator):
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:
* Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:
(JSC::generatorInternalFieldIndex):
* Source/JavaScriptCore/debugger/Debugger.cpp:
(JSC::Debugger::willAwait):
(JSC::Debugger::didAwait):
* Source/JavaScriptCore/debugger/Debugger.h:
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNewInternalFieldObject):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/ftl/FTLOperations.cpp:
(JSC::FTL::JSC_DEFINE_NOEXCEPT_JIT_OPERATION):
* Source/JavaScriptCore/heap/Heap.h:
* Source/JavaScriptCore/heap/HeapSubspaceTypes.h:
* Source/JavaScriptCore/interpreter/Interpreter.cpp:
(JSC::Interpreter::getAsyncStackTrace):
(JSC::Interpreter::getStackTrace):
* Source/JavaScriptCore/interpreter/Interpreter.h:
* Source/JavaScriptCore/jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* Source/JavaScriptCore/jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/jit/JITOperations.h:
* Source/JavaScriptCore/llint/LowLevelInterpreter.asm:
* Source/JavaScriptCore/lol/LOLJIT.cpp:
(JSC::LOL::LOLJIT::privateCompileMainPass):
* Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:
(JSC::JSC_DEFINE_COMMON_SLOW_PATH):
* Source/JavaScriptCore/runtime/CommonSlowPaths.h:
* Source/JavaScriptCore/runtime/JSAsyncFunctionGenerator.cpp: Added.
(JSC::JSAsyncFunctionGenerator::create):
(JSC::JSAsyncFunctionGenerator::createWithInitialValues):
(JSC::JSAsyncFunctionGenerator::createStructure):
(JSC::JSAsyncFunctionGenerator::JSAsyncFunctionGenerator):
(JSC::JSAsyncFunctionGenerator::finishCreation):
(JSC::JSAsyncFunctionGenerator::visitChildrenImpl):
* Source/JavaScriptCore/runtime/JSAsyncFunctionGenerator.h: Copied from Source/JavaScriptCore/runtime/JSGenerator.h.
* Source/JavaScriptCore/runtime/JSCast.h:
* Source/JavaScriptCore/runtime/JSGenerator.h:
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildrenImpl):
* Source/JavaScriptCore/runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::asyncFunctionGeneratorStructure const):
* Source/JavaScriptCore/runtime/JSMicrotask.cpp:
(JSC::runInternalMicrotask):
* Source/JavaScriptCore/runtime/JSType.cpp:
(WTF::printInternal):
* Source/JavaScriptCore/runtime/JSType.h:

Canonical link: https://commits.webkit.org/313404@main
https://bugs.webkit.org/show_bug.cgi?id=314754
rdar://177008615

Reviewed by Dan Glastonbury.

Update the list of reserved words according to the spec[1].

[1]: https://www.w3.org/TR/WGSL/#reserved-words

* LayoutTests/http/tests/webgpu/webgpu/shader/validation/parse/identifiers-expected.txt:
* Source/WebGPU/WGSL/Lexer.cpp:
(WGSL::Lexer<T>::nextToken):

Canonical link: https://commits.webkit.org/313405@main
…space

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

Reviewed by Claudio Saavedra.

generate-bundle entered the WebKit Container SDK but, unlike build-webkit
and the run-* scripts, never called maybe_use_container_sdk_root_dir().
With the tree mounted at a different path than at build time, the RPATH
baked into the WebKit binaries (/sdk/webkit/WebKitBuild/.../lib) failed
to resolve, causing ldd "libWPEWebKit-2.0.so.1 => not found".

* Tools/Scripts/generate-bundle:

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

Reviewed by Xabier Rodriguez-Calvar.

Add a check for USAC (xHE-AAC) codec support by probing
the GStreamer registry for a decoder matching
"audio/mpeg, mpegversion=(int)4, stream-format=(string)usac".

The stream-format=usac caps field is not part of the standard GStreamer
audio/mpeg caps definition, but some custom audio sinks advertise it, so it can
be used as an indicator of USAC decoding capability.

The WEBKIT_GST_CAN_PLAY_USAC environment variable still takes
precedence as a manual override.

See: WebPlatformForEmbedded/WPEWebKit#1654
Original author: Andrzej Surdej (https://github.com/asurdej-comcast)

* Source/WebCore/platform/graphics/gstreamer/GStreamerRegistryScanner.cpp:
(WebCore::GStreamerRegistryScanner::initializeDecoders):

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

Reviewed by Carlos Garcia Campos.

The debug repaint counter recomputed its string and re-measured its
text geometry on every composite of the layer, even though the count
only changes when the layer actually repaints its content. Cache the
shaped string and geometry, recomputing only when the count changes,
matching the on-screen FPS counter in ThreadedCompositor (PR WebKit#65093).

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

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

Reviewed by Carlos Garcia Campos.

The on-screen FPS overlay was specific to the TextureMapper path
(TextureMapperFPSCounter). Draw a Skia counterpart directly from
ThreadedCompositor so an on-screen FPS overlay is also available when
the Skia compositor is enabled.

The existing WEBKIT_SHOW_FPS envvar keeps its behavior (logging the
FPS to the console, with its value setting the calculation interval in
seconds). A new WEBKIT_DRAW_FPS=1 envvar additionally renders the
on-screen overlay, reusing that calculation interval.
WEBKIT_DRAW_FPS_FONT_SIZE configures the overlay font size (defaults to 14).

* Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/ThreadedCompositor.cpp:
(WebKit::ThreadedCompositor::paintToSkiaCanvas):
(WebKit::ThreadedCompositor::initializeFPSCounter):
(WebKit::ThreadedCompositor::updateFPSCounter):
(WebKit::ThreadedCompositor::drawFPSCounter):
* Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/ThreadedCompositor.h:

Canonical link: https://commits.webkit.org/313409@main
…Surface::writePixels to upload BGRA buffers to textures

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

Reviewed by Nikolas Zimmermann.

When using SkSurface::writePixels the BGRA to RGBA conversion is always
done by CPU before pixels are uploaded. With SkCanvas::drawImageRect is
the GL platform supports BGRA, the pixels are uploaded as BGRA and then
converted by the GPU before painting.

* Source/WebCore/platform/graphics/skia/SkiaBackingStore.cpp:
(WebCore::SkiaBackingStore::Tile::update):
* Source/WebCore/platform/graphics/skia/SkiaUtilities.cpp:
(WebCore::SkiaUtilities::paintImageRectToSurface):
* Source/WebCore/platform/graphics/skia/SkiaUtilities.h:
* Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayerBufferNativeImage.cpp:
(WebCore::CoordinatedPlatformLayerBufferNativeImage::tryEnsureBuffer):

Canonical link: https://commits.webkit.org/313410@main
…he (which then silently corrupts your build)

https://bugs.webkit.org/show_bug.cgi?id=314972
rdar://177267115

Reviewed by Adrian Taylor.

We currently set CMAKE_Swift_COMPILER as a CACHE FORCE after
enable_language(Swift) has already recorded the real swiftc.

Bug 1: On the next reconfigure (e.g. after CMakeLists.txt changes),
enable_language(Swift) records the the real swiftc, CMake sees the
cached compiler doesn't match the recorded one, decides the compiler
changed, and deletes the CMake cache.

Bug 2: When there's no CMake cache, we silently reconfigure to a set of
defaults that might not match your build (e.g. Debug => RelWithDebInfo).

* CMakeLists.txt: Set the Swift compiler as a normal variable, like we
do for C++. Since the cache isn't touched, the compiler-change check
never fires.

* Source/cmake/WebKitCommon.cmake: If we lose the cache, fail the build
instead of silently dropping preset values like CMAKE_BUILD_TYPE.

Canonical link: https://commits.webkit.org/313411@main
…s called multiple times

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

Reviewed by Carlos Garcia Campos.

In <https://webkit.org/blog-files/3d-transforms/transform-style.html>, the
animating semi-transparent layer left rendering artifacts if
PropagateDamagingInformation is enabled.

paintUsingOverlapRegions() splits layers into some overlap regions and some
non-overlap regions. paintSelf() can be called multiple times for a single
SkiaCompositingLayer. However, paintSelf() calculated the damage rect by
assuming it was called only once.

* LayoutTests/platform/glib/damage/layer-overlaps-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-overlaps.html: Added.
* Source/WebCore/platform/graphics/skia/SkiaCompositingLayer.cpp:
(WebCore::SkiaCompositingLayer::addPreviousRectToSharedFrameDamage):
(WebCore::SkiaCompositingLayer::paintSelf):
* Source/WebCore/platform/graphics/skia/SkiaCompositingLayer.h:

Canonical link: https://commits.webkit.org/313412@main
…hDecodeKey

https://bugs.webkit.org/show_bug.cgi?id=314997
rdar://177312155

Reviewed by Youenn Fablet.

Change 313296@main exposed a real problem where samples could be silently
dropped by the MediaPlayerPrivateWebM which at best resulted in invalid
memory tracking and at worse with decoding errors.
The content generated by the MediaRecorder could include content where
the format is changing mid-streams.
MediaRecorder-generated WebM streams can carry consecutive audio packets
with identical (DTS, PTS) keys in their compressed output. The
AudioSampleBufferConverter that produced them sets
OutputPresentationTimeStamp on each compressed packet using a running
m_currentOutputPresentationTimeStamp that only advances by each
packet's OutputDuration (native duration minus TrimDurationAtStart);
during a converter's priming phase that delta is zero, so several
consecutive primed packets emerge with the same OutputPT. This is most
visible immediately after an audio-track reconfiguration because
MediaRecorderPrivateEncoder spins up a fresh converter, which goes
through its own priming with the new format.

The SampleMap is keyed on (DTS, PTS) and accounts for sizeInBytes()
unconditionally for eviction; a duplicate key would either trip the
ASSERT in TrackBuffer::addSample or, worse, silently no-op the
insert and skew accounting, for video is would lead to decoding error.
Bump the incoming sample by one microsecond past the colliding entry
so each priming packet remains addressable in the buffer (they are
required as decoder pre-roll); the bump is well withing timeFudgeFactor()
and does not affect seek behaviour.

Covered by existing tests

* Source/WebCore/platform/graphics/cocoa/MediaPlayerPrivateWebM.mm:
(WebCore::MediaPlayerPrivateWebM::didProvideMediaDataForTrackId):

Canonical link: https://commits.webkit.org/313413@main
https://bugs.webkit.org/show_bug.cgi?id=314166
rdar://176326251

Reviewed by Alexey Proskuryakov and Elliott Williams.

* .submitproject: Prefer includes rather excludes in most cases.

Canonical link: https://commits.webkit.org/313414@main
…g Safari

rdar://175260977
https://bugs.webkit.org/show_bug.cgi?id=312281

Reviewed by Jean-Yves Avenard.

As shown in the logs from bugs.webkit.org/attachment.cgi?id=478546 comment 8,
IncomingAudioMediaStreamTrackRendererUnit::removeSource/addSource is frequently called in some Webex scenarios.
These calls can potentially stop and start the corresponding audio unit, which can disrupt audio rendering.
This flow mainly happens when changing the speaker, in which case disrupting the audio rendering is acceptable.

However, it can also happen when the stream attached to the HTMLMediaElement has tracks added or removed.
This happens in MediaPlayerPrivateMediaStreamAVFObjC::updateTracks.
This is useful for new tracks but unnecessary for already configured tracks.
To prevent this unnecessary work, we add a check in AudioMediaStreamTrackRendererCocoa::setAudioOutputDevice
to return early if the new device ID is already the one in use.

Manually tested.

* Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.cpp:
(WebCore::AudioMediaStreamTrackRendererCocoa::setAudioOutputDevice):

Canonical link: https://commits.webkit.org/313415@main
https://bugs.webkit.org/show_bug.cgi?id=315025
rdar://177345226

REGRESSION(313345@main): Causes crashes on iOS 26.2

Reverted change:

    [ Build-Failure ] error: 'pthread_jit_write_protect_np' is unavailable: not available on iOS
    rdar://177190630
    313345@main (3ab6c7c)

Canonical link: https://commits.webkit.org/313416@main
https://bugs.webkit.org/show_bug.cgi?id=314685
<rdar://176928238>

Reviewed by Simon Fraser.

This commit adds logging for unfilled frames during scrolling on iOS. This is calculated from the pixel count of blank tiles in the visible viewport.

Canonical link: https://commits.webkit.org/313417@main
…ools

https://bugs.webkit.org/show_bug.cgi?id=315026
rdar://177346454

Reviewed by Alexey Proskuryakov.

* .submitproject-append: Duplicate .submitproject-tools.

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

Reviewed by Geoffrey Garen and Richard Robinson.

We previously hard-coded a list of header-copying dependencies which needed to
be completed before WebKit was able to generate C++ bindings to its internal
Swift APIs. Instead of hard-coding this list, calculate it automatically.

This was previously reverted erroneously due to a build failure that was
actually caused by https://commits.webkit.org/313188@main. This is an
identical reland.

Canonical link: https://commits.webkit.org/313419@main
…laky on DEBUG bots

rdar://177334197
https://bugs.webkit.org/show_bug.cgi?id=315010

Reviewed by Eric Carlson.

We switch from a concurrent to a serial queue so that we are sure that the getInterfaceName callback is not called in parrallel.
This ensures that we only resolve the native promise once.

Canonical link: https://commits.webkit.org/313420@main
https://bugs.webkit.org/show_bug.cgi?id=314731
rdar://176978821

Reviewed by Dewei Zhu and Sihui Liu.

This will also move the cache directory to the GPU process's container.

* Source/WebKit/GPUProcess/GPUProcess.cpp:
(WebKit::GPUProcess::initializeGPUProcess):
* Source/WebKit/Shared/EntryPointUtilities/Cocoa/XPCService/XPCServiceMain.mm:
(WebKit::XPCServiceEventHandler):
* Source/WebKit/UIProcess/Launcher/cocoa/ProcessLauncherCocoa.mm:
(WebKit::ProcessLauncher::tryFinishLaunchingProcess):
* Source/WebKit/Resources/SandboxProfiles/ios/com.apple.WebKit.GPU.sb.in:

Canonical link: https://commits.webkit.org/313421@main
…peAndCrossOriginParent

https://bugs.webkit.org/show_bug.cgi?id=314439
rdar://176593716

Reviewed by Charlie Wolfe.

AuthenticatorCoordinator::scopeAndCrossOriginParent performs
security checks to check if a frame's ancestor frames are
same-origin, same-site, or cross-origin.

The method currently traverses the ancestors via the
current document's parent document (Document::parentDocument).

However, with site isolation enabled, some of the ancestor's documents
might not available if the ancestors are in a different process.

This patch updates this ancestor traversal to operate on the frame
tree and handles both Local or Remote frame cases.

In the case where the ancestor is a remote frame, we don't
have access to it's full URL. However, we can grab the registerable domain
from the SecurityOrigin and use that to perform the check which was
previously done with areRegistrableDomainsEqual.

This patch fixes http/wpt/webauthn/public-key-credential-same-origin-with-ancestors.https.html
with site isolation enabled.

* LayoutTests/platform/ios-site-isolation/TestExpectations:
* LayoutTests/platform/mac-site-isolation/TestExpectations:
* Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp:
(WebCore::AuthenticatorCoordinatorInternal::scopeAndCrossOriginParent):

Canonical link: https://commits.webkit.org/313422@main
… constant failure

https://bugs.webkit.org/show_bug.cgi?id=314577
rdar://176588656

Reviewed by Brent Fulgham.

addKeyToKeychain() hardcoded the same kSecAttrAlias for every credential,
so the test's two entries shared a credential ID and the post-assertion
SecItemUpdate bumped both modification dates identically, leaving the LRU
sort non-deterministic. Pass a distinct ID for the second credential.

* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/_WKWebAuthenticationPanel.mm:
(TestWebKitAPI::WebCore::addKeyToKeychain):
(TestWebKitAPI::TEST(WebAuthenticationPanel, LAGetAssertionMultipleOrder)):

Canonical link: https://commits.webkit.org/313423@main
…dia-api.html

is a constant timeout on iOS and constant text failure on mac
https://bugs.webkit.org/show_bug.cgi?id=314648
rdar://176606830

Reviewed by Wenson Hsieh.

text-track-selected-via-media-api.html needs to be updated to reflect the
new structure of the media controls context menu, which changed when the
feature CaptionDisplaySettings became enabled by default. Now, the text tracks
are accessed through a languages submenu.

The layout test has a javascript helper function contextMenuItem() that returns
a context menu item representing a given language string. The test uses the return
value to check that the appropriate language tracks are checked/unchecked. This
patch modifies contextMenuItem() to navigate through the languages submenu to
reach the needed context menu items.

The test uses UIHelper to simulate clicking/tapping on the context menu items. This
patch modifies the iOS path of the layout test to first call
UIHelper.chooseMenuAction("Languages") before UIHelper.chooseMenuAction("French"),
as the track items are only revealed after the Languages submenu has been opened.

The approach used on iOS does not work on mac:
UIScriptControllerMac::UIHelperchooseMenuAction("Languages") simulates clicking the
languages menu item and then closing the menu, hence the subsequent
UIHelperchooseMenuAction("French") cannot find the nested French menu item. Instead, this patch
modifies UIScriptControllerMac::chooseMenuAction to recursively search through nested
submenus to find a given item, and as a result, only UIHelper.chooseMenuAction("French")
is needed on mac. The recursive search is a breadth first search, given that almost
all callers of UIScriptControllerMac::UIHelperchooseMenuAction are looking for a menu
item on the top level.

* LayoutTests/media/modern-media-controls/tracks-support/text-track-selected-via-media-api.html:
* LayoutTests/resources/ui-helper.js:
(window.UIHelper.async chooseLanguageInMediaContextMenu):
* Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm:
(WTR::UIScriptControllerMac::chooseMenuAction):

Canonical link: https://commits.webkit.org/313424@main
…pite presence of the autofocus attribute and / or explicit focus() calls

https://bugs.webkit.org/show_bug.cgi?id=314893
rdar://177167634

Reviewed by Dominic Mazzoni.

When a <dialog> opens and the page focuses an element inside it (e.g. a heading
with tabindex="-1"), VoiceOver fails to move its cursor onto the focused element.

When dialog.show() runs, the dialog's content gets renderers and a children-changed
update is queued on the dialog's parent, but the actual subtree walk that adds new
descendants to the isolated tree's pending appends doesn't happen until
processQueuedNodeUpdates runs (via the snapshot timer, fired after
performDeferredCacheUpdate). When the deferred focus change runs first,
setIsolatedTreeFocusedObject writes the heading's AXID into focusedNodeID, but the
heading's AXIsolatedObject isn't in the reader-thread node map yet. Inside
NSAccessibilityHandleFocusChanged, AppKit synchronously calls
[NSApp accessibilityFocusedUIElement] on the same call stack. That lands on our
wrapper, goes through the AX thread to focusedNode(), and returns nil because the
focused AXID has no corresponding AXIsolatedObject. AppKit's currentElement is nil,
so it skips NSAccessibilityPostNotification entirely and VoiceOver is never told.

Fix this by calling processQueuedIsolatedNodeUpdates in platformHandleFocusedUIElementChanged
before NSAccessibilityHandleFocusChanged, so the focused object's subtree is in the
isolated tree before AppKit's synchronous focused-element query.

Also drop the callOnMainThread around the test-only accessibilityPostedNotification
call so the test path matches the timing of AppKit's synchronous
[NSApp accessibilityFocusedUIElement] query. With the previous async dispatch,
performDeferredCacheUpdate finished before the test JS listener fired, masking the
bug. Tests that need to dirty style/layout in the listener should defer it via
setTimeout (see focus-in-remote-frame.html), since real ATs cannot
synchronously dirty style/layout, and doing so in the middle of
performDeferredCacheUpdate breaks the invariant of layout needing to be
clean for the duration of the function.

* LayoutTests/accessibility/dialog-focus-on-open-expected.txt: Added.
* LayoutTests/accessibility/dialog-focus-on-open.html: Added.
* Source/WebCore/accessibility/mac/AXObjectCacheMac.mm:
(WebCore::AXObjectCache::platformHandleFocusedUIElementChanged):

Canonical link: https://commits.webkit.org/313425@main
https://bugs.webkit.org/show_bug.cgi?id=314963
rdar://177256813

Reviewed by Per Arne Vollan.

donePrepareForEviction is dispatched to the work queue from an async callback on the main thread. Between the m_closed
check in the callback and the execution on the work queue, close() can be called, setting m_closed and scheduling
cleanup of m_originStorageManagers. Add the same m_closed early return that donePrepareForTimeBasedEviction already has
for consistency and safety.

* Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp:
(WebKit::NetworkStorageManager::donePrepareForEviction):

Canonical link: https://commits.webkit.org/313427@main
https://bugs.webkit.org/show_bug.cgi?id=314663
rdar://176914827

Reviewed by Ryosuke Niwa and Anne van Kesteren.

* Tools/Scripts/webkitpy/w3c/test_converter.py:
(convert_for_webkit): Return None when there's nothing to modified; assert we only get expected file extensions.
(_W3CTestConverter.__init__): Add _W3CTestConverter._modified.
(_W3CTestConverter.output): Return None if nothing is modified.
(_W3CTestConverter.convert_reference_relpaths): Set modified.
(_W3CTestConverter.convert_style_data): Set modified.
(_W3CTestConverter.convert_attributes_if_needed): Set modified.
(_W3CTestConverter.add_webkit_test_runner_options_if_needed): Set modified.
* Tools/Scripts/webkitpy/w3c/test_converter_unittest.py: Update tests for None.
* Tools/Scripts/webkitpy/w3c/test_importer.py:
(TestImporter.import_tests): Don't pass JS to the rewriter.
* Tools/Scripts/webkitpy/w3c/test_importer_unittest.py:
(TestImporterTest.test_unmodified_files_not_rewritten): Add a test that we don't rewrite everything.

Canonical link: https://commits.webkit.org/313428@main
…l-link"

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

Reviewed by Claudio Saavedra.

This makes a few drive-by changes too:

 * This gets rid of the Python 2 `urlparse` import.

 * We now use `subprocess.run` instead of `subprocess.check_output`.

 * We now use `subprocess.DEVNULL` instead of opening `os.devnull`.

* Tools/glib/apply-build-revision-to-files.py:
(get_revision_from_most_recent_git_commit):

Canonical link: https://commits.webkit.org/313429@main
…rcent-encoding for unencoded URLs

https://bugs.webkit.org/show_bug.cgi?id=314975
rdar://177297247

Reviewed by Darin Adler.

WebCore's URL parser leaves some characters literal in the path (e.g. '[' and ']' per the
WHATWG URL spec), so `flower [A].jpg` becomes `flower%20[A].jpg`. +[NSURL URLWithString:]
reacts to those literal characters by re-encoding the whole path, turning the existing %20
into %2520 and yielding `flower%2520%5BA%5D.jpg`.

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

* Source/WebKit/Shared/API/Cocoa/_WKHitTestResult.mm:
(URLFromString): Go through WTF::URL::createNSURL() (CFURLCreateAbsoluteURLWithBytes)
instead of +[NSURL URLWithString:], so that there is no opportunity for disagreement between
different URL implementations.

* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/mac/ContextMenuTests.mm:
(TestWebKitAPI::TEST(ContextMenuTests, HitTestResultImageURLNotDoubleEncoded)):

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

Canonical link: https://commits.webkit.org/313431@main
atar13 and others added 21 commits May 20, 2026 20:16
https://bugs.webkit.org/show_bug.cgi?id=309708
rdar://172168772

Reviewed by Ryosuke Niwa.

When the Document destructor is called, it is possible
for it to take a code path where it references the document
which is actively being destroyed. Since the Document is
in the middle of it's destructor call, the Document is not in
a well-defined state it may have already freed member variables, etc.

This is the path which leads to the access of the document during
destruction:
- Document::~Document
- ScriptExecutionContext::~ScriptExecutionContext
- BaseAudioContext::deleteMarkedNodes
- AudioContext::~AudioContext
- Document::removeAudioProducer

To remove the audio producers safely, this patch does so when we are certain
the document is still alive. So, we will call this from AudioContext::stop()
which itself gets invoked from Document::commonTeardown -> ScriptExectionContext::stopActiveDOMObjects.

To be defensive, we can also guard the call to document->removeAudioProducer in
~AudioContext with a check to !BaseAudioContext::isStopped().
This ensures that we won't access the document while it is being torn down.
During teardown, ScriptExecutionContext will stop the AudioContext by
calling BaseAudioContext::stop which in turn sets
BaseAudioContext::m_isStopScheduled to true and causes
BaseAudoContext::isStopped to return true.

Adding a manual test since the layout test can take up to a few
minutes to trigger the bug.

If running the manual test, test it against an ASAN build to reproduce
the crash. On average, the test takes 49 seconds to trigger the bug.

* ManualTests/webaudio/nocrash-audiocontext-reference-destroyed-document.html: Added.
* Source/WebCore/Modules/webaudio/AudioContext.cpp:
(WebCore::AudioContext::~AudioContext):
(WebCore::AudioContext::stop):
* Source/WebCore/Modules/webaudio/AudioContext.h:
* Source/WebCore/Modules/webaudio/BaseAudioContext.h:

Originally-landed-as: 305413.492@rapid/safari-7624.2.5.110-branch (72b0f61). rdar://176061965
Canonical link: https://commits.webkit.org/313630@main
https://bugs.webkit.org/show_bug.cgi?id=315195

Reviewed by Fujii Hironori.

The new gdb full backtrace added in 313530@main is too verbose
and a bit hard to read. However, this extra info can be useful.

So to support a quick overview, this patch adds a simplified
backtrace report at the top just for the thread that crashed.

This also pass now -ascending to GDB, so the thread that crashes
appears first and is not needed to scroll to the bottom to see it.

* Tools/Scripts/webkitpy/port/linux_get_crash_log.py:
(GDBCrashLogGenerator._get_gdb_output):
(GDBCrashLogGenerator._generate_simplified_backtrace):
(GDBCrashLogGenerator.generate_crash_log):
* Tools/Scripts/webkitpy/port/linux_get_crash_log_unittest.py:
(GetCoredumpPathWithCoredumpctlTest.test_falls_back_to_latest_only_when_unreliable_fallback_is_enabled):
(GenerateSimplifiedBacktraceTest):
(setUp):
(_assert_main_thread_crash_output):
(test_main_thread_crash_ascending_order):
(test_main_thread_crash_descending_order):
(test_worker_thread_crash_is_marked_as_not_main):
(test_thread_name_with_spaces_is_preserved):
(test_thread_10_is_not_treated_as_thread_1):
(test_no_thread_info_data):
(test_thread_info_data_without_matching_tid):
(test_thread_1_line_without_lwp_falls_back_to_bare_header):
(test_returns_none_when_no_relevant_lines_present):
(test_preamble_frame_before_thread_1_block_is_ignored):

Canonical link: https://commits.webkit.org/313631@main
…ter logout

https://bugs.webkit.org/show_bug.cgi?id=315164
rdar://174779259

Reviewed by Brent Fulgham.

The Claude SPA's logout flow uses fetch('/api/auth/logout') to log the user
out. The server response clears the auth cookies, but leaves several
identification cookies (__ssid, __cf_bm, anthropic-device-id, lastActiveOrg,
activitySessionId) behind. On the next /chat boot, those non-auth cookies
are enough to push the SPA into an authenticated boot path; the bootstrap
call then 403s with "account_session_invalid", and the SPA reacts with
location.href = '/logout?...', producing an indefinite /chat <-> /logout
loop.

The bug appears to be on Anthropic's side; this quirk works around it by
deleting the surviving cookies after we observe a successful fetch to
claude.ai/api/auth/logout. The hook lives in
FetchResponse::Loader::didReceiveResponse so it fires for the SPA's logout
fetch.

* Source/WebCore/Modules/fetch/FetchResponse.cpp:
(WebCore::FetchResponse::Loader::didReceiveResponse):
* Source/WebCore/page/Quirks.cpp:
* Source/WebCore/page/Quirks.h:
* Source/WebCore/page/QuirksData.h:

Canonical link: https://commits.webkit.org/313632@main
…erify storage blocking policy

https://bugs.webkit.org/show_bug.cgi?id=314922
rdar://177202636

Reviewed by Per Arne Vollan.

While debugging cross-origin storage tests under Site Isolation, I noticed this test passes even when storage blocking
policy is not properly configured under SI. It turns out the test only exercises an IndexedDB behavior (open() succeeds)
that holds under both `StorageBlockingPolicy::AllowAll` and `StorageBlockingPolicy::BlockThirdParty`, so the result
tells us nothing about whether the policy is actually applied.

Rewrite the test to verify whether the third-party database is ephemeral instead: the storage should be ephemeral under
BlockThirdParty policy and persistent under AllowAll policy. With this change, if the wrong policy is in effect the test
produces a visibly different result instead of silently passing.

* LayoutTests/http/tests/security/cross-origin-indexeddb-expected.txt:
* LayoutTests/http/tests/security/cross-origin-indexeddb.html:
* LayoutTests/http/tests/security/resources/cross-origin-iframe-for-indexeddb-transience.html: Added.

Canonical link: https://commits.webkit.org/313633@main
https://bugs.webkit.org/show_bug.cgi?id=315255
rdar://177584900

Reviewed by Richard Robinson.

The header used double-quoted includes for FrameIdentifier.h,
ProcessIdentifier.h, ResourceLoaderIdentifier.h, and
ScriptExecutionContextIdentifier.h. This is invalid in a framework
private header: the WebCore module verifier (iOS-only) fails with
"Double-quoted include ... in framework header, expected angle-bracketed
instead" when WebCore_Private is built on the iOS internal SDK.

Open Source EWS does not run the module verifier, so the bad includes
have shipped on main since the file was first added in b/310162.

Change the four #includes to <WebCore/X.h> form and re-sort them with
the other angle-bracketed framework includes.

* Source/WebCore/inspector/InspectorIdentifierRegistry.h:

Canonical link: https://commits.webkit.org/313634@main
…n maps are out-of-sync

<https://bugs.webkit.org/show_bug.cgi?id=308844>
<rdar://157943937>

Reviewed by Brent Fulgham.

A crash occurs in `topLevelServiceWorkerClientFromPageIdentifier()` when
the Service Worker maps `m_clientIdentifiersPerOrigin` and `m_clientsById`
become out-of-sync.  The function iterates over client identifiers from
`m_clientIdentifiersPerOrigin` and calls `m_clientsById.find()` for each
one, but never checks whether the result equals `m_clientsById.end()`
before dereferencing it.

Add an end-iterator check in `topLevelServiceWorkerClientFromPageIdentifier()`
and use `continue` to skip missing clients (matching the pattern in
`clientIsAppInitiatedForRegistrableDomain()`).

Also replace the ASSERT-only guard in `serviceWorkerClientWithOriginByID()`
with a proper end-iterator check that returns `std::nullopt` in release
builds.

No test since this is a race condition with no known steps to reproduce.

* Source/WebCore/workers/service/server/SWServer.cpp:
(WebCore::SWServer::serviceWorkerClientWithOriginByID):
- Replace ASSERT-only check with end-iterator check returning
  std::nullopt.
(WebCore::SWServer::topLevelServiceWorkerClientFromPageIdentifier):
- Add end-iterator check with ASSERT_NOT_REACHED() to continue in order
  to skip missing clients.

Originally-landed-as: 305413.383@rapid/safari-7624.2.5.110-branch (91ab7f0). rdar://176067466
Canonical link: https://commits.webkit.org/313635@main
…property access

https://bugs.webkit.org/show_bug.cgi?id=309519
rdar://171512268

Reviewed by Keith Miller.

When computing the GetByStatus, we should check if the property lookup is a
direct property access before doing a prototype walk since direct accesses are
not supposed to consult the prototype.

* Source/JavaScriptCore/bytecode/GetByStatus.cpp:
(JSC::GetByStatus::computeFor):
* Source/JavaScriptCore/bytecode/GetByStatus.h:
* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* Source/JavaScriptCore/dfg/DFGNodeType.h:
(JSC::DFG::propertyLookupMode):

Originally-landed-as: 305413.572@rapid/safari-7624.2.5.110-branch (2f13ea2). rdar://176061387
Canonical link: https://commits.webkit.org/313636@main
https://bugs.webkit.org/show_bug.cgi?id=308445
rdar://168927271

Reviewed by Matthew Finkel.

When an about:blank popup made cross-origin requests, its firstPartyForCookies was set to about:blank,
which has an empty registrable domain. thirdPartyCookieBlockingDecisionForRequest() returns
ThirdPartyCookieBlockingDecision::None for empty domains, bypassing third-party cookie blocking.

FrameLoader::updateFirstPartyForCookies() should inherit the opener's firstPartyForCookies when the main
frame URL is an about:blank or other owner-inherited document.

* LayoutTests/http/tests/resourceLoadStatistics/third-party-cookie-blocking-about-blank-popup-expected.txt: Added.
* LayoutTests/http/tests/resourceLoadStatistics/third-party-cookie-blocking-about-blank-popup.html: Added.
* Source/WebCore/loader/FrameLoader.cpp:
(WebCore::FrameLoader::updateFirstPartyForCookies):

Originally-landed-as: 305413.366@rapid/safari-7624.2.5.110-branch (8acf843). rdar://176067216
Canonical link: https://commits.webkit.org/313637@main
…h a programmatic click on an associated label

https://bugs.webkit.org/show_bug.cgi?id=309082
rdar://171635705

Reviewed by Lily Spiniolas, Wenson Hsieh, and Abrar Rahman Protyasha.

288403@main ensured that haptic feedback for <input type=checkbox switch> required
user activation. However, it is also desired that haptics are only triggered for
trusted events. This goal can currently be bypassed by calling `click()` on a label
associated with the input. The result is that calling `click()` on the label,
immediately following a user gesture, can allow for haptics to be programmatically
triggered.

The underlying issue is that untrusted click events on label elements become
trusted click events on the associated control. This is because
`Element::dispatchSimulatedClick` unconditionally sets `SimulatedClickSource::UserAgent`.
While this is desirable for accessibility use cases, it is incorrect when the
underlying event is untrusted.

Fix by specifying `SimulatedClickSource::Bindings` if there is an underlying
event and it is untrusted.

Tests: fast/forms/label/label-click-event-dispatch-untrusted.html
       Tools/TestWebKitAPI/Tests/WebKitCocoa/SwitchInputTests.mm

* LayoutTests/fast/forms/label/label-click-event-dispatch-untrusted-expected.txt: Added.
* LayoutTests/fast/forms/label/label-click-event-dispatch-untrusted.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-label-element/label-forwarded-click-pointer-properties-expected.txt:
* Source/WebCore/dom/Element.cpp:
(WebCore::Element::dispatchSimulatedClick):

If there is an underlying event, the simulated click should be marked as from
"bindings", making it untrusted. This change is not made to `simulateClick` itself
since that is used by `Element::click()`, which has no underlying event and is
always untrusted.

* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SwitchInputTests.mm:
(TEST(SwitchInputTests, HapticFeedbackOnClick)):
(TEST(SwitchInputTests, HapticFeedbackRequiresUserGestureAndTrustedEvent)):
(TEST(SwitchInputTests, HapticFeedbackRequiresUserGesture)): Deleted.

Originally-landed-as: 305413.395@safari-7624-branch (2c99c89). rdar://176067574
Canonical link: https://commits.webkit.org/313638@main
…'overflow' issue committed to upstream libwebrtc)

rdar://171591634

Reviewed by Jean-Yves Avenard.

Cherry-pick of webmproject/libvpx@9a2d3d1

Originally-landed-as: 305413.430@rapid/safari-7624.2.5.110-branch (04fc2fd). rdar://176067350
Canonical link: https://commits.webkit.org/313639@main
…jC::setNetworkState during destruction

<https://bugs.webkit.org/show_bug.cgi?id=309455>
<rdar://172006984>

Reviewed by Jean-Yves Avenard.

Revoke all weak pointers at the start of the
`~MediaPlayerPrivateMediaSourceAVFObjC()` destructor to prevent
re-entrant callbacks during member destruction.  C++ destroys
`m_logger` before `m_mediaSourcePrivate` (reverse declaration
order), and the `m_mediaSourcePrivate` destructor can trigger
synchronous KVO notifications that invoke `WeakPtr`-guarded
callbacks on the partially-destroyed object.  Since the
`CanMakeWeakPtr` base class destructor runs after all member
destructors, `WeakPtr::get()` still succeeds, allowing
callbacks to access already-destroyed members.

* Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::~MediaPlayerPrivateMediaSourceAVFObjC):

Originally-landed-as: 305413.419@rapid/safari-7624.2.5.110-branch (4424466). rdar://176067520
Canonical link: https://commits.webkit.org/313640@main
…veIf

rdar://171096572

Reviewed by Tim Horton.

To avoid invalidating the loop iterator by removing the current element,
use HashMap::removeIf to correctly remove elements whose timeline have
become empty.

* Source/WebCore/animation/StyleOriginatedTimelinesController.cpp:
(WebCore::StyleOriginatedTimelinesController::documentDidResolveStyle):

Originally-landed-as: 305413.400@rapid/safari-7624.2.5.110-branch (a8304e8). rdar://176067567
Canonical link: https://commits.webkit.org/313641@main
…aselines

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

Unreviewed test gardening.

* LayoutTests/platform/glib/imported/w3c/web-platform-tests/css/css-values/attr-pseudo-elem-invalidation-2-expected.txt: Added.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/css/css-values/urls/url-request-modifiers-invalid.sub-expected.txt: Removed.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/css/css-values/urls/url-request-modifiers-serialize.sub-expected.txt: Removed.

Canonical link: https://commits.webkit.org/313642@main
…ling on release bots.

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

Unreviewed test gardening.

* LayoutTests/platform/glib/TestExpectations:

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

Reviewed by Carlos Garcia Campos.

After 312211@main, method 'resolveURLStringIfNeeded' always returns a
complete URL for 'ResolveURLs::YesExcludingURLsForPrivacy'.

This change made several tests regress for WebKitGTK since now 'href' or 'src'
values equal to a full filesystem URL. Before 312211@main, an extra check
returned a relative URL in case the URL's protocol was filesystem. This seems
to be the correct behaviour for WebKitGTK.

Reintroduce URL's protocol check, but only for WebKitGTK.

* LayoutTests/platform/gtk/TestExpectations:
* Source/WebCore/dom/Element.cpp:
(WebCore::Element::resolveURLStringIfNeeded const):

Canonical link: https://commits.webkit.org/313644@main
…or IOSMouseEventTestHarness.h

https://bugs.webkit.org/show_bug.cgi?id=315260
rdar://177590639

Reviewed by Charlie Wolfe and BJ Burg.

SwitchInputTests.mm imported "IOSMouseEventTestHarness.h" with a bare
filename. This resolved under the Xcode build because of its header
search paths, but broke the Mac CMake build, which only sees the header
via its repo-relative path.

Match the convention used by every other consumer of this header
(SampledPageTopColor.mm, UIDelegate.mm, UnifiedPDFTests.mm,
iOSMouseSupport.mm, NavigationAction.mm) and the harness's own .mm:
import as "Helpers/ios/IOSMouseEventTestHarness.h".

* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SwitchInputTests.mm:

Canonical link: https://commits.webkit.org/313645@main
…allbacks

https://bugs.webkit.org/show_bug.cgi?id=314216
rdar://176378344

Reviewed by Simon Fraser.

The two requestAnimationFrame (rAF) callbacks ran before any scroll,
so the snapshot raced with the scroll-induced layer commit. Move
scrollBy to script execution time so the first frame is already at the
target, and let the rAFs settle two render updates before
takeScreenshot.

Canonical link: https://commits.webkit.org/313646@main
…age with 60Hz display

https://bugs.webkit.org/show_bug.cgi?id=315209
rdar://176420489

Reviewed by Simon Fraser.

On macOS, an animation update is triggered both when a display refresh occurs on the
scrolling thread, somewhere under `RemoteLayerTreeEventDispatcher::didRefreshDisplay()`,
and when a page rendering update has completed on the main thread, in
`RemoteLayerTreeEventDispatcher::renderingUpdateComplete()`.

The latter call was added in 303810@main to ensure that programmatic scrolls would
correctly update progress-based animations. However, this has the undesired effects
that when the page rendering is updated, all animations, including those contained
in animation stacks that only contain time-based animations, are updated twice.

In the case of a Pro Motion display, typically this would mean that we update animations
twice every other frame, since page rendering updates still occur near 60Hz by default.
But on a display set to refresh at 60Hz, the issue is made worse since we end up
updating animations twice on every frame.

To address this, at least for the case where only time-based animations are used (the
vast majority of cases at this currently), we no longer update animation stacks that
only contain time-based animations when `RemoteLayerTreeEventDispatcher::renderingUpdateComplete()`
is called. We do so by adding a new enum argument to `updateAnimations()` and only
advance monotonic timelines and update animation stacks containing time-based animations
if the argument indicates that all animation stacks should be updated, as opposed to those
containing at least one progress-based animation.

* Source/WebKit/UIProcess/RemoteLayerTree/RemoteAnimationStack.h:
* Source/WebKit/UIProcess/RemoteLayerTree/RemoteAnimationStack.mm:
(WebKit::RemoteAnimationStack::RemoteAnimationStack):
(WebKit::RemoteAnimationStack::isTimeDependent const): Deleted.
* Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
(WebKit::RemoteScrollingCoordinatorProxyIOS::updateTimeDependentAnimationStacks):
* Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteLayerTreeEventDispatcher.h:
* Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteLayerTreeEventDispatcher.mm:
(WebKit::RemoteLayerTreeEventDispatcher::renderingUpdateComplete):
(WebKit::RemoteLayerTreeEventDispatcher::updateAnimations):

Canonical link: https://commits.webkit.org/313647@main
https://bugs.webkit.org/show_bug.cgi?id=315157
rdar://177475579

Reviewed by Cameron McCormack and Mike Wyrzykowski.

`WebXRAugmentedRealityModuleEnabled` is enabled on visionOS builds and shows
under internal settings. This option is intended to expose the prototype of
augmented reality on iOS devices, not visionOS devices, where there is no AR
support.

This is confusing to end users who flip the settings and expect immersive AR
support on visionPro. This change removes the option on shipping
visionOS. Introduction of ENABLE_WEBXR_AR is necessary for compilation of
JS-derived interface of WebXRSession+AR.idl to compile.

* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml:
* Source/WTF/wtf/PlatformEnable.h:
* Source/WTF/wtf/PlatformEnableCocoa.h:
* Source/WebCore/Modules/webxr/WebXRSession+AR.idl:
* Source/cmake/OptionsGTK.cmake:
* Source/cmake/OptionsWPE.cmake:

Canonical link: https://commits.webkit.org/313648@main
…ce1f12ea

# Conflicts:
#	Source/JavaScriptCore/bytecode/InstructionStream.h
#	Source/JavaScriptCore/runtime/AbstractModuleRecord.h
#	Source/JavaScriptCore/runtime/JSMicrotask.cpp
#	Source/JavaScriptCore/runtime/JSModuleLoader.cpp
#	Source/JavaScriptCore/runtime/JSPromise.cpp
#	Source/JavaScriptCore/runtime/StringConstructor.cpp
#	Source/JavaScriptCore/runtime/TypedArrayAdaptors.h
#	Source/WebCore/css/values/backgrounds/CSSBorderImageSlice.cpp
#	Source/WebCore/css/values/masking/CSSMaskBorderSlice.cpp
#	Source/WebCore/css/values/masking/CSSMaskBorderWidth.cpp
- BunV8HeapSnapshotBuilder: read SymbolImpl directly instead of
  Symbol::description(VM&), which now lazily allocates a JSString
- AbstractModuleRecord::estimatedSize: OrderedHashMap has no byteSize();
  approximate from capacity()
- JSModuleLoader::loadModuleSync: pass OptionSet<ModuleLoadFlag> to
  loadModule (replaces 3 bool args)
- CMakeLists.txt: drop removed JSHeapInt32/Double headers; export
  JSAsyncFunctionGenerator.h as a forwarding header
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

Review Change Stack

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 28

🤖 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/modules/import-defer-dynamic-syntax.js`:
- Around line 16-23: The test must distinguish synchronous throws from returned
rejected promises: call import.defer({ toString() { throw new
Error("specifier"); } }) and capture its return in a variable (e.g., promise) to
ensure the call itself does not throw synchronously, then await that promise and
assert the rejection message; update the block around the import.defer
invocation so the call is assigned to a promise variable (or wrapped to fail if
it throws synchronously) and only then use await and shouldBe(rejected.message,
"specifier") to validate the error.

In `@JSTests/stress/perform-promise-then-one-handler.js`:
- Line 1: This test calls $vm.* intrinsics (used in PerformPromiseThenOneHandler
paths) but doesn't enable DollarVM; add the standard DollarVM enable directive
at the top of the file so $vm is defined before any calls (place the directive
before the first $vm.* usage), e.g. insert the test harness directive used
across other JSTests to enable DollarVM intrinsics (so the $vm.* calls at the
spots referenced will not throw ReferenceError).

In `@JSTests/stress/string-prototype-match-watchpoint-invalidation.js`:
- Around line 113-117: The tests set up valueOfCount and install re.lastIndex
with a valueOf that increments it but never assert the counter; add explicit
assertions to verify lastIndex.valueOf was invoked in both coercion-path
scenarios by checking valueOfCount equals the expected number after the call to
match("a1b2c3", re) (and after the second scenario around lines 168-176), and
reset valueOfCount between scenarios so each path's coercion is independently
validated (use the existing symbols valueOfCount, re.lastIndex and the
match(...) invocations to locate where to insert the assertions).

In `@JSTests/wasm/stress/resources/pglite/jsc-harness.js`:
- Around line 97-101: The loop trusts len and computes bodyStart/bodyEnd without
bounds checks, allowing dv.getInt32 or subsequent body reads to go
out-of-bounds; before calling dv.getInt32 and before parsing the body or setting
i = bodyEnd, validate that (i + 1 + 4) and (i + 1 + len) are within bytes.length
(and that len is non-negative and reasonable), and if invalid, handle the
truncated/malformed frame (e.g., log/skip/abort the harness) in the same loop
that processes tag, len, bodyStart, bodyEnd; apply the same boundary checks to
the other parsing site referenced (around lines 142-143) so both dv.getInt32 and
body slicing never read past bytes.length.
- Around line 47-50: The current PGProtocol.cstr(s) and various response parsers
use single-byte charCodeAt/fromCharCode which truncates non-ASCII; replace these
with a UTF-8 TextEncoder/TextDecoder approach: create a shared TextEncoder
instance and have cstr(s) return encoder.encode(s) plus a null terminator
instead of masking with &0xff, and in the parsers for message types T (field
names), D (row column values), C (command tags), and E (error message parts) use
a TextDecoder to decode the byte subarray up to the 0 byte into a UTF-8 string
(rather than String.fromCharCode per byte). Ensure you handle the null
terminator removal consistently and reuse encoder/decoder instances for
performance.

In `@LayoutTests/accessibility/dialog-focus-on-open.html`:
- Around line 36-45: The awaited expectAsync call can throw and prevent cleanup;
wrap the async block started by setTimeout in try/catch/finally so that
showButton.press and await expectAsync/expect run inside try, any error is
captured in catch (append error text to output), and
accessibilityController.removeNotificationListener() plus debug(output) and
finishJSTest() are executed in finally; reference the existing symbols
showButton.press(), expectAsync("window.focusedAtNotificationTime"...),
expect("accessibilityController.focusedElement.domIdentifier"...),
accessibilityController.removeNotificationListener(), debug(output), and
finishJSTest() when making the change.

In
`@LayoutTests/accessibility/dynamic-subtree-replacement-with-stale-parent-children.html`:
- Around line 26-62: Wrap the async block body that starts with creating
makePageDirty and performs awaited operations (including the role change,
innerHTML swap, awaiting accessibilityController.accessibleElementById,
expectAsync, waitForElementById loops, and any other awaits) in a try/finally so
that clearInterval(makePageDirty) and finishJSTest() always run; specifically,
create the interval (makePageDirty) before the try, move all subsequent logic
into the try block, and place clearInterval(makePageDirty) and finishJSTest()
inside the finally block (optionally also calling debug(output) there) to
guarantee teardown even if awaits like expectAsync or waitForElementById reject.

In `@LayoutTests/applicationmanifest/developer-warnings.html`:
- Around line 6-10: The async IIFE currently awaits
testRunner.getApplicationManifest() but if that promise rejects
testRunner.notifyDone() is never called; wrap the await call in a try/finally
inside the same async IIFE so that testRunner.notifyDone() is invoked in the
finally block (and preserve the success alert inside the try, optionally handle
errors in a catch before the finally) to guarantee notifyDone always runs.

In `@LayoutTests/applicationmanifest/multiple-links.html`:
- Around line 11-15: The async IIFE currently awaits
testRunner.getApplicationManifest() and calls testRunner.notifyDone() only on
success, so thrown/rejected errors can skip notifyDone(); wrap the await call in
a try/finally: call testRunner.getApplicationManifest() inside try (optionally
set outputdiv in try or catch), and ensure testRunner.notifyDone() is invoked in
the finally block so the harness is always notified even on error; reference
testRunner.getApplicationManifest and testRunner.notifyDone when locating the
code to change.

In `@LayoutTests/fast/canvas/webgl/data-view-test-expected.txt`:
- Around line 32-33: Update the mismatched section label so it reflects the
actual assertion: change the heading string "Test for constructor wrong length
exception takes precedence over wrong byteoffset exception" to state that the
byteOffset error takes precedence (for example: "Test for constructor wrong
byteOffset exception takes precedence over wrong length exception") to match the
assertion shown by the failing construction of new Int32Array(... ) which throws
the RangeError about byteOffset modulo TypedArray.BYTES_PER_ELEMENT.

In `@LayoutTests/fast/repaint/blur-change.html`:
- Line 34: Update the test description string passed to description(...) so it
references blur rather than drop-shadow (e.g., "Test repaint rects when the blur
filter property changes" or mention blur(...)); locate the description(...) call
in the file and replace the misleading text so test messaging/fixtures match the
actual blur(...) behavior being tested.

In `@LayoutTests/fast/repaint/drop-shadow-writing-modes.html`:
- Around line 29-33: After mutating styles with
document.body.classList.add('changed'), force a rendering/layout/paint sync
before calling window.internals.repaintRectsAsText() to avoid racing with paint
commit; insert a flush such as reading a layout/paint-dependent property (e.g.,
document.body.offsetWidth or
window.getComputedStyle(document.body).getPropertyValue(...)) between the
mutation and the calls to window.internals.repaintRectsAsText() and
internals.stopTrackingRepaints() so the repaint rects are read after the browser
has applied the style change.

In
`@LayoutTests/http/tests/resourceLoadStatistics/third-party-cookie-blocking-about-blank-popup.html`:
- Around line 50-53: The current check treats any response lacking cookieName as
success, which counts fetch errors like the "ERROR: ..." payload as PASS; update
the logic around result and cookieName so that you first detect and fail on
fetch errors (e.g., if result startsWith or contains the "ERROR:" prefix) and
call testFailed with that error payload, otherwise proceed to check
result.indexOf(cookieName) === -1 to decide pass/fail; refer to the variables
cookieName, result and the testPassed/testFailed calls to locate and change the
conditional.

In `@LayoutTests/http/tests/security/cross-origin-blob-transfer.html`:
- Around line 11-15: Guard the message handler in the
window.addEventListener("message", t.step_func(...)) callback by verifying the
sender before processing: first check e.origin (e.g., e.origin ===
location.origin) or e.source if comparing to a known window, and also verify
e.data is a Blob if appropriate; only then call
e.data.text().then(t.step_func_done(...)) and assert_equals(text, "Blob
content"). This prevents handling unrelated messages and keeps the existing
t.step_func/t.step_func_done flow (refer to the message event callback,
e.data.text(), t.step_func_done, and assert_equals).

In `@LayoutTests/http/tests/security/cross-origin-iframe-fetch-after-crash.html`:
- Around line 15-31: The message handler attached with
window.addEventListener("message", ...) currently trusts any message and may act
on external senders; update the handler to first validate the sender (e.g.,
ensure event.source === document.querySelector("iframe").contentWindow and/or
check event.origin against the expected origin) before handling the
"pre-crash-ok" and "post-crash-ok" event.data values or calling testRunner. Keep
the existing branches for "pre-crash-ok" and "post-crash-ok" but bail out early
if the sender/origin check fails.
- Around line 34-41: The polling helper waitForNetworkProcessToRelaunch()
currently retries forever; add a bounded retry policy (e.g., maxAttempts or a
deadline timestamp) and ensure it fails explicitly after the limit by rejecting
the promise and calling notifyDone() (or otherwise signalling test failure)
instead of looping endlessly; update the function signature (e.g., add an
attempts parameter or check Date.now() against a deadline), use the existing
waitTime backoff logic, and when the cap is reached log the failure and call
notifyDone() so the test cannot hang indefinitely.

In `@LayoutTests/http/tests/security/cross-origin-indexeddb.html`:
- Around line 16-31: The message handler attached via
window.addEventListener("message", ...) does not validate the sender, so
unrelated postMessage events can trigger the stored/TRANSIENT/PERSISTENT logic;
update the listener in this file to early-return unless event.origin and/or
event.source match the expected iframe origin/source (e.g., compare event.origin
to the iframe's known origin or keep a saved reference to the
iframe.contentWindow and compare event.source), then only process messages and
call testRunner.notifyDone()/terminateNetworkProcess() for validated senders.

In
`@LayoutTests/http/tests/site-isolation/open-panel-in-cross-origin-iframe.html`:
- Around line 12-18: The message event handler registered with
window.addEventListener("message", async (event) => { ... }) accepts messages
from any sender which can make the test flaky; update the handler to only
process events that originate from the test iframe by checking event.source ===
iframe.contentWindow (and optionally verify event.origin matches the expected
origin) before reading event.data and proceeding with setting window.chosenFile,
calling shouldBeEqualToString, or finishJSTest; apply the same gated check to
the other message listener around the same payload handling.

In `@LayoutTests/http/tests/site-isolation/resources/file-input-iframe.html`:
- Around line 15-24: Restrict the message handler to only accept events from the
embedding parent by checking event.source === window.parent before processing;
inside the existing window.addEventListener("message", ...) callback,
early-return if event.source !== window.parent (while keeping the existing
event.data.type === "getInputRect" check), then compute rect via
input.getBoundingClientRect() and post the response to window.parent as before
using window.parent.postMessage; this change touches the message handler around
window.addEventListener, the event object check, and the existing getInputRect
handling.

In
`@LayoutTests/http/tests/site-isolation/resources/validation-message-iframe.html`:
- Around line 30-35: The message handler registered via
window.addEventListener("message", ...) accepts any sender; update the handler
to also verify event.source === window.parent before acting so only the harness
parent frame can trigger submission; keep the existing check for event.data ===
"submit" and then call document.getElementById("submit").click() and
requestAnimationFrame(() => parent.postMessage("submitted", "*")) only when both
conditions match.

In
`@LayoutTests/http/tests/site-isolation/validation-message-cross-origin-iframe.html`:
- Around line 43-47: The message handler currently resolves on any "submitted"
message from any source; update the window.addEventListener("message", ...)
callback to verify that event.data === "submitted" AND event.source ===
iframe.contentWindow before calling resolve so only messages from the target
iframe trigger completion; keep the once: true option and leave
iframe.contentWindow.postMessage("submit", "*") as-is.

In
`@LayoutTests/http/wpt/content-security-policy/sandbox-manifest-blocked-cross-origin.sub.html`:
- Around line 10-15: The async IIFE directly dereferences testRunner (calls
testRunner.getApplicationManifest() and testRunner.notifyDone()) which will
throw if the file runs outside the test harness; guard those calls by checking
testRunner exists and the needed methods exist before invoking them (e.g.,
verify typeof testRunner !== 'undefined' and typeof
testRunner.getApplicationManifest === 'function' and typeof
testRunner.notifyDone === 'function'), only call getApplicationManifest() and
notifyDone() when those checks pass, and otherwise skip or provide a safe
fallback; reference testRunner, getApplicationManifest, and notifyDone when
locating where to add these guards.

In `@LayoutTests/http/wpt/content-security-policy/sandbox-manifest-blocked.html`:
- Around line 8-13: The async IIFE uses testRunner.getApplicationManifest() and
testRunner.notifyDone() without checking for testRunner; add a presence guard at
the top of the IIFE (e.g. verify testRunner exists and that
getApplicationManifest is a function) and early-return or skip those calls when
absent so the code won’t throw outside the test harness—apply the guard to the
calls referencing testRunner (getApplicationManifest and notifyDone) in the
async function that queries the link element.

In `@LayoutTests/imported/w3c/web-platform-tests/beacon/resources/url-echo.py`:
- Around line 8-14: The handler reads cmd and id via request.GET.first and then
calls request.server.stash.put/take which can use None as a key; before touching
request.server.stash (e.g., before stash.put and stash.take), validate that both
cmd and id are present and if either is missing respond with a 400 error; update
the branches that use cmd and id (the cmd == b"store"/b"stat" checks and calls
to request.server.stash.put/take and request.url_parts.query) to only run after
this existence check so no stash operations occur with a null key.

In
`@LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-nn.html`:
- Around line 22-27: The awaitEvent-based listener in iframeDialogIsOpen
currently races on any window "message"; update iframeDialogIsOpen to only
accept message events coming from the target iframe by validating event.source
=== iframe.contentWindow (and event.origin if needed). If awaitEvent supports a
predicate, pass a filter that checks event.source === iframe.contentWindow (and
event.origin match), otherwise replace with an explicit addEventListener that
ignores messages from other sources before resolving and removes the listener
after use; keep the rest of the logic (postMessage "dialog_open", error check,
return data.open) unchanged.

In
`@LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynn.html`:
- Line 34: Await the promise returned by test_driver.bless() before any
subsequent activation steps to avoid a race with test_driver.send_keys();
specifically, update the call sites in dialog-same-origin-ynn.html (the
test_driver.bless() before the await test_driver.send_keys(...)) and the two
analogous call sites in dialog-same-origin-ynyn.html to use await
test_driver.bless() so the blessing/click completes before sending keys.

In
`@LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/resources/dialog-prevents-close.html`:
- Line 14: The message event handler is using the global/implicit name `event`
instead of the callback parameter `e`, which can fail in some environments;
update the listener callback to reference the passed-in argument (use `e.data`
instead of `event.data`) wherever the handler checks or accesses the message
payload (the function registered for "message" that currently declares `e`).
- Around line 5-6: Remove the duplicate script include for
"/resources/testdriver.js" so the file is only loaded once; locate the two
identical <script src="/resources/testdriver.js"></script> entries and delete
the redundant one (keep a single include) to avoid double-initializing the test
harness.
🪄 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: b1f52604-a6a0-4a85-8bed-d0a92ec9a580

📥 Commits

Reviewing files that changed from the base of the PR and between 01ecc4e and e54e803.

⛔ Files ignored due to path filters (3)
  • JSTests/wasm/stress/resources/pglite/pglite.wasm is excluded by !**/*.wasm
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/resources/w3c-import.log is excluded by !**/*.log
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/w3c-import.log is excluded by !**/*.log
📒 Files selected for processing (297)
  • .submitproject
  • .submitproject-append
  • .wkdev-sdk-version
  • CMakeLists.txt
  • CMakePresets.json
  • Configurations/CommonBase.xcconfig
  • Configurations/Version.xcconfig
  • Configurations/WebKitProjectPaths.xcconfig
  • JSTests/microbenchmarks/array-includes-string-8bit-long.js
  • JSTests/microbenchmarks/array-indexof-string-8bit-long.js
  • JSTests/microbenchmarks/array-indexof-string-8bit-short.js
  • JSTests/microbenchmarks/await-object-literal.js
  • JSTests/microbenchmarks/date-now-elapsed.js
  • JSTests/microbenchmarks/date-now.js
  • JSTests/microbenchmarks/promise-all-non-thenable-object.js
  • JSTests/microbenchmarks/promise-all-non-thenable.js
  • JSTests/microbenchmarks/promise-all-settled-non-thenable.js
  • JSTests/microbenchmarks/promise-race-non-thenable.js
  • JSTests/microbenchmarks/promise-resolve-non-thenable-object.js
  • JSTests/microbenchmarks/promise-resolve-object-literal.js
  • JSTests/microbenchmarks/promise-then-chain-object-literal.js
  • JSTests/microbenchmarks/regexp-match-digit-cached.js
  • JSTests/microbenchmarks/regexp-match-digit-literal.js
  • JSTests/microbenchmarks/string-match-digit-short.js
  • JSTests/microbenchmarks/string-match-letter-short.js
  • JSTests/modules/import-defer-dynamic-evaluation.js
  • JSTests/modules/import-defer-dynamic-rejects.js
  • JSTests/modules/import-defer-dynamic-syntax.js
  • JSTests/modules/import-defer-dynamic-tla.js
  • JSTests/modules/import-defer-dynamic.js
  • JSTests/modules/indirect-export-error.js
  • JSTests/modules/indirect-export-error/indirect-export-source-order-2.js
  • JSTests/modules/indirect-export-error/indirect-export-source-order.js
  • JSTests/stress/array-indexof-includes-string-word-compare.js
  • JSTests/stress/array-shift-intrinsic.js
  • JSTests/stress/array-sort-inline-ai-cell-butterfly-validation.js
  • JSTests/stress/array-sort-inline-isnan-comparator-cps.js
  • JSTests/stress/array-sort-inline-nested-in-comparator.js
  • JSTests/stress/array-unshift-intrinsic-ftl.js
  • JSTests/stress/array-unshift-intrinsic.js
  • JSTests/stress/asynciterator-prototype-symbol-async-dispose-return-argument.js
  • JSTests/stress/date-now-jit.js
  • JSTests/stress/dfg-perform-promise-then-one-handler-exit-ok.js
  • JSTests/stress/dfg-promise-resolve-fulfilled-object.js
  • JSTests/stress/dynamic-import-inline-microtask-result-promise.js
  • JSTests/stress/ftl-multigetbyoffset-constant-numberuse.js
  • JSTests/stress/iterator-prototype-flatMap-return-no-arguments.js
  • JSTests/stress/megamorphic-ic-symbol.js
  • JSTests/stress/object-define-property-fields-spilled-arg.js
  • JSTests/stress/perform-promise-then-one-handler.js
  • JSTests/stress/promise-combinator-non-thenable-element.js
  • JSTests/stress/promise-resolve-non-thenable-structure-cache-cross-realm.js
  • JSTests/stress/promise-resolve-non-thenable-structure-cache-dictionary.js
  • JSTests/stress/promise-resolve-non-thenable-structure-cache.js
  • JSTests/stress/spread-set-own-symbol-iterator-side-effects.js
  • JSTests/stress/string-prototype-match-edge-cases.js
  • JSTests/stress/string-prototype-match-strength-reduction.js
  • JSTests/stress/string-prototype-match-watchpoint-invalidation.js
  • JSTests/stress/string-substr-strength-reduction.js
  • JSTests/stress/string-substr.js
  • JSTests/stress/symbol-prototype-to-string-intrinsic.js
  • JSTests/stress/typedarray-constructor-allocatetypedarray-before-isdetachedbuffer-prototype-getter-detach.js
  • JSTests/stress/typedarray-constructor-allocatetypedarray-before-isdetachedbuffer.js
  • JSTests/stress/typedarray-constructor-allocatetypedarray-before-toindex-byteoffset.js
  • JSTests/stress/typedarray-constructor-allocatetypedarray-before-toindex-length.js
  • JSTests/stress/typedarray-constructor-byteoffset-modulo-elementsize-before-isdetachedbuffer-weird-byteoffset.js
  • JSTests/stress/typedarray-constructor-byteoffset-modulo-elementsize-before-isdetachedbuffer.js
  • JSTests/stress/typedarray-constructor-byteoffset-modulo-elementsize-before-toindex-length.js
  • JSTests/stress/typedarray-constructor-isdetachbuffer-before-bufferbytelength-modulo-elementsize-weird-byteoffset-detach.js
  • JSTests/stress/typedarray-constructor-isdetachbuffer-before-bufferbytelength-modulo-elementsize.js
  • JSTests/stress/typedarray-constructor-isdetachbuffer-before-newbytelength-lt-0-weird-byteoffset.js
  • JSTests/stress/typedarray-constructor-isdetachbuffer-before-newbytelength-lt-0.js
  • JSTests/stress/typedarray-constructor-isdetachbuffer-before-offset+newbytelength-gt-bufferbytelength-byteoffset-too-large.js
  • JSTests/stress/typedarray-constructor-isdetachbuffer-before-offset+newbytelength-gt-bufferbytelength-length-too-large.js
  • JSTests/stress/typedarray-constructor-toindex-byteoffset-before-isdetachedbuffer-weird-byteoffset-detach.js
  • JSTests/stress/typedarray-constructor-toindex-byteoffset-before-isdetachedbuffer.js
  • JSTests/stress/typedarray-constructor-toindex-byteoffset-detach-buffer.js
  • JSTests/stress/typedarray-constructor-toindex-length-before-isdetachedbuffer-weird-byteoffset-detach.js
  • JSTests/stress/typedarray-constructor-toindex-length-before-isdetachedbuffer-weird-length-detach.js
  • JSTests/stress/typedarray-constructor-toindex-length-before-isdetachedbuffer.js
  • JSTests/stress/typedarray-constructor-toindex-length-detach-buffer.js
  • JSTests/test262/config.yaml
  • JSTests/test262/expectations.yaml
  • JSTests/wasm/stress/lazy-table-copy-preserves-laziness.js
  • JSTests/wasm/stress/lazy-table-cross-instance.js
  • JSTests/wasm/stress/lazy-table-identity-across-paths.js
  • JSTests/wasm/stress/lazy-table-wrappers.js
  • JSTests/wasm/stress/pglite.js
  • JSTests/wasm/stress/resources/pglite/LICENSE.Emscripten
  • JSTests/wasm/stress/resources/pglite/LICENSE.PostgreSQL
  • JSTests/wasm/stress/resources/pglite/LICENSE.pglite
  • JSTests/wasm/stress/resources/pglite/README.md
  • JSTests/wasm/stress/resources/pglite/jsc-harness.js
  • JSTests/wasm/stress/resources/pglite/pglite.data
  • JSTests/wasm/stress/resources/pglite/pglite.js
  • JSTests/wasm/stress/resources/pglite/psql.js
  • LayoutTests/TestExpectations
  • LayoutTests/accessibility/dialog-focus-on-open-expected.txt
  • LayoutTests/accessibility/dialog-focus-on-open.html
  • LayoutTests/accessibility/dynamic-subtree-replacement-with-stale-parent-children-expected.txt
  • LayoutTests/accessibility/dynamic-subtree-replacement-with-stale-parent-children.html
  • LayoutTests/applicationmanifest/developer-warnings.html
  • LayoutTests/applicationmanifest/multiple-links-expected.txt
  • LayoutTests/applicationmanifest/multiple-links.html
  • LayoutTests/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt
  • LayoutTests/compositing/geometry/bounds-with-filters-expected.txt
  • LayoutTests/compositing/geometry/bounds-with-filters.html
  • LayoutTests/compositing/geometry/frame-clipping-layer-with-bottom-right-inset-expected.txt
  • LayoutTests/compositing/geometry/frame-clipping-layer-with-bottom-right-inset.html
  • LayoutTests/compositing/geometry/frame-clipping-layer-with-top-left-inset-expected.txt
  • LayoutTests/compositing/geometry/frame-clipping-layer-with-top-left-inset.html
  • LayoutTests/css3/filters/backdrop/backdrop-blur-and-subsequent-elements-expected.html
  • LayoutTests/css3/filters/backdrop/backdrop-blur-and-subsequent-elements.html
  • LayoutTests/css3/filters/drop-shadow-target-clipped.html
  • LayoutTests/editing/pasteboard/cjk-line-height-expected.txt
  • LayoutTests/fast/canvas/webgl/data-view-test-expected.txt
  • LayoutTests/fast/css/container-query-orientation-modal-dialog-crash-expected.txt
  • LayoutTests/fast/css/container-query-orientation-modal-dialog-crash.html
  • LayoutTests/fast/css/css-typed-om-typeerror-coalescing-pair-expected.txt
  • LayoutTests/fast/css/css-typed-om-typeerror-coalescing-pair.html
  • LayoutTests/fast/css/css-typed-om/css-builder-converter-initial-letter-crash-expected.txt
  • LayoutTests/fast/css/css-typed-om/css-builder-converter-initial-letter-crash.html
  • LayoutTests/fast/css/css-typed-om/css-typed-om-typeerror-associated-property-mismatch-expected.txt
  • LayoutTests/fast/css/css-typed-om/css-typed-om-typeerror-associated-property-mismatch.html
  • LayoutTests/fast/css/cssom-border-image-width-crash.html
  • LayoutTests/fast/css/cssom-mask-border-width-crash-expected.txt
  • LayoutTests/fast/css/cssom-mask-border-width-crash.html
  • LayoutTests/fast/css/cssom-translate-crash-expected.txt
  • LayoutTests/fast/css/cssom-translate-crash.html
  • LayoutTests/fast/css/getComputedStyle/computed-style-font-family-expected.txt
  • LayoutTests/fast/css/getComputedStyle/font-family-fallback-reset-expected.txt
  • LayoutTests/fast/css/getComputedStyle/font-family-fallback-reset.html
  • LayoutTests/fast/css/serialization-with-double-quotes-expected.txt
  • LayoutTests/fast/css/serialization-with-double-quotes.html
  • LayoutTests/fast/css/stylepropertymap-append-not-checking-for-variablereferencevalue-expected.txt
  • LayoutTests/fast/css/stylepropertymap-append-not-checking-for-variablereferencevalue.html
  • LayoutTests/fast/dom/StyleSheet/css-font-variation-settings-crash.html
  • LayoutTests/fast/dom/navigator-detached-no-crash-expected.txt
  • LayoutTests/fast/flexbox/preferred-width-empty-inline-block-expected.txt
  • LayoutTests/fast/flexbox/preferred-width-empty-inline-block.html
  • LayoutTests/fast/forms/ios/form-control-refresh/button/identical-buttons-have-same-corner-radius-expected.html
  • LayoutTests/fast/forms/ios/form-control-refresh/button/identical-buttons-have-same-corner-radius.html
  • LayoutTests/fast/forms/ios/select-menulist-text-align-chevron-padding-expected.txt
  • LayoutTests/fast/forms/ios/select-menulist-text-align-chevron-padding.html
  • LayoutTests/fast/forms/label/label-click-event-dispatch-untrusted-expected.txt
  • LayoutTests/fast/forms/label/label-click-event-dispatch-untrusted.html
  • LayoutTests/fast/grid/grid-item-block-content-size-suggestion-crash-expected.txt
  • LayoutTests/fast/grid/grid-item-block-content-size-suggestion-crash.html
  • LayoutTests/fast/hidpi/filters-drop-shadow.html
  • LayoutTests/fast/images/stopped-animation-deleted-image.html
  • LayoutTests/fast/overflow/intrinsic-width-container-with-scrollable-descendant-expected.html
  • LayoutTests/fast/overflow/intrinsic-width-container-with-scrollable-descendant.html
  • LayoutTests/fast/overflow/min-intrinsic-width-container-with-scrollable-descendant-expected.html
  • LayoutTests/fast/overflow/min-intrinsic-width-container-with-scrollable-descendant.html
  • LayoutTests/fast/repaint/blur-change-expected.txt
  • LayoutTests/fast/repaint/blur-change.html
  • LayoutTests/fast/repaint/drop-shadow-box-change-expected.txt
  • LayoutTests/fast/repaint/drop-shadow-box-change.html
  • LayoutTests/fast/repaint/drop-shadow-change-expected.txt
  • LayoutTests/fast/repaint/drop-shadow-change.html
  • LayoutTests/fast/repaint/drop-shadow-writing-modes-expected.txt
  • LayoutTests/fast/repaint/drop-shadow-writing-modes.html
  • LayoutTests/fast/repaint/select-option-background-color-tracked.html
  • LayoutTests/fast/scrolling/ios/fixed-position-in-vertical-rl-expected.html
  • LayoutTests/fast/scrolling/ios/fixed-position-in-vertical-rl.html
  • LayoutTests/fast/scrolling/ios/iframe-scroll-into-view.html
  • LayoutTests/fast/shadow-dom/style-invalidation-slotted-element-with-author-shadow-root-crash-expected.txt
  • LayoutTests/fast/shadow-dom/style-invalidation-slotted-element-with-author-shadow-root-crash.html
  • LayoutTests/fast/text-extraction/contenteditable-text-extraction-expected.txt
  • LayoutTests/fast/text-extraction/contenteditable-text-extraction.html
  • LayoutTests/fast/text-extraction/max-recursion-depth-cap-expected.html
  • LayoutTests/fast/text-extraction/max-recursion-depth-cap.html
  • LayoutTests/fast/text-extraction/text-extraction-scroll-fallback-to-large-container-expected.txt
  • LayoutTests/fast/text-extraction/text-extraction-scroll-fallback-to-large-container.html
  • LayoutTests/fast/text/font-face-family-expected.txt
  • LayoutTests/fast/text/font-face-family.html
  • LayoutTests/fast/text/font-stretch-parse-expected.txt
  • LayoutTests/fast/text/font-stretch-parse.html
  • LayoutTests/fast/text/font-style-parse-expected.txt
  • LayoutTests/fast/text/font-style-parse.html
  • LayoutTests/fast/text/font-weight-parse-expected.txt
  • LayoutTests/fast/text/font-weight-parse.html
  • LayoutTests/http/tests/cache/partitioned-cache-iframe.html
  • LayoutTests/http/tests/cache/partitioned-cache.html
  • LayoutTests/http/tests/cache/resources/partitioned-cache-loader.html
  • LayoutTests/http/tests/css/filters-on-iframes-transform.html
  • LayoutTests/http/tests/css/filters-on-iframes.html
  • LayoutTests/http/tests/css/resources/references-external-green.html
  • LayoutTests/http/tests/css/resources/references-external-red.html
  • LayoutTests/http/tests/navigation/page-cache-pending-image-load-cache-partition.html
  • LayoutTests/http/tests/navigation/pushstate-at-unique-origin-denied-expected.txt
  • LayoutTests/http/tests/navigation/pushstate-at-unique-origin-denied.py
  • LayoutTests/http/tests/resourceLoadStatistics/third-party-cookie-blocking-about-blank-popup-expected.txt
  • LayoutTests/http/tests/resourceLoadStatistics/third-party-cookie-blocking-about-blank-popup.html
  • LayoutTests/http/tests/security/contentSecurityPolicy/manifest-src-allowed-expected.txt
  • LayoutTests/http/tests/security/contentSecurityPolicy/manifest-src-allowed.html
  • LayoutTests/http/tests/security/contentSecurityPolicy/manifest-src-blocked-expected.txt
  • LayoutTests/http/tests/security/contentSecurityPolicy/manifest-src-blocked.html
  • LayoutTests/http/tests/security/contentSecurityPolicy/path-traversal-bypass-with-percent-encoding-expected.txt
  • LayoutTests/http/tests/security/contentSecurityPolicy/path-traversal-bypass-with-percent-encoding.html
  • LayoutTests/http/tests/security/credentials-iframes.html
  • LayoutTests/http/tests/security/credentials-main-resource.html
  • LayoutTests/http/tests/security/cross-origin-blob-transfer-expected.txt
  • LayoutTests/http/tests/security/cross-origin-blob-transfer.html
  • LayoutTests/http/tests/security/cross-origin-iframe-fetch-after-crash-expected.txt
  • LayoutTests/http/tests/security/cross-origin-iframe-fetch-after-crash.html
  • LayoutTests/http/tests/security/cross-origin-indexeddb-expected.txt
  • LayoutTests/http/tests/security/cross-origin-indexeddb.html
  • LayoutTests/http/tests/security/cross-origin-local-storage-allowed.html
  • LayoutTests/http/tests/security/cross-origin-local-storage.html
  • LayoutTests/http/tests/security/cross-origin-session-storage-third-party-blocked.html
  • LayoutTests/http/tests/security/cross-origin-websql.html
  • LayoutTests/http/tests/security/cross-origin-worker-indexeddb.html
  • LayoutTests/http/tests/security/history-pushState-replaceState-from-sandboxed-iframe-expected.txt
  • LayoutTests/http/tests/security/resources/cross-origin-iframe-fetch-after-crash-iframe.html
  • LayoutTests/http/tests/security/resources/cross-origin-iframe-for-indexeddb-transience.html
  • LayoutTests/http/tests/security/resources/document-for-cross-origin-worker-indexeddb.html
  • LayoutTests/http/tests/security/resources/history-pushState-replaceState-from-sandboxed-iframe.html
  • LayoutTests/http/tests/security/resources/load-local-storage.html
  • LayoutTests/http/tests/security/same-origin-document-domain-storage-allowed.html
  • LayoutTests/http/tests/security/same-origin-storage-blocked.html
  • LayoutTests/http/tests/security/same-origin-websql-blocked.html
  • LayoutTests/http/tests/security/sync-xhr-partition.html
  • LayoutTests/http/tests/site-isolation/inspector/network/cross-origin-iframe-request-id-uniqueness-expected.txt
  • LayoutTests/http/tests/site-isolation/inspector/network/cross-origin-iframe-request-id-uniqueness.html
  • LayoutTests/http/tests/site-isolation/open-panel-in-cross-origin-iframe-expected.txt
  • LayoutTests/http/tests/site-isolation/open-panel-in-cross-origin-iframe.html
  • LayoutTests/http/tests/site-isolation/resources/file-input-iframe.html
  • LayoutTests/http/tests/site-isolation/resources/validation-message-iframe.html
  • LayoutTests/http/tests/site-isolation/validation-message-cross-origin-iframe-expected.txt
  • LayoutTests/http/tests/site-isolation/validation-message-cross-origin-iframe.html
  • LayoutTests/http/tests/ssl/media-stream/resources/get-user-media-frame.html
  • LayoutTests/http/tests/webgpu/webgpu/shader/validation/expression/binary/short_circuiting_and_or-expected.txt
  • LayoutTests/http/tests/webgpu/webgpu/shader/validation/parse/identifiers-expected.txt
  • LayoutTests/http/wpt/content-security-policy/sandbox-manifest-blocked-cross-origin.sub-expected.txt
  • LayoutTests/http/wpt/content-security-policy/sandbox-manifest-blocked-cross-origin.sub.html
  • LayoutTests/http/wpt/content-security-policy/sandbox-manifest-blocked-expected.txt
  • LayoutTests/http/wpt/content-security-policy/sandbox-manifest-blocked.html
  • LayoutTests/imported/w3c/resources/import-expectations.json
  • LayoutTests/imported/w3c/resources/resource-files.json
  • LayoutTests/imported/w3c/web-platform-tests/beacon/beacon-url-encoding-euc-kr.https-expected.txt
  • LayoutTests/imported/w3c/web-platform-tests/beacon/beacon-url-encoding-euc-kr.https.html
  • LayoutTests/imported/w3c/web-platform-tests/beacon/resources/url-echo.py
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/META.yml
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/basic-expected.txt
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-nn.html
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynn.html
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynyn.html
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/resources/dialog-prevents-close.html
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/inside-event-listeners-expected.txt
  • LayoutTests/imported/w3c/web-platform-tests/common/reftest-wait.js
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-at-start-with-margin-top-collapses-with-parent-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-at-start-with-margin-top-collapses-with-parent-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-at-start-with-margin-top-collapses-with-parent.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-followed-by-empty-span-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-followed-by-empty-span-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-followed-by-empty-span.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-followed-by-line-break-and-text-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-followed-by-line-break-and-text-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-followed-by-line-break-and-text.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-large-margin-bottom-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-large-margin-bottom-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-large-margin-bottom.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-bottom-with-trailing-block-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-bottom-with-trailing-block-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-bottom-with-trailing-block.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-through-intervening-float-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-through-intervening-float-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-through-intervening-float.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-through-multiple-floats-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-through-multiple-floats-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-through-multiple-floats.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-with-parent-bottom-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-with-parent-bottom-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-with-parent-bottom.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-leading-and-trailing-text-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-leading-and-trailing-text-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-leading-and-trailing-text.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-leading-text-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-leading-text-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-leading-text.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-line-break-then-block-in-inline-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-line-break-then-block-in-inline-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-line-break-then-block-in-inline.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-multi-line-text-after-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-multi-line-text-after-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-multi-line-text-after.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-multi-line-text-before-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-multi-line-text-before-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-multi-line-text-before.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-text-then-block-in-inline-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-text-then-block-in-inline-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-text-then-block-in-inline.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margins-collapse-with-trailing-block-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margins-collapse-with-trailing-block-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margins-collapse-with-trailing-block.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-negative-margin-bottom-with-trailing-block-expected.html
💤 Files with no reviewable changes (18)
  • LayoutTests/fast/css/cssom-translate-crash.html
  • LayoutTests/fast/dom/StyleSheet/css-font-variation-settings-crash.html
  • LayoutTests/fast/css/css-typed-om/css-builder-converter-initial-letter-crash-expected.txt
  • LayoutTests/fast/css/cssom-mask-border-width-crash-expected.txt
  • LayoutTests/fast/flexbox/preferred-width-empty-inline-block.html
  • LayoutTests/http/tests/security/cross-origin-local-storage-allowed.html
  • LayoutTests/fast/css/css-typed-om/css-builder-converter-initial-letter-crash.html
  • LayoutTests/fast/css/css-typed-om-typeerror-coalescing-pair-expected.txt
  • LayoutTests/fast/css/cssom-translate-crash-expected.txt
  • LayoutTests/fast/css/cssom-border-image-width-crash.html
  • LayoutTests/http/tests/security/resources/load-local-storage.html
  • LayoutTests/fast/css/cssom-mask-border-width-crash.html
  • LayoutTests/fast/css/stylepropertymap-append-not-checking-for-variablereferencevalue.html
  • LayoutTests/fast/flexbox/preferred-width-empty-inline-block-expected.txt
  • LayoutTests/fast/css/css-typed-om-typeerror-coalescing-pair.html
  • LayoutTests/fast/css/stylepropertymap-append-not-checking-for-variablereferencevalue-expected.txt
  • JSTests/test262/config.yaml
  • JSTests/test262/expectations.yaml

Comment on lines +16 to +23
// Specifier ToString abrupt completion rejects (instead of throwing synchronously).
let rejected;
try {
await import.defer({ toString() { throw new Error("specifier"); } });
} catch (error) {
rejected = error;
}
shouldBe(rejected.message, "specifier");
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:

In current ECMAScript semantics for dynamic import-like operations, if converting the module specifier via ToString throws, is the result required to be a rejected Promise rather than a synchronous throw?

💡 Result:

Yes. In current ECMAScript semantics for the dynamic import expression, if evaluating the specifier part via ToString throws an exception, the dynamic import result is required to be a rejected Promise (i.e., no synchronous throw escapes from import). Authoritative support: - The ECMAScript specification’s abstract operation EvaluateImportCall produces either a Promise (normal completion) or an abrupt completion; if it later determines the module loading step produced an abrupt completion, it explicitly calls promiseCapability.[[Reject]] with the abrupt value (i.e., rejecting the promise rather than throwing) [1]. - In practice and in normative user-facing documentation, import “never synchronously throws an error” and failures (including errors during evaluation/loading) instead result in promise rejection [2]. Therefore, when ToString of the provided specifier expression throws, the import expression itself should result in a Promise that is rejected with that thrown value, not a synchronous throw from import.

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
ls -la
FILE="JSTests/modules/import-defer-dynamic-syntax.js"
if [ -f "$FILE" ]; then
  nl -ba "$FILE" | sed -n '1,120p' | sed -n '1,60p'
  nl -ba "$FILE" | sed -n '1,120p' | sed -n '10,40p'
else
  echo "Missing $FILE"
fi

Repository: oven-sh/WebKit

Length of output: 3896


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="JSTests/modules/import-defer-dynamic-syntax.js"
python3 - <<'PY'
from pathlib import Path
p = Path("JSTests/modules/import-defer-dynamic-syntax.js")
if not p.exists():
    raise SystemExit(f"Missing {p}")
lines = p.read_text(encoding="utf-8", errors="replace").splitlines()
start, end = 10, 40
for i in range(start, min(end, len(lines))):
    print(f"{i+1:4d}: {lines[i]}")
PY

Repository: oven-sh/WebKit

Length of output: 707


Split sync-throw vs promise-rejection checks for import.defer specifier toString() errors.

The current test only catches the error from await, so it would pass whether import.defer(...) throws synchronously or returns a rejected promise. Assert that the import.defer(...) call itself doesn’t throw before awaiting.

Proposed fix
 // Specifier ToString abrupt completion rejects (instead of throwing synchronously).
-let rejected;
-try {
-    await import.defer({ toString() { throw new Error("specifier"); } });
-} catch (error) {
-    rejected = error;
-}
+let syncThrow;
+let promise;
+try {
+    promise = import.defer({ toString() { throw new Error("specifier"); } });
+} catch (error) {
+    syncThrow = error;
+}
+shouldBe(syncThrow, undefined);
+
+let rejected;
+try {
+    await promise;
+} catch (error) {
+    rejected = error;
+}
 shouldBe(rejected.message, "specifier");
📝 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
// Specifier ToString abrupt completion rejects (instead of throwing synchronously).
let rejected;
try {
await import.defer({ toString() { throw new Error("specifier"); } });
} catch (error) {
rejected = error;
}
shouldBe(rejected.message, "specifier");
// Specifier ToString abrupt completion rejects (instead of throwing synchronously).
let syncThrow;
let promise;
try {
promise = import.defer({ toString() { throw new Error("specifier"); } });
} catch (error) {
syncThrow = error;
}
shouldBe(syncThrow, undefined);
let rejected;
try {
await promise;
} catch (error) {
rejected = error;
}
shouldBe(rejected.message, "specifier");
🤖 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/modules/import-defer-dynamic-syntax.js` around lines 16 - 23, The
test must distinguish synchronous throws from returned rejected promises: call
import.defer({ toString() { throw new Error("specifier"); } }) and capture its
return in a variable (e.g., promise) to ensure the call itself does not throw
synchronously, then await that promise and assert the rejection message; update
the block around the import.defer invocation so the call is assigned to a
promise variable (or wrapped to fail if it throws synchronously) and only then
use await and shouldBe(rejected.message, "specifier") to validate the error.

@@ -0,0 +1,167 @@
// Exercises both the converted (PerformPromiseThenOneHandler) and non-converted
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

Enable $vm intrinsics explicitly for this test file.

Line 147, Line 156, and Line 166 call $vm.*, but the file does not enable DollarVM. This can fail early with ReferenceError in configurations where it is off by default.

Suggested fix
+//@ requireOptions("--useDollarVM=1")
+
 // Exercises both the converted (PerformPromiseThenOneHandler) and non-converted
 // (PerformPromiseThen) paths produced by DFGConstantFoldingPhase. Each test
 // function is noInline'd and run in a hot loop so DFG/FTL tier-up is forced.
🤖 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/perform-promise-then-one-handler.js` at line 1, This test
calls $vm.* intrinsics (used in PerformPromiseThenOneHandler paths) but doesn't
enable DollarVM; add the standard DollarVM enable directive at the top of the
file so $vm is defined before any calls (place the directive before the first
$vm.* usage), e.g. insert the test harness directive used across other JSTests
to enable DollarVM intrinsics (so the $vm.* calls at the spots referenced will
not throw ReferenceError).

Comment on lines +113 to +117
var valueOfCount = 0;
re.lastIndex = { valueOf() { valueOfCount++; return 0; } };
shouldBe(match("a1b2c3", re), ["1", "2", "3"]);
// The slow path is hit after this since the compiled fast path bailed out.
})();
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

Assert lastIndex.valueOf is actually observed in the two coercion-path scenarios.

Both scenarios track valueOfCount but never validate it. That makes the tests pass even if the engine skips the intended coercion path.

Suggested patch
@@
     var valueOfCount = 0;
     re.lastIndex = { valueOf() { valueOfCount++; return 0; } };
     shouldBe(match("a1b2c3", re), ["1", "2", "3"]);
+    if (!valueOfCount)
+        throw new Error("expected lastIndex.valueOf to be observed");
     // The slow path is hit after this since the compiled fast path bailed out.
@@
     shouldBe(String.prototype.match.call(receiver, re), ["a"]);
+    if (!valueOfCount)
+        throw new Error("expected lastIndex.valueOf to be observed");
 })();

Also applies to: 168-176

🤖 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/string-prototype-match-watchpoint-invalidation.js` around
lines 113 - 117, The tests set up valueOfCount and install re.lastIndex with a
valueOf that increments it but never assert the counter; add explicit assertions
to verify lastIndex.valueOf was invoked in both coercion-path scenarios by
checking valueOfCount equals the expected number after the call to
match("a1b2c3", re) (and after the second scenario around lines 168-176), and
reset valueOfCount between scenarios so each path's coercion is independently
validated (use the existing symbols valueOfCount, re.lastIndex and the
match(...) invocations to locate where to insert the assertions).

Comment on lines +47 to +50
cstr(s) {
const out = new Uint8Array(s.length + 1);
for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i) & 0xff;
return out;
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

🧩 Analysis chain

🌐 Web query:

In PostgreSQL frontend/backend protocol, are SQL/query strings and text field payloads transmitted as UTF-8 bytes (not Latin-1 / single-byte char truncation)?

💡 Result:

Yes. In PostgreSQL’s frontend/backend wire protocol, messages are length-delimited byte streams, and the “query string” (simple query) and “text” representations are transmitted as raw bytes representing the client/driver’s encoded string data (UTF-8 bytes when the client is using UTF-8). The protocol does not operate in a Latin-1/single-byte-per-character way that would truncate multibyte UTF-8. Evidence: - The protocol specification defines that the message framing uses an Int32 byte length (“Length of message contents in bytes…”) and that fields like the query string are part of message “contents” with explicit byte counts, i.e., byte-oriented framing rather than character-counting or single-byte assumptions. For example, the simple Query message includes “Length of message contents in bytes” followed by “The query string itself” [1]. - For “text” values, the transmitted representation is based on the input/output conversion functions (“The text representation of values is whatever strings are produced and accepted by the input/output conversion functions…”) and the transmitted text format has no trailing null character [2]. This implies the protocol carries the encoded bytes produced by those conversions, not single-byte character truncation. - PostgreSQL explicitly supports UTF-8 as a character set/encoding for client-visible character data (“UTF-8” is listed among supported encodings) [3], and the protocol has a parameter for client_encoding in the startup/session parameter flow [4]. So, if a client sets client encoding to UTF-8 (typical for libpq/most drivers configured with UTF-8), then the SQL text and “text” field payloads travel over the wire as the corresponding UTF-8 byte sequences, with lengths in bytes ensuring multibyte characters are carried correctly (they may increase the byte length, but won’t be truncated as Latin-1 would).

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="JSTests/wasm/stress/resources/pglite/jsc-harness.js"

# Show the referenced region (around 47-50) plus a bit more context
nl -ba "$FILE" | sed -n '35,90p'

# Also show other places mentioned by the original comment (106-107, 120-121, 126-127, 133-134)
nl -ba "$FILE" | sed -n '95,145p'

Repository: oven-sh/WebKit

Length of output: 101


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="JSTests/wasm/stress/resources/pglite/jsc-harness.js"

# region around 47-50 (use cat -n since nl isn't available)
cat -n "$FILE" | sed -n '35,90p'

# other mentioned locations
cat -n "$FILE" | sed -n '95,145p'

Repository: oven-sh/WebKit

Length of output: 5596


Fix protocol text handling to use UTF-8 encoding/decoding (avoid byte truncation).

cstr(s) encodes strings with charCodeAt(i) & 0xff, and the response parsing reconstructs text via String.fromCharCode(bytes[q]) (effectively Latin-1/single-byte). This will corrupt any non-ASCII characters in SQL/query strings, named fields, text params, row values, command tags, and PostgreSQL error messages.

Locations:

  • PGProtocol.cstr(s) (47-50)
  • Parsing: field names (T, 106-107), row column values (D, 120-121), command tags (C, 126-127), error message parts (E, 133-134)
💡 Proposed fix
+const textEncoder = new TextEncoder();
+const textDecoder = new TextDecoder("utf-8");

 const PGProtocol = {
@@
     cstr(s) {
-        const out = new Uint8Array(s.length + 1);
-        for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i) & 0xff;
+        const encoded = textEncoder.encode(s);
+        const out = new Uint8Array(encoded.length + 1);
+        out.set(encoded);
         return out;
     },
@@
-                let name = ""; for (let q = p; q < end; q++) name += String.fromCharCode(bytes[q]);
+                const name = textDecoder.decode(bytes.subarray(p, end));
@@
-                let s = ""; for (let q = p; q < p + colLen; q++) s += String.fromCharCode(bytes[q]);
+                const s = textDecoder.decode(bytes.subarray(p, p + colLen));
@@
-            let s = ""; for (let q = bodyStart; q < bodyEnd && bytes[q] !== 0; q++) s += String.fromCharCode(bytes[q]);
+            const end = bytes.indexOf(0, bodyStart);
+            const s = textDecoder.decode(bytes.subarray(bodyStart, end === -1 ? bodyEnd : Math.min(end, bodyEnd)));
@@
-                let v = ""; for (let q = p; q < end; q++) v += String.fromCharCode(bytes[q]);
+                const v = textDecoder.decode(bytes.subarray(p, end));
🤖 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/wasm/stress/resources/pglite/jsc-harness.js` around lines 47 - 50,
The current PGProtocol.cstr(s) and various response parsers use single-byte
charCodeAt/fromCharCode which truncates non-ASCII; replace these with a UTF-8
TextEncoder/TextDecoder approach: create a shared TextEncoder instance and have
cstr(s) return encoder.encode(s) plus a null terminator instead of masking with
&0xff, and in the parsers for message types T (field names), D (row column
values), C (command tags), and E (error message parts) use a TextDecoder to
decode the byte subarray up to the 0 byte into a UTF-8 string (rather than
String.fromCharCode per byte). Ensure you handle the null terminator removal
consistently and reuse encoder/decoder instances for performance.

Comment on lines +97 to +101
while (i < bytes.length) {
const tag = String.fromCharCode(bytes[i]);
const len = dv.getInt32(i + 1, false);
const bodyStart = i + 5, bodyEnd = i + 1 + len;
if (tag === "T") {
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

Validate backend frame boundaries before parsing message bodies.

len is trusted immediately. A malformed/truncated frame can drive out-of-bounds reads or broken cursor progression (i = bodyEnd), which can hang/fail the harness.

🛡️ Proposed fix
     while (i < bytes.length) {
+        if (i + 5 > bytes.length)
+            throw new Error(`Truncated backend message header at offset ${i}`);
         const tag = String.fromCharCode(bytes[i]);
         const len = dv.getInt32(i + 1, false);
         const bodyStart = i + 5, bodyEnd = i + 1 + len;
+        if (len < 4 || bodyEnd > bytes.length || bodyEnd <= i)
+            throw new Error(`Malformed backend message frame at offset ${i} (tag=${tag}, len=${len})`);

Also applies to: 142-143

🤖 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/wasm/stress/resources/pglite/jsc-harness.js` around lines 97 - 101,
The loop trusts len and computes bodyStart/bodyEnd without bounds checks,
allowing dv.getInt32 or subsequent body reads to go out-of-bounds; before
calling dv.getInt32 and before parsing the body or setting i = bodyEnd, validate
that (i + 1 + 4) and (i + 1 + len) are within bytes.length (and that len is
non-negative and reasonable), and if invalid, handle the truncated/malformed
frame (e.g., log/skip/abort the harness) in the same loop that processes tag,
len, bodyStart, bodyEnd; apply the same boundary checks to the other parsing
site referenced (around lines 142-143) so both dv.getInt32 and body slicing
never read past bytes.length.

Comment on lines +8 to +14
cmd = request.GET.first(b"cmd")
id = request.GET.first(b"id")

if cmd == b"store":
request.server.stash.put(id, request.url_parts.query)
elif cmd == b"stat":
stored = request.server.stash.take(id)
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

Require cmd and id before touching stash.

Line 8 and Line 9 can produce None, and Line 12/Line 14 would then read/write under a shared null key. That can cause cross-test interference. Return 400 when either parameter is missing.

Suggested patch
     cmd = request.GET.first(b"cmd")
     id = request.GET.first(b"id")
+    if cmd is None or id is None:
+        response.status = 400
+        return
 
     if cmd == b"store":
         request.server.stash.put(id, request.url_parts.query)
📝 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
cmd = request.GET.first(b"cmd")
id = request.GET.first(b"id")
if cmd == b"store":
request.server.stash.put(id, request.url_parts.query)
elif cmd == b"stat":
stored = request.server.stash.take(id)
cmd = request.GET.first(b"cmd")
id = request.GET.first(b"id")
if cmd is None or id is None:
response.status = 400
return
if cmd == b"store":
request.server.stash.put(id, request.url_parts.query)
elif cmd == b"stat":
stored = request.server.stash.take(id)
🤖 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 `@LayoutTests/imported/w3c/web-platform-tests/beacon/resources/url-echo.py`
around lines 8 - 14, The handler reads cmd and id via request.GET.first and then
calls request.server.stash.put/take which can use None as a key; before touching
request.server.stash (e.g., before stash.put and stash.take), validate that both
cmd and id are present and if either is missing respond with a 400 error; update
the branches that use cmd and id (the cmd == b"store"/b"stat" checks and calls
to request.server.stash.put/take and request.url_parts.query) to only run after
this existence check so no stash operations occur with a null key.

Comment on lines +22 to +27
async function iframeDialogIsOpen(iframe, signal) {
const reply = awaitEvent(window, "message", signal);
iframe.contentWindow.postMessage("dialog_open", "*");
const {data} = (await reply);
if (data.error) throw new Error(data.error);
return data.open;
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 message events to the target iframe.

Line 23 currently accepts the first message on window without validating event.source/event.origin. That can race with unrelated messages and misreport dialog state.

Suggested patch
     async function iframeDialogIsOpen(iframe, signal) {
-      const reply = awaitEvent(window, "message", signal);
+      const reply = new Promise((resolve) => {
+        const onMessage = (event) => {
+          if (event.source !== iframe.contentWindow || event.origin !== location.origin)
+            return;
+          window.removeEventListener("message", onMessage);
+          resolve(event);
+        };
+        window.addEventListener("message", onMessage, { signal });
+      });
       iframe.contentWindow.postMessage("dialog_open", "*");
       const {data} = (await reply);
       if (data.error) throw new Error(data.error);
       return data.open;
     }
🤖 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
`@LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-nn.html`
around lines 22 - 27, The awaitEvent-based listener in iframeDialogIsOpen
currently races on any window "message"; update iframeDialogIsOpen to only
accept message events coming from the target iframe by validating event.source
=== iframe.contentWindow (and event.origin if needed). If awaitEvent supports a
predicate, pass a filter that checks event.source === iframe.contentWindow (and
event.origin match), otherwise replace with an explicit addEventListener that
ignores messages from other sources before resolving and removes the listener
after use; keep the rest of the logic (postMessage "dialog_open", error check,
return data.open) unchanged.

await awaitEvent(iframe1, "load", t.get_signal());
await awaitEvent(iframe2, "load", t.get_signal());

test_driver.bless();
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify bless API shape in local WPT resources.
fd -i 'testdriver.js' | xargs -r rg -n 'function\s+bless\s*\(|\bbless\s*:\s*function\b|\bbless\s*\('

# Verify un-awaited bless call sites in these iframe tests.
rg -nP '\btest_driver\.bless\s*\(' \
  LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynn.html \
  LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynyn.html

Repository: oven-sh/WebKit

Length of output: 704


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect bless implementation in testdriver.js
sed -n '1010,1080p' LayoutTests/imported/w3c/web-platform-tests/resources/testdriver.js | cat -n

# Find other call sites and whether they await/chain bless()
rg -nP 'await\s+test_driver\.bless\s*\(' LayoutTests/imported/w3c/web-platform-tests -S || true
rg -nP 'test_driver\.bless\s*\(\s*\)\s*;' LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes -S || true
rg -nP 'test_driver\.bless\s*\(' LayoutTests/imported/w3c/web-platform-tests -S || true

Repository: oven-sh/WebKit

Length of output: 50371


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show surrounding code for the bless calls in the specific iframe tests
sed -n '1,120p' LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynn.html | cat -n
echo "----"
sed -n '1,140p' LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynyn.html | cat -n

Repository: oven-sh/WebKit

Length of output: 5539


Await test_driver.bless() before dispatching test_driver.send_keys().
test_driver.bless() returns a Promise (resolved after the bless “click”), but dialog-same-origin-ynn.html calls it without await and then proceeds to await test_driver.send_keys(...), so activation setup can race. Same pattern exists in dialog-same-origin-ynyn.html (two call sites).

Suggested patch
-      test_driver.bless();
+      await test_driver.bless();
📝 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
test_driver.bless();
await test_driver.bless();
🤖 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
`@LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynn.html`
at line 34, Await the promise returned by test_driver.bless() before any
subsequent activation steps to avoid a race with test_driver.send_keys();
specifically, update the call sites in dialog-same-origin-ynn.html (the
test_driver.bless() before the await test_driver.send_keys(...)) and the two
analogous call sites in dialog-same-origin-ynyn.html to use await
test_driver.bless() so the blessing/click completes before sending keys.

Comment on lines +5 to +6
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver.js"></script>
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

Remove duplicate testdriver.js include.

Line 6 duplicates Line 5. Loading it twice is unnecessary and can introduce test harness side effects.

Proposed fix
 <script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
🤖 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
`@LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/resources/dialog-prevents-close.html`
around lines 5 - 6, Remove the duplicate script include for
"/resources/testdriver.js" so the file is only loaded once; locate the two
identical <script src="/resources/testdriver.js"></script> entries and delete
the redundant one (keep a single include) to avoid double-initializing the test
harness.

d.showModal();
d.addEventListener("cancel", (e) => e.preventDefault());
window.addEventListener("message", async (e) => {
if (event.data == "dialog_open") {
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

Use the listener argument instead of implicit global event.

Line 14 checks event.data, but the callback argument is e. This can mis-handle messages or throw in environments where event is not set.

Proposed fix
-      if (event.data == "dialog_open") {
+      if (e.data === "dialog_open") {
📝 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 (event.data == "dialog_open") {
if (e.data === "dialog_open") {
🤖 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
`@LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/resources/dialog-prevents-close.html`
at line 14, The message event handler is using the global/implicit name `event`
instead of the callback parameter `e`, which can fail in some environments;
update the listener callback to reference the passed-in argument (use `e.data`
instead of `event.data`) wherever the handler checks or accesses the message
payload (the function registered for "message" that currently declares `e`).

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 21, 2026

Preview Builds

Commit Release Date
d0bc4acd autobuild-preview-pr-236-d0bc4acd 2026-05-21 16:57:21 UTC
e54e803f autobuild-preview-pr-236-e54e803f 2026-05-21 08:08:07 UTC

…e queue

settleInlineInternalMicrotask was added by upstream 8f74209 (inlined
InternalMicrotask reaction). It bypasses the m_synchronousModuleQueue check
that other queueMicrotask call sites have, so a module-loader microtask
attached as an inline reaction is queued asynchronously even during
loadModuleSync. The result: require(esm) sees a Pending promise and throws
'async module unsupported'.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

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

⚠️ Outside diff range comments (1)
LayoutTests/imported/w3c/web-platform-tests/common/reftest-wait.js (1)

34-38: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Handle readyState === "complete" in failure path.

Line 34 currently only handles "interactive" immediately; when state is "complete", Line 37 registers DOMContentLoaded too late and fail() never runs.

Proposed fix
-  if (!condition) {
-    if (document.readyState == "interactive") {
-      fail();
-    } else {
-      document.addEventListener("DOMContentLoaded", fail, false);
-    }
+  if (!condition) {
+    if (document.readyState === "loading") {
+      document.addEventListener("DOMContentLoaded", fail, { once: true });
+    } else {
+      fail();
+    }
     return false;
   }
🤖 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 `@LayoutTests/imported/w3c/web-platform-tests/common/reftest-wait.js` around
lines 34 - 38, The current logic only triggers fail() immediately when
document.readyState === "interactive" but misses the "complete" state, so change
the condition in the block around document.readyState and DOMContentLoaded to
treat both "interactive" and "complete" as immediate failure: if
document.readyState is "interactive" or "complete" then call fail()
synchronously; otherwise keep registering
document.addEventListener("DOMContentLoaded", fail, false). Update checks
referencing document.readyState and the use of fail and DOMContentLoaded
accordingly.
♻️ Duplicate comments (10)
LayoutTests/http/tests/site-isolation/resources/validation-message-iframe.html (1)

30-35: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Filter message events by sender to avoid unintended submissions.

The message handler accepts event.data === "submit" from any sender. This should be restricted to event.source === window.parent so only the test harness frame can trigger submission.

🔒 Proposed fix to validate message source
 window.addEventListener("message", (event) => {
-    if (event.data === "submit") {
+    if (event.source === window.parent && event.data === "submit") {
         document.getElementById("submit").click();
         requestAnimationFrame(() => parent.postMessage("submitted", "*"));
     }
 });
🤖 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
`@LayoutTests/http/tests/site-isolation/resources/validation-message-iframe.html`
around lines 30 - 35, The message handler currently accepts any postMessage with
event.data === "submit" and triggers the form submit via
document.getElementById("submit").click() and parent.postMessage("submitted",
"*"); restrict the handler to only react when event.source === window.parent
(and optionally check event.origin if needed) before calling
document.getElementById("submit").click() and posting back, so only the parent
test harness can trigger the submission.
LayoutTests/http/tests/site-isolation/validation-message-cross-origin-iframe.html (1)

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

Bind the "submitted" message to the target iframe.

Line 44 currently accepts "submitted" from any window; gate it by event.source === iframe.contentWindow.

Proposed fix
         window.addEventListener("message", (event) => {
-            if (event.data === "submitted")
+            if (event.source === iframe.contentWindow && event.data === "submitted")
                 resolve();
         }, { once: true });
🤖 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
`@LayoutTests/http/tests/site-isolation/validation-message-cross-origin-iframe.html`
around lines 43 - 45, The message handler currently treats any "submitted"
message as valid; update the listener registered in
window.addEventListener("message", ...) to additionally check that event.source
=== iframe.contentWindow before calling resolve(), so only messages originating
from the target iframe (identified by the iframe variable and its contentWindow)
are accepted.
LayoutTests/applicationmanifest/developer-warnings.html (1)

6-10: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Call notifyDone() in a finally block.

If Line 7 throws/rejects, completion is never signaled.

Proposed fix
     (async () => {
-        await testRunner.getApplicationManifest();
-        alert("Pass");
-        testRunner.notifyDone();
+        try {
+            await testRunner.getApplicationManifest();
+            alert("Pass");
+        } finally {
+            testRunner.notifyDone();
+        }
     })();
🤖 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 `@LayoutTests/applicationmanifest/developer-warnings.html` around lines 6 - 10,
The current async IIFE calls await testRunner.getApplicationManifest() and then
testRunner.notifyDone(), but if the await rejects notifyDone() is never called;
wrap the await call in a try/finally (or try/catch/finally) so that
testRunner.notifyDone() is invoked from the finally block (keeping the
alert("Pass") on success inside try and optionally alert an error inside catch)
to guarantee completion is always signaled for the async IIFE that invokes
testRunner.getApplicationManifest().
LayoutTests/fast/canvas/webgl/data-view-test-expected.txt (1)

32-33: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix heading/assertion precedence mismatch.

Line 32 says wrong length precedence, but Line 33 expects byteOffset precedence.

Proposed fix
-Test for constructor wrong length exception takes precedence over wrong byteoffset exception
+Test for constructor wrong byteoffset exception takes precedence over wrong length exception
🤖 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 `@LayoutTests/fast/canvas/webgl/data-view-test-expected.txt` around lines 32 -
33, The test heading/assertion is mismatched: the heading says "wrong length
exception takes precedence" but the expected assertion shows a byteOffset error
for the expression view = new Int32Array(new ArrayBuffer(100), 1, 101). Update
the expected output for the expression "view = new Int32Array(new
ArrayBuffer(100), 1, 101)" to assert the RangeError corresponding to the wrong
length (the length/byteLength overflow error) instead of the byteOffset modulo
error so the message and assertion precedence align with the heading.
LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynn.html (1)

34-34: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Await test_driver.bless() before dispatching keys.

Without await, activation setup can race send_keys(...).

Proposed fix
-      test_driver.bless();
+      await test_driver.bless();
🤖 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
`@LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynn.html`
at line 34, The call to test_driver.bless() is not awaited, which can race with
subsequent send_keys(...) calls; change the invocation in this file to await
test_driver.bless() (i.e., ensure the surrounding scope is async or otherwise
awaits the promise) before dispatching any key events so activation/setup
completes first.
LayoutTests/http/wpt/content-security-policy/sandbox-manifest-blocked.html (1)

8-13: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Guard async manifest calls when testRunner is absent.

The IIFE directly dereferences testRunner while setup uses optional chaining.

Proposed fix
     (async () => {
+        if (!window.testRunner || typeof testRunner.getApplicationManifest !== "function")
+            return;
         const success = await testRunner.getApplicationManifest();
         const elem = document.querySelector("link");
         outputdiv.innerHTML = `Fetched manifest: ${elem.href}, success: ${success}`;
         testRunner.notifyDone();
     })();
🤖 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 `@LayoutTests/http/wpt/content-security-policy/sandbox-manifest-blocked.html`
around lines 8 - 13, The IIFE currently dereferences testRunner directly; before
calling testRunner.getApplicationManifest() and testRunner.notifyDone(), guard
against a missing testRunner (e.g., if (!testRunner) or using optional chaining)
and handle the fallback path: set a sensible default for success, still resolve
elem via document.querySelector("link") and update outputdiv.innerHTML with a
message that includes the fetched manifest href and the fallback success value,
then only call testRunner.notifyDone() when testRunner is present; update
references in this block (the IIFE, testRunner.getApplicationManifest,
testRunner.notifyDone, elem, outputdiv.innerHTML) accordingly.
LayoutTests/accessibility/dialog-focus-on-open.html (1)

36-45: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guarantee cleanup and finishJSTest() on async failure.

A thrown/rejected expectAsync(...) can bypass teardown and leave this test hanging.

Proposed fix
     setTimeout(async function() {
-        showButton.press();
-
-        output += await expectAsync("window.focusedAtNotificationTime", "'heading'");
-        output += expect("accessibilityController.focusedElement.domIdentifier", "'heading'");
-
-        accessibilityController.removeNotificationListener();
-        debug(output);
-        finishJSTest();
+        try {
+            showButton.press();
+            output += await expectAsync("window.focusedAtNotificationTime", "'heading'");
+            output += expect("accessibilityController.focusedElement.domIdentifier", "'heading'");
+        } catch (e) {
+            output += `\nError: ${e}`;
+        } finally {
+            accessibilityController.removeNotificationListener();
+            debug(output);
+            finishJSTest();
+        }
     }, 0);
🤖 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 `@LayoutTests/accessibility/dialog-focus-on-open.html` around lines 36 - 45,
The async callback can throw and skip teardown; wrap the body of the setTimeout
handler in a try/catch/finally (or attach a .catch/.finally) so that
accessibilityController.removeNotificationListener() and finishJSTest() always
run; keep showButton.press() and the await
expectAsync("window.focusedAtNotificationTime", "'heading'")/expect(...) logic,
append to output as before, call debug(output) in the try or finally as
appropriate, and perform cleanup and finishJSTest() in the finally block to
guarantee teardown even on rejection.
LayoutTests/http/tests/security/cross-origin-indexeddb.html (1)

16-31: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate message sender before processing test state.

Unfiltered messages can incorrectly trigger stored / TRANSIENT / PERSISTENT paths.

Proposed fix
 window.addEventListener("message", event => {
+    const iframeWindow = document.querySelector("iframe").contentWindow;
+    if (event.origin !== "http://localhost:8000" || event.source !== iframeWindow)
+        return;
+
     if (event.data === "stored") {
         log("Third-party iframe stored data in IndexedDB; terminating network process.");
         if (window.testRunner)
             testRunner.terminateNetworkProcess();
🤖 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 `@LayoutTests/http/tests/security/cross-origin-indexeddb.html` around lines 16
- 31, The message handler registered with window.addEventListener("message",
event => { ... }) must validate the sender before interpreting event.data;
update that handler to ignore messages not from the expected test iframe by
checking the sender (e.g., compare event.source === expectedIframe.contentWindow
or verify event.origin against a known trusted origin) and only then proceed to
handle "stored"/"TRANSIENT"/"PERSISTENT" and call testRunner.notifyDone();
ensure untrusted messages are returned/ignored early.
LayoutTests/applicationmanifest/multiple-links.html (1)

11-15: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Call notifyDone() from finally to avoid harness hangs.

Line 11–15 can miss testRunner.notifyDone() if getApplicationManifest() throws/rejects.

Proposed fix
 if (window.testRunner) {
     (async () => {
-        const success = await testRunner.getApplicationManifest();
-        outputdiv.innerHTML = `manifest fetch success: ${success}`;
-        testRunner.notifyDone();
+        try {
+            const success = await testRunner.getApplicationManifest();
+            outputdiv.innerHTML = `manifest fetch success: ${success}`;
+        } finally {
+            testRunner.notifyDone();
+        }
     })();
 }
🤖 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 `@LayoutTests/applicationmanifest/multiple-links.html` around lines 11 - 15,
The IIFE currently awaits testRunner.getApplicationManifest() and only calls
testRunner.notifyDone() on the success path, so if getApplicationManifest()
rejects the harness can hang; wrap the await in try/catch/finally (or use
.finally()) so that testRunner.notifyDone() is invoked in the finally block
regardless of success or error, preserving the existing outputdiv.innerHTML
update in the try or catch as appropriate and referencing
getApplicationManifest() and testRunner.notifyDone() to locate the change.
LayoutTests/accessibility/dynamic-subtree-replacement-with-stale-parent-children.html (1)

26-62: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Ensure teardown always runs for the async test body.

Line 26–62 can skip clearInterval(makePageDirty) and finishJSTest() if any awaited step fails, which can hang the test.

Proposed fix
     setTimeout(async function() {
         var notificationCounter = 0;
         var makePageDirty = setInterval(function() {
@@
             document.getElementById("container").setAttribute("aria-atomic", String(notificationCounter++));
         }, 1);
-
-        // Update the role, triggering a full node update.
-        document.getElementById("container").setAttribute("role", "group");
-        var newContents = "";
-        for (var i = 1; i <= buttonCount; i++)
-            newContents += `<button id="q${i}-button">Q${i}</button>`;
-        newContents += `<button id="nav-button">Next</button>`;
-        document.getElementById("container").innerHTML = newContents;
-
-        container = accessibilityController.accessibleElementById("container");
-        output += "\nAfter swap:\n";
-        output += await expectAsync("container.childrenCount", "13");
-
-        reachableButtons = 0;
-        for (var i = 1; i <= buttonCount; i++) {
-            let button = await waitForElementById(`q${i}-button`);
-            if (button)
-                reachableButtons++;
-        }
-        output += expect("reachableButtons", "buttonCount");
-
-        clearInterval(makePageDirty);
-
-        debug(output);
-        finishJSTest();
+        try {
+            // Update the role, triggering a full node update.
+            document.getElementById("container").setAttribute("role", "group");
+            var newContents = "";
+            for (var i = 1; i <= buttonCount; i++)
+                newContents += `<button id="q${i}-button">Q${i}</button>`;
+            newContents += `<button id="nav-button">Next</button>`;
+            document.getElementById("container").innerHTML = newContents;
+
+            container = accessibilityController.accessibleElementById("container");
+            output += "\nAfter swap:\n";
+            output += await expectAsync("container.childrenCount", "13");
+
+            reachableButtons = 0;
+            for (var i = 1; i <= buttonCount; i++) {
+                let button = await waitForElementById(`q${i}-button`);
+                if (button)
+                    reachableButtons++;
+            }
+            output += expect("reachableButtons", "buttonCount");
+        } finally {
+            clearInterval(makePageDirty);
+            debug(output);
+            finishJSTest();
+        }
     }, 0);
🤖 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
`@LayoutTests/accessibility/dynamic-subtree-replacement-with-stale-parent-children.html`
around lines 26 - 62, The async callback passed to setTimeout can exit early on
rejected awaits and skip cleanup (clearInterval(makePageDirty) and
finishJSTest()); wrap the body of that async function in a try/finally (or
ensure a .finally() on Promises) so that clearInterval(makePageDirty) and
finishJSTest() always run regardless of failures; locate the anonymous async
function (the setTimeout handler), the makePageDirty variable, and the calls to
clearInterval(makePageDirty) and finishJSTest() and move/ensure those calls into
a finally block that executes after awaited calls like expectAsync and
waitForElementById.
🤖 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/promise-resolve-non-thenable-structure-cache-dictionary.js`:
- Line 32: Declare and initialize the missing variable testLoopCount near the
top of the file (e.g., immediately after the helper functions) so the for-loops
that reference it (the for (...) using testLoopCount) do not throw a
ReferenceError; set it to an appropriate integer or source it from
configuration/environment if intended to be configurable, and ensure the same
identifier testLoopCount is used consistently across the loops at the locations
where it is currently referenced.

In `@LayoutTests/fast/repaint/drop-shadow-box-change.html`:
- Around line 31-35: After adding the 'changed' class to document.body, wait for
the next rendering frame before calling window.internals.repaintRectsAsText()
and internals.stopTrackingRepaints(); replace the immediate read with a
requestAnimationFrame (or two nested requestAnimationFrame calls) to ensure the
style mutation has been applied and paint/repaint rects are stable before
debugging and stopping tracking.

In `@LayoutTests/fast/repaint/drop-shadow-change.html`:
- Around line 28-33: After adding the 'changed' class to document.body, force a
rendering flush before calling window.internals.repaintRectsAsText() to avoid
capturing stale/empty repaint rects; insert a synchronous layout/paint trigger
(for example, read a layout-affecting property such as
document.body.offsetHeight or window.getComputedStyle(document.body).width)
immediately after document.body.classList.add('changed') and before calling
repaintRectsAsText(), then proceed to call window.internals.repaintRectsAsText()
and internals.stopTrackingRepaints().

In `@LayoutTests/fast/text-extraction/contenteditable-text-extraction.html`:
- Around line 12-22: The test currently awaits UIHelper.requestTextExtraction in
the load event handler and may never call testRunner.notifyDone() if that
promise rejects; wrap the await in a try/finally (or use .catch(...) and a
finally) inside the addEventListener callback so that testRunner.notifyDone() is
always invoked regardless of success or error, referencing the async load
handler, UIHelper.requestTextExtraction, and
testRunner.notifyDone()/testRunner.waitUntilDone()/testRunner.dumpAsText() to
locate where to add the try/finally.

In
`@LayoutTests/http/tests/resourceLoadStatistics/third-party-cookie-blocking-about-blank-popup.html`:
- Around line 46-48: The message handler registered via
window.addEventListener("message", function handler(event) { ... }) should first
verify the message came from the popup before acting; update the handler to
check event.source === popup (or the actual popup variable name used in the
test) and only then inspect event.data.type === "fetch-done" and
removeEventListener("message", handler). This prevents unrelated postMessage
events from being consumed and causing flakes.

In
`@LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynyn.html`:
- Around line 23-27: The message handler currently accepts the first window
"message" event which can come from the wrong iframe; change the reply
acceptance so it only resolves when event.source === iframe.contentWindow. In
practice update the awaitEvent(window, "message", signal) usage (or the code
that handles its result) to check event.source === iframe.contentWindow and
ignore/continue waiting for other messages until the source matches, then
extract data and proceed (the variables/functions to change are awaitEvent,
reply, and the check before reading data/error).

---

Outside diff comments:
In `@LayoutTests/imported/w3c/web-platform-tests/common/reftest-wait.js`:
- Around line 34-38: The current logic only triggers fail() immediately when
document.readyState === "interactive" but misses the "complete" state, so change
the condition in the block around document.readyState and DOMContentLoaded to
treat both "interactive" and "complete" as immediate failure: if
document.readyState is "interactive" or "complete" then call fail()
synchronously; otherwise keep registering
document.addEventListener("DOMContentLoaded", fail, false). Update checks
referencing document.readyState and the use of fail and DOMContentLoaded
accordingly.

---

Duplicate comments:
In `@LayoutTests/accessibility/dialog-focus-on-open.html`:
- Around line 36-45: The async callback can throw and skip teardown; wrap the
body of the setTimeout handler in a try/catch/finally (or attach a
.catch/.finally) so that accessibilityController.removeNotificationListener()
and finishJSTest() always run; keep showButton.press() and the await
expectAsync("window.focusedAtNotificationTime", "'heading'")/expect(...) logic,
append to output as before, call debug(output) in the try or finally as
appropriate, and perform cleanup and finishJSTest() in the finally block to
guarantee teardown even on rejection.

In
`@LayoutTests/accessibility/dynamic-subtree-replacement-with-stale-parent-children.html`:
- Around line 26-62: The async callback passed to setTimeout can exit early on
rejected awaits and skip cleanup (clearInterval(makePageDirty) and
finishJSTest()); wrap the body of that async function in a try/finally (or
ensure a .finally() on Promises) so that clearInterval(makePageDirty) and
finishJSTest() always run regardless of failures; locate the anonymous async
function (the setTimeout handler), the makePageDirty variable, and the calls to
clearInterval(makePageDirty) and finishJSTest() and move/ensure those calls into
a finally block that executes after awaited calls like expectAsync and
waitForElementById.

In `@LayoutTests/applicationmanifest/developer-warnings.html`:
- Around line 6-10: The current async IIFE calls await
testRunner.getApplicationManifest() and then testRunner.notifyDone(), but if the
await rejects notifyDone() is never called; wrap the await call in a try/finally
(or try/catch/finally) so that testRunner.notifyDone() is invoked from the
finally block (keeping the alert("Pass") on success inside try and optionally
alert an error inside catch) to guarantee completion is always signaled for the
async IIFE that invokes testRunner.getApplicationManifest().

In `@LayoutTests/applicationmanifest/multiple-links.html`:
- Around line 11-15: The IIFE currently awaits
testRunner.getApplicationManifest() and only calls testRunner.notifyDone() on
the success path, so if getApplicationManifest() rejects the harness can hang;
wrap the await in try/catch/finally (or use .finally()) so that
testRunner.notifyDone() is invoked in the finally block regardless of success or
error, preserving the existing outputdiv.innerHTML update in the try or catch as
appropriate and referencing getApplicationManifest() and testRunner.notifyDone()
to locate the change.

In `@LayoutTests/fast/canvas/webgl/data-view-test-expected.txt`:
- Around line 32-33: The test heading/assertion is mismatched: the heading says
"wrong length exception takes precedence" but the expected assertion shows a
byteOffset error for the expression view = new Int32Array(new ArrayBuffer(100),
1, 101). Update the expected output for the expression "view = new
Int32Array(new ArrayBuffer(100), 1, 101)" to assert the RangeError corresponding
to the wrong length (the length/byteLength overflow error) instead of the
byteOffset modulo error so the message and assertion precedence align with the
heading.

In `@LayoutTests/http/tests/security/cross-origin-indexeddb.html`:
- Around line 16-31: The message handler registered with
window.addEventListener("message", event => { ... }) must validate the sender
before interpreting event.data; update that handler to ignore messages not from
the expected test iframe by checking the sender (e.g., compare event.source ===
expectedIframe.contentWindow or verify event.origin against a known trusted
origin) and only then proceed to handle "stored"/"TRANSIENT"/"PERSISTENT" and
call testRunner.notifyDone(); ensure untrusted messages are returned/ignored
early.

In
`@LayoutTests/http/tests/site-isolation/resources/validation-message-iframe.html`:
- Around line 30-35: The message handler currently accepts any postMessage with
event.data === "submit" and triggers the form submit via
document.getElementById("submit").click() and parent.postMessage("submitted",
"*"); restrict the handler to only react when event.source === window.parent
(and optionally check event.origin if needed) before calling
document.getElementById("submit").click() and posting back, so only the parent
test harness can trigger the submission.

In
`@LayoutTests/http/tests/site-isolation/validation-message-cross-origin-iframe.html`:
- Around line 43-45: The message handler currently treats any "submitted"
message as valid; update the listener registered in
window.addEventListener("message", ...) to additionally check that event.source
=== iframe.contentWindow before calling resolve(), so only messages originating
from the target iframe (identified by the iframe variable and its contentWindow)
are accepted.

In `@LayoutTests/http/wpt/content-security-policy/sandbox-manifest-blocked.html`:
- Around line 8-13: The IIFE currently dereferences testRunner directly; before
calling testRunner.getApplicationManifest() and testRunner.notifyDone(), guard
against a missing testRunner (e.g., if (!testRunner) or using optional chaining)
and handle the fallback path: set a sensible default for success, still resolve
elem via document.querySelector("link") and update outputdiv.innerHTML with a
message that includes the fetched manifest href and the fallback success value,
then only call testRunner.notifyDone() when testRunner is present; update
references in this block (the IIFE, testRunner.getApplicationManifest,
testRunner.notifyDone, elem, outputdiv.innerHTML) accordingly.

In
`@LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynn.html`:
- Line 34: The call to test_driver.bless() is not awaited, which can race with
subsequent send_keys(...) calls; change the invocation in this file to await
test_driver.bless() (i.e., ensure the surrounding scope is async or otherwise
awaits the promise) before dispatching any key events so activation/setup
completes first.
🪄 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: fa2fe452-159b-47fb-965c-c692f2b84e6b

📥 Commits

Reviewing files that changed from the base of the PR and between 01ecc4e and d0bc4ac.

⛔ Files ignored due to path filters (3)
  • JSTests/wasm/stress/resources/pglite/pglite.wasm is excluded by !**/*.wasm
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/resources/w3c-import.log is excluded by !**/*.log
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/w3c-import.log is excluded by !**/*.log
📒 Files selected for processing (297)
  • .submitproject
  • .submitproject-append
  • .wkdev-sdk-version
  • CMakeLists.txt
  • CMakePresets.json
  • Configurations/CommonBase.xcconfig
  • Configurations/Version.xcconfig
  • Configurations/WebKitProjectPaths.xcconfig
  • JSTests/microbenchmarks/array-includes-string-8bit-long.js
  • JSTests/microbenchmarks/array-indexof-string-8bit-long.js
  • JSTests/microbenchmarks/array-indexof-string-8bit-short.js
  • JSTests/microbenchmarks/await-object-literal.js
  • JSTests/microbenchmarks/date-now-elapsed.js
  • JSTests/microbenchmarks/date-now.js
  • JSTests/microbenchmarks/promise-all-non-thenable-object.js
  • JSTests/microbenchmarks/promise-all-non-thenable.js
  • JSTests/microbenchmarks/promise-all-settled-non-thenable.js
  • JSTests/microbenchmarks/promise-race-non-thenable.js
  • JSTests/microbenchmarks/promise-resolve-non-thenable-object.js
  • JSTests/microbenchmarks/promise-resolve-object-literal.js
  • JSTests/microbenchmarks/promise-then-chain-object-literal.js
  • JSTests/microbenchmarks/regexp-match-digit-cached.js
  • JSTests/microbenchmarks/regexp-match-digit-literal.js
  • JSTests/microbenchmarks/string-match-digit-short.js
  • JSTests/microbenchmarks/string-match-letter-short.js
  • JSTests/modules/import-defer-dynamic-evaluation.js
  • JSTests/modules/import-defer-dynamic-rejects.js
  • JSTests/modules/import-defer-dynamic-syntax.js
  • JSTests/modules/import-defer-dynamic-tla.js
  • JSTests/modules/import-defer-dynamic.js
  • JSTests/modules/indirect-export-error.js
  • JSTests/modules/indirect-export-error/indirect-export-source-order-2.js
  • JSTests/modules/indirect-export-error/indirect-export-source-order.js
  • JSTests/stress/array-indexof-includes-string-word-compare.js
  • JSTests/stress/array-shift-intrinsic.js
  • JSTests/stress/array-sort-inline-ai-cell-butterfly-validation.js
  • JSTests/stress/array-sort-inline-isnan-comparator-cps.js
  • JSTests/stress/array-sort-inline-nested-in-comparator.js
  • JSTests/stress/array-unshift-intrinsic-ftl.js
  • JSTests/stress/array-unshift-intrinsic.js
  • JSTests/stress/asynciterator-prototype-symbol-async-dispose-return-argument.js
  • JSTests/stress/date-now-jit.js
  • JSTests/stress/dfg-perform-promise-then-one-handler-exit-ok.js
  • JSTests/stress/dfg-promise-resolve-fulfilled-object.js
  • JSTests/stress/dynamic-import-inline-microtask-result-promise.js
  • JSTests/stress/ftl-multigetbyoffset-constant-numberuse.js
  • JSTests/stress/iterator-prototype-flatMap-return-no-arguments.js
  • JSTests/stress/megamorphic-ic-symbol.js
  • JSTests/stress/object-define-property-fields-spilled-arg.js
  • JSTests/stress/perform-promise-then-one-handler.js
  • JSTests/stress/promise-combinator-non-thenable-element.js
  • JSTests/stress/promise-resolve-non-thenable-structure-cache-cross-realm.js
  • JSTests/stress/promise-resolve-non-thenable-structure-cache-dictionary.js
  • JSTests/stress/promise-resolve-non-thenable-structure-cache.js
  • JSTests/stress/spread-set-own-symbol-iterator-side-effects.js
  • JSTests/stress/string-prototype-match-edge-cases.js
  • JSTests/stress/string-prototype-match-strength-reduction.js
  • JSTests/stress/string-prototype-match-watchpoint-invalidation.js
  • JSTests/stress/string-substr-strength-reduction.js
  • JSTests/stress/string-substr.js
  • JSTests/stress/symbol-prototype-to-string-intrinsic.js
  • JSTests/stress/typedarray-constructor-allocatetypedarray-before-isdetachedbuffer-prototype-getter-detach.js
  • JSTests/stress/typedarray-constructor-allocatetypedarray-before-isdetachedbuffer.js
  • JSTests/stress/typedarray-constructor-allocatetypedarray-before-toindex-byteoffset.js
  • JSTests/stress/typedarray-constructor-allocatetypedarray-before-toindex-length.js
  • JSTests/stress/typedarray-constructor-byteoffset-modulo-elementsize-before-isdetachedbuffer-weird-byteoffset.js
  • JSTests/stress/typedarray-constructor-byteoffset-modulo-elementsize-before-isdetachedbuffer.js
  • JSTests/stress/typedarray-constructor-byteoffset-modulo-elementsize-before-toindex-length.js
  • JSTests/stress/typedarray-constructor-isdetachbuffer-before-bufferbytelength-modulo-elementsize-weird-byteoffset-detach.js
  • JSTests/stress/typedarray-constructor-isdetachbuffer-before-bufferbytelength-modulo-elementsize.js
  • JSTests/stress/typedarray-constructor-isdetachbuffer-before-newbytelength-lt-0-weird-byteoffset.js
  • JSTests/stress/typedarray-constructor-isdetachbuffer-before-newbytelength-lt-0.js
  • JSTests/stress/typedarray-constructor-isdetachbuffer-before-offset+newbytelength-gt-bufferbytelength-byteoffset-too-large.js
  • JSTests/stress/typedarray-constructor-isdetachbuffer-before-offset+newbytelength-gt-bufferbytelength-length-too-large.js
  • JSTests/stress/typedarray-constructor-toindex-byteoffset-before-isdetachedbuffer-weird-byteoffset-detach.js
  • JSTests/stress/typedarray-constructor-toindex-byteoffset-before-isdetachedbuffer.js
  • JSTests/stress/typedarray-constructor-toindex-byteoffset-detach-buffer.js
  • JSTests/stress/typedarray-constructor-toindex-length-before-isdetachedbuffer-weird-byteoffset-detach.js
  • JSTests/stress/typedarray-constructor-toindex-length-before-isdetachedbuffer-weird-length-detach.js
  • JSTests/stress/typedarray-constructor-toindex-length-before-isdetachedbuffer.js
  • JSTests/stress/typedarray-constructor-toindex-length-detach-buffer.js
  • JSTests/test262/config.yaml
  • JSTests/test262/expectations.yaml
  • JSTests/wasm/stress/lazy-table-copy-preserves-laziness.js
  • JSTests/wasm/stress/lazy-table-cross-instance.js
  • JSTests/wasm/stress/lazy-table-identity-across-paths.js
  • JSTests/wasm/stress/lazy-table-wrappers.js
  • JSTests/wasm/stress/pglite.js
  • JSTests/wasm/stress/resources/pglite/LICENSE.Emscripten
  • JSTests/wasm/stress/resources/pglite/LICENSE.PostgreSQL
  • JSTests/wasm/stress/resources/pglite/LICENSE.pglite
  • JSTests/wasm/stress/resources/pglite/README.md
  • JSTests/wasm/stress/resources/pglite/jsc-harness.js
  • JSTests/wasm/stress/resources/pglite/pglite.data
  • JSTests/wasm/stress/resources/pglite/pglite.js
  • JSTests/wasm/stress/resources/pglite/psql.js
  • LayoutTests/TestExpectations
  • LayoutTests/accessibility/dialog-focus-on-open-expected.txt
  • LayoutTests/accessibility/dialog-focus-on-open.html
  • LayoutTests/accessibility/dynamic-subtree-replacement-with-stale-parent-children-expected.txt
  • LayoutTests/accessibility/dynamic-subtree-replacement-with-stale-parent-children.html
  • LayoutTests/applicationmanifest/developer-warnings.html
  • LayoutTests/applicationmanifest/multiple-links-expected.txt
  • LayoutTests/applicationmanifest/multiple-links.html
  • LayoutTests/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt
  • LayoutTests/compositing/geometry/bounds-with-filters-expected.txt
  • LayoutTests/compositing/geometry/bounds-with-filters.html
  • LayoutTests/compositing/geometry/frame-clipping-layer-with-bottom-right-inset-expected.txt
  • LayoutTests/compositing/geometry/frame-clipping-layer-with-bottom-right-inset.html
  • LayoutTests/compositing/geometry/frame-clipping-layer-with-top-left-inset-expected.txt
  • LayoutTests/compositing/geometry/frame-clipping-layer-with-top-left-inset.html
  • LayoutTests/css3/filters/backdrop/backdrop-blur-and-subsequent-elements-expected.html
  • LayoutTests/css3/filters/backdrop/backdrop-blur-and-subsequent-elements.html
  • LayoutTests/css3/filters/drop-shadow-target-clipped.html
  • LayoutTests/editing/pasteboard/cjk-line-height-expected.txt
  • LayoutTests/fast/canvas/webgl/data-view-test-expected.txt
  • LayoutTests/fast/css/container-query-orientation-modal-dialog-crash-expected.txt
  • LayoutTests/fast/css/container-query-orientation-modal-dialog-crash.html
  • LayoutTests/fast/css/css-typed-om-typeerror-coalescing-pair-expected.txt
  • LayoutTests/fast/css/css-typed-om-typeerror-coalescing-pair.html
  • LayoutTests/fast/css/css-typed-om/css-builder-converter-initial-letter-crash-expected.txt
  • LayoutTests/fast/css/css-typed-om/css-builder-converter-initial-letter-crash.html
  • LayoutTests/fast/css/css-typed-om/css-typed-om-typeerror-associated-property-mismatch-expected.txt
  • LayoutTests/fast/css/css-typed-om/css-typed-om-typeerror-associated-property-mismatch.html
  • LayoutTests/fast/css/cssom-border-image-width-crash.html
  • LayoutTests/fast/css/cssom-mask-border-width-crash-expected.txt
  • LayoutTests/fast/css/cssom-mask-border-width-crash.html
  • LayoutTests/fast/css/cssom-translate-crash-expected.txt
  • LayoutTests/fast/css/cssom-translate-crash.html
  • LayoutTests/fast/css/getComputedStyle/computed-style-font-family-expected.txt
  • LayoutTests/fast/css/getComputedStyle/font-family-fallback-reset-expected.txt
  • LayoutTests/fast/css/getComputedStyle/font-family-fallback-reset.html
  • LayoutTests/fast/css/serialization-with-double-quotes-expected.txt
  • LayoutTests/fast/css/serialization-with-double-quotes.html
  • LayoutTests/fast/css/stylepropertymap-append-not-checking-for-variablereferencevalue-expected.txt
  • LayoutTests/fast/css/stylepropertymap-append-not-checking-for-variablereferencevalue.html
  • LayoutTests/fast/dom/StyleSheet/css-font-variation-settings-crash.html
  • LayoutTests/fast/dom/navigator-detached-no-crash-expected.txt
  • LayoutTests/fast/flexbox/preferred-width-empty-inline-block-expected.txt
  • LayoutTests/fast/flexbox/preferred-width-empty-inline-block.html
  • LayoutTests/fast/forms/ios/form-control-refresh/button/identical-buttons-have-same-corner-radius-expected.html
  • LayoutTests/fast/forms/ios/form-control-refresh/button/identical-buttons-have-same-corner-radius.html
  • LayoutTests/fast/forms/ios/select-menulist-text-align-chevron-padding-expected.txt
  • LayoutTests/fast/forms/ios/select-menulist-text-align-chevron-padding.html
  • LayoutTests/fast/forms/label/label-click-event-dispatch-untrusted-expected.txt
  • LayoutTests/fast/forms/label/label-click-event-dispatch-untrusted.html
  • LayoutTests/fast/grid/grid-item-block-content-size-suggestion-crash-expected.txt
  • LayoutTests/fast/grid/grid-item-block-content-size-suggestion-crash.html
  • LayoutTests/fast/hidpi/filters-drop-shadow.html
  • LayoutTests/fast/images/stopped-animation-deleted-image.html
  • LayoutTests/fast/overflow/intrinsic-width-container-with-scrollable-descendant-expected.html
  • LayoutTests/fast/overflow/intrinsic-width-container-with-scrollable-descendant.html
  • LayoutTests/fast/overflow/min-intrinsic-width-container-with-scrollable-descendant-expected.html
  • LayoutTests/fast/overflow/min-intrinsic-width-container-with-scrollable-descendant.html
  • LayoutTests/fast/repaint/blur-change-expected.txt
  • LayoutTests/fast/repaint/blur-change.html
  • LayoutTests/fast/repaint/drop-shadow-box-change-expected.txt
  • LayoutTests/fast/repaint/drop-shadow-box-change.html
  • LayoutTests/fast/repaint/drop-shadow-change-expected.txt
  • LayoutTests/fast/repaint/drop-shadow-change.html
  • LayoutTests/fast/repaint/drop-shadow-writing-modes-expected.txt
  • LayoutTests/fast/repaint/drop-shadow-writing-modes.html
  • LayoutTests/fast/repaint/select-option-background-color-tracked.html
  • LayoutTests/fast/scrolling/ios/fixed-position-in-vertical-rl-expected.html
  • LayoutTests/fast/scrolling/ios/fixed-position-in-vertical-rl.html
  • LayoutTests/fast/scrolling/ios/iframe-scroll-into-view.html
  • LayoutTests/fast/shadow-dom/style-invalidation-slotted-element-with-author-shadow-root-crash-expected.txt
  • LayoutTests/fast/shadow-dom/style-invalidation-slotted-element-with-author-shadow-root-crash.html
  • LayoutTests/fast/text-extraction/contenteditable-text-extraction-expected.txt
  • LayoutTests/fast/text-extraction/contenteditable-text-extraction.html
  • LayoutTests/fast/text-extraction/max-recursion-depth-cap-expected.html
  • LayoutTests/fast/text-extraction/max-recursion-depth-cap.html
  • LayoutTests/fast/text-extraction/text-extraction-scroll-fallback-to-large-container-expected.txt
  • LayoutTests/fast/text-extraction/text-extraction-scroll-fallback-to-large-container.html
  • LayoutTests/fast/text/font-face-family-expected.txt
  • LayoutTests/fast/text/font-face-family.html
  • LayoutTests/fast/text/font-stretch-parse-expected.txt
  • LayoutTests/fast/text/font-stretch-parse.html
  • LayoutTests/fast/text/font-style-parse-expected.txt
  • LayoutTests/fast/text/font-style-parse.html
  • LayoutTests/fast/text/font-weight-parse-expected.txt
  • LayoutTests/fast/text/font-weight-parse.html
  • LayoutTests/http/tests/cache/partitioned-cache-iframe.html
  • LayoutTests/http/tests/cache/partitioned-cache.html
  • LayoutTests/http/tests/cache/resources/partitioned-cache-loader.html
  • LayoutTests/http/tests/css/filters-on-iframes-transform.html
  • LayoutTests/http/tests/css/filters-on-iframes.html
  • LayoutTests/http/tests/css/resources/references-external-green.html
  • LayoutTests/http/tests/css/resources/references-external-red.html
  • LayoutTests/http/tests/navigation/page-cache-pending-image-load-cache-partition.html
  • LayoutTests/http/tests/navigation/pushstate-at-unique-origin-denied-expected.txt
  • LayoutTests/http/tests/navigation/pushstate-at-unique-origin-denied.py
  • LayoutTests/http/tests/resourceLoadStatistics/third-party-cookie-blocking-about-blank-popup-expected.txt
  • LayoutTests/http/tests/resourceLoadStatistics/third-party-cookie-blocking-about-blank-popup.html
  • LayoutTests/http/tests/security/contentSecurityPolicy/manifest-src-allowed-expected.txt
  • LayoutTests/http/tests/security/contentSecurityPolicy/manifest-src-allowed.html
  • LayoutTests/http/tests/security/contentSecurityPolicy/manifest-src-blocked-expected.txt
  • LayoutTests/http/tests/security/contentSecurityPolicy/manifest-src-blocked.html
  • LayoutTests/http/tests/security/contentSecurityPolicy/path-traversal-bypass-with-percent-encoding-expected.txt
  • LayoutTests/http/tests/security/contentSecurityPolicy/path-traversal-bypass-with-percent-encoding.html
  • LayoutTests/http/tests/security/credentials-iframes.html
  • LayoutTests/http/tests/security/credentials-main-resource.html
  • LayoutTests/http/tests/security/cross-origin-blob-transfer-expected.txt
  • LayoutTests/http/tests/security/cross-origin-blob-transfer.html
  • LayoutTests/http/tests/security/cross-origin-iframe-fetch-after-crash-expected.txt
  • LayoutTests/http/tests/security/cross-origin-iframe-fetch-after-crash.html
  • LayoutTests/http/tests/security/cross-origin-indexeddb-expected.txt
  • LayoutTests/http/tests/security/cross-origin-indexeddb.html
  • LayoutTests/http/tests/security/cross-origin-local-storage-allowed.html
  • LayoutTests/http/tests/security/cross-origin-local-storage.html
  • LayoutTests/http/tests/security/cross-origin-session-storage-third-party-blocked.html
  • LayoutTests/http/tests/security/cross-origin-websql.html
  • LayoutTests/http/tests/security/cross-origin-worker-indexeddb.html
  • LayoutTests/http/tests/security/history-pushState-replaceState-from-sandboxed-iframe-expected.txt
  • LayoutTests/http/tests/security/resources/cross-origin-iframe-fetch-after-crash-iframe.html
  • LayoutTests/http/tests/security/resources/cross-origin-iframe-for-indexeddb-transience.html
  • LayoutTests/http/tests/security/resources/document-for-cross-origin-worker-indexeddb.html
  • LayoutTests/http/tests/security/resources/history-pushState-replaceState-from-sandboxed-iframe.html
  • LayoutTests/http/tests/security/resources/load-local-storage.html
  • LayoutTests/http/tests/security/same-origin-document-domain-storage-allowed.html
  • LayoutTests/http/tests/security/same-origin-storage-blocked.html
  • LayoutTests/http/tests/security/same-origin-websql-blocked.html
  • LayoutTests/http/tests/security/sync-xhr-partition.html
  • LayoutTests/http/tests/site-isolation/inspector/network/cross-origin-iframe-request-id-uniqueness-expected.txt
  • LayoutTests/http/tests/site-isolation/inspector/network/cross-origin-iframe-request-id-uniqueness.html
  • LayoutTests/http/tests/site-isolation/open-panel-in-cross-origin-iframe-expected.txt
  • LayoutTests/http/tests/site-isolation/open-panel-in-cross-origin-iframe.html
  • LayoutTests/http/tests/site-isolation/resources/file-input-iframe.html
  • LayoutTests/http/tests/site-isolation/resources/validation-message-iframe.html
  • LayoutTests/http/tests/site-isolation/validation-message-cross-origin-iframe-expected.txt
  • LayoutTests/http/tests/site-isolation/validation-message-cross-origin-iframe.html
  • LayoutTests/http/tests/ssl/media-stream/resources/get-user-media-frame.html
  • LayoutTests/http/tests/webgpu/webgpu/shader/validation/expression/binary/short_circuiting_and_or-expected.txt
  • LayoutTests/http/tests/webgpu/webgpu/shader/validation/parse/identifiers-expected.txt
  • LayoutTests/http/wpt/content-security-policy/sandbox-manifest-blocked-cross-origin.sub-expected.txt
  • LayoutTests/http/wpt/content-security-policy/sandbox-manifest-blocked-cross-origin.sub.html
  • LayoutTests/http/wpt/content-security-policy/sandbox-manifest-blocked-expected.txt
  • LayoutTests/http/wpt/content-security-policy/sandbox-manifest-blocked.html
  • LayoutTests/imported/w3c/resources/import-expectations.json
  • LayoutTests/imported/w3c/resources/resource-files.json
  • LayoutTests/imported/w3c/web-platform-tests/beacon/beacon-url-encoding-euc-kr.https-expected.txt
  • LayoutTests/imported/w3c/web-platform-tests/beacon/beacon-url-encoding-euc-kr.https.html
  • LayoutTests/imported/w3c/web-platform-tests/beacon/resources/url-echo.py
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/META.yml
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/basic-expected.txt
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-nn.html
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynn.html
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynyn.html
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/resources/dialog-prevents-close.html
  • LayoutTests/imported/w3c/web-platform-tests/close-watcher/inside-event-listeners-expected.txt
  • LayoutTests/imported/w3c/web-platform-tests/common/reftest-wait.js
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-at-start-with-margin-top-collapses-with-parent-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-at-start-with-margin-top-collapses-with-parent-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-at-start-with-margin-top-collapses-with-parent.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-followed-by-empty-span-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-followed-by-empty-span-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-followed-by-empty-span.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-followed-by-line-break-and-text-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-followed-by-line-break-and-text-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-followed-by-line-break-and-text.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-large-margin-bottom-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-large-margin-bottom-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-large-margin-bottom.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-bottom-with-trailing-block-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-bottom-with-trailing-block-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-bottom-with-trailing-block.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-through-intervening-float-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-through-intervening-float-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-through-intervening-float.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-through-multiple-floats-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-through-multiple-floats-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-through-multiple-floats.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-with-parent-bottom-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-with-parent-bottom-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-collapses-with-parent-bottom.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-leading-and-trailing-text-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-leading-and-trailing-text-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-leading-and-trailing-text.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-leading-text-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-leading-text-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-leading-text.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-line-break-then-block-in-inline-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-line-break-then-block-in-inline-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-line-break-then-block-in-inline.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-multi-line-text-after-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-multi-line-text-after-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-multi-line-text-after.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-multi-line-text-before-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-multi-line-text-before-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-multi-line-text-before.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-text-then-block-in-inline-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-text-then-block-in-inline-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margin-with-text-then-block-in-inline.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margins-collapse-with-trailing-block-expected.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margins-collapse-with-trailing-block-ref.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-margins-collapse-with-trailing-block.html
  • LayoutTests/imported/w3c/web-platform-tests/css/CSS2/box-display/block-in-inline-negative-margin-bottom-with-trailing-block-expected.html
💤 Files with no reviewable changes (18)
  • LayoutTests/fast/css/cssom-translate-crash-expected.txt
  • LayoutTests/fast/flexbox/preferred-width-empty-inline-block.html
  • LayoutTests/fast/dom/StyleSheet/css-font-variation-settings-crash.html
  • LayoutTests/fast/css/cssom-mask-border-width-crash.html
  • LayoutTests/fast/css/stylepropertymap-append-not-checking-for-variablereferencevalue.html
  • LayoutTests/fast/css/cssom-mask-border-width-crash-expected.txt
  • LayoutTests/fast/css/css-typed-om-typeerror-coalescing-pair.html
  • LayoutTests/fast/flexbox/preferred-width-empty-inline-block-expected.txt
  • LayoutTests/fast/css/stylepropertymap-append-not-checking-for-variablereferencevalue-expected.txt
  • LayoutTests/fast/css/css-typed-om/css-builder-converter-initial-letter-crash-expected.txt
  • LayoutTests/fast/css/cssom-border-image-width-crash.html
  • JSTests/test262/config.yaml
  • LayoutTests/http/tests/security/resources/load-local-storage.html
  • LayoutTests/http/tests/security/cross-origin-local-storage-allowed.html
  • LayoutTests/fast/css/css-typed-om/css-builder-converter-initial-letter-crash.html
  • LayoutTests/fast/css/css-typed-om-typeerror-coalescing-pair-expected.txt
  • JSTests/test262/expectations.yaml
  • LayoutTests/fast/css/cssom-translate-crash.html

$vm.toCacheableDictionary(o);

// Warm: would tempt the cache to record NonThenable on the dictionary structure.
for (let i = 0; i < testLoopCount; 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 | 🔴 Critical | ⚡ Quick win

Undefined variable testLoopCount.

The variable testLoopCount is referenced on lines 32, 51, 68, and 82 but is never declared or defined in this file. This will cause a ReferenceError at runtime.

🐛 Proposed fix

Add the variable declaration near the top of the file, after the helper functions:

 }
 
+const testLoopCount = 10000;
+
 // --- 1. CacheableDictionary: add `then` in place after warm-up ---
 asyncTest(async function cacheableDictionaryGainsThen() {

Also applies to: 51-51, 68-68, 82-82

🤖 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/promise-resolve-non-thenable-structure-cache-dictionary.js` at
line 32, Declare and initialize the missing variable testLoopCount near the top
of the file (e.g., immediately after the helper functions) so the for-loops that
reference it (the for (...) using testLoopCount) do not throw a ReferenceError;
set it to an appropriate integer or source it from configuration/environment if
intended to be configurable, and ensure the same identifier testLoopCount is
used consistently across the loops at the locations where it is currently
referenced.

Comment on lines +31 to +35
document.body.classList.add('changed');

if (window.internals) {
debug(window.internals.repaintRectsAsText());
internals.stopTrackingRepaints();
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

Wait for a rendering update after the style mutation before reading repaint rects.

At Line 31, the class change is applied, but repaint rectangles are read immediately on Line 34. This can race and cause flaky output.

Proposed fix
             document.body.classList.add('changed');
+            await UIHelper.renderingUpdate();
 
             if (window.internals) {
                 debug(window.internals.repaintRectsAsText());
                 internals.stopTrackingRepaints();
             }
📝 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
document.body.classList.add('changed');
if (window.internals) {
debug(window.internals.repaintRectsAsText());
internals.stopTrackingRepaints();
document.body.classList.add('changed');
await UIHelper.renderingUpdate();
if (window.internals) {
debug(window.internals.repaintRectsAsText());
internals.stopTrackingRepaints();
🤖 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 `@LayoutTests/fast/repaint/drop-shadow-box-change.html` around lines 31 - 35,
After adding the 'changed' class to document.body, wait for the next rendering
frame before calling window.internals.repaintRectsAsText() and
internals.stopTrackingRepaints(); replace the immediate read with a
requestAnimationFrame (or two nested requestAnimationFrame calls) to ensure the
style mutation has been applied and paint/repaint rects are stable before
debugging and stopping tracking.

Comment on lines +28 to +33
document.body.classList.add('changed');

if (window.internals) {
debug(window.internals.repaintRectsAsText());
internals.stopTrackingRepaints();
}
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

Flush rendering before reading repaint rects.

repaintRectsAsText() is read immediately after the style mutation at Line 28. Add a rendering update before Line 31 to avoid stale/empty repaint captures and flaky expectations.

Proposed fix
             document.body.classList.add('changed');
+            await UIHelper.renderingUpdate();
 
             if (window.internals) {
                 debug(window.internals.repaintRectsAsText());
                 internals.stopTrackingRepaints();
             }
📝 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
document.body.classList.add('changed');
if (window.internals) {
debug(window.internals.repaintRectsAsText());
internals.stopTrackingRepaints();
}
document.body.classList.add('changed');
await UIHelper.renderingUpdate();
if (window.internals) {
debug(window.internals.repaintRectsAsText());
internals.stopTrackingRepaints();
}
🤖 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 `@LayoutTests/fast/repaint/drop-shadow-change.html` around lines 28 - 33, After
adding the 'changed' class to document.body, force a rendering flush before
calling window.internals.repaintRectsAsText() to avoid capturing stale/empty
repaint rects; insert a synchronous layout/paint trigger (for example, read a
layout-affecting property such as document.body.offsetHeight or
window.getComputedStyle(document.body).width) immediately after
document.body.classList.add('changed') and before calling repaintRectsAsText(),
then proceed to call window.internals.repaintRectsAsText() and
internals.stopTrackingRepaints().

Comment on lines +12 to +22
addEventListener("load", async () => {
if (!window.testRunner)
return;

testRunner.dumpAsText();
testRunner.waitUntilDone();
document.body.textContent = await UIHelper.requestTextExtraction({
mergeParagraphs: true
});
testRunner.notifyDone();
});
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 notifyDone() is always reached.

If Line 18 rejects, the test never calls testRunner.notifyDone() and can timeout.

Proposed fix
 addEventListener("load", async () => {
     if (!window.testRunner)
         return;

     testRunner.dumpAsText();
     testRunner.waitUntilDone();
-    document.body.textContent = await UIHelper.requestTextExtraction({
-        mergeParagraphs: true
-    });
-    testRunner.notifyDone();
+    try {
+        document.body.textContent = await UIHelper.requestTextExtraction({
+            mergeParagraphs: true
+        });
+    } finally {
+        testRunner.notifyDone();
+    }
 });
📝 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
addEventListener("load", async () => {
if (!window.testRunner)
return;
testRunner.dumpAsText();
testRunner.waitUntilDone();
document.body.textContent = await UIHelper.requestTextExtraction({
mergeParagraphs: true
});
testRunner.notifyDone();
});
addEventListener("load", async () => {
if (!window.testRunner)
return;
testRunner.dumpAsText();
testRunner.waitUntilDone();
try {
document.body.textContent = await UIHelper.requestTextExtraction({
mergeParagraphs: true
});
} finally {
testRunner.notifyDone();
}
});
🤖 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 `@LayoutTests/fast/text-extraction/contenteditable-text-extraction.html` around
lines 12 - 22, The test currently awaits UIHelper.requestTextExtraction in the
load event handler and may never call testRunner.notifyDone() if that promise
rejects; wrap the await in a try/finally (or use .catch(...) and a finally)
inside the addEventListener callback so that testRunner.notifyDone() is always
invoked regardless of success or error, referencing the async load handler,
UIHelper.requestTextExtraction, and
testRunner.notifyDone()/testRunner.waitUntilDone()/testRunner.dumpAsText() to
locate where to add the try/finally.

Comment on lines +46 to +48
window.addEventListener("message", function handler(event) {
if (event.data && event.data.type === "fetch-done") {
window.removeEventListener("message", handler);
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

Filter postMessage events by popup source before evaluating result.

Without validating event.source, unrelated messages can be consumed by this handler and cause flaky outcomes.

Suggested fix
-                window.addEventListener("message", function handler(event) {
-                    if (event.data && event.data.type === "fetch-done") {
+                window.addEventListener("message", function handler(event) {
+                    if (event.source !== popup)
+                        return;
+                    if (event.data && event.data.type === "fetch-done") {
                         window.removeEventListener("message", handler);
                         var result = event.data.result;
📝 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
window.addEventListener("message", function handler(event) {
if (event.data && event.data.type === "fetch-done") {
window.removeEventListener("message", handler);
window.addEventListener("message", function handler(event) {
if (event.source !== popup)
return;
if (event.data && event.data.type === "fetch-done") {
window.removeEventListener("message", handler);
🤖 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
`@LayoutTests/http/tests/resourceLoadStatistics/third-party-cookie-blocking-about-blank-popup.html`
around lines 46 - 48, The message handler registered via
window.addEventListener("message", function handler(event) { ... }) should first
verify the message came from the popup before acting; update the handler to
check event.source === popup (or the actual popup variable name used in the
test) and only then inspect event.data.type === "fetch-done" and
removeEventListener("message", handler). This prevents unrelated postMessage
events from being consumed and causing flakes.

Comment on lines +23 to +27
const reply = awaitEvent(window, "message", signal);
iframe.contentWindow.postMessage("dialog_open", "*");
const {data} = (await reply);
if (data.error) throw new Error(data.error);
return data.open;
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

Filter message replies by iframe source.

Line 23 resolves on the first message event from window; with two iframes, a reply from the non-target iframe can be consumed by mistake. Gate on event.source === iframe.contentWindow before accepting the reply.

🤖 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
`@LayoutTests/imported/w3c/web-platform-tests/close-watcher/iframes/dialog-same-origin-ynyn.html`
around lines 23 - 27, The message handler currently accepts the first window
"message" event which can come from the wrong iframe; change the reply
acceptance so it only resolves when event.source === iframe.contentWindow. In
practice update the awaitEvent(window, "message", signal) usage (or the code
that handles its result) to check event.source === iframe.contentWindow and
ignore/continue waiting for other messages until the source matches, then
extract data and proceed (the variables/functions to change are awaitEvent,
reply, and the check before reading data/error).

@sosukesuzuki sosukesuzuki merged commit 0d85951 into main May 22, 2026
73 of 85 checks passed
Jarred-Sumner pushed a commit to oven-sh/bun that referenced this pull request May 22, 2026
Upgrades Bun's WebKit fork to upstream `39d4ce1f12ea` (~422 upstream
commits since `49d2e914a4cc`). Fork PR: oven-sh/WebKit#236.

> **Note:** `WEBKIT_VERSION` currently points at the **preview build**
(`autobuild-preview-pr-236-e54e803f`). After oven-sh/WebKit#236 is
merged, this should be updated to the merge-commit autobuild before this
PR is merged.

# WebKit Upgrade: `49d2e914a4cc` → `39d4ce1f12ea`

~422 upstream commits total; ~80 touch `Source/JavaScriptCore`,
`Source/WTF`, or `Source/bmalloc`.

## ⚠️ Embedder-facing API / ABI changes

These directly affect Bun's bindings and were resolved during the merge.

- **`JSType` enum changed** — `HeapDoubleType` and `HeapInt32Type`
removed; `JSAsyncFunctionGeneratorType` added after `JSGeneratorType`;
constant `LastMaybeFalsyCellPrimitive` renamed to
`LastValueCompareCellType`. Every JSType value after `HeapBigIntType`
shifts down by 2, and every value after `JSGeneratorType` shifts up by
1. Bun's mirror of this enum in `src/jsc/bindings/JSType.zig` (and any
consumers) must be regenerated/checked.
- **`JSGenerator` split into `JSGenerator` +
`JSAsyncFunctionGenerator`** (`e0704d3127d5`, bug 314933).
`sizeof(JSGenerator)` shrinks 64 → 48 bytes by moving the `Context`
internal field into the new `JSAsyncFunctionGenerator` class. Async
functions now drive a `JSAsyncFunctionGenerator`, not a plain
`JSGenerator`. Anything that downcasts the async function generator must
use the new type.
- **`JSPromise::performPromiseThenWithInternalMicrotask` signature
changed** (`8f742098b444`, bug 314788). Fourth parameter was `JSValue
promise`, now `JSCell* cell`. Pass `nullptr` where `jsUndefined()` was
passed before. `setInlineMicrotaskReaction` also gained the `JSCell*`
parameter; the inline reaction now stores a separate cell payload
alongside the context, so a single `JSPromise` can carry an inlined
`InternalMicrotask` reaction plus a result-promise cell without
allocating a `JSPromiseReaction`.
- **`JSModuleLoader::loadModule` now takes `OptionSet<ModuleLoadFlag>`**
instead of separate `bool evaluate, bool dynamic, bool useImportMap`
parameters (`7f062965e945`, bug 314794). New flag
`ModuleLoadFlag::Deferred` added for `import.defer()`.
`ModuleLoadingContext::create` likewise switched to the OptionSet.
- **`globalObjectMethodTable()->moduleLoaderImportModule` gained a
trailing `bool deferred` parameter** (`7f062965e945`). Bun's
`JSGlobalObject` method table override must accept and (for now, can
ignore) it.
- **`JSHeapInt32` / `JSHeapDouble` removed** (`3bb4fc93fb37`, bug
314894). These were the experimental 32-bit-JSValues "compressed heap"
boxing types; the headers, IsoSubspaces, and includes are gone.
- **`Symbol::toString(JSGlobalObject*)` added** (`5e57a5812ef4`, bug
314842). Caches the descriptive string on the `Symbol` object.
`stringConstructor()` now calls it instead of building the string
inline.
- **`AbstractModuleRecord::ImportEntries` / `ExportEntries` switched to
`WTF::OrderedHashMap`** (`4d67159942bc`, bug 314961). Was
`UncheckedKeyHashMap`. Iteration order is now insertion order;
module-binding error messages are deterministic.

### `JSType.h` diff

```diff
@@ -31,10 +31,12 @@ namespace JSC {
     macro(CellType, SpecCellOther) \
     macro(StructureType, SpecCellOther) \
+    \
+    /* These JSCells require non-pointer-comparison identity check */ \
+    /* (e.g. String value comparison). Keep in sync with LastValueCompareCellType. */ \
     macro(StringType, SpecString) \
     macro(HeapBigIntType, SpecHeapBigInt) \
-    macro(HeapDoubleType, SpecCellOther) \
-    macro(HeapInt32Type, SpecCellOther) \
+    \
     macro(SymbolType, SpecSymbol) \
@@ -133,6 +135,7 @@ namespace JSC {
     macro(JSGeneratorType, SpecObjectOther) \
+    macro(JSAsyncFunctionGeneratorType, SpecObjectOther) \
     macro(JSAsyncGeneratorType, SpecObjectOther) \
@@ -168,7 +171,7 @@ enum JSType : uint8_t {
-static constexpr uint32_t LastMaybeFalsyCellPrimitive = HeapBigIntType;
+static constexpr uint32_t LastValueCompareCellType = HeapBigIntType;
```

## Promise / async-function fast path work

A coordinated batch of patches replacing JS-builtin promise plumbing
with C++ `InternalMicrotask` plumbing and removing
per-`await`/per-element allocations. Combined effect: large reductions
in object allocation and promise-resolution latency.

- `8f742098b444` — Inlined `InternalMicrotask` reaction: a pending
`JSPromise` can carry a single `InternalMicrotask` reaction (task id +
context + cell) directly in its `m_packed` / `m_slot` fields instead of
allocating a `JSSlimPromiseReaction`.
- `c3276f48dfd6` — Optimize the initial `then` call path for plain
promises.
- `cdf77b6570ff` — Cache `isDefinitelyNonThenable` result on
`Structure`; avoids re-walking the prototype chain for the same shape.
- `b1a624172673` — Inline allocation for `Promise.resolve()` of a
non-thenable object.
- `c71210975aaf` — Avoid creating both first resolving functions when
only one is needed in `Promise.all` / `Promise.any`.
- `0f6a35669fa8` — Avoid per-element `JSPromiseCombinatorsContext`
allocation in promise combinators.
- `4ed24b821a12` — Skip intermediate promise allocation for non-thenable
elements in `Promise` combinators.
- `e0704d3127d5` — `JSGenerator` shrink + `JSAsyncFunctionGenerator`
split (see above).

## DFG / FTL / JIT

- `b07dca9615f1` — `GetByStatus::computeFor` should not walk the proto
chain for direct property access (bug 309519).
- `fb8bfead603e` — Fix incorrect side-effect modeling for
`Spread(SetObjectUse)` in the DFG abstract interpreter (bug 315132).
- `c415e39f485b` — Introduce private tmp mechanism in DFG
`ByteCodeParser` (bug 315173).
- `1aeca6948c89` — DFG abstract interpreter misclassifies
`ArraySortCompact` result as `SpecObjectOther` (bug 315143).
- `227528432e5f` — Collect profiles from Baseline JIT compiler when
transitioning LLInt → Baseline (bug 315183).
- `7429d22f2bfd` — Fix DFG CPS validation for inlined sort comparator
(bug 315144).
- `d53865edf63b` — Add new `DateNow` DFG node (bug 315065).
- `596590000220` — Implement DFG / FTL `ArrayUnshift` (bug 315068).
- `dfe5dc6ed106` — Implement `ArrayShift` DFG node (bug 314926).
- `953bc0380f0b` — Add missing `ExitOK` after constant folding `then`
(bug 315042).
- `4d1b8f9f75bb` — Add `StringSubstr` DFG node (bug 314921).
- `67969621f703` — Inline `String#startsWith` / `String#endsWith` with
constant search string in DFG/FTL (bug 314517).
- `ce3942e437cb` — Extend megamorphic ByVal IC with symbols (bug
314890).
- `8f52a29461ca` — Optimize `===` (`stricteq`) with non-String /
non-HeapBigInt cells; uses the new `LastValueCompareCellType` boundary
(bug 314855).
- `59a20ddcb9ca` — Use scratch buffer for
`ObjectDefinePropertyFromFields` (bug 315074).

## Runtime / interpreter

- `1440f8619f82` — Implement `String#match` in C++ (bug 314466).
- `f9477aedc258` — Compare 8-bit strings a word at a time in
`Array#indexOf` / `Array#includes` (bug 314877).
- `a3aa7524f30f` — Use `truncateDoubleToInt32`/`64()` in more round-trip
double-to-int checks (bug 314884). Touches `TypedArrayAdaptors.h`.
- `8608a8ac3b20` — Fix test262 failure in
`TypedArray/constructor-buffer-sequence.js` (bug 313927).
- `918d694777b9` — Fix / update iterator return function call's
arguments (bug 315095).
- `72272dcc4feb` — `ScopedArgumentsTable` `ScopeOffset` buffer should
allocate from `fastMalloc` (bug 315082).
- `83e85f875a70` — Simplify bytecode writer (bug 314878).
`InstructionStream.h` now includes `<wtf/UnalignedAccess.h>` directly.
- `3c73fbe0cf5d` — Shard `JSTypedArrayViewPrototype` host functions
across `@no-unify` translation units (bug 313968).

## Modules

- `7f062965e945` — Implement dynamic `import.defer()` semantics (bug
314794). See API changes above.
- `4d67159942bc` — Use `OrderedHashMap` for module `ImportEntries` /
`ExportEntries` so error reporting is deterministic (bug 314961).

## Temporal

- `7f9fbe74e492` — Fix `fractionToDouble` for large denominators;
consolidate `ZonedDateTime` diff (bug 314848).
- `20ca333f3a4d` — Add duration rounding, calendar field resolution, and
date-time difference algorithms (bug 314765).

## Wasm

- `ca0c6bb18657` — JS wrappers for Wasm Tables created lazily (bug
314958).
- `29ac32293df6` — Build JS wrappers and `JSToWasmCallee`s lazily (bug
314910).
- `280445b02587` — Address an unexpected safer-cpp failure in
`WasmConstExprGenerator.cpp`.

## WTF / build infrastructure

- `368c0bec7652` — Introduce `WTF::toArray()` to work around
`std::to_array()` not being detected as `NODELETE` by static analysis
(bug 313933). Many files migrated by `97bbefac03a5`.
- `097a8276c97a` — Simplify `WTF::Variant` (build-speed work, bug
315055).
- `912cfd18d9b4` — `[Win]` `OSAllocator::tryProtect` fails when memory
spans multiple reserved regions (bug 315080).
- `b15055c7b0ed` — Update / fix Lock/Condition performance test binaries
(bug 315171).
- `6cfb79671c10` — `[CMake]` Touching a WTF `.cpp` no longer triggers an
11-second LLInt rebuild (bug 315226).
- `5780e754ea9b` — `[CMake]` Standardize `-Wunsafe-buffer-usage` flags
(bug 314991).
- `13415f9ed9f3` — Remove `-fsafe-buffer-usage-suggestions` (bug
314917).
- `99f0b44bc5ce` — `[CMake]` Fix some Linux builds with precompiled
headers (bug 314763).
- `c1f868200266` / `f31bec07e0e3` / `67ab82bd25dc` — Swift-in-WTF
interop work (parts 4), with one revert/reland cycle (bug 314469 /
315224 / 315166).
- `f1e8bc403871` / `286cd2780073` — WTF module-verification fixes for
some configurations (bugs 314977, 314858).
- `94043d8f9138` / `b035254290ed` — Suppress new Clang-22
`-Wunsafe-buffer-usage` warnings on GTK/WPE.
- `e6f4d3c2b495` — Adopt `ReducedResolutionSeconds` more widely (bug
314722).
- `dc311bb8313d` — `[Win]` Enable `MemoryPressureHandlerWin` and
implement a low-memory watcher (bug 297533).

## Cleanup / removal

- `3bb4fc93fb37` — Remove `JSHeapInt32` / `JSHeapDouble` (experimental
32-bit-JSValues boxing). Drops two `JSType` enum values and two
IsoSubspaces.
- `85bcefbc014c` — Fix a few more missing includes (bug 314821).
- `85015722cb65` — Fix a stray `-Wunsafe-buffer-usage` pragma that
accidentally disabled the check (bug 314771).

## Not relevant to Bun's `JSCOnly` build

- `b958a2407b33` — Order files for WebCore/JSC on macOS framework
builds.
- `2bfe8aece710` — Site Isolation Web Inspector network ID changes
(mostly WebCore/WebKit2).
- `8e1c6277f598` / `6c766638e894` / `f34545487d2f` — Threaded time-based
animations toggling.
- `f3d2e2f2ea01` — GTK/WPE skia compositor default.
- `02ee8d8ba70b`, `79003b865f9f`, `8f1f5a27db3d`, `56a1500e4215`,
`761dfab7357a`, `d47452669e1a`, `3784776034f9`, `39d4ce1f12ea` —
Cocoa/visionOS/sandbox/HDR/AVCapture/MTE platform work.
- `5a256540dbde`, `17c8e7383a38`, `fb6c928ed4b3`, `3ab6c7c73f9a`,
`3cef60980461` — iOS/watchOS/tvOS SDK build fixes and reverts.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Jarred-Sumner pushed a commit to oven-sh/bun that referenced this pull request May 23, 2026
Upgrades Bun's WebKit fork to upstream `39d4ce1f12ea` (~422 upstream
commits since `49d2e914a4cc`). Fork PR: oven-sh/WebKit#236.

> **Note:** `WEBKIT_VERSION` currently points at the **preview build**
(`autobuild-preview-pr-236-e54e803f`). After oven-sh/WebKit#236 is
merged, this should be updated to the merge-commit autobuild before this
PR is merged.

# WebKit Upgrade: `49d2e914a4cc` → `39d4ce1f12ea`

~422 upstream commits total; ~80 touch `Source/JavaScriptCore`,
`Source/WTF`, or `Source/bmalloc`.

## ⚠️ Embedder-facing API / ABI changes

These directly affect Bun's bindings and were resolved during the merge.

- **`JSType` enum changed** — `HeapDoubleType` and `HeapInt32Type`
removed; `JSAsyncFunctionGeneratorType` added after `JSGeneratorType`;
constant `LastMaybeFalsyCellPrimitive` renamed to
`LastValueCompareCellType`. Every JSType value after `HeapBigIntType`
shifts down by 2, and every value after `JSGeneratorType` shifts up by
1. Bun's mirror of this enum in `src/jsc/bindings/JSType.zig` (and any
consumers) must be regenerated/checked.
- **`JSGenerator` split into `JSGenerator` +
`JSAsyncFunctionGenerator`** (`e0704d3127d5`, bug 314933).
`sizeof(JSGenerator)` shrinks 64 → 48 bytes by moving the `Context`
internal field into the new `JSAsyncFunctionGenerator` class. Async
functions now drive a `JSAsyncFunctionGenerator`, not a plain
`JSGenerator`. Anything that downcasts the async function generator must
use the new type.
- **`JSPromise::performPromiseThenWithInternalMicrotask` signature
changed** (`8f742098b444`, bug 314788). Fourth parameter was `JSValue
promise`, now `JSCell* cell`. Pass `nullptr` where `jsUndefined()` was
passed before. `setInlineMicrotaskReaction` also gained the `JSCell*`
parameter; the inline reaction now stores a separate cell payload
alongside the context, so a single `JSPromise` can carry an inlined
`InternalMicrotask` reaction plus a result-promise cell without
allocating a `JSPromiseReaction`.
- **`JSModuleLoader::loadModule` now takes `OptionSet<ModuleLoadFlag>`**
instead of separate `bool evaluate, bool dynamic, bool useImportMap`
parameters (`7f062965e945`, bug 314794). New flag
`ModuleLoadFlag::Deferred` added for `import.defer()`.
`ModuleLoadingContext::create` likewise switched to the OptionSet.
- **`globalObjectMethodTable()->moduleLoaderImportModule` gained a
trailing `bool deferred` parameter** (`7f062965e945`). Bun's
`JSGlobalObject` method table override must accept and (for now, can
ignore) it.
- **`JSHeapInt32` / `JSHeapDouble` removed** (`3bb4fc93fb37`, bug
314894). These were the experimental 32-bit-JSValues "compressed heap"
boxing types; the headers, IsoSubspaces, and includes are gone.
- **`Symbol::toString(JSGlobalObject*)` added** (`5e57a5812ef4`, bug
314842). Caches the descriptive string on the `Symbol` object.
`stringConstructor()` now calls it instead of building the string
inline.
- **`AbstractModuleRecord::ImportEntries` / `ExportEntries` switched to
`WTF::OrderedHashMap`** (`4d67159942bc`, bug 314961). Was
`UncheckedKeyHashMap`. Iteration order is now insertion order;
module-binding error messages are deterministic.

### `JSType.h` diff

```diff
@@ -31,10 +31,12 @@ namespace JSC {
     macro(CellType, SpecCellOther) \
     macro(StructureType, SpecCellOther) \
+    \
+    /* These JSCells require non-pointer-comparison identity check */ \
+    /* (e.g. String value comparison). Keep in sync with LastValueCompareCellType. */ \
     macro(StringType, SpecString) \
     macro(HeapBigIntType, SpecHeapBigInt) \
-    macro(HeapDoubleType, SpecCellOther) \
-    macro(HeapInt32Type, SpecCellOther) \
+    \
     macro(SymbolType, SpecSymbol) \
@@ -133,6 +135,7 @@ namespace JSC {
     macro(JSGeneratorType, SpecObjectOther) \
+    macro(JSAsyncFunctionGeneratorType, SpecObjectOther) \
     macro(JSAsyncGeneratorType, SpecObjectOther) \
@@ -168,7 +171,7 @@ enum JSType : uint8_t {
-static constexpr uint32_t LastMaybeFalsyCellPrimitive = HeapBigIntType;
+static constexpr uint32_t LastValueCompareCellType = HeapBigIntType;
```

## Promise / async-function fast path work

A coordinated batch of patches replacing JS-builtin promise plumbing
with C++ `InternalMicrotask` plumbing and removing
per-`await`/per-element allocations. Combined effect: large reductions
in object allocation and promise-resolution latency.

- `8f742098b444` — Inlined `InternalMicrotask` reaction: a pending
`JSPromise` can carry a single `InternalMicrotask` reaction (task id +
context + cell) directly in its `m_packed` / `m_slot` fields instead of
allocating a `JSSlimPromiseReaction`.
- `c3276f48dfd6` — Optimize the initial `then` call path for plain
promises.
- `cdf77b6570ff` — Cache `isDefinitelyNonThenable` result on
`Structure`; avoids re-walking the prototype chain for the same shape.
- `b1a624172673` — Inline allocation for `Promise.resolve()` of a
non-thenable object.
- `c71210975aaf` — Avoid creating both first resolving functions when
only one is needed in `Promise.all` / `Promise.any`.
- `0f6a35669fa8` — Avoid per-element `JSPromiseCombinatorsContext`
allocation in promise combinators.
- `4ed24b821a12` — Skip intermediate promise allocation for non-thenable
elements in `Promise` combinators.
- `e0704d3127d5` — `JSGenerator` shrink + `JSAsyncFunctionGenerator`
split (see above).

## DFG / FTL / JIT

- `b07dca9615f1` — `GetByStatus::computeFor` should not walk the proto
chain for direct property access (bug 309519).
- `fb8bfead603e` — Fix incorrect side-effect modeling for
`Spread(SetObjectUse)` in the DFG abstract interpreter (bug 315132).
- `c415e39f485b` — Introduce private tmp mechanism in DFG
`ByteCodeParser` (bug 315173).
- `1aeca6948c89` — DFG abstract interpreter misclassifies
`ArraySortCompact` result as `SpecObjectOther` (bug 315143).
- `227528432e5f` — Collect profiles from Baseline JIT compiler when
transitioning LLInt → Baseline (bug 315183).
- `7429d22f2bfd` — Fix DFG CPS validation for inlined sort comparator
(bug 315144).
- `d53865edf63b` — Add new `DateNow` DFG node (bug 315065).
- `596590000220` — Implement DFG / FTL `ArrayUnshift` (bug 315068).
- `dfe5dc6ed106` — Implement `ArrayShift` DFG node (bug 314926).
- `953bc0380f0b` — Add missing `ExitOK` after constant folding `then`
(bug 315042).
- `4d1b8f9f75bb` — Add `StringSubstr` DFG node (bug 314921).
- `67969621f703` — Inline `String#startsWith` / `String#endsWith` with
constant search string in DFG/FTL (bug 314517).
- `ce3942e437cb` — Extend megamorphic ByVal IC with symbols (bug
314890).
- `8f52a29461ca` — Optimize `===` (`stricteq`) with non-String /
non-HeapBigInt cells; uses the new `LastValueCompareCellType` boundary
(bug 314855).
- `59a20ddcb9ca` — Use scratch buffer for
`ObjectDefinePropertyFromFields` (bug 315074).

## Runtime / interpreter

- `1440f8619f82` — Implement `String#match` in C++ (bug 314466).
- `f9477aedc258` — Compare 8-bit strings a word at a time in
`Array#indexOf` / `Array#includes` (bug 314877).
- `a3aa7524f30f` — Use `truncateDoubleToInt32`/`64()` in more round-trip
double-to-int checks (bug 314884). Touches `TypedArrayAdaptors.h`.
- `8608a8ac3b20` — Fix test262 failure in
`TypedArray/constructor-buffer-sequence.js` (bug 313927).
- `918d694777b9` — Fix / update iterator return function call's
arguments (bug 315095).
- `72272dcc4feb` — `ScopedArgumentsTable` `ScopeOffset` buffer should
allocate from `fastMalloc` (bug 315082).
- `83e85f875a70` — Simplify bytecode writer (bug 314878).
`InstructionStream.h` now includes `<wtf/UnalignedAccess.h>` directly.
- `3c73fbe0cf5d` — Shard `JSTypedArrayViewPrototype` host functions
across `@no-unify` translation units (bug 313968).

## Modules

- `7f062965e945` — Implement dynamic `import.defer()` semantics (bug
314794). See API changes above.
- `4d67159942bc` — Use `OrderedHashMap` for module `ImportEntries` /
`ExportEntries` so error reporting is deterministic (bug 314961).

## Temporal

- `7f9fbe74e492` — Fix `fractionToDouble` for large denominators;
consolidate `ZonedDateTime` diff (bug 314848).
- `20ca333f3a4d` — Add duration rounding, calendar field resolution, and
date-time difference algorithms (bug 314765).

## Wasm

- `ca0c6bb18657` — JS wrappers for Wasm Tables created lazily (bug
314958).
- `29ac32293df6` — Build JS wrappers and `JSToWasmCallee`s lazily (bug
314910).
- `280445b02587` — Address an unexpected safer-cpp failure in
`WasmConstExprGenerator.cpp`.

## WTF / build infrastructure

- `368c0bec7652` — Introduce `WTF::toArray()` to work around
`std::to_array()` not being detected as `NODELETE` by static analysis
(bug 313933). Many files migrated by `97bbefac03a5`.
- `097a8276c97a` — Simplify `WTF::Variant` (build-speed work, bug
315055).
- `912cfd18d9b4` — `[Win]` `OSAllocator::tryProtect` fails when memory
spans multiple reserved regions (bug 315080).
- `b15055c7b0ed` — Update / fix Lock/Condition performance test binaries
(bug 315171).
- `6cfb79671c10` — `[CMake]` Touching a WTF `.cpp` no longer triggers an
11-second LLInt rebuild (bug 315226).
- `5780e754ea9b` — `[CMake]` Standardize `-Wunsafe-buffer-usage` flags
(bug 314991).
- `13415f9ed9f3` — Remove `-fsafe-buffer-usage-suggestions` (bug
314917).
- `99f0b44bc5ce` — `[CMake]` Fix some Linux builds with precompiled
headers (bug 314763).
- `c1f868200266` / `f31bec07e0e3` / `67ab82bd25dc` — Swift-in-WTF
interop work (parts 4), with one revert/reland cycle (bug 314469 /
315224 / 315166).
- `f1e8bc403871` / `286cd2780073` — WTF module-verification fixes for
some configurations (bugs 314977, 314858).
- `94043d8f9138` / `b035254290ed` — Suppress new Clang-22
`-Wunsafe-buffer-usage` warnings on GTK/WPE.
- `e6f4d3c2b495` — Adopt `ReducedResolutionSeconds` more widely (bug
314722).
- `dc311bb8313d` — `[Win]` Enable `MemoryPressureHandlerWin` and
implement a low-memory watcher (bug 297533).

## Cleanup / removal

- `3bb4fc93fb37` — Remove `JSHeapInt32` / `JSHeapDouble` (experimental
32-bit-JSValues boxing). Drops two `JSType` enum values and two
IsoSubspaces.
- `85bcefbc014c` — Fix a few more missing includes (bug 314821).
- `85015722cb65` — Fix a stray `-Wunsafe-buffer-usage` pragma that
accidentally disabled the check (bug 314771).

## Not relevant to Bun's `JSCOnly` build

- `b958a2407b33` — Order files for WebCore/JSC on macOS framework
builds.
- `2bfe8aece710` — Site Isolation Web Inspector network ID changes
(mostly WebCore/WebKit2).
- `8e1c6277f598` / `6c766638e894` / `f34545487d2f` — Threaded time-based
animations toggling.
- `f3d2e2f2ea01` — GTK/WPE skia compositor default.
- `02ee8d8ba70b`, `79003b865f9f`, `8f1f5a27db3d`, `56a1500e4215`,
`761dfab7357a`, `d47452669e1a`, `3784776034f9`, `39d4ce1f12ea` —
Cocoa/visionOS/sandbox/HDR/AVCapture/MTE platform work.
- `5a256540dbde`, `17c8e7383a38`, `fb6c928ed4b3`, `3ab6c7c73f9a`,
`3cef60980461` — iOS/watchOS/tvOS SDK build fixes and reverts.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.