Skip to content

Conversation

@sosukesuzuki
Copy link

Upgrade WebKit Jan 4, 2026. Happy new year 🎉


WebKit Changes Summary

Merge Range: 1a1813b764ce694de82fa83d
Date Range: December 24, 2025 → January 3, 2026
Total Commits: 146


JavaScriptCore (JSC) Performance Improvements

Array Operations

  • Fast path for Array.from(set) - Optimized conversion from Set to Array
  • Fast path for Array.from(arguments) in strict mode - Improved performance for arguments object conversion
  • Use hasSpecialProperties for checking iterable - More efficient iterable detection

Async/Generator Optimizations

  • AsyncGenerator inline first queue item - Reduced memory allocation by embedding the first queue entry
  • Inline async function body when there is no await - Skip unnecessary promise wrapping for sync async functions
  • Move MicrotaskQueue driving AsyncGenerator code to C++ - Removed JS "WithoutPromise" variants
  • Use InternalMicrotask in AsyncFromSyncIterator - More efficient async iteration
  • Embed SuspendReason into State in JSAsyncGenerator - Reduced struct size

String Methods Moved to C++

  • String#padStart and String#padEnd - Native implementation replacing JS builtins
  • String#repeat - Native C++ implementation
  • String.prototype.replace / String.prototype.replaceAll - Full C++ implementation
  • RegExp.prototype[Symbol.replace] - Native C++ implementation
  • HTML-annotation String methods (anchor, big, bold, etc.) - Moved to C++

Promise Improvements

  • Track "then" property addition in Structure - Enables better optimization for promise-like objects
  • Implement @InternalPromise.@internalAll in C++ - Native Promise.all for internal use

Memory Optimizations

  • Shrink sizeof(QueuedTask) by embedding uint8_t payload into CompactRefPtrTuple
  • Treat unused catch binding as optional catch binding - Reduced bytecode size
  • Remove unused @setClone - Dead code removal

Bug Fixes

  • Fix %TypedArray%.prototype.includes to align with ECMA-262
  • Exception check error fixes

WTF (Web Template Framework)

Performance

  • Optimize String::fromUTF8 using simdutf - SIMD-accelerated UTF-8 decoding
  • Simplify SortedArrayMap / SortedArraySet - Removed requirement for separate std::array static variable
  • PlainText(): avoid extra buffer allocation for empty ranges

New Features

  • Introduce ThreadSafeWeakRef and adopt it where appropriate
  • Enable CHECK_REF_COUNTED_LIFECYCLE - Better reference counting validation

Improvements

  • Update Vector's uninitializedCopy() to use std::span
  • Simplify strlenSpan() and compareSpansConstExpr()
  • Fix subtle bug in SortedArrayMap's lessThanASCIICaseFolding()
  • RefCountedWithInlineWeakPtr fixes for GCC Release builds
  • Align ref and weakRef counting on uint32_t

Platform Fixes

  • Use OS(WINDOWS) instead of PLATFORM(WIN) - Consistent platform detection
  • Should not release RefPtr before using - Fixed use-after-free potential

Memory Safety (Safer C++)

Significant effort to reduce unsafe buffer usage across the codebase:

WTF

  • Drop WTF_ALLOW_UNSAFE_BUFFER_USAGE from: DateMath.cpp, MemoryDump, dragonbox, FixedBitVector

WebCore

  • Reduce unsafe member variables in:
    • GraphicsLayer, AudioMediaStreamTrackRenderer
    • AXSearchManager, FrameSnapshotting
    • WebCore/platform/graphics, scrolling code
    • MathMLRowElement, MediaSourcePrivateAVFObjC
    • mediastream code, WebAuthn code, mediasource/ code
    • User* files in WebCore/page

Platform-Specific

  • GLIB: NetworkCacheDataGLib, WebSocketTaskSoup
  • Cocoa: FaceDetectorImplementation.mm

Type Safety

  • Remove static_cast from: InspectorCSSAgent, WebCore/bridge, WebCore/svg, Internals, ScriptModuleLoader, platform/graphics, Modules/mediastream

SVG Improvements

  • Don't check 'visibility' in LegacyRenderSVGResourceMasker - Spec compliance fix
  • Synthesize preserveAspectRatio='none' for SVGs embedded in <img> without viewBox
  • stroke-dasharray applied to markers can now be overridden by ="0"
  • SVG <stop> offset attribute correctly rejects invalid values with trailing garbage
  • SVGLengthValue::setValueAsString avoids unnecessary String allocations
  • Introduce decoratedBoundingBox to fix repaint rect and bounding box conflation in SVG resources
  • Migrate from repaintRectInLocalCoordinates(Accurate) to direct computation
  • Fix typo in SVGRadialGradientElement.h lengths

CSS/Style System

MathML

  • Enable math-depth by default
  • Make math-style and math-shift animate discretely
  • <mpadded> treats percentage values as absent for width/height/depth attribute

Property Handling

  • Convert 'caret-color' property to strong style types
  • Generate logical property getter/setters via RenderStyleGen
  • Generate setters for hasExplicitlySet flags*
  • Remove custom style building code for fill and stroke properties
  • Extract color/transform related computation from RenderStyle to UsedStyle

Layout Fixes

  • -webkit-line-clamp supports inline-block children
  • offsetHeight/offsetWidth of inline box wrapping block box now returns correct values (was 0)
  • getClientRects now includes entry for inline boxes with block children
  • Fix block-in-inline client rects
  • Text layout consistency improvements for list-style-type

Core Image Filter Acceleration

New GPU-accelerated filter implementations for macOS/iOS:

  • FEMerge in Core Image
  • FEOffset in Core Image
  • FEGaussianBlur in Core Image (with geometry fixes)
  • GPU acceleration for morphology filters

AutoFill Debugging

  • Automatically extract items from same-origin subframes
  • Fix text extraction hanging indefinitely when invoked from system daemons
  • Heuristically shorten/redact high-entropy URLs in extracted text
  • Deduplicate shortened URLs and report replacements to client
  • Add system trace points for text extraction performance analysis

Swift in WebKit

  • Work towards modularizing PAL (part 3)
  • Re-land modularization of WebGPU (part 2)
  • Work towards having a proper JSC module (part 3)
  • Fix Swift modules depending on WTF occasionally needing erroneous imports

Platform & Build Changes

Removals

  • Remove ENABLE_TOUCH_EVENT_REGIONS definition
  • Stop using LocalServiceAdditions.h and MockLocalServiceAdditions.h
  • Remove unused WTF_MAKE_TZONE_OR_ISO_ALLOCATED macros

Build Fixes

  • Fix watchOS and tvOS builds after 305052@main
  • Fix WPE generated API header regression
  • Add missing hyphenation dictionaries to GTK APT dependencies
  • Fix LOG_CHANNEL_PREFIXFonts undeclared identifier in FontDescriptionCocoa.cpp
  • Fix ASSERTION FAILED in WTF_OptionSet tests on GTK/WPE

Web Platform Features

  • Expose operator lighter in SVGFECompositeElement IDL
  • Fix HTMLImageElement.currentSrc for empty src attribute
  • Resync web-animations from WPT upstream

Bug Fixes & Gardening

  • Multiple test expectation updates for macOS, iOS, GTK, WPE, GStreamer
  • Fix assertion failures in JSEventListener, PointerLockTests
  • Fix GStreamerVideoFrameConverter weak pointer assertion
  • Fix RecordMetaData::cacheStorageVersion uninitialized member
  • Fix run-builtins-generator-tests --reset-results regression

annevk and others added 30 commits December 24, 2025 08:57
https://bugs.webkit.org/show_bug.cgi?id=304564

Reviewed by Simon Fraser.

uint32_t is more explicit than unsigned and can reduce memory compared
to size_t on 64-bit platforms. And given that only ThreadSafeWeakPtr is
using size_t at the moment, this should be a reasonable change to make.

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

Reviewed by Simon Fraser.

This is a fairly mechanical change, but there are a couple noteworthy
aspects:

- TrackListBase derived classes already supported downcasting, but this
  was not being used and it was incorrect for AudioTrackList as that
  advertised itself as a VideoTrackList. This change removes all that
  infrastructure.
- SPECIALIZE_TYPE_TRAITS_CANVAS is removed as it remained only useful
  for CustomPaintCanvas.
- ManagedMediaSource and ManagedSourceBuffer did not implement
  eventTargetInterface(), but they do appear in EventTargetFactory.in.
  So patch adds eventTargetInterface() to them.

See also https://github.com/WebKit/WebKit/wiki/Safer-CPP-Guidelines

Canonical link: https://commits.webkit.org/304922@main
…mputedStyle::initial*()

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

Reviewed by Darin Adler.

Migrate all callers of the `RenderStyle::initial*()` functions to use
`Style::ComputedStyle::initial*()` and remove the now unnecessary
forwarded initial value functions.

* Source/WebCore/CMakeLists.txt:
* Source/WebCore/DerivedSources-output.xcfilelist:
* Source/WebCore/DerivedSources.make:
* Source/WebCore/Headers.cmake:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/animation/ScrollTimeline.cpp:
* Source/WebCore/css/scripts/process-css-properties.py:
* Source/WebCore/css/scripts/test/TestCSSPropertiesResults/RenderStyleProperties+InitialInlines.h: Removed.
* Source/WebCore/css/scripts/test/TestCSSPropertiesResults/RenderStyleProperties.h:
* Source/WebCore/css/scripts/test/TestCSSPropertiesResults/StyleBuilderGenerated.cpp:
* Source/WebCore/html/HTMLInputElement.cpp:
* Source/WebCore/layout/formattingContexts/grid/UnplacedGridItem.cpp:
* Source/WebCore/layout/formattingContexts/inline/InlineLineBoxVerticalAligner.cpp:
* Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp:
* Source/WebCore/layout/formattingContexts/inline/IntrinsicWidthHandler.cpp:
* Source/WebCore/layout/formattingContexts/inline/RangeBasedLineBuilder.cpp:
* Source/WebCore/layout/formattingContexts/inline/TextOnlySimpleLineBuilder.cpp:
* Source/WebCore/layout/integration/LayoutIntegrationBoxTreeUpdater.cpp:
* Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp:
* Source/WebCore/rendering/RenderBox.cpp:
* Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp:
* Source/WebCore/rendering/RenderFlexibleBox.cpp:
* Source/WebCore/rendering/RenderImage.cpp:
* Source/WebCore/rendering/RenderReplaced.cpp:
* Source/WebCore/rendering/RenderTheme.cpp:
* Source/WebCore/rendering/adwaita/RenderThemeAdwaita.cpp:
* Source/WebCore/rendering/mac/RenderThemeMac.mm:
* Source/WebCore/rendering/style/RenderStyle+InitialInlines.h: Removed.
* Source/WebCore/rendering/style/RenderStyle.h:
* Source/WebCore/rendering/style/SVGRenderStyle.cpp:
* Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp:
* Source/WebCore/rendering/style/StyleAppleColorFilterData.cpp:
* Source/WebCore/rendering/style/StyleBackdropFilterData.cpp:
* Source/WebCore/rendering/style/StyleBackgroundData.cpp:
* Source/WebCore/rendering/style/StyleBorderImageData.cpp:
* Source/WebCore/rendering/style/StyleBoxData.cpp:
* Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.cpp:
* Source/WebCore/rendering/style/StyleFilterData.cpp:
* Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp:
* Source/WebCore/rendering/style/StyleFontData.cpp:
* Source/WebCore/rendering/style/StyleGridData.cpp:
* Source/WebCore/rendering/style/StyleGridItemData.cpp:
* Source/WebCore/rendering/style/StyleInheritedData.cpp:
* Source/WebCore/rendering/style/StyleMarqueeData.cpp:
* Source/WebCore/rendering/style/StyleMaskBorderData.cpp:
* Source/WebCore/rendering/style/StyleMiscNonInheritedData.cpp:
* Source/WebCore/rendering/style/StyleMultiColData.cpp:
* Source/WebCore/rendering/style/StyleRareInheritedData.cpp:
* Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp:
* Source/WebCore/rendering/style/StyleTransformData.cpp:
* Source/WebCore/rendering/style/StyleVisitedLinkColorData.cpp:
* Source/WebCore/rendering/svg/SVGPaintServerHandling.h:
* Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp:
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGResource.cpp:
* Source/WebCore/rendering/updating/RenderTreeBuilderSVG.cpp:
* Source/WebCore/style/MatchedDeclarationsCache.cpp:
* Source/WebCore/style/StyleAdjuster.cpp:
* Source/WebCore/style/StyleBuilder.cpp:
* Source/WebCore/style/StyleBuilderCustom.h:
* Source/WebCore/style/StyleExtractorCustom.h:
* Source/WebCore/style/values/backgrounds/StyleBorderImage.cpp:
* Source/WebCore/style/values/masking/StyleMaskBorder.cpp:
* Source/WebCore/style/values/motion/StyleOffsetAnchor.cpp:
* Source/WebCore/style/values/motion/StyleOffsetPosition.cpp:
* Tools/TestWebKitAPI/Tests/WebCore/PlatformDynamicRangeLimitTests.cpp:

Canonical link: https://commits.webkit.org/304923@main
https://bugs.webkit.org/show_bug.cgi?id=301224
rdar://163144949

Unreviewed test gardening.

Tests imported/w3c/web-platform-tests/uievents/mouse/mouseover-at-removing-mousedown-target.html?duration=16 &
imported/w3c/web-platform-tests/uievents/mouse/mouseover-at-removing-mousedown-target.html?duration=42 fail
for iOS EWS builds. Update the expected results accordingly.

* LayoutTests/platform/ios/TestExpectations:
* LayoutTests/platform/ios/imported/w3c/web-platform-tests/uievents/mouse/mouseover-at-removing-mousedown-target_duration=16-expected.txt: Added.
* LayoutTests/platform/ios/imported/w3c/web-platform-tests/uievents/mouse/mouseover-at-removing-mousedown-target_duration=42-expected.txt: Added.

Canonical link: https://commits.webkit.org/304925@main
https://bugs.webkit.org/show_bug.cgi?id=304667
rdar://167114539

Reviewed by Mike Wyrzykowski.

- Complete the modularization of JSC by fully enabling the module verifier and not suppressing any errors
- Enable the JSC private module in more configurations and platforms
- Disable the JSC private module in configurations where it was previously ill-formed

* Source/JavaScriptCore/Configurations/JavaScriptCore.xcconfig:

Canonical link: https://commits.webkit.org/304926@main
…/redact high-entropy URLs in extracted text

https://bugs.webkit.org/show_bug.cgi?id=304653
rdar://165847831

Reviewed by Richard Robinson.

Add support for a flag, `-shortenURLs`, that clients can use to opt into aggressive policy around
shortening link `href` and image `src` when performing text extraction. For links, we discard all
query parameters and fragments, and any path components that are not "low-entropy" (based on the
results of a fast, very lightweight binary classifier — see below). For images, we use the last path
component only if it's "low-entropy", and otherwise fall back to "image" (preserving any existing
file extension).

Test: fast/text-extraction/debug-text-extraction-shorten-urls.html

* LayoutTests/fast/text-extraction/debug-text-extraction-shorten-urls-expected.txt: Added.
* LayoutTests/fast/text-extraction/debug-text-extraction-shorten-urls.html: Added.

Add a layout test to exercise this new option.

* Source/WebCore/Headers.cmake:
* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/page/text-extraction/TextExtraction.cpp:
(WebCore::TextExtraction::extractItemData):
* Source/WebCore/page/text-extraction/TextExtractionTypes.h:

Use the helpers below to strip out high-entropy path components from extracted URLs, along with any
query parameters and fragment.

* Source/WebCore/platform/StringEntropyHelpers.cpp: Added.
(WebCore::StringEntropyHelpers::symbol):
(WebCore::StringEntropyHelpers::dequantize):
(WebCore::StringEntropyHelpers::bigramWeight):
(WebCore::StringEntropyHelpers::entropyScore):
(WebCore::StringEntropyHelpers::isProbablyHumanReadable):
(WebCore::StringEntropyHelpers::lowEntropyLastPathComponent):
(WebCore::StringEntropyHelpers::removeHighEntropyComponents):

Add the fast path component classifier; see above for more details. Each character is mapped to one
of 10 character symbol types (e.g. uppercase hex, lowercase hex, uppercase non-hex, lowercase non-
hex, digits, etc.); the classifier is a very simple single-layer perceptron that takes (as inputs)
bigrams where each bigram consists of two adjacent symbol types. The 100 weights corresponding to
each bigram are encoded in a tiny lookup table, where each weight is quantized to a single byte
(`uint8_t`).

* Source/WebCore/platform/StringEntropyHelpers.h: Added.
* Source/WebKit/Shared/TextExtractionToStringConversion.cpp:
(WebKit::centerEllipsize):
(WebKit::TextExtractionAggregator::shortenURLs const):
(WebKit::addPartsForItem):
(WebKit::addTextRepresentationRecursive):
(WebKit::normalizedURLString): Deleted.

Honor the `shortenURLs` flag by using the shortened versions of link hrefs and image sources.

* Source/WebKit/Shared/TextExtractionToStringConversion.h:
* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:
* Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _extractDebugTextWithConfigurationWithoutUpdatingFilterRules:completionHandler:]):
* Source/WebKit/UIProcess/API/Cocoa/_WKTextExtraction.h:
* Source/WebKit/UIProcess/API/Cocoa/_WKTextExtraction.mm:
(-[_WKTextExtractionConfiguration setShortenURLs:]):
* Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* Tools/TestRunnerShared/UIScriptContext/UIScriptController.h:
* Tools/TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
(WTR::toTextExtractionTestOptions):

Add plumbing from `UIHelper` -> `WebKitTestRunner`, for the new `shortenURLs` flag.

* Tools/WebKitTestRunner/cocoa/UIScriptControllerCocoa.mm:
(WTR::createTextExtractionConfiguration):

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

Reviewed by Antti Koivisto.

This has been progressed by [blocks-in-inline].

* LayoutTests/fast/inline/inline-box-offset-width-height-and-continuation-expected.txt: Added.
* LayoutTests/fast/inline/inline-box-offset-width-height-and-continuation.html: Added.

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

Reviewed by Anne van Kesteren.

304701@main changed to use `PLATFORM(WIN)` to detect being in Windows.

But since the `PLATFORM` macro isn't provided JSCOnly build, we cannot build JSCOnly on Windows.

So this patch changes to use `OS(WINDOWS)` instead  of `PLATFORM(WIN)`.

* Source/WTF/wtf/RefCountDebugger.cpp:

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

Reviewed by Yusuke Suzuki.

This patch reverts 304888@main to reland 304331@main.

The original patch used PromiseAllResolveJob which calls resolve() to settle
the result promise. However, resolve() looks up the "then" property on the
resolution value, which can have user-observable side effects. For example,
if Object.prototype.then is set to a custom function, it would be called
when resolving the result array, breaking the InternalPromise pipeline.

InternalPromise requires using fulfill() instead of resolve() because
fulfill() directly settles the promise without looking up "then". This is
the key difference between InternalPromise and regular Promise - InternalPromise
must not trigger any user-observable operations.

This patch:

- Adds InternalPromiseAllResolveJob which uses fulfill() instead of resolve()
- Updates JSInternalPromiseConstructor to use InternalPromiseAllResolveJob
- Also uses fulfill() for the empty array case
- Adds a test to verify Object.prototype.then is not called through module loader

---

This patch changes to implement `@InternalPromiseAll.@internalAll` in C++.

                                       TipOfTree                  Patched

internal-promise-internal-all        7.2714+-0.6089     ^      4.1862+-0.2744        ^ definitely 1.7370x faster

* JSTests/microbenchmarks/internal-promise-internal-all.js: Added.
* JSTests/modules/object-prototype-then-should-not-be-called-through-internal-promise.js: Added.
(Object.prototype.then):
* JSTests/modules/object-prototype-then-should-not-be-called-through-internal-promise/test.js: Added.
* Source/JavaScriptCore/CMakeLists.txt:
* Source/JavaScriptCore/DerivedSources-input.xcfilelist:
* Source/JavaScriptCore/DerivedSources.make:
* Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj:
* Source/JavaScriptCore/builtins/InternalPromiseConstructor.js: Removed.
* Source/JavaScriptCore/runtime/JSInternalPromiseConstructor.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
* Source/JavaScriptCore/runtime/JSMicrotask.cpp:
(JSC::internalPromiseAllResolveJob):
(JSC::runInternalMicrotask):
* Source/JavaScriptCore/runtime/Microtask.h:

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

Unreviewed gardening.

* LayoutTests/platform/glib/TestExpectations:
* LayoutTests/platform/gtk/TestExpectations:
* LayoutTests/platform/wpe/TestExpectations:
* LayoutTests/platform/wpe/fast/forms/datalist/datalist-searchinput-appearance-expected.txt: Added.
* LayoutTests/platform/wpe/fast/forms/datalist/datalist-textinput-appearance-expected.txt: Added.

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

Unreviewed test gardening by invoking `./Tools/Scripts/run-builtins-generator-tests --reset-results`.

* Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Combined.js-result:
* Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Separate.js-result:
* Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Combined.js-result:
* Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Separate.js-result:
* Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Combined.js-result:
* Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Separate.js-result:
* Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-InternalClashingNames-Combined.js-result:
* Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-AnotherGuardedInternalBuiltin-Separate.js-result:
* Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-ArbitraryConditionalGuard-Separate.js-result:
* Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-GuardedBuiltin-Separate.js-result:
* Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-GuardedInternalBuiltin-Separate.js-result:
* Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-UnguardedBuiltin-Separate.js-result:
* Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-xmlCasingTest-Separate.js-result:
* Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCoreJSBuiltins.h-result:

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

Unreviewed gardening.

These are passing in GTK/WPE so they can be unskipped. Also remove
redundant expectations that are exactly the same in all platforms.

* LayoutTests/editing/caret/emoji-expected.txt: Renamed from LayoutTests/platform/mac/editing/caret/emoji-expected.txt.
* LayoutTests/editing/deleting/delete-emoji-2-expected.txt: Renamed from LayoutTests/platform/ios/editing/deleting/delete-emoji-2-expected.txt.
* LayoutTests/editing/deleting/delete-emoji-3-expected.txt: Renamed from LayoutTests/platform/ios/editing/deleting/delete-emoji-3-expected.txt.
* LayoutTests/editing/deleting/delete-emoji-4-expected.txt: Renamed from LayoutTests/platform/ios/editing/deleting/delete-emoji-4-expected.txt.
* LayoutTests/editing/deleting/delete-emoji-5-expected.txt: Renamed from LayoutTests/platform/ios/editing/deleting/delete-emoji-5-expected.txt.
* LayoutTests/editing/deleting/delete-emoji-6-expected.txt: Renamed from LayoutTests/platform/ios/editing/deleting/delete-emoji-6-expected.txt.
* LayoutTests/editing/deleting/delete-emoji-7-expected.txt: Renamed from LayoutTests/platform/ios/editing/deleting/delete-emoji-7-expected.txt.
* LayoutTests/editing/deleting/delete-emoji-8-expected.txt: Renamed from LayoutTests/platform/ios/editing/deleting/delete-emoji-8-expected.txt.
* LayoutTests/editing/deleting/delete-emoji-9-expected.txt: Renamed from LayoutTests/platform/ios/editing/deleting/delete-emoji-9-expected.txt.
* LayoutTests/platform/glib/TestExpectations:
* LayoutTests/platform/mac/editing/deleting/delete-emoji-2-expected.txt: Removed.
* LayoutTests/platform/mac/editing/deleting/delete-emoji-3-expected.txt: Removed.
* LayoutTests/platform/mac/editing/deleting/delete-emoji-4-expected.txt: Removed.
* LayoutTests/platform/mac/editing/deleting/delete-emoji-5-expected.txt: Removed.
* LayoutTests/platform/mac/editing/deleting/delete-emoji-6-expected.txt: Removed.
* LayoutTests/platform/mac/editing/deleting/delete-emoji-7-expected.txt: Removed.
* LayoutTests/platform/mac/editing/deleting/delete-emoji-8-expected.txt: Removed.
* LayoutTests/platform/mac/editing/deleting/delete-emoji-9-expected.txt: Removed.
* LayoutTests/platform/win/editing/caret/emoji-expected.txt: Removed.
* LayoutTests/platform/win/editing/deleting/delete-emoji-2-expected.txt: Removed.
* LayoutTests/platform/win/editing/deleting/delete-emoji-3-expected.txt: Removed.
* LayoutTests/platform/win/editing/deleting/delete-emoji-4-expected.txt: Removed.
* LayoutTests/platform/win/editing/deleting/delete-emoji-5-expected.txt: Removed.
* LayoutTests/platform/win/editing/deleting/delete-emoji-6-expected.txt: Removed.
* LayoutTests/platform/win/editing/deleting/delete-emoji-7-expected.txt: Removed.
* LayoutTests/platform/win/editing/deleting/delete-emoji-8-expected.txt: Removed.
* LayoutTests/platform/win/editing/deleting/delete-emoji-9-expected.txt: Removed.

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

Reviewed by Sam Weinig.

Address a couple of existing FIXMEs asking for these classes to be
moved out of GraphicsLayer to enable us to reduce unsafeness in a
subsequent change (so we can clearly attribute blame in case something
goes amiss).

We did take the liberty of making GraphicLayerAnimationValue's
m_timingFunction const as part of this change as that's trivial enough.

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

Reviewed by Alan Baradlay.

Fixes layering violation in WebCore's PathUtilities.h by moving
PathUtilities::pathWithShrinkWrappedRectsForOutline(...) to live
on OutlinePainter.

The issue was that `pathWithShrinkWrappedRectsForOutline` used
non-platform layer types `Style::BorderRadius` and `WritingMode`,
so, the function needed to live above the platform layer.

To make this possible, the `FloatPointGraph` that used to live
in PathUtilities.cpp was moved into its own files, along with
the `polygonsForRect` utility function.

* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/platform/graphics/FloatPointGraph.cpp: Added.
* Source/WebCore/platform/graphics/FloatPointGraph.h: Added.
* Source/WebCore/platform/graphics/PathUtilities.cpp:
* Source/WebCore/platform/graphics/PathUtilities.h:
* Source/WebCore/rendering/OutlinePainter.cpp:
* Source/WebCore/rendering/OutlinePainter.h:

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

Reviewed by Alan Baradlay.

Extracts the transform related functions from `RenderStyle` into
a new class, `Style::TransformResolver`.

`Style::TransformResolver` has static functions that directly
parallel the functions from RenderStyle (except they take the
style as a parameter), but can also be instantiated with a
style and TransformationMatrix reference, and then used to
apply multiple operations, simplifying some callers.

* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/animation/KeyframeEffect.cpp:
* Source/WebCore/platform/animation/AcceleratedEffectValues.cpp:
* Source/WebCore/rendering/MotionPath.cpp:
* Source/WebCore/rendering/MotionPath.h:
* Source/WebCore/rendering/RenderBox.cpp:
* Source/WebCore/rendering/RenderBox.h:
* Source/WebCore/rendering/RenderBoxModelObject.cpp:
* Source/WebCore/rendering/RenderBoxModelObject.h:
* Source/WebCore/rendering/RenderLayer.cpp:
* Source/WebCore/rendering/RenderLayer.h:
* Source/WebCore/rendering/RenderLayerBacking.cpp:
* Source/WebCore/rendering/RenderLayerModelObject.cpp:
* Source/WebCore/rendering/RenderLayerModelObject.h:
* Source/WebCore/rendering/style/RenderStyle+GettersInlines.h:
* Source/WebCore/rendering/style/RenderStyle+SettersInlines.h:
* Source/WebCore/rendering/style/RenderStyle.cpp:
* Source/WebCore/rendering/style/RenderStyle.h:
* Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp:
* Source/WebCore/rendering/svg/RenderSVGForeignObject.h:
* Source/WebCore/rendering/svg/RenderSVGHiddenContainer.h:
* Source/WebCore/rendering/svg/RenderSVGImage.cpp:
* Source/WebCore/rendering/svg/RenderSVGImage.h:
* Source/WebCore/rendering/svg/RenderSVGModelObject.cpp:
* Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp:
* Source/WebCore/rendering/svg/RenderSVGResourceClipper.h:
* Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp:
* Source/WebCore/rendering/svg/RenderSVGResourceMarker.h:
* Source/WebCore/rendering/svg/RenderSVGShape.cpp:
* Source/WebCore/rendering/svg/RenderSVGShape.h:
* Source/WebCore/rendering/svg/RenderSVGText.cpp:
* Source/WebCore/rendering/svg/RenderSVGText.h:
* Source/WebCore/rendering/svg/RenderSVGTextPath.cpp:
* Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp:
* Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h:
* Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp:
* Source/WebCore/rendering/svg/RenderSVGViewportContainer.h:
* Source/WebCore/style/StyleExtractorCustom.h:
* Source/WebCore/style/StyleTransformResolver.cpp: Added.
* Source/WebCore/style/StyleTransformResolver.h: Added.
* Source/WebCore/style/computed/StyleComputedStyle.cpp:
* Source/WebCore/style/computed/StyleComputedStyle.h:
* Source/WebCore/style/values/motion/StyleOffsetPath.h:
* Source/WebCore/svg/SVGGraphicsElement.cpp:

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

Unreviewed gardening.

* LayoutTests/TestExpectations:
* LayoutTests/platform/glib/TestExpectations:
* LayoutTests/platform/gtk/TestExpectations:
* LayoutTests/platform/ios/TestExpectations:
* LayoutTests/platform/wpe-legacy-api/TestExpectations:
* LayoutTests/platform/wpe/TestExpectations:

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

Reviewed by Yusuke Suzuki.

This patch fixes `%TypedArray%.prototype.includes`
by adding range check to ensure the `index` is less than the array length,
aligning the behavior with ECMA-262[1].

[1]: https://tc39.es/ecma262/#sec-%typedarray%.prototype.includes

* JSTests/stress/typedarray-resize-includes.js:
(throw.new.Error):
* JSTests/test262/expectations.yaml:
* Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h:
(JSC::genericTypedArrayViewProtoFuncIncludes):

Canonical link: https://commits.webkit.org/304940@main
https://bugs.webkit.org/show_bug.cgi?id=304105
rdar://problem/166704079

Reviewed by Said Abou-Hallawa.

As defined in the Compositing and Blending spec [1], the 'lighter'
operator is specified.

This PR, as discussed in [2], exposes the 'lighter' value to IDL.

[1] https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_plus
[2] w3c/svgwg#424

* LayoutTests/imported/w3c/web-platform-tests/svg/types/scripted/SVGAnimatedEnumeration-SVGFECompositeElement-expected.txt:

* LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGFECompositeElement-expected.txt: Removed.
* LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGFECompositeElement.html: Removed.

Removed this test because it is duplicated in WPT.

* Source/WebCore/svg/SVGFECompositeElement.h:
(WebCore::SVGIDLEnumLimits<CompositeOperationType>::highestExposedEnumValue): Deleted.
* Source/WebCore/svg/SVGFECompositeElement.idl:
* Source/WebCore/svg/properties/SVGDecoratedEnumeration.h:
* Source/WebCore/svg/properties/SVGPropertyTraits.h:
(WebCore::SVGIDLEnumLimits::highestExposedEnumValue): Deleted.

Canonical link: https://commits.webkit.org/304941@main
…FontDescriptionCocoa.cpp

https://bugs.webkit.org/show_bug.cgi?id=304699
rdar://167189789

Reviewed by Vitor Roriz.

Add Logging.h header

* Source/WebCore/platform/graphics/cocoa/FontDescriptionCocoa.cpp:

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

Unreviewed gardening.

* LayoutTests/platform/glib/TestExpectations:
* LayoutTests/platform/gtk/TestExpectations:
* LayoutTests/platform/wpe/TestExpectations:

Canonical link: https://commits.webkit.org/304944@main
…onflation in SVG resources

https://bugs.webkit.org/show_bug.cgi?id=278551
rdar://problem/134573463

Reviewed by Simon Fraser.

SVG mask and gradient incorrectly used repaintRectInLocalCoordinates(Accurate)
when they needed a geometric bounding box. This conflates two distinct
concepts: repaint rects (for damage/invalidation, can be approximate)
and bounding boxes (for geometric calculations, must be accurate).

This change introduces decoratedBoundingBox, which returns the
bounding box including fill, stroke, and markers. It is intended
for use with masks, gradients, and clippers, separate from repaint semantics.

This PR only adds the decoratedBoundingBox infrastructure and updates
call-sites for semantic correctness without altering rendering behavior.
It still forwards to repaintRectInLocalCoordinates(Accurate), so
rendering remains unchanged.

A follow-up PR will remove the dependency on repaintRectInLocalCoordinates(Accurate)
and compute decorated bounds directly.

* Source/WebCore/rendering/RenderObject.cpp:
(WebCore::RenderObject::decoratedBoundingBox const):
* Source/WebCore/rendering/RenderObject.h:
* Source/WebCore/rendering/svg/RenderSVGContainer.h:
* Source/WebCore/rendering/svg/RenderSVGForeignObject.h:
* Source/WebCore/rendering/svg/RenderSVGImage.h:
* Source/WebCore/rendering/svg/RenderSVGInline.cpp:
(WebCore::RenderSVGInline::decoratedBoundingBox const):
* Source/WebCore/rendering/svg/RenderSVGInline.h:
* Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp:
(WebCore::RenderSVGResourceMasker::applyMask):
* Source/WebCore/rendering/svg/RenderSVGRoot.h:
* Source/WebCore/rendering/svg/RenderSVGShape.h:
* Source/WebCore/rendering/svg/RenderSVGText.cpp:
(WebCore::RenderSVGText::decoratedBoundingBox const):
* Source/WebCore/rendering/svg/RenderSVGText.h:
* Source/WebCore/rendering/svg/SVGBoundingBoxComputation.h:
(WebCore::SVGBoundingBoxComputation::computeDecoratedBoundingBox):
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGContainer.cpp:
(WebCore::LegacyRenderSVGContainer::decoratedBoundingBox const):
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGContainer.h:
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGForeignObject.h:
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGImage.h:
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGResourceGradient.cpp:
(WebCore::calculateGradientGeometry):
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGResourceMasker.cpp:
(WebCore::LegacyRenderSVGResourceMasker::applyResource):
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGRoot.cpp:
(WebCore::LegacyRenderSVGRoot::decoratedBoundingBox const):
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGRoot.h:
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGShape.cpp:
(WebCore::LegacyRenderSVGShape::decoratedBoundingBox const):
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGShape.h:

Canonical link: https://commits.webkit.org/304945@main
…ebCore::GStreamerVideoFrameConverter, WTF::DefaultWeakPtrImpl, WTF::RawPtrTraits<WTF::DefaultWeakPtrImpl> >::get() const

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

Reviewed by Philippe Normand.

* Source/WebCore/platform/graphics/gstreamer/GStreamerVideoFrameConverter.h:

Canonical link: https://commits.webkit.org/304946@main
https://bugs.webkit.org/show_bug.cgi?id=302099
<rdar://problem/164650313>

Reviewed by Antti Koivisto.

Outside list markers should not contribute to the min/max width (they are not even supposed to be here in IFC.)

Test: fast/lists/list-marker-outside-inside-flex-item.html

* LayoutTests/fast/lists/list-marker-outside-inside-flex-item-expected.html: Added.
* LayoutTests/fast/lists/list-marker-outside-inside-flex-item.html: Added.
* Source/WebCore/layout/formattingContexts/inline/IntrinsicWidthHandler.cpp:
(WebCore::Layout::IntrinsicWidthHandler::computedIntrinsicWidthForConstraint):

Canonical link: https://commits.webkit.org/304947@main
…undary

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

Reviewed by Antti Koivisto.

The term "IsBetween" is somewhat misleading, as it suggests an (unshaped) run occurring between two shaped runs.

* Source/WebCore/layout/formattingContexts/inline/InlineLine.h:
(WebCore::Layout::Line::Run::isInsideShapingBoundary const):
(WebCore::Layout::Line::Run::isBetweenShapingBoundaries const): Deleted.
* Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp:
(WebCore::Layout::LineBuilder::commitCandidateContent):
* Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayBox.h:
(WebCore::InlineDisplay::Box::Text::isInsideShapingBoundary const):
(WebCore::InlineDisplay::Box::Text::isBetweenShapingBoundaries const): Deleted.
* Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayContentBuilder.cpp:
(WebCore::Layout::InlineDisplayContentBuilder::appendTextDisplayBox):
* Source/WebCore/rendering/TextBoxPainter.cpp:
(WebCore::TextBoxPainter::isInsideShapedContent const):

Canonical link: https://commits.webkit.org/304948@main
…an inline box

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

Reviewed by Antti Koivisto.

A single block inside inline (<span><div></div></span>) generates 3 "lines" and getClientRects is supposed to return all of them.
However due to ignoring 0px width (non-leading) inline boxes in collectInlineBoxRects, we only return 2 (the first, leading (0px tall)
line and the one generated by the block).
Having all lines included makes block-in-inline-client-rects-001.html fail but we already render such content incorrectly on trunk.

<div>
  <span style="outline: 1px solid green">
    <div style="width: 500px"></div>
  </span>
</div>

There should _not_ be a green line here.

* LayoutTests/TestExpectations:
* LayoutTests/fast/block/inside-inlines/getClientRects-on-inline-box-missing-entry-expected.txt: Added.
* LayoutTests/fast/block/inside-inlines/getClientRects-on-inline-box-missing-entry.html: Added.
* LayoutTests/fast/inline/blocks-in-inline-client-rects-expected.txt: Removed.  : this is a copy of block-in-inline-client-rects-001.html
* LayoutTests/fast/inline/blocks-in-inline-client-rects.html: Removed.
* Source/WebCore/layout/integration/inline/LayoutIntegrationLineLayout.cpp:
(WebCore::LayoutIntegration::LineLayout::collectInlineBoxRects const):

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

Reviewed by Darin Adler.

Replaces hand written logical property getters and setters
on RenderStyle with generated equivalents.

Currently, only properties that are part of a "logical property
group" of type 'axis' or 'side' get generated logical functions.
There are currently no 'corner' logical property getters or
setters on RenderStyle, so this is not a change.

For named "logical property group" of type "axis", like 'size',
which contains the 'width' and height' properties, we generate:

    inline const Style::PreferredSize& logicalWidth(WritingMode) const;
    inline const Style::PreferredSize& logicalHeight(WritingMode) const;
    inline const Style::PreferredSize& logicalWidth() const;
    inline const Style::PreferredSize& logicalHeight() const;
    inline void setLogicalWidth(Style::PreferredSize&&);
    inline void setLogicalHeight(Style::PreferredSize&&);

For named "logical property group" of type "side", like 'padding',
which contains the 'padding-left', 'padding-right', etc. properties,
we generate:

    inline const Style::PaddingEdge& paddingStart(WritingMode) const;
    inline const Style::PaddingEdge& paddingEnd(WritingMode) const;
    inline const Style::PaddingEdge& paddingBefore(WritingMode) const;
    inline const Style::PaddingEdge& paddingAfter(WritingMode) const;
    inline const Style::PaddingEdge& paddingLogicalLeft(WritingMode) const;
    inline const Style::PaddingEdge& paddingLogicalRight(WritingMode) const;
    inline const Style::PaddingEdge& paddingStart() const;
    inline const Style::PaddingEdge& paddingEnd() const;
    inline const Style::PaddingEdge& paddingBefore() const;
    inline const Style::PaddingEdge& paddingAfter() const;
    inline const Style::PaddingEdge& paddingLogicalLeft() const;
    inline const Style::PaddingEdge& paddingLogicalRight() const;
    inline void setPaddingStart(Style::PaddingEdge&&);
    inline void setPaddingEnd(Style::PaddingEdge&&);
    inline void setPaddingBefore(Style::PaddingEdge&&);
    inline void setPaddingAfter(Style::PaddingEdge&&);
    inline void setPaddingLogicalLeft(Style::PaddingEdge&&);
    inline void setPaddingLogicalRight(Style::PaddingEdge&&);

A few small renames were necessary to achieve a consistent naming convention:

- containIntrinsicLogicalWidth/containIntrinsicLogicalHeight were renamed to
logicalContainIntrinsicWidth/logicalContainIntrinsicHeight.

- borderAfterWidth/borderBeforeWidth/borderStartWidth/borderEndWidth were
renamed to borderWidthAfter/borderWidthBefore/borderWidthStart/borderWidthEnd.

The logical inset functions logicalLeft/logicalRight/logicalTop/logicalBottom
were left as aliases for now, as I wasn't clear on whether the convention should
of logicalTop/logicalBottom was something to bring forward.

* Source/WebCore/css/scripts/process-css-properties.py:
* Source/WebCore/css/scripts/test/TestCSSProperties.json:
* Source/WebCore/css/scripts/test/TestCSSPropertiesResults/RenderStyleProperties+GettersInlines.h:
* Source/WebCore/css/scripts/test/TestCSSPropertiesResults/RenderStyleProperties+SettersInlines.h:
* Source/WebCore/css/scripts/test/TestCSSPropertiesResults/RenderStyleProperties.h:
* Source/WebCore/css/scripts/test/TestCSSPropertiesResults/StyleChangedAnimatablePropertiesGenerated.cpp:
* Source/WebCore/css/scripts/test/TestCSSPropertiesResults/StyleComputedStyleProperties+GettersInlines.h:
* Source/WebCore/css/scripts/test/TestCSSPropertiesResults/StyleComputedStyleProperties+InitialInlines.h:
* Source/WebCore/css/scripts/test/TestCSSPropertiesResults/StyleComputedStyleProperties+SettersInlines.h:
* Source/WebCore/css/scripts/test/TestCSSPropertiesResults/StyleComputedStyleProperties.h:
* Source/WebCore/dom/Document.cpp:
* Source/WebCore/rendering/RenderBoxModelObjectInlines.h:
* Source/WebCore/rendering/cocoa/RenderThemeCocoa.mm:
* Source/WebCore/rendering/style/RenderStyle+GettersInlines.h:
* Source/WebCore/rendering/style/RenderStyle+SettersInlines.h:
* Source/WebCore/rendering/style/RenderStyle.cpp:
* Source/WebCore/rendering/style/RenderStyle.h:
* Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:

Canonical link: https://commits.webkit.org/304950@main
@coderabbitai
Copy link

coderabbitai bot commented Jan 4, 2026

Walkthrough

This PR introduces extensive test coverage for Array.from operations, String prototype methods, and RegExp symbol.replace behavior, while refactoring core async generator and promise handling infrastructure. Changes span test additions across microbenchmarks and stress tests, layout test updates, and significant JavaScript and C++ runtime modifications for promise resolution and async function optimization.

Changes

Cohort / File(s) Summary
Array.from microbenchmarks
JSTests/microbenchmarks/array-from-cloned-arguments.js, JSTests/microbenchmarks/array-from-set-double-small.js, JSTests/microbenchmarks/array-from-set-double-large.js, JSTests/microbenchmarks/array-from-set-int-small.js, JSTests/microbenchmarks/array-from-set-int-large.js, JSTests/microbenchmarks/array-from-set-object-small.js, JSTests/microbenchmarks/array-from-set-object-large.js
Add microbenchmarks for Array.from with cloned arguments and Set conversion with various value types (doubles, integers, objects) and set sizes (small/large).
String padStart/padEnd microbenchmarks
JSTests/microbenchmarks/string-prototype-padStart-single-char-resolved.js, JSTests/microbenchmarks/string-prototype-padStart-multiple-chars-resolved.js, JSTests/microbenchmarks/string-prototype-padEnd-single-char-resolved.js, JSTests/microbenchmarks/string-prototype-padEnd-multiple-chars-resolved.js
Add microbenchmarks exercising String.prototype.padStart and padEnd with single and multi-character fill strings over 1M iterations.
Promise microbenchmarks
JSTests/microbenchmarks/internal-promise-internal-all.js
Add microbenchmark for internal Promise.all over 10K iterations with pre-resolved promises.
Array.from stress tests
JSTests/stress/array-from-cloned-arguments.js, JSTests/stress/array-from-set.js
Add comprehensive stress tests validating Array.from(arguments) and Array.from(Set) with extensive type coverage, edge cases, and large-set handling.
Async function stress tests
JSTests/stress/async-function-without-await.js, JSTests/stress/async-stack-trace-basic.js, JSTests/stress/async-stack-trace-nested.js, JSTests/stress/async-stack-trace-nested-deep.js
Add stress tests for async function behavior without await and async stack trace validation across nested calls.
RegExp Symbol.replace stress tests
JSTests/stress/regexp-prototype-symbol-replace-basic.js, JSTests/stress/regexp-prototype-symbol-replace-capture-groups.js, JSTests/stress/regexp-prototype-symbol-replace-edge-cases.js, JSTests/stress/regexp-prototype-symbol-replace-functional.js, JSTests/stress/regexp-prototype-symbol-replace-named-groups.js, JSTests/stress/regexp-prototype-symbol-replace-slow-path.js, JSTests/stress/regexp-prototype-symbol-replace-unicode.js
Add comprehensive stress tests for RegExp.prototype[Symbol.replace] covering basic/global replacements, capture groups, backreferences, functional replacements, named groups, Unicode handling, and slow-path behaviors.
String method stress tests
JSTests/stress/string-pad-start-end.js, JSTests/stress/string-repeat-complex.js
Add stress tests for String.prototype padStart/padEnd with Unicode variants and String.prototype repeat with edge cases and coercions.
TypedArray includes stress test
JSTests/stress/typedarray-resize-includes.js, JSTests/stress/unused-catch-binding.js
Add stress test for includes with buffer resizing during index coercion and comprehensive catch binding behavior validation.
Internal Promise module test
JSTests/modules/object-prototype-then-should-not-be-called-through-internal-promise.js, JSTests/modules/object-prototype-then-should-not-be-called-through-internal-promise/test.js
Add module test verifying Object.prototype.then is not invoked during internal Promise resolution.
Test262 expectations
JSTests/test262/expectations.yaml
Remove two TypedArray includes test expectations relating to buffer shrinking.
Layout test expectations
LayoutTests/TestExpectations, LayoutTests/fast/*/expected.txt, LayoutTests/platform/*/expected.txt
Update rendering expectations across platforms (glib, gtk, ios, mac, wpe, win) for inline widths and layout dimensions; add/remove CSS and layout test entries.
WebVTT and Web Platform Tests
LayoutTests/imported/w3c/web-platform-tests/webvtt/rendering/cues-with-video/*.html, LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-trigger/*.html, LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/*
Add WebVTT processing tests, web-animations trigger/animation-types tests, and update expected outputs; rename AnimationTrigger to TimelineTrigger.
Text extraction tests
LayoutTests/fast/text-extraction/, LayoutTests/http/tests/text-extraction/
Add new HTML test files and expected outputs for text extraction with URL shortening and subframe handling.
3D point-mapping test removals
LayoutTests/transforms/3d/point-mapping/3d-point-mapping-*.html, LayoutTests/platform/*/transforms/3d/point-mapping/3d-point-mapping-*-expected.txt
Remove 3D point-mapping test files and corresponding expected outputs across multiple platforms.
Emoji deletion test removals
LayoutTests/platform/*/editing/deleting/delete-emoji-*-expected.txt, LayoutTests/platform/win/editing/caret/emoji-expected.txt
Remove emoji deletion expected-output test fixtures across multiple platforms.
Async generator builtins
Source/JavaScriptCore/builtins/AsyncGeneratorPrototype.js, Source/JavaScriptCore/builtins/AsyncFromSyncIteratorPrototype.js, Source/JavaScriptCore/builtins/AsyncIteratorPrototype.js
Refactor async generator queue handling from separate queue management functions to loop-based state machine using internal microtask system; replace promise callbacks with microtask continuations.
String prototype builtins removal
Source/JavaScriptCore/builtins/StringPrototype.js
Remove string method implementations (repeat, padStart, padEnd, replace, replaceAll, createHTML, anchor, big, blink, bold, fixed, fontcolor, fontsize, italics, link, small, strike, sub, sup) relocating to C++.
RegExp prototype builtins removal
Source/JavaScriptCore/builtins/RegExpPrototype.js
Remove getSubstitution helper and Symbol.replace implementation.
Module loader builtins
Source/JavaScriptCore/builtins/ModuleLoader.js
Add new private recursive functions for async module evaluation, loading, and evaluation with await support.
Builtin names
Source/JavaScriptCore/builtins/BuiltinNames.h
Replace promise-related without-promise macros with async/microtask-related entries (resolveWithInternalMicrotaskForAsyncAwait, asyncGeneratorQueueEnqueue/Dequeue variants).
Link-time constants
Source/JavaScriptCore/bytecode/LinkTimeConstant.h, Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h, Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp
Update AsyncGenerator field mappings from suspend-reason/queue-first/queue-last to queue/resume-value/resume-mode/resume-promise; introduce InternalMicrotask constants.
Build configuration
Source/JavaScriptCore/CMakeLists.txt, Source/JavaScriptCore/DerivedSources.make, Source/JavaScriptCore/DerivedSources-input.xcfilelist, Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Remove InternalPromiseConstructor.js from build sources.
Xcode configuration
Source/JavaScriptCore/Configurations/JavaScriptCore.xcconfig
Update module verifier flags and per-SDK private module declarations.
DFG changes
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp, Source/JavaScriptCore/dfg/DFGFixupPhase.cpp, Source/JavaScriptCore/dfg/DFGGraph.cpp, Source/JavaScriptCore/dfg/DFGNode.h, Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp, Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
Remove StringPrototypeReplace intrinsic inlining cases; update allocator macros and iterator protocol checks.
Bytecode generator
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp, Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h, Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
Add async-function-without-await optimization path with inlining; update async generator field emitters and return node finally-scope handling.
Parser changes
Source/JavaScriptCore/parser/Parser.cpp, Source/JavaScriptCore/parser/Parser.h, Source/JavaScriptCore/parser/ParserModes.h, Source/JavaScriptCore/parser/SourceProviderCacheItem.h
Add await-usage tracking, async-function-without-await feature flag, and body inlining path for async functions; propagate implementation visibility through cache.
Runtime async generator
Source/JavaScriptCore/runtime/JSAsyncGenerator.h, Source/JavaScriptCore/runtime/JSAsyncGenerator.cpp
Introduce queue-based async generator with enqueue/dequeue, resume state management, and new field accessors (queue, resumeValue, resumeMode, resumePromise).
Runtime global object
Source/JavaScriptCore/runtime/JSGlobalObject.cpp, Source/JavaScriptCore/runtime/JSGlobalObject.h, Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h
Replace resolveWithoutPromiseForAsyncAwait with resolveWithInternalMicrotaskForAsyncAwait; add asyncGeneratorQueueEnqueue/Dequeue functions; update queueMicrotask signature.
Runtime array construction
Source/JavaScriptCore/runtime/ArrayConstructor.cpp
Add fast paths for Array.from(ClonedArguments) and Array.from(Set) with optimized butterfly allocation.
Runtime JSArray
Source/JavaScriptCore/runtime/JSArray.cpp, Source/JavaScriptCore/runtime/JSArrayBufferView.cpp
Simplify isIteratorProtocolFastAndNonObservable to use hasSpecialProperties() check.
Runtime support classes
Source/JavaScriptCore/runtime/CommonIdentifiers.h, Source/JavaScriptCore/runtime/ClassInfo.h, Source/JavaScriptCore/runtime/JSFunctionWithFields.h, Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h, Source/JavaScriptCore/runtime/JSCast.h, Source/JavaScriptCore/runtime/Intrinsic.h, Source/JavaScriptCore/runtime/ExecutionCounter.h
Add resumeMode identifier; update allocator macros; rename FunctionWithFields async field constants; remove string replace intrinsics.
Inspector scripts
Source/JavaScriptCore/inspector/InjectedScriptManager.h, Source/JavaScriptCore/inspector/augmentable/AlternateDispatchableAgent.h, Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_protocol_type_conversions_header.py, Source/JavaScriptCore/inspector/scripts/tests/expected/*
Add isWebInjectedScriptManager virtual method; update allocator macros; refactor enum-string mapping to SortedArrayMap; add JSExportMacros and Platform includes to generated headers.
Builtin test expectations
Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-*-result, Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-*-result, Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-*-result, Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCoreJSBuiltins.h-result
Add forward declarations and #include to generated builtin headers.
JIT validation
Source/JavaScriptCore/assembler/JITOperationValidation.h
Wrap WebKitAdditions include with diagnostic pragmas for module compilation.

Possibly related PRs

  • Related to async generator refactoring: PRs modifying JSAsyncGenerator behavior, promise resolution patterns, and internal microtask infrastructure would align with the comprehensive async generator queue redesign.
  • Related to Array.from optimizations: PRs implementing Set support or ClonedArguments fast-paths in ArrayConstructor directly complement the new fast-path handling.
  • Related to builtin relocations: PRs moving string/regexp methods from JavaScript builtins to C++ implementations would correspond to the removal of StringPrototype and RegExpPrototype method implementations.

Pre-merge checks

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Upgrade WebKit Jan 4, 2026' is generic and does not clearly convey the main changes or objectives of this large multi-component pull request. Consider a more specific title that highlights major changes such as 'JSC performance optimizations: Array.from fast paths, async inlining, string methods to C++' or similar to better reflect the primary objectives.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description is comprehensive and well-organized, covering JavaScriptCore optimizations, WTF improvements, memory safety work, SVG fixes, CSS/style changes, and platform updates with clear section headings and bullet points.

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

Copy link

@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: 14

Caution

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

⚠️ Outside diff range comments (1)
Source/JavaScriptCore/inspector/scripts/tests/expected/type-declaration-object-type.json-result (1)

1764-1773: LGTM: Refactor to SortedArrayMap for efficient enum parsing.

The switch to SortedArrayMap with ComparableASCIILiteral keys provides O(log n) lookup via binary search, which is an improvement over linear iteration. The keys are correctly sorted alphabetically ("Left", "Middle", "None", "Right").

Note: The indentation on line 1769 ( }) }; with 3 spaces) appears inconsistent with the rest of the block. Since this is auto-generated code, the fix should be applied to the generate-inspector-protocol-bindings.py script if this formatting is unintentional.

♻️ Duplicate comments (33)
LayoutTests/platform/win/fast/forms/input-number-click-expected.txt (1)

2-2: This typographical error was already flagged in a previous review.

The word "numnber" on line 2 should be corrected to "number" to match the test intent. This issue was previously flagged but remains unfixed in the current commit.

🔎 Proposed fix
-Test for the spin control behavior in a type=numnber input.
+Test for the spin control behavior in a type=number input.
Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_protocol_type_conversions_header.py (1)

169-172: Fix indentation to align with the opening statement.

The closing }) }; on line 172 uses 3 spaces, but should use 4 spaces to align with the opening static constexpr SortedArrayMap statement on line 169.

🔎 Proposed fix
-        lines.append('   }) };')
+        lines.append('    }) };')
LayoutTests/platform/wpe-legacy-api/TestExpectations (1)

87-87: Missing required bug reference for Failure expectation.

Line 87 marks the test as [ Failure ] without a bug reference, violating the policy stated at line 29: "ALWAYS WITH BUG ENTRIES for things like Timeout, Failure and Crash." This issue was already flagged in a previous review.

LayoutTests/platform/wpe/TestExpectations (3)

529-538: Add bug entries for crash expectations and fix comment grammar.

These Skip entries for datalist crashes still lack the required bug references. According to the file guidelines (line 115), crash expectations must have associated bug entries. Additionally, the comment on line 529 contains a grammatical error.


544-547: Add bug entries for failure expectations.

These datalist test failures still lack the required bug references per the file guidelines (line 115).


1011-1011: Add bug entry for the new failure expectation.

This new canvas toDataURL test failure still lacks the required bug reference per the file guidelines (line 115).

LayoutTests/platform/mac-wk2/TestExpectations (1)

2453-2455: Truncated assertion path in comment (previously flagged).

The comment on line 2453 has a truncated path ending with bindings/js/ without specifying the complete source file. This was previously noted in past reviews. Consider updating the comment to include the full file path when available to aid future debugging.

The Skip directives on lines 2454-2455 are properly formatted with the Debug configuration qualifier and appropriate bug reference.

LayoutTests/fast/lists/list-marker-outside-inside-flex-item.html (1)

1-24: Test is functionally correct.

The test structure and CSS properties are appropriate for validating list marker behavior with flex item children. The two test cases effectively cover baseline positioning and margin-left variants.

Note: Previous review comments identified minor style preferences (blank line at Line 5, expanding the test comment), but these don't affect the test's functionality.

LayoutTests/imported/w3c/web-platform-tests/web-animations/crashtests/set-timeline-undefined-progress.html (1)

17-18: Remove the empty script tag.

The empty <script> tag serves no purpose and should be removed.

LayoutTests/svg/as-image/svg-image-aspect-ration-par-none.html (1)

1-1: Fix typo in filename.

This issue was already identified in a previous review. The filename contains "aspect-ration-par-none" but should be "aspect-ratio-par-none".

JSTests/stress/async-stack-trace-nested.js (1)

175-178: Test expectations correctly updated for line number shift.

The test expectation updates accurately reflect the one-line shift caused by the insertion at line 155. However, if the unreachable code on line 155 is removed as suggested, these changes should also be reverted.

LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-trigger/event-trigger-alternate.tentative.html (1)

42-45: Incorrect currentTime calculation.

The calculation on line 44 is incorrect. animation.currentTime is relative to the animation's own timeline (starting from 0), not the document timeline. Adding animation.startTime (which is the document timeline time when the animation started) produces an incorrect value.

🔎 Proposed fix
         // Advance to middle of duration so that animation doesn't finish too
         // quickly after reversing.
-        animation.currentTime = animation.startTime + (ANIMATION_DURATION_MS/2);
+        animation.currentTime = ANIMATION_DURATION_MS / 2;
         await waitForAnimationFrames(1);
LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-trigger/event-trigger-repeat.tentative.html (1)

36-44: Previous timing concern already documented.

The potential race condition in the progress comparison at lines 40-44 has been identified in the past review. The rest of the test logic appears sound.

LayoutTests/http/tests/text-extraction/resources/subframe2.html (1)

17-21: The postMessage wildcard usage has already been flagged.

A previous review already identified that the "*" targetOrigin in the postMessage call should be replaced with a specific origin for better security practices in test code.

LayoutTests/fast/text-extraction/debug-text-extraction-shorten-urls.html (1)

34-34: Correct misleading link text.

The link text says "Email with params" but the mailto: URL contains no parameters (like ?subject= or &body=). Either add parameters to match the description or update the link text.

🔎 Proposed fix

Option 1 - Add parameters to match the description:

-        <a href="mailto:[email protected]">Email with params</a>
+        <a href="mailto:[email protected]?subject=Test&body=Hello">Email with params</a>

Option 2 - Update the link text to match the URL:

-        <a href="mailto:[email protected]">Email with params</a>
+        <a href="mailto:[email protected]">Email link</a>
LayoutTests/http/tests/text-extraction/resources/subframe1.html (2)

24-24: Fix invalid JavaScript URL.

The javascript:void link is missing parentheses and should be javascript:void(0) to be valid JavaScript. While this is a test fixture, using correct syntax ensures the test accurately reflects real-world scenarios.

🔎 Proposed fix
-            <a href="javascript:void">Forgot your email?</a>
+            <a href="javascript:void(0)">Forgot your email?</a>

36-45: Avoid wildcard origin in postMessage and validate message origin.

The script uses postMessage("loaded", "*") which broadcasts the message to any origin, and the message listener doesn't validate event.origin. While this is a test fixture, it demonstrates insecure messaging patterns that could be copied into production code.

🔎 Proposed fix
     addEventListener("load", () => {
         let subframe = document.querySelector("iframe");
         addEventListener("message", event => {
+            // Validate message origin if needed, or at minimum check source
+            if (event.source !== subframe.contentWindow)
+                return;
             if (event.data === "loaded")
-                window.parent.postMessage("loaded", "*");
+                window.parent.postMessage("loaded", window.location.origin);
         }, { once: true });
         subframe.src = "subframe2.html";
     });

Note: For same-origin frames, you can use window.location.origin. For cross-origin scenarios in tests, consider using a specific expected origin rather than "*".

LayoutTests/http/tests/text-extraction/debug-text-extraction-subframes.html (1)

36-44: Fix race condition and add origin validation in loadFrame.

The loadFrame function has two issues:

  1. Race condition: When loading multiple frames sequentially, a "loaded" message from frame 2 could incorrectly resolve frame 1's promise, since the listener doesn't verify which frame sent the message.

  2. Missing origin validation: The message listener doesn't validate event.source or event.origin, accepting "loaded" messages from any window or frame.

🔎 Proposed fix
 async function loadFrame(iframe, src) {
     await new Promise(resolve => {
-        addEventListener("message", event => {
+        const handler = (event) => {
+            // Verify the message came from the expected iframe
+            if (event.source !== iframe.contentWindow)
+                return;
             if (event.data === "loaded") {
+                removeEventListener("message", handler);
                 resolve();
+            }
-        }, { once: true });
+        };
+        addEventListener("message", handler);
         iframe.src = src;
     });
 }

Note: The fix removes { once: true } and manually calls removeEventListener only when the correct source is confirmed, preventing the listener from being removed by messages from unrelated frames.

LayoutTests/platform/ios/TestExpectations (1)

8185-8187: Add a tracking bug tag for the new WebVTT ImageOnlyFailure

The new expectation for line_1_wrapped_cue_grow_downwards.html mirrors the adjacent media_height_19.html test but lacks a webkit.org/b/... bug tag. For future triage, consider either:

  • Prepending the same bug id as media_height_19.html if they share a root cause, e.g.:
Example adjustment
-imported/w3c/web-platform-tests/webvtt/rendering/cues-with-video/processing-model/line_1_wrapped_cue_grow_downwards.html [ ImageOnlyFailure ]
+webkit.org/b/296709 imported/w3c/web-platform-tests/webvtt/rendering/cues-with-video/processing-model/line_1_wrapped_cue_grow_downwards.html [ ImageOnlyFailure ]
  • Or adding a new bug id specific to this test.
JSTests/stress/regexp-prototype-symbol-replace-named-groups.js (1)

52-54: Undefined variable testLoopCount will cause ReferenceError.

This issue was flagged in a previous review. The variable testLoopCount is referenced but never defined.

JSTests/stress/regexp-prototype-symbol-replace-capture-groups.js (1)

62-64: Undefined variable testLoopCount will cause ReferenceError.

This issue was flagged in a previous review. The variable testLoopCount is referenced but never defined.

JSTests/stress/regexp-prototype-symbol-replace-basic.js (1)

56-58: Undefined variable testLoopCount will cause ReferenceError.

This issue was flagged in a previous review. The variable testLoopCount is referenced but never defined.

JSTests/stress/regexp-prototype-symbol-replace-functional.js (1)

95-97: Undefined variable testLoopCount will cause ReferenceError.

This issue was flagged in a previous review. The variable testLoopCount is referenced but never defined.

LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/TimelineTrigger/constructor.html (1)

3-5: Update the help link to reference TimelineTrigger.

The title has been correctly updated to "TimelineTrigger constructor", but the help link on line 5 still references the old "animationtrigger-interface" fragment. This inconsistency should be resolved.

🔎 Proposed fix
 <title>TimelineTrigger constructor</title>
 <link rel="help"
-      href="https://drafts.csswg.org/web-animations-2/#the-animationtrigger-interface">
+      href="https://drafts.csswg.org/web-animations-2/#the-timelinetrigger-interface">
 <script src="/https/github.com/resources/testharness.js"></script>
LayoutTests/platform/mac-sonoma-wk1/transforms/3d/general/perspective-non-layer-expected.txt (1)

6-6: Platform-specific width variation requires verification.

Similar to the mac-wk2 file, the RenderInline {SPAN} width has been reduced to 148. The layer repositioning at line 11 (from 15,12 in mac-wk2 to 11,11 here) is an expected downstream effect of the width change.

This represents a different width than mac-wk2 (148 vs 156), which is typical for platform-specific rendering. However, the root cause verification requested in the previous comment applies here as well—ensure this change is intentional and caused by the intended code modifications in the PR.

Also applies to: 8-8, 11-11

LayoutTests/platform/mac-sequoia-wk2/transforms/3d/general/perspective-non-layer-expected.txt (1)

6-6: Consistent pattern across platforms confirms intentional change.

The RenderInline {SPAN} width reduction to 148 matches the mac-sonoma-wk1 variant, and the layer repositioning is consistent (line 11: 11,11). This three-way consistency across platform expectations strongly suggests an intentional, coordinated rendering behavior change rather than a test fluke.

However, the root cause verification remains critical—ensure that the underlying code change (from the CSS/layout fixes mentioned in the PR) is correct and that these files were regenerated via the test suite rather than manually edited.

Also applies to: 8-8, 11-11

LayoutTests/platform/win/TestExpectations (2)

4618-4622: Offscreen-canvas remote-read image skip is fine; optional metadata for consistency

Adding http/tests/security/offscreen-canvas-remote-read-remote-image.html [ Skip ] matches other OffscreenCanvas/remote-read skips and the earlier “OffscreenCanvas isn’t supported yet” block. Optionally, for consistency with nearby canvas-remote-read-remote-video-* entries, you could add a short # Failure / # Crash comment and/or reuse their bug reference if it’s the same root cause.


1960-1967: Add rationale/bug reference for new performance resource timing cross-origin media skips

The four performance-resource-timing-*-cross-origin-media*.html tests are now skipped on Win without any accompanying comment or bug link, unlike the adjacent webkit.org/b/226299 entries. Consider adding a brief comment (and bug ID if available) explaining whether these are flaky or blocked by a Win-specific limitation so future gardeners know when and why to revisit them.

JSTests/stress/array-from-cloned-arguments.js (1)

1-11: Strict mode directive is ineffective where it is placed

"use strict"; on Line 6 is after a function declaration, so it does not form a directive prologue and the file (and test) are not in strict mode. If the goal is to cover the strict‑mode Array.from(arguments) / ClonedArguments fast path, move the directive to the top of the file or make it the first statement inside test().

JSTests/stress/unused-catch-binding.js (1)

261-279: Async IIFEs still not awaited; assertion failures may not be surfaced

The async IIFEs for testAsyncUnusedCatch and testAsyncUsedCatch are invoked but their returned promises are ignored. Because shouldBe throws inside an async function, failures will become promise rejections rather than synchronous errors, and may not be seen by the harness.

To make failures reliably visible, either:

  • Add a top‑level async wrapper that awaits these IIFEs, or
  • Convert these tests to synchronous functions (dropping async) if you don’t need true async behavior.
LayoutTests/platform/glib/TestExpectations (1)

1120-1125: Please add bug IDs (or Bug(GLIB)) to new non‑PASS/Skip expectations

Per the file header, only PASSING/UNSUPPORTED entries should omit bug IDs, and an earlier review already flagged these same spots. These new or updated non‑PASS entries still have no bug prefix:

  • Lines 1120–1125: compositing/blend-mode/non-separable-blend-modes.html and the four compositing/repaint/copy-forward-* tests (ImageOnlyFailure / ImageOnlyFailure Pass).
  • Lines 2615–2617: webrtc/peerconnection-new-candidate-page-cache.html, fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html, http/wpt/webrtc/rtcNetworkInterface.html are [ Skip ] under the LibWebRTC block but lack an explicit bug, unlike 2613–2614 which use webkit.org/b/235885.
  • Line 3994 (and ideally the neighbor at 3995 while you are here): imported/blink/fast/backgrounds/root-background-with-page-scaled-out.html [ ImageOnlyFailure Pass ] in NEEDS TRIAGING with no bug.

Please either reuse the appropriate existing bug IDs (e.g. 235885 for the LibWebRTC tests) or file a new bug/Bug(GLIB) and prefix each line explicitly.

Example of how to make these expectations traceable
- compositing/blend-mode/non-separable-blend-modes.html [ ImageOnlyFailure ]
+ Bug(GLIB) compositing/blend-mode/non-separable-blend-modes.html [ ImageOnlyFailure ]

- compositing/repaint/copy-forward-dirty-region-purged-backbuffer.html [ ImageOnlyFailure Pass ]
+ Bug(GLIB) compositing/repaint/copy-forward-dirty-region-purged-backbuffer.html [ ImageOnlyFailure Pass ]

- compositing/repaint/copy-forward-clear-rect.html [ ImageOnlyFailure Pass ]
+ Bug(GLIB) compositing/repaint/copy-forward-clear-rect.html [ ImageOnlyFailure Pass ]

- compositing/repaint/copy-forward-dirty-region-purged.html [ ImageOnlyFailure Pass ]
+ Bug(GLIB) compositing/repaint/copy-forward-dirty-region-purged.html [ ImageOnlyFailure Pass ]

- compositing/repaint/not-self-painting-layer-stops-compositing.html [ ImageOnlyFailure Pass ]
+ Bug(GLIB) compositing/repaint/not-self-painting-layer-stops-compositing.html [ ImageOnlyFailure Pass ]

- webrtc/peerconnection-new-candidate-page-cache.html [ Skip ]
+ webkit.org/b/235885 webrtc/peerconnection-new-candidate-page-cache.html [ Skip ]

- fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html [ Skip ]
+ webkit.org/b/235885 fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html [ Skip ]

- http/wpt/webrtc/rtcNetworkInterface.html [ Skip ]
+ webkit.org/b/235885 http/wpt/webrtc/rtcNetworkInterface.html [ Skip ]

- imported/blink/fast/backgrounds/root-background-with-page-scaled-out.html [ ImageOnlyFailure Pass ]
+ Bug(GLIB) imported/blink/fast/backgrounds/root-background-with-page-scaled-out.html [ ImageOnlyFailure Pass ]

Adjust the specific bug IDs if these map to different issues than suggested above.

Also applies to: 2613-2617, 3994-3995

LayoutTests/TestExpectations (1)

609-609: Formatting inconsistency persists.

Line 609 still has a double space before [ Pass ], which is inconsistent with the other entries (lines 605-608, 610-613). This was previously flagged but remains unfixed.

🔎 Proposed fix
-imported/w3c/web-platform-tests/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_line.html  [ Pass ]
+imported/w3c/web-platform-tests/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_line.html [ Pass ]
Source/JavaScriptCore/parser/Parser.cpp (1)

2281-2286: ImplementationVisibility propagation and caching: semantics improved; avoid enum-order-dependent std::max (same concern as prior review)

The new visibility wiring does the right high-level things:

  • In parseFunctionBody, async wrappers that actually use await now promote the implementation visibility and write it back to the current scope before building metadata (Lines 2281-2285), so the body scope’s view of visibility is authoritative.
  • In parseFunctionInfo, for generator/async-wrapper modes you now:
    • Parse the body in a dedicated generatorBodyScope with an inner body parse mode (Lines 2713-2726),
    • Read generatorBodyScope->implementationVisibility() back into a local implementationVisibility (Line 2733),
    • Use that value for createFunctionMetadata(...) (through performParsingFunctionBody()), and
    • Store the same implementationVisibility into the cache parameters (Line 2777).
  • On the cached path, you correctly reconstruct metadata using static_cast<ImplementationVisibility>(cachedInfo->implementationVisibility) (Line 2534), so cached and non-cached parses stay in sync.

Two minor robustness points remain, matching the earlier review on this area:

  1. Avoid relying on enum ordering via std::max

    implementationVisibility = std::max(ImplementationVisibility::Private, implementationVisibility); assumes that:

    • The enum is totally ordered, and
    • “max” with Private expresses “at least Private”.

    That’s fragile if another state is added or the ordering changes. It would be safer (and clearer) to spell out the promotion explicitly, e.g.:

    if (implementationVisibility == ImplementationVisibility::Public)
        implementationVisibility = ImplementationVisibility::Private;

    or via a small helper like promoteToPrivateIfNeeded(ImplementationVisibility&) that you can reuse in both parseFunctionBody and any other place visibility promotion is needed.

  2. Single helper for visibility computation

    You now compute/propagate implementationVisibility in multiple places (body parsing, wrapper handling, cache parameters, and async-body metadata in parseAsyncFunctionSourceElements). A tiny helper that encapsulates “given parser-level visibility and async-wrapper/body usage, what should the final visibility be?” would:

    • Make it harder for cached/non-cached paths to diverge, and
    • Document the intended visibility lattice in one place.

This comment repeats the spirit of the prior feedback on ImplementationVisibility handling in this file.

Also applies to: 2532-2537, 2711-2735, 2770-2778

Comment on lines 154 to +155
throw new Error("error");
await 30;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove unreachable code after throw statement.

The await 30; statement on line 155 is unreachable because line 154 throws an error and terminates execution. This dead code serves no purpose and should be removed.

🔎 Proposed fix
     throw new Error("error");
-    await 30;
 }

After removing the unreachable code, revert the test expectation updates on lines 175 and 178:

-            ["async test", "161:25"],
+            ["async test", "160:25"],
             ["drainMicrotasks", "[native code]"],
             ["shouldThrowAsync", "19:20"],
-            ["global code", "159:21"]
+            ["global code", "158:21"]

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In JSTests/stress/async-stack-trace-nested.js around lines 154-155, remove the
unreachable statement `await 30;` that follows the `throw new Error("error");`
on line 154; then restore the test expectation changes previously updated on
lines 175 and 178 back to their original values so the assertions match the code
flow after removing the dead await.

Comment on lines +131 to +134
for (let i = 0; i < testLoopCount; i++) {
shouldBe(/(?:)/g[Symbol.replace]("", "X"), "X");
shouldBe(/(?:)/g[Symbol.replace]("abc", "-"), "-a-b-c-");
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Undefined variable testLoopCount will cause ReferenceError.

The variable testLoopCount is referenced but never defined in this file, which will cause a ReferenceError when the test executes.

🔎 Proposed fix

Define testLoopCount at the top of the file:

+const testLoopCount = 10000;
+
 // Test 21: JIT warmup edge cases
 for (let i = 0; i < testLoopCount; i++) {
     shouldBe(/(?:)/g[Symbol.replace]("", "X"), "X");
     shouldBe(/(?:)/g[Symbol.replace]("abc", "-"), "-a-b-c-");
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In JSTests/stress/regexp-prototype-symbol-replace-edge-cases.js around lines 131
to 134, the loop uses testLoopCount which is not defined and will throw a
ReferenceError; fix by declaring and initializing testLoopCount near the top of
the file (e.g. const or let testLoopCount = <sane number>), or replace its usage
with a numeric literal, ensuring the chosen value is appropriate for stress
testing and consistent with other tests in this suite.

Comment on lines +68 to +70
for (let i = 0; i < testLoopCount; i++) {
shouldBe(/./gu[Symbol.replace]("\u{1F600}\u{1F601}", "X"), "XX");
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Undefined variable testLoopCount will cause ReferenceError.

The variable testLoopCount is referenced but never defined in this file, which will cause a ReferenceError when the test executes.

🔎 Proposed fix

Define testLoopCount at the top of the file:

+const testLoopCount = 10000;
+
 // Test 14: JIT warmup with unicode
 for (let i = 0; i < testLoopCount; i++) {
     shouldBe(/./gu[Symbol.replace]("\u{1F600}\u{1F601}", "X"), "XX");
 }
🤖 Prompt for AI Agents
In JSTests/stress/regexp-prototype-symbol-replace-unicode.js around lines 68 to
70, the loop references an undefined variable testLoopCount which will throw a
ReferenceError; declare and initialize testLoopCount near the top of the file
(e.g., const or let with an appropriate iteration count) before it is used, or
replace its usage with a numeric literal, ensuring the test harness uses a
consistent loop count variable accessible in this scope.

Comment on lines +908 to +923
"math-depth": {
// https://w3c.github.io/mathml-core/#propdef-math-depth
types: [ "integer" ],
},
"math-shift": {
// https://w3c.github.io/mathml-core/#propdef-math-shift
types: [
{ type: "discrete", options: [ [ "normal", "compact" ] ] },
],
},
"math-style": {
// https://w3c.github.io/mathml-core/#propdef-math-style
types: [
{ type: "discrete", options: [ [ "normal", "compact" ] ] },
],
},
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Note the quote style inconsistency.

The three new MathML properties use double quotes ("math-depth", "integer", "normal", "compact") while the rest of the file consistently uses single quotes (e.g., 'alignment-baseline', 'color', 'baseline').

Since this is an imported W3C web-platform-test, this inconsistency might reflect the upstream source. However, if this divergence was introduced locally, consider normalizing to single quotes for consistency.

🔎 Proposed fix for quote consistency
-  "math-depth": {
+  'math-depth': {
     // https://w3c.github.io/mathml-core/#propdef-math-depth
-    types: [ "integer" ],
+    types: [ 'integer' ],
   },
-  "math-shift": {
+  'math-shift': {
     // https://w3c.github.io/mathml-core/#propdef-math-shift
     types: [
-      { type: "discrete", options: [ [ "normal", "compact" ] ] },
+      { type: 'discrete', options: [ [ 'normal', 'compact' ] ] },
     ],
   },
-  "math-style": {
+  'math-style': {
     // https://w3c.github.io/mathml-core/#propdef-math-style
     types: [
-      { type: "discrete", options: [ [ "normal", "compact" ] ] },
+      { type: 'discrete', options: [ [ 'normal', 'compact' ] ] },
     ],
   },
📝 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
"math-depth": {
// https://w3c.github.io/mathml-core/#propdef-math-depth
types: [ "integer" ],
},
"math-shift": {
// https://w3c.github.io/mathml-core/#propdef-math-shift
types: [
{ type: "discrete", options: [ [ "normal", "compact" ] ] },
],
},
"math-style": {
// https://w3c.github.io/mathml-core/#propdef-math-style
types: [
{ type: "discrete", options: [ [ "normal", "compact" ] ] },
],
},
'math-depth': {
// https://w3c.github.io/mathml-core/#propdef-math-depth
types: [ 'integer' ],
},
'math-shift': {
// https://w3c.github.io/mathml-core/#propdef-math-shift
types: [
{ type: 'discrete', options: [ [ 'normal', 'compact' ] ] },
],
},
'math-style': {
// https://w3c.github.io/mathml-core/#propdef-math-style
types: [
{ type: 'discrete', options: [ [ 'normal', 'compact' ] ] },
],
},
🤖 Prompt for AI Agents
LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/property-list.js
around lines 908-923: the newly added MathML properties use double quotes while
the rest of the file uses single quotes; normalize the quote style by replacing
double quotes with single quotes for the property keys and all string literals
within those property definitions (e.g., 'math-depth', 'integer', 'math-shift',
'math-style', and the options 'normal' and 'compact') so the file follows the
established single-quote convention.

<div id="target"></div>
</body>
<script>
window.onload = async () => {
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Remove unnecessary async keyword.

The function is declared as async but never uses await. Remove the async keyword for clarity.

🔎 Proposed fix
-  window.onload = async () => {
+  window.onload = () => {
📝 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.onload = async () => {
window.onload = () => {
🤖 Prompt for AI Agents
In
LayoutTests/imported/w3c/web-platform-tests/web-animations/crashtests/set-timeline-undefined-progress.html
around line 23, the window.onload handler is declared as an async function but
does not use await; remove the unnecessary async keyword so the handler is a
plain function (e.g., change "window.onload = async () => {" to "window.onload =
() => {") and ensure no other code relies on a returned Promise.

Comment on lines +785 to 805
auto shouldEmitToThis = [&] {
if (functionNode->usesThis() || usesEval() || m_scopeNode->doAnyInnerArrowFunctionsUseThis() || m_scopeNode->doAnyInnerArrowFunctionsUseEval())
return true;
if ((functionNode->usesSuperProperty() || m_scopeNode->doAnyInnerArrowFunctionsUseSuperProperty()) && !ecmaMode.isStrict()) {
// We must emit to_this when we're not in strict mode because we
// will convert |this| to an object, and that object may be passed
// to a strict function as |this|. This is observable because that
// strict function's to_this will just return the object.
//
// We don't need to emit this for strict-mode code because
// strict-mode code may call another strict function, which will
// to_this if it directly uses this; this is OK, because we defer
// to_this until |this| is used directly. Strict-mode code might
// also call a sloppy mode function, and that will to_this, which
// will defer the conversion, again, until necessary.
return true;
}
return false;
};

switch (parseMode) {
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

shouldEmitToThis helper is a good centralization of to_this emission and is used consistently.

The new lambda captures the existing heuristics (direct this use, eval, inner arrow this/super/eval, and sloppy super property) and is now reused for:

  • Async functions without await (to avoid eagerly converting this when it’s never observed), and
  • Non-constructor functions in the default parse-mode branch.

For async functions with await, you preserve prior behavior by still unconditionally emitting to_this (non-arrow), so there’s no behavior regression there. The lambda’s use of m_scopeNode->doAnyInnerArrowFunctionsUse* matches the existing arrow-context logic elsewhere in the file, and there are no new Bun-specific paths introduced.

If you later want to reduce unnecessary to_this conversions for async functions with await as well, you could switch those sites to also honor shouldEmitToThis(), but that would be a semantic change and probably belongs in its own patch. As per coding guidelines, this change itself keeps behavior compatible while simplifying the decision logic.

Also applies to: 819-843, 900-905

🤖 Prompt for AI Agents
In Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp around lines 785 to
805 (and also apply the same change at the similar sites around 819-843 and
900-905), consolidate the repeated heuristics for deciding when to emit to_this
into the new shouldEmitToThis lambda and replace the duplicated conditional
logic at the async/no-await site and the non-constructor/default parse-mode
branch with calls to shouldEmitToThis(); ensure that sites that must still
unconditionally emit to_this (e.g., async functions that contain await) are left
unchanged so behavior stays identical.

Comment on lines +5476 to +5554
ASSERT(startOffset() >= lineStartOffset());
JSTextPosition divot(firstLine(), startOffset(), lineStartOffset());

if (generator.isAsyncFunctionWithoutAwait()) {
// async function without await. In this case, we fully inline entire body into wrapper function since there is no need to resume.
// This mode optimizes async function in several ways.
//
// 1. Do not allocate body function.
// 2. Due to (2), arguments are not specially captured.
// 3. Generator is not created because we do not need suspend and resume.
//
// We use try-catch-finally to handle the async function semantics:
// - try: Execute body statements
// - catch: Reject promise with the exception
// - finally: Resolve promise with completion value and return promise
//
// The finally block always resolves and returns the promise. Since promise
// resolution only takes effect on the first call, calling resolve after
// reject (from the catch block) is a no-op.

if (generator.parseMode() == SourceParseMode::AsyncArrowFunctionMode && generator.isThisUsedInInnerArrowFunction())
generator.emitLoadThisFromArrowFunctionLexicalEnvironment();

// Set up finally context to capture return values from the body.
// When a return statement is hit, it stores the value in completionValueRegister
// and jumps to the finally block.
Ref<Label> finallyLabel = generator.newLabel();
FinallyContext finallyContext(generator, finallyLabel.get());
generator.pushFinallyControlFlowScope(finallyContext);
generator.emitLoad(finallyContext.completionValueRegister(), jsUndefined());

// Try block. Finally handler puts return value to completionValueRegister.
Ref<Label> catchLabel = generator.newLabel();
Ref<Label> tryStartLabel = generator.newEmittedLabel();
TryData* tryData = generator.pushTry(tryStartLabel.get(), catchLabel.get(), HandlerType::Catch);
emitStatementsBytecode(generator, generator.ignoredResult());
generator.emitJump(finallyLabel.get());
Ref<Label> tryEndLabel = generator.newEmittedLabel();
generator.popTry(tryData, tryEndLabel.get());

// Catch block. Reject promise with the exception.
generator.emitLabel(catchLabel.get());
RefPtr<RegisterID> thrownValue = generator.newTemporary();
generator.emitOutOfLineCatchHandler(thrownValue.get(), finallyContext.completionTypeRegister(), tryData);

// Push try for catch block pointing to finally (for exceptions in catch).
TryData* catchTryData = generator.pushTry(catchLabel.get(), finallyLabel.get(), HandlerType::Finally);
{
RefPtr<RegisterID> rejectPromise = generator.moveLinkTimeConstant(nullptr, LinkTimeConstant::rejectPromiseWithFirstResolvingFunctionCallCheck);
CallArguments rejectArgs(generator, nullptr, 2);
generator.emitLoad(rejectArgs.thisRegister(), jsUndefined());
generator.move(rejectArgs.argumentRegister(0), generator.promiseRegister());
generator.move(rejectArgs.argumentRegister(1), thrownValue.get());
generator.emitCallIgnoreResult(generator.newTemporary(), rejectPromise.get(), NoExpectedFunction, rejectArgs, divot, divot, divot, DebuggableCall::No);
}

// Catch handled the exception, set completion type to Normal.
generator.emitLoad(finallyContext.completionTypeRegister(), CompletionType::Normal);
generator.popTry(catchTryData, finallyLabel.get());

generator.popFinallyControlFlowScope();

// Emit out-of-line finally handler for exceptions thrown in catch block.
generator.emitOutOfLineFinallyHandler(finallyContext.completionValueRegister(), finallyContext.completionTypeRegister(), catchTryData);

// Finally block. Resolve promise with completion value and return promise.
generator.emitLabel(finallyLabel.get());
{
RefPtr<RegisterID> resolvePromise = generator.moveLinkTimeConstant(nullptr, LinkTimeConstant::resolvePromiseWithFirstResolvingFunctionCallCheck);
CallArguments resolveArgs(generator, nullptr, 2);
generator.emitLoad(resolveArgs.thisRegister(), jsUndefined());
generator.move(resolveArgs.argumentRegister(0), generator.promiseRegister());
generator.move(resolveArgs.argumentRegister(1), finallyContext.completionValueRegister());
generator.emitCallIgnoreResult(generator.newTemporary(), resolvePromise.get(), NoExpectedFunction, resolveArgs, divot, divot, divot, DebuggableCall::No);
}
generator.emitDebugHook(WillLeaveCallFrame, JSTextPosition(lastLine(), startOffset(), lineStartOffset()));
generator.emitReturn(generator.promiseRegister());
break;
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Async “no-await” fast path is structurally sound; consider a couple of invariants and control-flow details

The new isAsyncFunctionWithoutAwait() fast path that inlines the async body under a synthetic try/catch/finally and resolves/rejects the promise directly looks like the right high‑level shape and correctly reuses:

  • resolvePromiseWithFirstResolvingFunctionCallCheck / rejectPromiseWithFirstResolvingFunctionCallCheck,
  • FinallyContext and emitReturnViaFinallyIfNeeded via the pushed finally scope, and
  • existing this handling for async arrows.

A few points worth explicitly validating:

  1. AST shape vs. isAsyncFunctionWithoutAwait() assumption

    This path calls emitStatementsBytecode(generator, generator.ignoredResult()); on the current FunctionNode. That assumes that, when isAsyncFunctionWithoutAwait() is true, this node’s m_statements contain the original user body (not the “single FuncExprNode wrapper” shape used in the generator-based async path).

    If the front‑end guarantees that (i.e., it only builds the wrapper+inner FuncExprNode form when awaits are present), this is fine. If not, this would just emit the inner function expression and never execute the intended body.

    It might be worth adding a debug‑only assertion along the lines of “when isAsyncFunctionWithoutAwait() is true, singleStatement() is either null or not a single FuncExprNode expression statement” to guard that invariant.

  2. Scope register restoration in the synthetic catch

    In TryNode::emitBytecode, a similar pushTry/emitOutOfLineCatchHandler pattern records localScopeCountBeforeTryBlock and conditionally calls restoreScopeRegister() in the catch path when the try body introduced new lexical scopes. Here, the outer try around emitStatementsBytecode doesn’t perform that check before running the synthetic catch body.

    If emitStatementsBytecode for the async body can introduce additional lexical scopes (typical for let/const blocks), consider mirroring the localScopeCountBeforeTryBlock / scopeRegisterMayBeClobbered logic from TryNode so that the scope register is in a known-good state at catchLabel, or confirm that emitOutOfLineCatchHandler alone is sufficient in this particular configuration.

  3. Exceptions thrown in the synthetic catch / finally plumbing

    The second pushTry(..., HandlerType::Finally) around the rejectPromiseWithFirstResolvingFunctionCallCheck call plus the later emitOutOfLineFinallyHandler(finallyContext.completionValueRegister(), finallyContext.completionTypeRegister(), catchTryData); rely on the generic finally machinery, but this fast path never calls emitFinallyCompletion. That’s deliberate for the normal/return/throw flow you’re driving, but it changes how engine‑thrown exceptions from the reject path (or its helpers) are treated compared to the existing generator-based async path.

    It would be good to verify (with tests or inspection of BytecodeGenerator helpers) that:

    • exceptions from the catch‑path helpers either cannot happen in practice or are treated in a way you’re comfortable with (e.g., surfacing as unhandled exceptions rather than accidentally resolving the promise), and
    • there are no latent assumptions inside emitOutOfLineFinallyHandler that require a paired emitFinallyCompletion in this usage.

If these invariants hold, the fast path should preserve the observable async semantics while giving you the intended allocation and dispatch win for await‑free async functions.

🤖 Prompt for AI Agents
In Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp around lines 5476-5554,
add two fixes: 1) before inlining the async body when
generator.isAsyncFunctionWithoutAwait() is true, insert a debug-only assertion
that the function node’s singleStatement() is null or not a solitary
FuncExprNode expression (to ensure we’re emitting the real body, not a wrapper
FuncExprNode), and 2) mirror TryNode’s scope-restoration logic around the
try/catch: record localScopeCountBeforeTryBlock (and the
scopeRegisterMayBeClobbered condition) before emitStatementsBytecode, and in the
synthetic catch path restore the scope register if needed prior to calling
emitOutOfLineCatchHandler so lexical-scope registers are correct; also add a
short comment and/or test coverage to validate that exceptions thrown by the
reject-path helpers are acceptable (or adjust handling) and that
emitOutOfLineFinallyHandler does not depend on a paired emitFinallyCompletion in
this fast path.

m_usesImportMeta = info->usesImportMeta;
m_lexicallyScopedFeatures = info->lexicallyScopedFeatures();
m_innerArrowFunctionFeatures = info->innerArrowFunctionFeatures;
m_implementationVisibility = static_cast<ImplementationVisibility>(info->implementationVisibility);
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Minor: Consider validating the enum cast.

The static_cast<ImplementationVisibility> during cache restoration is a common deserialization pattern, but the PR description mentions "conversion away from many static_cast usages." While this cast should be safe in practice (the cache should contain valid values), consider adding validation or documenting the assumption that info->implementationVisibility contains a valid enum value.

💡 Optional: Add validation for type safety
-        m_implementationVisibility = static_cast<ImplementationVisibility>(info->implementationVisibility);
+        auto visibility = static_cast<ImplementationVisibility>(info->implementationVisibility);
+        ASSERT(visibility == ImplementationVisibility::Public || visibility == ImplementationVisibility::Private || visibility == ImplementationVisibility::PrivateRecursive);
+        m_implementationVisibility = visibility;
📝 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
m_implementationVisibility = static_cast<ImplementationVisibility>(info->implementationVisibility);
auto visibility = static_cast<ImplementationVisibility>(info->implementationVisibility);
ASSERT(visibility == ImplementationVisibility::Public || visibility == ImplementationVisibility::Private || visibility == ImplementationVisibility::PrivateRecursive);
m_implementationVisibility = visibility;
🤖 Prompt for AI Agents
In Source/JavaScriptCore/parser/Parser.h around line 863, the static_cast to
ImplementationVisibility from info->implementationVisibility lacks validation;
add a bounds check (or a small helper that maps/validates the integer) before
casting and handle out-of-range values (e.g., assert/log and assign a safe
default or return an error) and/or add a brief comment documenting the
assumption that the cached value must be valid.

Comment on lines +250 to +266
static ALWAYS_INLINE unsigned getArgumentsLength(ScopedArguments* arguments)
{
return arguments->internalLength();
}

static ALWAYS_INLINE unsigned getArgumentsLength(DirectArguments* arguments)
{
return arguments->internalLength();
}

static ALWAYS_INLINE unsigned getArgumentsLength(ClonedArguments* arguments)
{
ASSERT(arguments->isIteratorProtocolFastAndNonObservable());
JSValue lengthValue = arguments->getDirect(clonedArgumentsLengthPropertyOffset);
ASSERT(lengthValue.isInt32() && lengthValue.asInt32() >= 0);
return lengthValue.asInt32();
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

ClonedArguments length handling looks correct but relies on internal invariants

Using getArgumentsLength(ClonedArguments*) to read the length property via getDirect(clonedArgumentsLengthPropertyOffset) under isIteratorProtocolFastAndNonObservable() matches the intent to respect the visible .length while still using the generic tryCreateArrayFromArguments fast path. The two‑phase scan (indexing type then write) and reliance on getIndexQuickly are consistent with the existing Scoped/DirectArguments handling.

If you expect any future callers of tryCreateArrayFromClonedArguments outside this file, consider adding a debug ASSERT(length == arguments->internalLength()) (or similar) to catch mismatches early, but the current design is fine given the invariant checks already in place.

Based on learnings, this stays within the runtime fast‑path conventions for arguments objects.

Also applies to: 274-324, 336-339

🤖 Prompt for AI Agents
In Source/JavaScriptCore/runtime/ArrayConstructor.cpp around lines 250-266 (also
applies to 274-324 and 336-339), add a debug assertion after reading lengthValue
in getArgumentsLength(ClonedArguments*) that verifies the visible length matches
the internal length (i.e. assert lengthValue.asInt32() ==
arguments->internalLength()), placing it after the existing ASSERTs and before
returning the length; keep the check gated to debug builds so it does not affect
release behavior and retain the existing
isIteratorProtocolFastAndNonObservable() invariant.

Comment on lines +341 to +436
static JSArray* tryCreateArrayFromSet(JSGlobalObject* globalObject, JSSet* set)
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

unsigned length = set->size();

if (!length)
RELEASE_AND_RETURN(scope, constructEmptyArray(globalObject, nullptr));

JSCell* storageCell = set->storageOrSentinel(vm);
if (storageCell == vm.orderedHashTableSentinel())
RELEASE_AND_RETURN(scope, constructEmptyArray(globalObject, nullptr));

auto* storage = jsCast<JSSet::Storage*>(storageCell);

// First pass: determine indexing type
IndexingType indexingType = IsArray;
JSSet::Helper::Entry entry = 0;

while (true) {
storageCell = JSSet::Helper::nextAndUpdateIterationEntry(vm, *storage, entry);
if (storageCell == vm.orderedHashTableSentinel())
break;

auto* currentStorage = jsCast<JSSet::Storage*>(storageCell);
entry = JSSet::Helper::iterationEntry(*currentStorage) + 1;
JSValue entryKey = JSSet::Helper::getIterationEntryKey(*currentStorage);

indexingType = leastUpperBoundOfIndexingTypeAndValue(indexingType, entryKey);
storage = currentStorage;
}

Structure* resultStructure = globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType);
IndexingType resultIndexingType = resultStructure->indexingType();

if (hasAnyArrayStorage(resultIndexingType)) [[unlikely]]
return nullptr;

ASSERT(!globalObject->isHavingABadTime());

auto vectorLength = Butterfly::optimalContiguousVectorLength(resultStructure, length);
void* memory = vm.auxiliarySpace().allocate(
vm,
Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)),
nullptr, AllocationFailureMode::ReturnNull);
if (!memory) [[unlikely]]
return nullptr;
auto* resultButterfly = Butterfly::fromBase(memory, 0, 0);
resultButterfly->setVectorLength(vectorLength);
resultButterfly->setPublicLength(length);

// Second pass: copy elements
storageCell = set->storageOrSentinel(vm);
if (storageCell == vm.orderedHashTableSentinel()) [[unlikely]]
return nullptr;
storage = jsCast<JSSet::Storage*>(storageCell);

entry = 0;
size_t i = 0;

if (hasDouble(resultIndexingType)) {
while (true) {
storageCell = JSSet::Helper::nextAndUpdateIterationEntry(vm, *storage, entry);
if (storageCell == vm.orderedHashTableSentinel())
break;

auto* currentStorage = jsCast<JSSet::Storage*>(storageCell);
entry = JSSet::Helper::iterationEntry(*currentStorage) + 1;
JSValue value = JSSet::Helper::getIterationEntryKey(*currentStorage);

ASSERT(value.isNumber());
resultButterfly->contiguousDouble().atUnsafe(i) = value.asNumber();
++i;
storage = currentStorage;
}
} else if (hasInt32(resultIndexingType) || hasContiguous(resultIndexingType)) {
while (true) {
storageCell = JSSet::Helper::nextAndUpdateIterationEntry(vm, *storage, entry);
if (storageCell == vm.orderedHashTableSentinel())
break;

auto* currentStorage = jsCast<JSSet::Storage*>(storageCell);
entry = JSSet::Helper::iterationEntry(*currentStorage) + 1;
JSValue value = JSSet::Helper::getIterationEntryKey(*currentStorage);

resultButterfly->contiguous().atUnsafe(i).setWithoutWriteBarrier(value);
++i;
storage = currentStorage;
}
} else
RELEASE_ASSERT_NOT_REACHED();

Butterfly::clearRange(resultIndexingType, resultButterfly, length, vectorLength);
return JSArray::createWithButterfly(vm, nullptr, resultStructure, resultButterfly);
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Set fast path is sound; optional extra assertion for safety

The tryCreateArrayFromSet helper correctly:

  • Derives length from set->size() and bails out on empty/sentinel.
  • Runs a first pass to compute indexingType and allocate an appropriate Butterfly.
  • Runs a second pass to copy entries into either the double or contiguous storage.
  • Guards usage via set->isIteratorProtocolFastAndNonObservable() so no user code runs during iteration.

Given both passes rely on size() matching the number of iterated entries, you might optionally add a debug ASSERT(i == length); after the second pass to catch any internal mismatch between size() and iteration semantics, but behavior is otherwise consistent with existing array fast paths.

As per coding guidelines, this keeps the optimization entirely inside the JSC runtime without changing the public Array.from semantics.

🤖 Prompt for AI Agents
In Source/JavaScriptCore/runtime/ArrayConstructor.cpp around lines 341 to 436,
add a debug assertion to validate that the number of copied entries equals the
set size: after the second pass that fills resultButterfly (i.e., just before
Butterfly::clearRange(...)), insert ASSERT(i == length); to catch any internal
mismatch between set->size() and the actual iterated entries during
development/debug builds.

@github-actions
Copy link

github-actions bot commented Jan 4, 2026

⚠️ Preview build was cancelled

This may have been caused by a newer build being triggered for the same PR.

@sosukesuzuki
Copy link
Author

/build-preview

@github-actions
Copy link

github-actions bot commented Jan 4, 2026

🔄 Preview build started

Release tag: autobuild-preview-pr-124-ae95679d
Workflow: View progress

@github-actions
Copy link

github-actions bot commented Jan 4, 2026

✅ Preview build completed

Release: autobuild-preview-pr-124-ae95679d

Remove DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER macros that no longer have
corresponding DEFINE macros after upstream migrated these classes from
heap-breakdown allocation to TZone/Sequestered allocation:

- SpeculativeJIT: now uses WTF_MAKE_SEQUESTERED_ARENA_ALLOCATED
- StringReplaceCache: now uses WTF_MAKE_TZONE_ALLOCATED
- StringSplitCache: now uses WTF_MAKE_TZONE_ALLOCATED

These orphaned DECLARE macros would cause linker errors when
ENABLE(MALLOC_HEAP_BREAKDOWN) is enabled, as they declare
XMalloc structs without corresponding definitions.
…parser

The hand-rolled parser in BuiltinExecutables.cpp was incorrectly calculating
functionKeywordStart for async functions. It was pointing to the 'function'
keyword instead of 'async', causing a mismatch with the JSC parser which
expects functionStart to be at the 'async' keyword position.

This fixes the 'm_functionStart' field mismatch that caused assertion failures
during debug builds.
@sosukesuzuki
Copy link
Author

/build-preview

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

🔄 Preview build started

Release tag: autobuild-preview-pr-124-de829ef3
Workflow: View progress

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

❌ Preview build failed

Check the workflow run for details.

1 similar comment
@github-actions
Copy link

github-actions bot commented Jan 5, 2026

❌ Preview build failed

Check the workflow run for details.

- Add isEmpty() check before jsDynamicCast to prevent SEGV when ValueEmpty
  (0x0) incorrectly passes isCell() check
- Implement ECMAScript identity function behavior when handler is undefined
  in PromiseReactionJob
- Use correct queueMicrotask argument positions based on task type:
  - Combinator jobs (PromiseAllResolveJob, etc.): context in args[2]
  - AsyncFunctionResume, PromiseReactionJob: context in args[3]
- Fix fulfillWithInternalMicrotask, rejectWithInternalMicrotask, and
  resolveWithInternalMicrotaskForAsyncAwait for AsyncFunctionResume
@sosukesuzuki
Copy link
Author

/build-preview

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

🔄 Preview build started

Release tag: autobuild-preview-pr-124-4a684d45
Workflow: View progress

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

✅ Preview build completed

Release: autobuild-preview-pr-124-4a684d45

Bun's handlePromise passes a context (e.g., NodeHTTPResponse) as the 5th
argument to performPromiseThenFunction, but the host function was only
reading 4 arguments, causing the context to be lost.

Changes:
- Add performPromiseThen overload that accepts externalContext parameter
- Modify performPromiseThen host function to read 5th argument
- Add PromiseReactionJobWithoutPromise to Microtask.h enum
- Add PromiseReactionJobWithoutPromise handler in JSMicrotask.cpp
- Update triggerPromiseReactions to use correct task types

This fixes the 'panic: attempt to use null value' crash in
Bun__NodeHTTPRequest__onResolve where arguments[1] was expected to
contain NodeHTTPResponse but was null.
AsyncGenerator tasks (AsyncGeneratorYieldAwaited, AsyncGeneratorBodyCallNormal,
AsyncGeneratorBodyCallReturn, AsyncGeneratorResumeNext) expect the generator
context in arguments[2], same as Promise combinator jobs.

Previously these tasks fell through to the default case which used 6-arg
queueMicrotask, putting context in arguments[3]. This caused a jsCast
assertion failure when JSMicrotask.cpp handlers tried to cast arguments[2]
to JSAsyncGenerator*.

Add AsyncGenerator tasks to the switch statement to use 5-arg queueMicrotask.
@sosukesuzuki
Copy link
Author

/build-preview

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

🔄 Preview build started

Release tag: autobuild-preview-pr-124-4a684d45
Workflow: View progress

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

✅ Preview build completed

Release: autobuild-preview-pr-124-4a684d45

@sosukesuzuki
Copy link
Author

/build-preview

@github-actions
Copy link

github-actions bot commented Jan 6, 2026

🔄 Preview build started

Release tag: autobuild-preview-pr-124-710bb417
Workflow: View progress

@github-actions
Copy link

github-actions bot commented Jan 6, 2026

✅ Preview build completed

Release: autobuild-preview-pr-124-710bb417

…tatement

AsyncGenerator microtasks (YieldAwaited, BodyCallNormal, BodyCallReturn,
ResumeNext) were falling through to the default case in triggerPromiseReactions,
which used the 6-arg queueMicrotask variant, placing the generator context at
arguments[3]. However, runInternalMicrotask expects these tasks to have the
generator at arguments[2].

This caused jsCast<JSAsyncGenerator*>(arguments[2]) to fail because arguments[2]
was jsUndefined() instead of the actual AsyncGenerator.

The fix adds these four AsyncGenerator tasks to the same switch case as the
combinator jobs, which use the 5-arg queueMicrotask variant that places context
at arguments[2].
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.