Upgrade to upstream WebKit baf4a9a7ec0b - #488
Conversation
…bleStreamDefaultReader::read() fires when a worker is terminated mid-read https://bugs.webkit.org/show_bug.cgi?id=321607 Reviewed by Youenn Fablet. The test streams/pipeTo-in-worker-terminate-crash.html terminates workers mid-flight, which should not trigger a crash. In such scenarios, the read operation might happen while we have a pending TerminationException. With the current assertion, instead of returning silently as a non-assertion build would, we end up with a crash. To address it, this commit relaxes the assertion by accepting this termination state as valid, an approach also currently taken by ReadableStreamDefaultController.cpp (since 243538@main). * LayoutTests/platform/wpe/TestExpectations: * Source/WebCore/Modules/streams/ReadableStreamDefaultReader.cpp: (WebCore::ReadableStreamDefaultReader::read): Canonical link: https://commits.webkit.org/319395@main
https://bugs.webkit.org/show_bug.cgi?id=321999 rdar://185184613 Reviewed by Yijia Huang. Let's just use `@newPromise` and @rejectPromiseWithFirstResolvingFunctionCallCheck etc. that is much more efficient (not allocating an object for a tuple), not doing any property lookup. As a result, nobody is using @newPromiseCapability anymore. So this patch removes it from builtin JS. * Source/JavaScriptCore/builtins/BuiltinNames.h: * Source/JavaScriptCore/bytecode/LinkTimeConstant.h: * Source/JavaScriptCore/runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::init): * Source/WebCore/Modules/streams/ReadableStreamDefaultReader.js: (getter.closed): * Source/WebCore/Modules/streams/ReadableStreamInternals.js: (readableStreamDefaultReaderClosedForBindings): (readableStreamDefaultReaderClosedPromise): (readableStreamReaderGenericInitialize): (readableStreamTee): (const.pullAlgorithm): (readableStreamTeePullFunction): (readableStreamTeeBranch1CancelFunction): (readableStreamTeeBranch2CancelFunction): (readableStreamError): (readableStreamClose): (readableStreamReaderGenericRelease): * Source/WebCore/Modules/streams/TransformStreamInternals.js: (createInternalTransformStreamFromTransformer): (createTransformStream): (transformStreamSetBackpressure): (transformStreamDefaultControllerPerformTransform): (transformStreamDefaultSinkWriteAlgorithm): (transformStreamDefaultSinkCloseAlgorithm): (transformStreamDefaultSourcePullAlgorithm): * Source/WebCore/Modules/streams/WritableStreamInternals.js: (writableStreamDefaultWriterClosedForBindings): (writableStreamDefaultWriterReadyForBindings): (setUpWritableStreamDefaultWriter): (writableStreamAbort): (writableStreamClose): (writableStreamAddWriteRequest): (writableStreamFinishErroring): (writableStreamFinishInFlightWrite): (writableStreamFinishInFlightWriteWithError): (writableStreamRejectCloseAndClosedPromiseIfNeeded): (writableStreamUpdateBackpressure): (writableStreamDefaultWriterEnsureClosedPromiseRejected): (writableStreamDefaultWriterEnsureReadyPromiseRejected): (writableStreamDefaultWriterClosedPromise): (writableStreamDefaultWriterReadyPromise): Canonical link: https://commits.webkit.org/319396@main
https://bugs.webkit.org/show_bug.cgi?id=321579 rdar://184690236 Reviewed by Charlie Wolfe. CookieRequestHeaderFieldValue returned the full Cookie header to a web process, HttpOnly cookies included. A web process must never see an HttpOnly value. The message also validated only firstParty, which does not constrain the url the cookies are read for. Its only caller is Vary: Cookie cache validation, which compares the value and never reads it. Return a SHA-1 digest instead, as a std::array<uint8_t, 20> with std::nullopt for "no Cookie header". The digest is salted per network process launch, so a web process cannot recover the header by hashing candidates. collectVaryingRequestHeaders() stores its values in a Vector<std::pair<String, String>> that the network cache writes to disk, so the digest is base64 encoded at that boundary. std::array<uint8_t, N> is an opaque IPC data type, so the reply parameter needs an entry in opaque_ipc_types.tracking.in. messages.py did not know a header for std::array yet. Dropping frameID, pageID and webPageProxyID preserves behavior, because that caller always passed std::nullopt for the first two and shouldRelaxThirdPartyCookieBlockingForPage() already returned No. Existing cache entries hold a raw header, so Vary: Cookie entries revalidate once. The cache version stays the same on purpose, because a bump would discard every cached resource instead of only those. WebCookieJar::cookieRequestHeaderFieldValue now returns nothing. Its only WebKit2 caller is Web Inspector WebSocket handshake reporting, and both channels discard it. WebKitLegacy uses the unchanged base class implementation. Test: Tools/TestWebKitAPI/Tests/WebKit/WKWebView/IPCTestingAPI.mm * Source/WebCore/loader/CookieJar.cpp: (WebCore::CookieJar::cookieRequestHeaderFieldValueDigest const): * Source/WebCore/loader/CookieJar.h: * Source/WebCore/platform/network/CacheValidation.cpp: (WebCore::computeCookieHeaderDigestForVary): (WebCore::encodeCookieHeaderDigestForVary): (WebCore::cookieRequestHeaderFieldValueForVary): (WebCore::collectVaryingRequestHeaders): (WebCore::verifyVaryingRequestHeaders): (WebCore::cookieRequestHeaderFieldValue): Deleted. * Source/WebCore/platform/network/CacheValidation.h: * Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp: (WebKit::NetworkConnectionToWebProcess::cookieRequestHeaderFieldValueDigest): (WebKit::NetworkConnectionToWebProcess::cookieRequestHeaderFieldValue): Deleted. * Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h: * Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in: * Source/WebKit/NetworkProcess/NetworkProcess.h: * Source/WebKit/Scripts/webkit/messages.py: * Source/WebKit/Scripts/webkit/opaque_ipc_types.tracking.in: * Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp: (WebKit::WebCookieJar::cookieRequestHeaderFieldValue const): (WebKit::WebCookieJar::cookieRequestHeaderFieldValueDigest const): * Source/WebKit/WebProcess/WebPage/WebCookieJar.h: * Tools/TestWebKitAPI/Tests/WebKit/WKWebView/IPCTestingAPI.mm: (EmptyFirstPartyForCookiesCookieRequestHeaderFieldValueDigest)): (InvalidSameSiteInfoCookieRequestHeaderFieldValueDigest)): (EmptyFirstPartyForCookiesCookieRequestHeaderFieldValue)): Deleted. (InvalidSameSiteInfoCookieRequestHeaderFieldValue)): Deleted. Canonical link: https://commits.webkit.org/319397@main
https://bugs.webkit.org/show_bug.cgi?id=322043 rdar://185140001 Reviewed by Megan Gardner, Lily Spiniolas, Aditya Keerthi, and Abrar Rahman Protyasha. * Source/WTF/wtf/PlatformEnable.h: Temporarily disable this flag. Canonical link: https://commits.webkit.org/319398@main
…IsolatedSiteStore.PersistsAcrossSessions is a flaky failure https://bugs.webkit.org/show_bug.cgi?id=321957 rdar://185141546 Unreviewed test Gardening The test is a flaky failure, so updating the test expectation to reflect the correct flag. * TestExpectations/apitests: Canonical link: https://commits.webkit.org/319399@main
https://bugs.webkit.org/show_bug.cgi?id=322041 Reviewed by Adrian Perez de Castro. The test started failing when the bots switched to clang in 318539@main. WebKitCompilerFlags.cmake passes "-mllvm -dwarf-linkage-names=Abstract", which GCC ignores but which makes clang drop the mangled name from the debug info of regular function definitions. Only the plain name is left, so symbolize() named the test frame "TestBody" instead of "TestWebKitAPI::StackTraceTest_StackTraceWorks_Test::TestBody()". Every frame of a debug build backtrace lost its namespace and class this way. Release builds were fine because they have no debug info to begin with. Look the name up in the symbol table first, which always stores the mangled name, and only ask the debug info when the symbol table has nothing. Also fix two smaller problems in the same code: the symbol was read uninitialized when neither lookup found anything, and libbacktrace always calls the error callback, so passing null for it would crash on the first failed lookup. * Source/WTF/wtf/StackTrace.cpp: (WTF::backtraceErrorCallback): (WTF::backtraceState): (WTF::backtraceSyminfoCallback): (WTF::backtraceFullCallback): (WTF::symbolize): Canonical link: https://commits.webkit.org/319400@main
https://bugs.webkit.org/show_bug.cgi?id=321746 Reviewed by Devin Rousso. WebPageProxy::close() cancels tracking of the active popup menu, but only drops its reference to the active context menu without dismissing it. On macOS and Windows the menu runs a nested run loop that keeps the proxy alive, so the menu stays on screen tracking a closed page. Cancel tracking of the active context menu in close(), matching popup menus. Implemented with -[NSMenu cancelTracking] on macOS and ::EndMenu() on Windows. GTK needs no override since its menus are non-modal and popped down by the proxy destructor; WPE shows no native menu. Test: Tools/TestWebKitAPI/Tests/WebKit/WKWebView/mac/ContextMenuTests.mm * Source/WebKit/UIProcess/WebContextMenuProxy.h: (WebKit::WebContextMenuProxy::cancelTracking): * Source/WebKit/UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::close): * Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h: * Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm: (WebKit::WebContextMenuProxyMac::cancelTracking): * Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp: (WebKit::WebContextMenuProxyWin::cancelTracking): (WebKit::WebContextMenuProxyWin::showContextMenuWithItems): * Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h: * Tools/TestWebKitAPI/Tests/WebKit/WKWebView/mac/ContextMenuTests.mm: (TestWebKitAPI::TEST(ContextMenuTests, MenuTrackingCancelledWhenPageCloses)): Canonical link: https://commits.webkit.org/319401@main
….html https://bugs.webkit.org/show_bug.cgi?id=322050 Unreviewed gardening. The pixel test result now matches the legacy SVG engine, remove the LBSE baseline. * LayoutTests/platform/mac-tahoe-wk2-lbse-text/svg/zoom/page/zoom-background-images-expected.png: Removed. Canonical link: https://commits.webkit.org/319402@main
https://bugs.webkit.org/show_bug.cgi?id=321991 Reviewed by Nikolas Zimmermann. Added background color support to GraphicsLayerCoordinated, CoordinatedPlatformLayer and SkiaCompositingLayer. The "paint flushing" feature of WebInspector is using GraphicsLayer::setBackgroundColor. For Skia compositor, there is one more bug for the "paint flushing" feature. See <https://webkit.org/b/321993>. * Source/WebCore/platform/graphics/skia/SkiaCompositingLayer.h: * Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayer.cpp: (WebCore::CoordinatedPlatformLayer::setBackgroundColor): (WebCore::CoordinatedPlatformLayer::flushCompositingStateOnTarget): (WebCore::CoordinatedPlatformLayer::flushCompositingStateOnSkiaTarget): * Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayer.h: * Source/WebCore/platform/graphics/texmap/coordinated/GraphicsLayerCoordinated.cpp: (WebCore::GraphicsLayerCoordinated::setBackgroundColor): (WebCore::GraphicsLayerCoordinated::commitLayerChanges): * Source/WebCore/platform/graphics/texmap/coordinated/GraphicsLayerCoordinated.h: * Source/WebCore/platform/graphics/skia/SkiaCompositingLayer.cpp: (WebCore::SkiaCompositingLayer::paintContents): Canonical link: https://commits.webkit.org/319403@main
…ests before reporting results https://bugs.webkit.org/show_bug.cgi?id=319725 rdar://182558497 Reviewed by Aakash Jain. The Site-Isolation-Tests EWS queue reported a change as failing after a single test run, skipping the retry ladder that every other layout-test queue uses to avoid blaming a change for flaky or pre-existing failures. The queue can reuse the existing ladder as-is. Both the first run and the re-run need the site-isolation flavor, since each consults results-db and can pass the build early when every failure is already known. Without it the re-run would query regular WK2 history for this queue, which could mark a site-isolation-specific regression as pre-existing and hide it. * Tools/CISupport/ews-build/steps.py: (RunWebKitTests.rerun_step): Added, so a queue can substitute its own re-run step. (RunWebKitTests.evaluateCommand): Use rerun_step(). (RunWebKitTestsInSiteIsolationMode.doStepIf): (SiteIsolationResultsDBMixin): Added, holding the site-isolation results-db flavor and reports_to_results_db for both site-isolation steps. (SiteIsolationResultsDBMixin.results_db_query_configuration): Moved from RunWebKitTestsEWSSiteIsolation. (RunWebKitTestsEWSSiteIsolation): Moved below ReRunWebKitTests so it can reference the re-run step. Removed the single-run evaluateCommand and the filter_failures_using_results_db override that duplicated the base implementation. (RunWebKitTestsEWSSiteIsolation.rerun_step): (ReRunWebKitTestsEWSSiteIsolation): Added, the re-run step for this queue. (RunWebKitTestsEWSSiteIsolation.results_db_query_configuration): Deleted. (RunWebKitTestsEWSSiteIsolation.filter_failures_using_results_db): Deleted. (RunWebKitTestsEWSSiteIsolation.evaluateCommand): Deleted. * Tools/CISupport/ews-build/steps_unittest.py: Add unit tests. Canonical link: https://commits.webkit.org/319404@main
https://bugs.webkit.org/show_bug.cgi?id=322059 don't need this anymore Reverted change: Disable fullscreen scroll pocket support https://bugs.webkit.org/show_bug.cgi?id=322043 319398@main (5e3cb10) Canonical link: https://commits.webkit.org/319405@main
…reeSyncData when a remote web process terminates while loading cross-site iframes in private browsing https://bugs.webkit.org/show_bug.cgi?id=321633 rdar://184724123 Reviewed by Abrar Rahman Protyasha. broadcastFrameTreeSyncData has a RELEASE_ASSERT that site isolation is enabled. Four of its five callers check the preference first; the one in remoteProcessDidTerminate does not. 7e7db43 added the assert, the guarded callsite in didCommitLoad, and this unguarded one, all in the same commit. siteIsolationEnabled is a mutable preference, and nothing tears down a RemotePageProxy or removes a page from its BrowsingContextGroup when it is turned off on a live page - WebPreferences::update() only calls WebPageProxy::preferencesDidChange(). So a remote page created while site isolation was enabled outlives the preference change, and when its process later terminates, RemotePageProxy::processDidTerminate reaches remoteProcessDidTerminate, which broadcasts unconditionally and the release assert kills the UI process. Check the preference at the callsite, the way didCommitLoad does. The test kills the iframe process and waits for it to exit rather than waiting on -waitForWebContentProcessDidTerminate. An iframe process is not the page's siteIsolatedProcess(), so WebProcessProxy::terminationReason() reports NonMainFrameWebContentProcessCrash, and NavigationState::NavigationClient::processDidTerminate returns early for that reason without invoking the delegate. Waiting on it never completes, so the test times out instead of failing. * Source/WebKit/UIProcess/WebFrameProxy.cpp: (WebKit::WebFrameProxy::remoteProcessDidTerminate): * Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm: (TestWebKitAPI::setFeatureEnabled): (TestWebKitAPI::enableFeature): Canonical link: https://commits.webkit.org/319406@main
…n-picture/picture-in-picture-interruption.html is a flaky failure https://bugs.webkit.org/show_bug.cgi?id=322051 rdar://185244348 Unreviewed test gardening * LayoutTests/platform/mac-wk2/TestExpectations: Canonical link: https://commits.webkit.org/319407@main
https://bugs.webkit.org/show_bug.cgi?id=321769 rdar://172301423 Reviewed by Sihui Liu. The existing process count limiter depends on various codepaths maintaining an LRU list of all WebProcesses at navigation time. With Site Isolation enabled, this strategy doesn't work, since the LRU list maintenance didn't fan out to remote frame processes, so processes that should logically be clustered together in the LRU list ended up spread apart. This patch replaces the LRU list of WebProcess with an LRU list of WebPageProxy. LRU in this case means: 1. Non-visible pages, in order of creation time 2. Visible pages, in order of last visible or focused time So we upon reaching the process count limit, we first try to kill the page that was visible the longest time ago. This also contains a couple of other drive-by fixes: 1. We arbitrarily raise the process count limit from 400 to 512 when Site Isolation is enabled. 2. We stop prewarming processes if we're close to the process count limit. Tests: Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm Tools/TestWebKitAPI/Tests/WebKit/WKWebView/WebContentProcessDidTerminate.mm * Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h: * Source/WebKit/UIProcess/BrowsingContextGroup.cpp: (WebKit::BrowsingContextGroup::hasVisiblePage const): * Source/WebKit/UIProcess/BrowsingContextGroup.h: * Source/WebKit/UIProcess/ProvisionalFrameProxy.cpp: (WebKit::ProvisionalFrameProxy::ProvisionalFrameProxy): * Source/WebKit/UIProcess/WebPageProxy.cpp: (WebKit::leastRecentlyVisiblePages): (WebKit::leastRecentlyHiddenPages): (WebKit::m_pageForTesting): (WebKit::WebPageProxy::close): (WebKit::WebPageProxy::loadRequestWithNavigationShared): (WebKit::WebPageProxy::loadFile): (WebKit::WebPageProxy::loadDataWithNavigationShared): (WebKit::WebPageProxy::loadSimulatedRequest): (WebKit::WebPageProxy::loadAlternateHTML): (WebKit::WebPageProxy::reload): (WebKit::WebPageProxy::goToBackForwardItem): (WebKit::WebPageProxy::sendGoToBackForwardItemForFrame): (WebKit::WebPageProxy::dispatchActivityStateChange): (WebKit::WebPageProxy::leastRecentlyVisiblePageToUnload): (WebKit::WebPageProxy::viewIsBecomingVisible): (WebKit::WebPageProxy::viewIsBecomingInvisible): * Source/WebKit/UIProcess/WebPageProxy.h: * Source/WebKit/UIProcess/WebProcessCache.cpp: (WebKit::WebProcessCache::canCacheProcess const): * Source/WebKit/UIProcess/WebProcessPool.cpp: (WebKit::WebProcessPool::prewarmProcess): (WebKit::WebProcessPool::didReachGoodTimeToPrewarm): (WebKit::WebProcessPool::reclaimIdleProcesses): (WebKit::WebProcessPool::handleMemoryPressureWarning): (WebKit::WebProcessPool::hasAnyProcessPoolUsedSiteIsolation): (WebKit::WebProcessPool::processForNavigation): * Source/WebKit/UIProcess/WebProcessPool.h: * Source/WebKit/UIProcess/WebProcessProxy.cpp: (WebKit::maxProcessCount): (WebKit::WebProcessProxy::setProcessCountLimit): (WebKit::WebProcessProxy::runningProcessCount): (WebKit::WebProcessProxy::isNearingProcessCountLimit): (WebKit::WebProcessProxy::hasReachedProcessCountLimit): (WebKit::WebProcessProxy::didStartRunningProcess): (WebKit::WebProcessProxy::didStopRunningProcess): (WebKit::WebProcessProxy::create): (WebKit::WebProcessProxy::reclaimProcessesIfNeeded): (WebKit::WebProcessProxy::createForRemoteWorkers): (WebKit::WebProcessProxy::~WebProcessProxy): (WebKit::WebProcessProxy::addProvisionalPageProxy): (WebKit::WebProcessProxy::addRemotePageProxy): (WebKit::WebProcessProxy::shutDown): (WebKit::WebProcessProxy::addExistingWebPage): (WebKit::WebProcessProxy::processDidTerminateOrFailedToLaunch): (WebKit::WebProcessProxy::didFinishLaunching): (WebKit::WebProcessProxy::establishRemoteWorkerContext): (WebKit::liveProcessesLRU): Deleted. (WebKit::WebProcessProxy::markProcessAsRecentlyUsed): Deleted. * Source/WebKit/UIProcess/WebProcessProxy.h: * Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm: (TestWebKitAPI::(SiteIsolation, ProcessLimitUnloadsAllProcessesOfLeastRecentlyVisiblePage)): * Tools/TestWebKitAPI/Tests/WebKit/WKWebView/WebContentProcessDidTerminate.mm: (TEST(WKNavigation, WebProcessLimit)): (TEST(WKNavigation, WebProcessLimitPrefersUnloadingNonVisiblePages)): Canonical link: https://commits.webkit.org/319408@main
…serting it https://bugs.webkit.org/show_bug.cgi?id=322030 Reviewed by Alex Christensen. FetchOptions::encodePersistent() writes destination as its raw value, and says that changes to its encoding should bump the NetworkCache Storage format version. We can just avoid the change in order. * Source/WebCore/Modules/fetch/FetchRequestDestination.idl: * Source/WebCore/loader/FetchOptions.h: * Source/WebCore/loader/FetchOptionsDestination.h: * Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in: Canonical link: https://commits.webkit.org/319409@main
rdar://180057740 https://bugs.webkit.org/show_bug.cgi?id=317430 Reviewed by Jean-Yves Avenard. ISOBoxes and their subclasses are parsed representations of ISO-BMFF media data. In addition to reading these boxes from files and memory, we may also want to serialize these boxes to memory, for features like mp4-file authoring and editing. Add the ability to write a box (and all its children) to memory. Each box must be able to calculate its own size, so there is a new pair of methods: `partialSize` and `requiredSize`. Base ISOBoxes boxes need their subclasses' sizes to be fully calculated, hence the split between the two functions. Also add a `serialize` and virtual `write` method, and a convenience template `checkedReadSequence` and `checkedWriteSequence` to support reading and writing data arrays. Test: Tools/TestWebKitAPI/Tests/WebCore/ISOBox.cpp * Source/WebCore/platform/graphics/iso/ISOBox.cpp: (WebCore::ISOBox::ISOBox): (WebCore::ISOBox::peekBox): (WebCore::ISOBox::read): (WebCore::ISOBox::updateSize): (WebCore::ISOBox::partialSize const): (WebCore::ISOBox::requiredSize const): (WebCore::ISOBox::parse): (WebCore::ISOBox::write const): (WebCore::ISOBox::serialize const): (WebCore::ISOFullBox::ISOFullBox): (WebCore::ISOFullBox::parse): (WebCore::ISOFullBox::write const): (WebCore::ISOFullBox::parseVersionAndFlags): * Source/WebCore/platform/graphics/iso/ISOBox.h: (WebCore::ISOBox::checkedRead): (WebCore::ISOBox::checkedReadSequence): (WebCore::ISOBox::checkedWrite): (WebCore::ISOBox::checkedWriteSequence): (WebCore::ISOFullBox::setVersion): (WebCore::ISOFullBox::setFlags): * Source/WebCore/platform/graphics/iso/ISOOriginalFormatBox.cpp: (WebCore::ISOOriginalFormatBox::ISOOriginalFormatBox): (WebCore::ISOOriginalFormatBox::parse): * Source/WebCore/platform/graphics/iso/ISOOriginalFormatBox.h: * Source/WebCore/platform/graphics/iso/ISOProtectionSchemeInfoBox.cpp: (WebCore::ISOProtectionSchemeInfoBox::ISOProtectionSchemeInfoBox): (WebCore::ISOProtectionSchemeInfoBox::parse): (WebCore::ISOProtectionSchemeInfoBox::updateSize): (WebCore::ISOProtectionSchemeInfoBox::partialSize const): * Source/WebCore/platform/graphics/iso/ISOProtectionSchemeInfoBox.h: * Source/WebCore/platform/graphics/iso/ISOProtectionSystemSpecificHeaderBox.cpp: (WebCore::ISOProtectionSystemSpecificHeaderBox::commonSystemID const): (WebCore::ISOProtectionSystemSpecificHeaderBox::ISOProtectionSystemSpecificHeaderBox): (WebCore::ISOProtectionSystemSpecificHeaderBox::peekSystemID): (WebCore::ISOProtectionSystemSpecificHeaderBox::parse): (WebCore::ISOProtectionSystemSpecificHeaderBox::parseData): (WebCore::ISOProtectionSystemSpecificHeaderBox::write const): (WebCore::ISOProtectionSystemSpecificHeaderBox::writeData const): (WebCore::ISOProtectionSystemSpecificHeaderBox::partialSize const): * Source/WebCore/platform/graphics/iso/ISOProtectionSystemSpecificHeaderBox.h: * Source/WebCore/platform/graphics/iso/ISOSchemeInformationBox.cpp: (WebCore::ISOSchemeInformationBox::ISOSchemeInformationBox): (WebCore::ISOSchemeInformationBox::parse): (WebCore::ISOSchemeInformationBox::updateSize): (WebCore::ISOSchemeInformationBox::partialSize const): * Source/WebCore/platform/graphics/iso/ISOSchemeInformationBox.h: * Source/WebCore/platform/graphics/iso/ISOSchemeTypeBox.cpp: (WebCore::ISOSchemeTypeBox::ISOSchemeTypeBox): (WebCore::ISOSchemeTypeBox::parse): * Source/WebCore/platform/graphics/iso/ISOSchemeTypeBox.h: * Source/WebCore/platform/graphics/iso/ISOTrackEncryptionBox.cpp: (WebCore::ISOTrackEncryptionBox::ISOTrackEncryptionBox): (WebCore::ISOTrackEncryptionBox::parse): (WebCore::ISOTrackEncryptionBox::parsePayload): * Source/WebCore/platform/graphics/iso/ISOTrackEncryptionBox.h: * Source/WebCore/platform/graphics/iso/ISOVTTCue.cpp: (WebCore::ISOWebVTTCue::ISOWebVTTCue): * Source/WebCore/platform/graphics/iso/ISOVTTCue.h: * Tools/TestWebKitAPI/Tests/WebCore/ISOBox.cpp: (TestWebKitAPI::TEST(ISOBox, ISOFairPlayStreamingPsshBox)): (TestWebKitAPI::serializeBox): (TestWebKitAPI::TEST(ISOBox, FairPlay_KeyRequestInfoBox_Write)): (TestWebKitAPI::TEST(ISOBox, FairPlay_KeyRequestInfoBox_Roundtrip)): (TestWebKitAPI::TEST(ISOBox, FairPlay_InfoBox_Write)): (TestWebKitAPI::TEST(ISOBox, FairPlay_InfoBox_Roundtrip)): (TestWebKitAPI::TEST(ISOBox, FairPlay_KeyAssetIdBox_ParseAndRewrite)): (TestWebKitAPI::TEST(ISOBox, FairPlay_KeyRequestBox_WriteWithFkriOnly)): (TestWebKitAPI::TEST(ISOBox, FairPlay_KeyRequestBox_RoundtripWithAssetId)): (TestWebKitAPI::TEST(ISOBox, FairPlay_InitDataBox_WriteAndRoundtrip)): (TestWebKitAPI::TEST(ISOBox, FairPlay_PsshBox_ParseWriteParseRoundtrip)): (TestWebKitAPI::TEST(ISOBox, PsshBox_V1_PartialSizeIncludesSystemIDAndDataSize)): Canonical link: https://commits.webkit.org/319410@main
https://bugs.webkit.org/show_bug.cgi?id=320910 rdar://183940963 Reviewed by Simon Fraser. Flips SVGExternalResourcesEnabled from preview to stable. * Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml: Canonical link: https://commits.webkit.org/319411@main
rdar://183688843 https://bugs.webkit.org/show_bug.cgi?id=320705 Reviewed by Tim Nguyen. This patch implements parsing support for @supports named-feature(). The supported name features are hardcoded; it's expected that features will be added rather sparingly (at most one or two yearly), and only when it's implemented in WebKit. Test: imported/w3c/web-platform-tests/css/css-conditional/at-supports-named-feature-001.html * LayoutTests/imported/w3c/web-platform-tests/css/css-conditional/at-supports-named-feature-001-expected.txt: - Test progression. * LayoutTests/imported/w3c/web-platform-tests/css/css-conditional/at-supports-named-feature-001.html: - Add some invalid test cases. - Fix a bug where the test uses `Boolean.prototype.toString` to serialize a string, but that method returns "false" for every input, including `true`. * Source/WebCore/css/CSSValueKeywords.in: * Source/WebCore/css/parser/CSSSupportsParser.cpp: (WebCore::CSSSupportsParser::consumeSupportsFunction): (WebCore::CSSSupportsParser::consumeSupportsNamedFeatureFunction): * Source/WebCore/css/parser/CSSSupportsParser.h: Canonical link: https://commits.webkit.org/319412@main
…owed to play can interrupt play in another app https://bugs.webkit.org/show_bug.cgi?id=322011 rdar://184545492 Reviewed by Eric Carlson. Playing a trailer in the TV app on visionOS and then opening a page carrying an autoplaying video paused the trailer, and it did not resume. Following 317782@main, void MediaSessionManagerInterface::sessionCanProduceAudioChanged() unconditionally called maybeActivateAudioSession() synchronously; When the element was first loaded, and not yet known to have audible content, it was allowed to play and the MediaSession state became Playing, shortly after when the metadata was loaded and readyState moved to HAVE_METADATA (having canProduceAudio() now returning true but not yet actually audible having not loaded any content to render), maybeActivateAudioSession() activated the AudioSession only to then immediately deny playback and pause the video. This caused any other application currently playing audio on visionOS or iPadOS to be paused. The audio session is now activated only for a session whose client would be allowed to begin playing. PlatformMediaSessionInterface gains playbackPermitted(), defaulting to true so that AudioContext, MediaSession and MediaStream sessions are unaffected, and MediaElementSession answers it with playbackStateChangePermitted(MediaPlaybackState::Playing). MediaSessionManagerInterface::audioSessionActivationRequired() is activeAudioSessionRequired() plus that condition and is consulted only by maybeActivateAudioSession(). maybeDeactivateAudioSession() keeps using activeAudioSessionRequired(): the permission is state-dependent and can be false for a session that is legitimately playing, and deactivation must stay conservative. Asserting that no activation happened needs the GPU process's view, as a web process's own AudioSession reports the state it asked for and reports it optimistically. AudioSession counts transitions from inactive to active, and the count is readable through internals.systemAudioSessionActivationCount(), plumbed the way systemAudioSessionCategory() already is. * LayoutTests/fast/harness/internals-object-property-access-on-window-without-frame-crash.html: Skip the new internals function, which sends IPC behind AllowTestOnlyIPC that this test does not set. * LayoutTests/media/audio-session-not-activated-for-denied-audible-element-expected.txt: Added. * LayoutTests/media/audio-session-not-activated-for-denied-audible-element.html: Added. * LayoutTests/media/audio-session-not-activated-when-unmuting-denied-element-expected.txt: Added. * LayoutTests/media/audio-session-not-activated-when-unmuting-denied-element.html: Added. * LayoutTests/platform/glib/TestExpectations: Skip both, no USE(AUDIO_SESSION) support. * Source/WebCore/html/MediaElementSession.h: * Source/WebCore/platform/audio/AudioSession.cpp: (WebCore::AudioSession::tryToSetActive): Count activations. * Source/WebCore/platform/audio/AudioSession.h: * Source/WebCore/platform/audio/MediaSessionManagerInterface.cpp: (WebCore::MediaSessionManagerInterface::audioSessionActivationRequired const): Added. (WebCore::MediaSessionManagerInterface::maybeActivateAudioSession): Use it. * Source/WebCore/platform/audio/MediaSessionManagerInterface.h: * Source/WebCore/platform/audio/PlatformMediaSessionInterface.h: * Source/WebCore/testing/Internals.cpp: (WebCore::Internals::systemAudioSessionActivationCount): Added. * Source/WebCore/testing/Internals.h: * Source/WebCore/testing/Internals.idl: * Source/WebKit/GPUProcess/media/RemoteAudioSessionProxy.cpp: (WebKit::RemoteAudioSessionProxy::systemActivationCountForTesting): Added. * Source/WebKit/GPUProcess/media/RemoteAudioSessionProxy.h: * Source/WebKit/GPUProcess/media/RemoteAudioSessionProxy.messages.in: * Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.cpp: (WebKit::RemoteAudioSession::systemActivationCountForTesting): Added. * Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.h: Canonical link: https://commits.webkit.org/319413@main
https://bugs.webkit.org/show_bug.cgi?id=321523 rdar://184633468 Reviewed by Basuke Suzuki. In 317835@main I thought there was no way to get a sec_protocol_metadata_t from a nw_protocol_metadata_t for WebTransport, so I introduced SecurityProtocolMetadata to get it from the TLS handshake and I was going to introduce a new function nw_webtransport_metadata_copy_sec_protocol_metadata to get it directly. In my review feedback, I was informed that there's already a way to get the sec_protocol_metadata_t. It's different if WebTransport is using H2 or H3, but it works both ways. I introduce a test that not only uses H2 with WebTransport for the first time in WebKit's tests, but it also generates keying material on the server to verify that the client and the server are able to generate the exact same bytes, which is the whole point of exportKeyingMaterial but it's currently not tested in wpt. Test: Tools/TestWebKitAPI/Tests/WebKit/WKWebView/WebTransport.mm * Source/WebCore/PAL/pal/spi/cocoa/NetworkSPI.h: * Source/WebKit/Configurations/AllowedSPI.toml: * Source/WebKit/NetworkProcess/cocoa/NetworkSoftLink.h: * Source/WebKit/NetworkProcess/cocoa/NetworkSoftLink.mm: * Source/WebKit/NetworkProcess/webtransport/NetworkTransportSession.h: (WebKit::NetworkTransportSession::SecurityProtocolMetadata::create): Deleted. (WebKit::NetworkTransportSession::SecurityProtocolMetadata::receivedMetadata): Deleted. (WebKit::NetworkTransportSession::SecurityProtocolMetadata::metadata const): Deleted. * Source/WebKit/NetworkProcess/webtransport/cocoa/NetworkTransportSessionCocoa.mm: (WebKit::NetworkTransportSession::create): (WebKit::NetworkTransportSession::NetworkTransportSession): (WebKit::createParameters): (WebKit::NetworkTransportSession::securityMetadata const): (WebKit::NetworkTransportSession::exportKeyingMaterial): * Tools/TestWebKitAPI/Helpers/cocoa/NetworkConnection.h: * Tools/TestWebKitAPI/Helpers/cocoa/NetworkConnection.mm: (TestWebKitAPI::securityMetadata): (TestWebKitAPI::ConnectionGroup::exportKeyingMaterial const): * Tools/TestWebKitAPI/Helpers/cocoa/WebTransportServer.h: * Tools/TestWebKitAPI/Helpers/cocoa/WebTransportServer.mm: (TestWebKitAPI::WebTransportServer::WebTransportServer): * Tools/TestWebKitAPI/Tests/WebKit/WKWebView/WebTransport.mm: (TestWebKitAPI::ExportKeyingMaterial)): Canonical link: https://commits.webkit.org/319414@main
…/the-audio-api/the-audionode-interface/audionode-channel-rules.html is a flaky crash https://bugs.webkit.org/show_bug.cgi?id=321961 rdar://185147134 Unreviewed test gardening * LayoutTests/platform/mac-wk2/TestExpectations: Canonical link: https://commits.webkit.org/319415@main
…only be used in the WKContentWorld.pageWorld https://bugs.webkit.org/show_bug.cgi?id=322036 rdar://185228555 Reviewed by Alex Christensen. This patch implements a version of WKWebView._hitTest(at:inFrameCoordinates:) that allows to specify a WKContentWorld. * Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _hitTestAtPoint:inFrameCoordinateSpace:completionHandler:]): (-[WKWebView _hitTestAtPoint:inFrameCoordinateSpace:inContentWorld:completionHandler:]): * Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h: * Source/WebKit/UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::hitTestAtPoint): * Source/WebKit/UIProcess/WebPageProxy.h: * Source/WebKit/WebProcess/WebPage/WebFrame.cpp: (WebKit::createJSHandle): (WebKit::WebFrame::createAndPrepareToSendJSHandle const): * Source/WebKit/WebProcess/WebPage/WebFrame.h: * Source/WebKit/WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::hitTestAtPoint): * Source/WebKit/WebProcess/WebPage/WebPage.h: * Source/WebKit/WebProcess/WebPage/WebPage.messages.in: * Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm: (TestWebKitAPI::(SiteIsolation, HitTesting)): (TestWebKitAPI::(SiteIsolation, HitTestingInContentWorld)): Canonical link: https://commits.webkit.org/319416@main
…ork.html is a flakey text failure https://bugs.webkit.org/show_bug.cgi?id=225430 rdar://77587091 Reviewed by Alexey Proskuryakov. CFNetwork was missing counting a \r\n of the chunked response before, but now with it correctly counts them. This also matches the value of the gtk test expectations. 318278@main made it happen more reliably by using the same network loader for tests as our users use. * LayoutTests/platform/mac-site-isolation/TestExpectations: * LayoutTests/platform/mac-wk2/TestExpectations: * LayoutTests/platform/mac/http/tests/inspector/network/resource-sizes-network-expected.txt: Canonical link: https://commits.webkit.org/319417@main
…ntPolicy /Volumes/Data/worker/Apple-Tahoe-Debug-Build/build/Source/WebCore/loader/DocumentLoader.cpp https://bugs.webkit.org/show_bug.cgi?id=320913 rdar://183941470 Reviewed by Alex Christensen. 318278@main turned the CFNetwork NW loader on unconditionally. For multipart/x-mixed-replace it hands the network process the follow-up parts, their data and the end of the load without waiting for the previous part's response completion handler, whose content-policy check is asynchronous (DocumentLoader::responseReceived() -> checkContentPolicy() IPCs to the UIProcess). 313118@main made NetworkResourceLoader tolerate the extra responses by queuing the response completion handlers in a Deque instead of overwriting a single one, but it kept forwarding every message to the WebProcess immediately. The WebProcess cannot process anything past a response it has not validated yet: a follow-up response hits ASSERT(!m_waitingForContentPolicy) in DocumentLoader::responseReceived(), and a follow-up didFinishLoading() runs SubresourceLoader::didFinishLoading() through releaseResources(), which clears the loader's identifier, so WebResourceLoader never sends ContinueDidReceiveResponse and the load hangs. Re-serialize delivery, restoring the one-part-at-a-time semantics the legacy NSURLSession loader provided. didReceiveResponse() claims the pipeline via m_isProcessingResponse and wraps the completion handler so that it is released once the response is resolved, which for a main resource is when the WebProcess answers ContinueDidReceiveResponse. While the pipeline is claimed, every follow-up message is held in m_deferredMessages, and it is replayed in order once the response is released, stopping at the next response so it too waits. The state is tracked explicitly rather than derived from m_responseCompletionHandlers for two reasons. didReceiveResponse() can take asynchronous steps before appending the handler (processClearSiteDataHeader()), and nothing may be delivered in that window. It also resolves responses without appending anything at all: when a main resource is blocked by CSP frame-ancestors or X-Frame-Options, by COOP/COEP, by NetworkLoadChecker::validateResponse(), by content filtering, or is dropped for keepalive, it answers PolicyAction::Ignore having sent no DidReceiveResponse. Messages queued behind such a response are dropped rather than replayed, so that WebContent is never handed the body of a part the network process just blocked, nor a DidReceiveData with no preceding DidReceiveResponse. Deferred messages are likewise dropped with PolicyAction::Ignore on teardown so their completion handlers are still answered, and the queue is bounded so a WebProcess that never answers cannot grow the network process' memory without limit. This is a workaround for the CFNetwork bug, so it is gated on the new HAVE(BROKEN_MULTIPART_RESPONSE_FLOW_CONTROL), on by default on COCOA ports. A FIXME points at rdar://185073080 to turn it off on platforms that have the CFNetwork fix. Nothing outside multipart is affected: m_isProcessingResponse is false when those messages arrive for subresources and for single-response loads. No new tests, unskipped existing test. * LayoutTests/platform/mac-wk2/TestExpectations: * Source/WTF/wtf/PlatformHave.h: * Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp: (WebKit::NetworkResourceLoader::~NetworkResourceLoader): (WebKit::NetworkResourceLoader::convertToDownload): (WebKit::NetworkResourceLoader::didReceiveResponse): (WebKit::NetworkResourceLoader::didReceiveBuffer): (WebKit::NetworkResourceLoader::didFinishLoading): (WebKit::NetworkResourceLoader::didFailLoading): (WebKit::NetworkResourceLoader::continueDidReceiveResponse): (WebKit::NetworkResourceLoader::responseProcessingCompleted): (WebKit::NetworkResourceLoader::deliverDeferredMessages): (WebKit::NetworkResourceLoader::cancelDeferredMessages): (WebKit::NetworkResourceLoader::failDueToExcessiveDeferredMessages): * Source/WebKit/NetworkProcess/NetworkResourceLoader.h: Canonical link: https://commits.webkit.org/319418@main
… again https://bugs.webkit.org/show_bug.cgi?id=322054 rdar://185245662 Reviewed by Dan Hecht. Basically applying the similar optimization to 318347@main. Let's avoid lexing int32 value twice in the fast path. * Source/JavaScriptCore/runtime/LiteralParser.cpp: (JSC::reviverMode>::Lexer::lexNumber): Canonical link: https://commits.webkit.org/319419@main
https://bugs.webkit.org/show_bug.cgi?id=322048 rdar://185243612 Reviewed by Sosuke Suzuki. This patch introduces deferred Array materialization mechanism in JSON.parse. Instead of placing an element each time, we push it to the stack, and we materialize Array at the end of Array literal. This stack is used for arrays nested way, so when materializing, we use the slice between [stackBase, end). This avoids growing and reallocating butterflies, which reduces wasted allocation during JSON.parse. Also we do drive-by fixes, 1. MarkedVector::append ends up calling slowAppend after it gets mallocBase(). This is inefficient and not correct. We should do it only when (1) expanding capacity or (2) newly registering a m_markSet. 2. Accessing outOfLineCapacity requires some additional loads. But we do not need to care about it when offset is not reaching to firstOutOfLineOffset. Let's avoid loading them. Test: JSTests/stress/json-parse-array-materialization.js * JSTests/stress/json-parse-array-materialization.js: Added. (shouldBe): (shouldThrow): (Array.isArray): * Source/JavaScriptCore/runtime/LiteralParser.cpp: (JSC::reviverMode>::materializeArray): (JSC::requires): * Source/JavaScriptCore/runtime/LiteralParser.h: * Source/JavaScriptCore/runtime/MarkedVector.h: (JSC::MarkedVector::append): Canonical link: https://commits.webkit.org/319420@main
…k per spec https://bugs.webkit.org/show_bug.cgi?id=313736 rdar://182678875 Reviewed by Pascoe. A credential request's promise is now settled from a queued task, as the spec requires. It used to settle straight away, or from inside the picker's dismissal callback. The promise, the abort signal and the abort algorithm also move off the per-page coordinator and onto a new DigitalCredentialsSession, which belongs to the document that asked for the credential. The coordinator said it was an ActiveDOMObject, but it is created before the main frame has a document, so it was never really registered as one. That meant nothing told it when a document was stopped or suspended, which is why get-non-fully-active.https.html kept failing (webkit.org/b/317884). Its mac-wk2 and ios expectations are removed. When the picker returns an answer we no longer ask it to dismiss, because it dismisses itself in the same call. The abort path still asks it to, since nothing there guarantees the picker is gone before the promise settles. There is no test for a document that is suspended and then destroyed. This also stops the picker reporting a good response twice. Canonical link: https://commits.webkit.org/319421@main
https://bugs.webkit.org/show_bug.cgi?id=322002 Reviewed by Darin Adler. Fixes crash that happens when a StyleSingleAnimationRange's offset is a calc value and the Animation.rangeStart or Animation.rangeEnd getters are called. The code was unconditionally accessing the result of tryPercentage() which returns std::nullopt in the calc case. To fix this, we use the switchOn form to ensure all alternatives are handled. Test: fast/animation/css-animation-range-calc-crash.html * LayoutTests/fast/animation/css-animation-range-calc-crash-expected.txt: Added. * LayoutTests/fast/animation/css-animation-range-calc-crash.html: Added. * Source/WebCore/style/values/animations/StyleSingleAnimationRange.cpp: Canonical link: https://commits.webkit.org/319422@main
…undaries (to reduce false positives when redacting PII) https://bugs.webkit.org/show_bug.cgi?id=322061 rdar://185254024 Reviewed by Abrar Rahman Protyasha. Adjust the string replacement heuristics for text extractions, such that it only redacts text if it spans word boundaries, in order to limit false positives (which may actually cause us to indirectly and unintentionally leak information, which the agent would not have otherwise observed). Test: TextExtractionTests.ReplacementStringsWordBoundaries * Source/WebKit/Shared/TextExtractionToStringConversion.cpp: (WebKit::isWordCharacter): (WebKit::anchorsToWordBoundary): (WebKit::matchIsWordBounded): (WebKit::applyReplacements): * Tools/TestWebKitAPI/Tests/WebKit/WKWebView/TextExtractionTests.mm: (TestWebKitAPI::TEST(TextExtractionTests, ReplacementStringsWordBoundaries)): Canonical link: https://commits.webkit.org/319423@main
…credentials https://bugs.webkit.org/show_bug.cgi?id=322068 Reviewed by Michael Catanzaro. nce an authentication challenge has been answered for a host, libsoup's SoupAuthManager stamps the cached credentials onto every later request in that protection space, replacing an Authorization header the page had set itself. The Fetch standard uses the cached credential only "If httpRequest's header list does not contain `Authorization`", and the Cocoa and curl ports already behave that way. Set SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE, libsoup's per-message opt-out, when the request already carries an Authorization header. A challenge still reaches the authentication handler and the retry authenticates as before. Test: Tools/TestWebKitAPI/Tests/WebKit/WKWebView/glib/TestAuthentication.cpp * Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp: (WebKit::NetworkDataTaskSoup::createRequest): * Tools/TestWebKitAPI/Tests/WebKit/WKWebView/glib/TestAuthentication.cpp: (testWebViewAuthenticationPageProvidedAuthorizationHeader): (serverCallback): (beforeAll): Canonical link: https://commits.webkit.org/319424@main
https://bugs.webkit.org/show_bug.cgi?id=322231 rdar://185461584 Reviewed by Ryosuke Niwa. A newly created page can run with the wrong hidden page throttling timer state: - If the page is created in a new WebProcess, then the initial state is incorrect, because we don't pass the hidden page throttling state as part of process creation. - If the page is created in an existing WebProcess, then the initial state is incorrect, because we don't store the last used hidden page throttling state anywhere and apply it to the newly created page. Fix this by adding hiddenPageDOMTimerThrottlingIncreaseLimit as a process creation parameter and also store it globally on the WebProcess side. This happens more when Site Isolation is enabled, since creating a new iframe while hidden will create a new process with potentially stale throttling flags. * LayoutTests/http/tests/site-isolation/hidden-page-dom-timer-throttling-limit-expected.txt: Added. * LayoutTests/http/tests/site-isolation/hidden-page-dom-timer-throttling-limit.html: Added. * LayoutTests/http/tests/site-isolation/resources/dom-timer-throttling-state-frame.html: Added. * Source/WebCore/page/Page.h: (WebCore::Page::domTimerAlignmentIntervalIncreaseLimit const): * Source/WebCore/testing/Internals.cpp: (WebCore::Internals::domTimerAlignmentInterval const): (WebCore::Internals::domTimerAlignmentIntervalIncreaseLimit const): * Source/WebCore/testing/Internals.h: * Source/WebCore/testing/Internals.idl: * Source/WebKit/Shared/WebProcessCreationParameters.h: * Source/WebKit/Shared/WebProcessCreationParameters.serialization.in: * Source/WebKit/UIProcess/WebProcessPool.cpp: (WebKit::WebProcessPool::initializeNewWebProcess): (WebKit::WebProcessPool::updateHiddenPageThrottlingAutoIncreaseLimit): * Source/WebKit/UIProcess/WebProcessPool.h: * Source/WebKit/WebProcess/WebProcess.cpp: (WebKit::WebProcess::initializeWebProcess): (WebKit::WebProcess::createWebPage): (WebKit::WebProcess::setHiddenPageDOMTimerThrottlingIncreaseLimit): * Source/WebKit/WebProcess/WebProcess.h: Canonical link: https://commits.webkit.org/319630@main
…ase enum values. https://bugs.webkit.org/show_bug.cgi?id=322307 rdar://185544976 Reviewed by Tim Nguyen. The values of GridLanesLayout::Phase repeated the name of the enum itself (LayoutPhase, MinContentPhase, MaxContentPhase). Drop the redundant suffix so the values read as Phase::Layout, Phase::MinContent and Phase::MaxContent. No change in behavior. * Source/WebCore/rendering/GridLanesLayout.cpp: (WebCore::GridLanesLayout::calculateGridLanesIntrinsicLogicalWidth): (WebCore::GridLanesLayout::insertIntoGridAndLayoutItem): * Source/WebCore/rendering/GridLanesLayout.h: * Source/WebCore/rendering/RenderGrid.cpp: (WebCore::RenderGrid::layoutGridLanes): (WebCore::RenderGrid::computeIntrinsicLogicalWidths): Canonical link: https://commits.webkit.org/319631@main
… in inline layout https://bugs.webkit.org/show_bug.cgi?id=321473 <rdar://problem/185157814> Reviewed by Antti Koivisto. Marker content is inline content: what it measures, where it sits on the line and how bidi orders it are inline layout's answers to give. Every kind of marker goes through it except a disc, circle or square, which the marker measures and paints itself from the font metrics, into a box it sizes for that purpose alone. So marker drawing exists twice, and the two have to be kept in step. It is also what stands in the way of making an inside marker an inline box, which is where this is going: an inline box has no box of its own to paint into, so anything the marker draws for itself has nowhere to go. A list-style-image that fails to load now rebuilds the marker rather than relaying it out. It falls back to its list-style-type, and that text needs renderers the marker was not built with. Nothing about the element's style changed, and a pseudo-element list item is only revisited through its host (RenderTreeUpdater::updateAfterDescendants), so imageChanged() invalidates the host's renderers instead of the element's style. * Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp: (WebCore::Layout::TextUtil::width): * Source/WebCore/layout/integration/LayoutIntegrationBoxTreeUpdater.cpp: (WebCore::LayoutIntegration::markerTextSynthesizesGlyph): (WebCore::LayoutIntegration::BoxTreeUpdater::createLayoutBox): (WebCore::LayoutIntegration::updateContentCharacteristic): (WebCore::LayoutIntegration::BoxTreeUpdater::updateContent): * Source/WebCore/layout/layouttree/LayoutInlineTextBox.h: (WebCore::Layout::InlineTextBox::hasSynthesizedGlyph const): * Source/WebCore/rendering/RenderListMarker.cpp: (WebCore::RenderListMarker::textNeedsBidiResolution const): (WebCore::RenderListMarker::needsContentContainer const): (WebCore::RenderListMarker::paint): (WebCore::RenderListMarker::layoutContentContainer): (WebCore::RenderListMarker::imageChanged): (WebCore::RenderListMarker::updateContent): (WebCore::RenderListMarker::updateContentContainerText): (WebCore::RenderListMarker::computeIntrinsicLogicalWidthContributions): (WebCore::RenderListMarker::updateInlineMargins): (WebCore::RenderListMarker::relativeMarkerRect): (WebCore::RenderListMarker::synthesizesGlyph const): (WebCore::RenderListMarker::drawsBulletShape const): Deleted. * Source/WebCore/rendering/RenderListMarker.h: * Source/WebCore/rendering/RenderTreeAsText.cpp: (WebCore::write): * Source/WebCore/rendering/TextBoxPainter.cpp: (WebCore::TextBoxPainter::paint): (WebCore::TextBoxPainter::hasSynthesizedGlyph const): (WebCore::TextBoxPainter::paintSynthesizedGlyph): * Source/WebCore/rendering/TextBoxPainter.h: Canonical link: https://commits.webkit.org/319632@main
…e/aria-owns-id-change.html (layout-tests) is a constant Timeout. https://bugs.webkit.org/show_bug.cgi?id=322313 rdar://185553044 Unreviewed test gardening. * LayoutTests/platform/mac/TestExpectations: Canonical link: https://commits.webkit.org/319633@main
https://bugs.webkit.org/show_bug.cgi?id=322303 rdar://185541345 Reviewed by Dan Hecht. We found that WasmWorklist's PriorityQueue's ordering is opposite and not correct. The reason is that PriorityQueue and std::priority_queue's comparator is opposite and when changing std::priority_queue to PriorityQueue, we didn't change the comparator. But this is error-prone. This patch fixes that issue and also change PriorityQueue's comparator to align it to std::priority_queue's one. So by default, taking std::less, and populating the greatest value first. Doing the same in PriorityQueue. Test: Tools/TestWebKitAPI/Tests/WTF/PriorityQueue.cpp * Source/JavaScriptCore/b3/air/AirAllocateRegistersByGreedy.cpp: (JSC::B3::Air::Greedy::TmpPriority::operator<): (JSC::B3::Air::Greedy::TmpPriority::isHigherPriority): Deleted. * Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp: (JSC::DFG::InliningCandidateIsLowerPriority::operator() const): (JSC::DFG::InliningPlan::build): (JSC::DFG::isHigherPriorityInliningCandidate): Deleted. * Source/JavaScriptCore/wasm/WasmInliningDecision.cpp: (JSC::Wasm::InliningNodeIsLowerPriority::operator() const): (JSC::Wasm::InliningDecision::expand): (JSC::Wasm::isHigherPriority): Deleted. * Source/JavaScriptCore/wasm/WasmWorklist.cpp: (JSC::Wasm::Worklist::completePlanSynchronously): * Source/JavaScriptCore/wasm/WasmWorklist.h: (JSC::Wasm::Worklist::QueueElementIsLowerPriority::operator() const): (JSC::Wasm::Worklist::isHigherPriority): Deleted. * Source/WTF/wtf/MathExtras.h: (isLessThan): Deleted. (isLessThanEqual): Deleted. (isGreaterThan): Deleted. (isGreaterThanEqual): Deleted. * Source/WTF/wtf/PriorityQueue.h: * Source/WebCore/loader/ResourceMonitorThrottler.h: * Source/WebCore/page/ImageAnalysisQueue.h: (WebCore::ImageAnalysisQueue::firstIsHigherPriority): Deleted. * Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.cpp: (WebKit::NetworkCache::Storage::ReadOperationIsLowerPriority::operator() const): (WebKit::NetworkCache::Storage::isHigherPriority): Deleted. * Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.h: * Tools/TestWebKitAPI/Tests/WTF/PriorityQueue.cpp: (enqueue): (dequeue): (TEST(WTF_PriorityQueue, Basic)): (TEST(WTF_PriorityQueue, ReversedComparator)): (MoveOnlyIsLessThan::operator() const): (MoveOnlyIsGreaterThan::operator() const): (TEST(WTF_PriorityQueue, MoveOnly)): (TEST(WTF_PriorityQueue, DecreaseKey)): (TEST(WTF_PriorityQueue, IncreaseKey)): (TEST(WTF_PriorityQueue, IncreaseKeyWithAReversedComparator)): (TEST(WTF_PriorityQueue, Iteration)): (TEST(WTF_PriorityQueue, EqualElementsAreAValidHeap)): (ReversibleComparator::operator() const): (TEST(WTF_PriorityQueue, IsValidHeapDetectsAGreaterChild)): (PrioritizedTaskIsLowerPriority::operator() const): (TEST(WTF_PriorityQueue, IncreaseKeyMovesTowardsTheFront)): (TEST(WTF_PriorityQueue, RandomActions)): (isHigherPriority): Deleted. (TEST(WTF_PriorityQueue, CustomPriorityFunction)): Deleted. Canonical link: https://commits.webkit.org/319634@main
…roke https://bugs.webkit.org/show_bug.cgi?id=322250 rdar://185485580 Reviewed by Simon Fraser. PathOrShapeGradientApplier bracketed each gradient apply in its own context->save()/restore() pair, costing two IPC messages per gradient-filled shape paint when rendering in the GPU process. The pair has been vestigial since 32921@main moved the CTM mutations it was originally added for into the gradient's own space transform. Remove it. All callers already bracket the apply/postApply sequence in an outer GraphicsContextStateSaver, and LegacyRenderSVGResourceSolidColor has never restored this state either, so gradient paint now behaves like solid-color paint. Worth ~2.5% on MotionMark 1.3 Suits. * Source/WebCore/rendering/svg/legacy/LegacyRenderSVGResourceGradient.cpp: (WebCore::PathOrShapeGradientApplier::applyResource): (WebCore::PathOrShapeGradientApplier::postApplyResource): Canonical link: https://commits.webkit.org/319635@main
https://bugs.webkit.org/show_bug.cgi?id=322259 rdar://185490398 Reviewed by Kimmo Kinnunen. Timeout's constructor eagerly computes ApproximateTime::now() + delta, but StreamClientConnection::send() only consults the deadline if tryAcquire() has to block, which is rare since the ring buffer normally has room. The cost was paid on every message, and showed up in MotionMark 1.3 Suits profiles where IPC accounted for ~22% of samples. Add StreamClientConnectionBuffer::acquireNoWait() for the non-blocking case and try it first when the destination ID is unchanged, falling back to the existing Timeout-based path otherwise. Skipping trySendDestinationIDIfNeeded() on that fast path is equivalent to the early return it would have taken, since m_currentDestinationID is only assigned after the SetStreamDestinationID message has been released. Timeout keeps its by-value semantics, so the shared budget across trySendDestinationIDIfNeeded() + tryAcquire() is unaffected. * Source/WebKit/Platform/IPC/StreamClientConnection.h: (IPC::StreamClientConnection::send): * Source/WebKit/Platform/IPC/StreamClientConnectionBuffer.h: (IPC::StreamClientConnectionBuffer::acquireNoWait): Canonical link: https://commits.webkit.org/319636@main
https://bugs.webkit.org/show_bug.cgi?id=255434 rdar://108030923 Reviewed by Alan Baradlay. Now that margin-trim only applies to block containers, RenderBlockFlow is the only renderer that can trim one of its children's margins. The machinery for it does not need to sit on RenderBox anymore, where every other layout system can see it. To help cleanup the code a bit and make the responsibility clear we can move most of the code that lives in RenderBox into RenderBlockFlow. * Source/WebCore/rendering/RenderBox.cpp: (WebCore::RenderBox::computeLogicalWidth const): (WebCore::RenderBox::computeOrTrimInlineMargin const): Deleted. Instead of having a "compute or trim," function let's just replace it with the code inline since it's really only used in one place. Canonical link: https://commits.webkit.org/319637@main
https://bugs.webkit.org/show_bug.cgi?id=322240 rdar://181259623 Reviewed by Sihui Liu. This can happen when a LocalFrame is trying to access its RemoteFrame parent, as the RemoteFrame is being destroyed -- for example in response to the message WebPage::frameWasRemovedInAnotherProcess. Fix this by by calling detachFromParent on all the children in FrameTree::~FrameTree(). No new tests, since reproducing this issue depends on having an extension installed in Safari. * Source/WebCore/page/FrameTree.cpp: (WebCore::FrameTree::~FrameTree): Canonical link: https://commits.webkit.org/319638@main
https://bugs.webkit.org/show_bug.cgi?id=322300 Reviewed by Sihui Liu. Always enable UseUIProcessForBackForwardItemLoading in the test. * LayoutTests/fast/events/suspend-timers.html: Canonical link: https://commits.webkit.org/319639@main
…cus is inside the dialog or it was modal https://bugs.webkit.org/show_bug.cgi?id=322310 rdar://185549474 Reviewed by Tim Nguyen. The close the dialog steps gate the focus restore [1]: If subject's node document's focused area of the document's DOM anchor is a shadow-including inclusive descendant of subject, or wasModal is true, then run the focusing steps for element; the viewport should not be scrolled by doing this step. We ran that unconditionally, so closing a non-modal dialog yanked focus back even when the author had moved it elsewhere. The stray focus change is observable: it fires focusin, letting a listener re-enter the dialog's own state machine. Capture wasModal after removing the open attribute, matching the spec's step order, and gate on it. The check uses the composed tree, not the shadow-including tree: a node slotted into a dialog inside a shadow root is not a shadow-including descendant, yet focus restore is expected for it. See whatwg/html#8904 [2], cited by dialog-focus-previous-outside.html for that case. This removes the FIXME from 319173@main and fixes the bug by handling focus properly. [1] https://html.spec.whatwg.org/multipage/interactive-elements.html#close-the-dialog [2] whatwg/html#8904 * LayoutTests/imported/w3c/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby-corner-cases-expected.txt: Progression * LayoutTests/imported/w3c/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-focus-previous-outside-expected.txt: Ditto * Source/WebCore/html/HTMLDialogElement.cpp: (WebCore::HTMLDialogElement::close): Canonical link: https://commits.webkit.org/319640@main
…deBlock Upstream 3d0e6c1 moved the parse results (features, line count, end column, the source URL directives) from UnlinkedCodeBlock to UnlinkedGlobalCodeBlock. Both callers pass a program or module code block.
|
Caution Review failedAn error occurred during the review process. Please try again later. Comment |
Upstream 9a18171 replaced linux/RealTimeThreads.cpp with linux/HighPriorityThreads.cpp. The fork's Android source list still named the removed file.
There was a problem hiding this comment.
Thanks — 6281729 fixes the Android PlatformJSCOnly.cmake entry (now builds linux/HighPriorityThreads.cpp), and this pass found no further issues.
Given the scope — a 387-commit upstream merge with hand-resolved conflicts across YarrJIT, URLParser, Atomics.wait termination, the module loader, CodeCache/CachedTypes, and ThreadingPOSIX — a human review of the conflict resolutions is still warranted.
What was reviewed:
- Confirmed the ANDROID branch of
PlatformJSCOnly.cmakenow listsHighPriorityThreads.cppandRealTimeThreads.cppis gone from the tree. - Re-checked the other fork-only build lists for stale references to files this merge deletes/renames — none found.
- Spot-checked the
recordParseFromUnlinkedCodeBlockfollow-up (d7ff6be) against theUnlinkedGlobalCodeBlocksplit from3d0e6c14b1.
Extended reasoning...
Overview
This PR merges upstream WebKit baf4a9a7ec0b (387 commits, 82 touching JSC/WTF/bmalloc) into the Bun fork. Beyond the mechanical merge, it includes hand-resolved conflicts in yarr/YarrJIT.cpp, WTF/URLParser.{cpp,h}, WaiterListManager::waitSyncImpl (Atomics.wait termination, reconciling upstream 03e836de2f with the fork's #432), JSModuleLoader/JSMicrotask (dropping the fork's #262 in favor of upstream's f324cca020), CodeCache.cpp, CachedTypes.cpp (bitfield layout across the new CachedGlobalCodeBlock split), SyntheticModuleRecord, and ThreadingPOSIX.cpp (opting out of upstream's new Linux sched_setattr policy under USE(BUN_JSC_ADDITIONS)). It also removes @newPromiseCapability, requiring coordinated changes on the Bun side. Two follow-up commits landed after the merge: d7ff6bea27 (adapting recordParseFromUnlinkedCodeBlock to the UnlinkedGlobalCodeBlock split) and 6281729b4e (the Android CMake fix from my previous review).
Previous review resolved
My prior review flagged that the fork-only elseif (ANDROID) branch in Source/WTF/wtf/PlatformJSCOnly.cmake still listed the deleted linux/RealTimeThreads.cpp. Commit 6281729b4e renames it to linux/HighPriorityThreads.cpp, which I've verified at HEAD (line 127). The bug hunting system found no further issues this pass.
Security risks
No new attack surface is introduced by the merge mechanics themselves; the upstream commits are already public and reviewed. The hand-resolved conflicts do touch security-adjacent code (Yarr JIT codegen, CachedTypes serialized layout, module loader error handling), where a mis-merge could introduce memory-safety or cache-poisoning issues — which is precisely why these resolutions need human eyes rather than automated sign-off.
Level of scrutiny
High. This is not a mechanical change: each conflict resolution in the description encodes a judgment call (keep fork, take upstream, or blend), several of which the description explicitly flags for the reviewer ("Drop that hunk if following upstream is preferred" for the ThreadingPOSIX scheduling opt-out; the #262 drop with a repro-based justification). The bytecode cache layout change (CachedCodeBlock/CachedGlobalCodeBlock split with the fork's MSVC-portable bitfields) and the WaiterListManager reconciliation are correctness-critical and non-obvious.
Other factors
The author reports a debug+ASAN build passes, the new upstream regexp tests pass in both JIT and interpreter mode, and Bun links against the tree — good signal, but not a substitute for reviewing the conflict hunks. The PR description is unusually thorough and makes a human review tractable; it also documents an explicit policy question (Linux thread scheduling opt-out) that a maintainer should decide on. Given all of this, deferring to a human reviewer is the right call even with zero automated findings.
Preview Builds
|
Points WEBKIT_VERSION at the oven-sh/WebKit#488 preview build, which merges upstream WebKit main at baf4a9a7ec0b into the fork (387 commits since the previous merge base 47f7250137c6, 82 of them in JavaScriptCore, WTF or bmalloc) and includes the fork's commits since b7f217b4a6.
There was a problem hiding this comment.
Thanks for the fix in 6281729 — the ANDROID branch of PlatformJSCOnly.cmake now lists linux/HighPriorityThreads.cpp, so the Android CI configure will succeed. I re-reviewed after that commit and the origin/main merge and didn't find further issues. Given the scope — a 387-commit upstream merge with hand-resolved conflicts in YarrJIT, Atomics.wait termination, the module loader, CachedTypes layout, and Linux thread scheduling — a human pass over the conflict resolutions is still worthwhile.
Checked on this pass: the ThreadingPOSIX.cpp USE(BUN_JSC_ADDITIONS) guard around updateSchedulingAttributes is intact; the waitSyncImpl merge keeps the fork's under-lock termination delivery with upstream's throwTerminationExceptionIfNeeded() at the callers; the CachedCodeBlock bitfield-width changes for #141 portable layout are preserved after fields moved to CachedGlobalCodeBlock; and recordParseFromUnlinkedCodeBlock's signature change to UnlinkedGlobalCodeBlock* is consistent with the moved accessors.
Extended reasoning...
Overview
This PR merges upstream WebKit baf4a9a7ec0b (387 commits, 82 touching JSC/WTF/bmalloc) into Bun's fork, plus a follow-up merge of origin/main (d0fae3b) to pick up #330, #450, #491. It touches 300+ files across JSC runtime, DFG/FTL, Yarr JIT, Wasm, WTF threading, the module loader, bytecode cache serialization, and a large volume of tests/LayoutTests. The PR description documents each conflict resolution and per-commit API/behavior notes in detail.
The one issue flagged in my previous review — the fork-only elseif (ANDROID) branch in PlatformJSCOnly.cmake still listing the deleted linux/RealTimeThreads.cpp — was fixed in 6281729 and verified at HEAD (line 127 now reads linux/HighPriorityThreads.cpp). That inline thread is resolved.
Security risks
Several conflict-resolved areas are security-relevant: yarr/YarrJIT.cpp (regex JIT codegen, kept at the fork's version per #299 policy), CachedTypes.cpp (bytecode cache deserialization layout), Wasm bounds-check/signal-handler changes, and AtomicsObject termination handling. These are upstream-authored changes plus fork-side merge resolutions; nothing in the diff or the bug-hunt pass surfaced a concrete issue, but the attack surface is exactly the kind that merits a human maintainer confirming the resolutions match intent.
Level of scrutiny
High. This is not a mechanical change: it is a large upstream merge with ~10 hand-resolved conflicts in core engine paths (JIT, GC-adjacent cache invalidation, module loader semantics, thread scheduling policy), several of which the PR author explicitly flags as judgment calls (e.g., the Linux sched_setattr no-op under USE(BUN_JSC_ADDITIONS), dropping the fork's #262 in favor of upstream's fetch-failure eviction). An automated review cannot substitute for a maintainer signing off on those policy choices.
Other factors
The PR description includes verification (debug+ASAN build, 928 regexp/string/yarr stress runs, Bun link + test suites, Atomics.wait worker-terminate check), and CI preview builds were published for 6281729. The author addressed my prior finding promptly. No outstanding unaddressed reviewer comments. Still, per the approval guidelines — large, complex, touches critical code paths, contains design/policy decisions — this should not be auto-approved.
|
Superseded by #501. That PR merges this branch's head (d0fae3b, with its conflict resolutions and review fixes) and then upstream main at 55d9d90 on top of the fork's current main. This branch conflicts with main since the bytecode cache work (#490, #493, #494, #497) landed; the CachedTypes.cpp resolution is described in #501. Closing as a duplicate. |
### Problem - Bun's WebKit pin `aea1f010b6` is 412 upstream commits behind `8c4fd56347`, 90 of them in JavaScriptCore, WTF or bmalloc. oven-sh/WebKit#503 merges that range into the fork. - Upstream removed the `@newPromiseCapability` private builtin (`38027ff0ec`). Six call sites in Bun's bundled modules use it, so `node:events`, `node:util`, `node:dgram` and the HTTP server fail to load (`Private symbol not found: newPromiseCapability`). - #40263 and oven-sh/WebKit#501 were a parallel attempt at `55d9d9007f`, one WebCore-only commit ahead. Both are closed in favor of this pair. ### Fix - oven-sh/WebKit#503 is merged. `WEBKIT_VERSION` is `cb61607f1a4bae79d7701965062634dee9efb349`, its merge commit on the fork's main (release `autobuild-cb61607f1a4bae79d7701965062634dee9efb349`, 42 tarballs). That commit is the preview build this PR was tested against (`d2654c3b`) plus oven-sh/WebKit `a0a80b2276` (an optional depth bound on `recursivelyGenerateUnlinkedCodeBlockForProgram/ForModuleProgram`). - The six call sites create their promise with `$newPromise()` and settle it with `$resolvePromise` / `$rejectPromise`, or the `...WithFirstResolvingFunctionCallCheck` variants where a second settle is possible. `builtins.d.ts` follows. - `EncodeURIComponent.cpp` includes `<wtf/HexNumber.h>` itself (upstream `314133b7a6` no longer does). - Verified: `test/js/bun/jsc/webkit-upgrade-8c4fd56347.test.ts` pins four JavaScript-visible engine changes that fail at the current pin. The events, util and dgram tests cover the ported settlement paths. ### Background - Bun links a prebuilt JavaScriptCore from oven-sh/WebKit releases. `scripts/build/deps/webkit.ts` names the release tag. - Built-in modules (`src/js/`) go through JavaScriptCore's builtin compiler. A `$name` call becomes the private name `@name`, which has to exist in the engine. - `$newPromise` creates a pending promise. `$resolvePromise` / `$rejectPromise` settle it and require it to be pending. The `...WithFirstResolvingFunctionCallCheck` variants ignore calls after the first, like a Promise executor's functions. <details><summary>Notes</summary> - Duplicate resolution: oven-sh/WebKit#501 and #503 have the same structure (main at `62f427b86f`, then #488's head `d0fae3b3c9`, then upstream/main) and the same `CachedTypes.cpp` resolution (the two files differ in comments and an unused alias). WTF and bmalloc are identical. The only upstream difference is WebCore's `55d9d9007f` (`MediaElementAudioSourceNode` use-after-free), which the JSCOnly port does not compile. #503 was kept because this PR's CI run was green (Build #104490). The test file `webkit-upgrade-8c4fd56347.test.ts` is carried over from #40263. - oven-sh/WebKit#488 (upstream `baf4a9a7ec0b`) stopped merging after the fork's bytecode cache rework (#490, #493, #494, #497). The per-commit review of the upstream range (API and ABI changes, behavior changes, performance) and the conflict resolutions are in oven-sh/WebKit#503. The new conflict in this round is `CachedTypes.cpp`: the fork's new code block record layout against upstream moving the global-only fields (`features`, `lineCount`, source URL directives) to `UnlinkedGlobalCodeBlock` and deleting `m_jumpTargets`. - The ported call sites (the changes of #40054, carried over): `node:events` (`once`), `node:util` (`aborted`), `node:dgram` (`Symbol.asyncDispose`) and the HTTP server (CONNECT, Upgrade, the per-request completion promise). `builtins.d.ts` declares `$newPromise`, `$resolvePromiseWithFirstResolvingFunctionCallCheck` and `$rejectPromiseWithFirstResolvingFunctionCallCheck` and drops `$newPromiseCapability`. `@newPromise` is a bytecode intrinsic and `@resolvePromise` / `@rejectPromise` are link-time constants, so they exist in every engine build. `util.aborted` registers and unregisters its `FinalizationRegistry` entry with the same token (the promise). - Behavior changes in the upstream range that are visible from JavaScript: `Promise.try` follows the updated spec (`PromiseResolve` instead of `NewPromiseCapability`); the module map no longer caches fetch failures, so a second `import()` of a specifier whose load failed re-runs Bun's module loader instead of rejecting with the cached error; `Uint8Array.prototype.setFromBase64` on a zero-length target returns `{ read: 0, written: 0 }` without validating the input; `WebAssembly.Module.imports()/exports()` descriptors drop the non-standard `type` field; re-exported imported Wasm globals and tags keep object identity; a DFG `++`/`--` on an `int32` that overflows with an unused result now deoptimizes instead of wrapping (`7711916200`). The first, third, fourth and last of these are pinned by `test/js/bun/jsc/webkit-upgrade-8c4fd56347.test.ts`. - Performance changes of note: `SymbolTableEntry` no longer allocates a `WatchpointSet` per watched variable until the DFG watches it (`cea233cede`); `Object.assign` with several sources clones the first one through `objectCloneFast` (`96ca975b2a`); `JSON.parse` allocates arrays once at their final size; `TypedArray.prototype.sort()` without a comparator uses a radix sort for 2/4/8-byte element types; `Map`/`Set` `forEach` is inlined in the DFG and FTL; `RegExp` cells shrink from 96 to 80 bytes; `UnlinkedFunctionCodeBlock` shrinks from 216 to 192 bytes. - `src/jsc/bindings/NodeVMSyntheticModule.cpp` calls `SymbolTable::set(NoLockingNecessary, ...)`. After `cea233cede` only the locked overload exists. `NoLockingNecessary` converts to a `ConcurrentJSLocker`, so the call compiles unchanged. - The upstream change to Linux thread scheduling (per-QOS `sched_setattr` on every WTF thread, `SCHED_BATCH` compiler threads on hosts with 4 or fewer cores) is gated off for Bun in the fork: Bun's threads keep inheriting the process scheduling attributes. - Suites run on a local debug + ASAN build against the merged WebKit (`bun run build:local`): `test/js/bun/jsc`, `bun/jsc-stress` (116/116), `node/events`, `node/util`, `node/dgram`, `node/vm`, `node/module`, `bun/resolve`, `node/worker_threads`, `bun/wasm`, `web/url`, `web/atomics`, `node/http/node-http-connect`, `node/async_hooks`, `node/string_decoder`, `bundler/bundler_compile`, `bundler/bun-build-api`: 3,548 pass. The failures are 5 s timeouts under debug + ASAN, this machine's IPv6 multicast `ENODEV`, and one test that fails the same way at the current pin. `bun build --bytecode` output from that build loads and runs. A debug + ASAN build against the `autobuild-preview-pr-503-311eab61` prebuilt runs `test/js/bun/jsc/webkit-upgrade-8c4fd56347.test.ts`, `test/js/bun/jsc/webkit-upgrade-3722912f.test.ts`, `node/events/event-emitter.test.ts` and `node/util/test-aborted.test.ts`: 106 pass. - Every push to oven-sh/WebKit#503 produces a new preview tag (`autobuild-preview-pr-503-<first 8 of the head sha>`), and this PR's `WEBKIT_VERSION` follows it. CI lanes that fetch the prebuilt fail on the download until that tag's Actions run has published the release. - Rebase over #40201: Bun main moved its pin to the fork's `c148a12dd82b` and calls the bytecode APIs that release added (`EncoderStringTable`, persistent payloads). The `311eab61` preview predates them, so the branch could not rebase until oven-sh/WebKit#503 merged the fork's main (head `d2654c3b`, 0 commits behind). The rebase itself conflicted only on the `WEBKIT_VERSION` line. A debug + ASAN build against `autobuild-preview-pr-503-d2654c3b` passes `webkit-upgrade-8c4fd56347.test.ts`, `node/events/event-emitter.test.ts`, `node/util/test-aborted.test.ts`, `node/dgram` (except the IPv6 multicast `ENODEV` of this machine), `node/http/node-http-connect.test.ts`, `web/atomics`, `web/url`, `node/string_decoder` and `test/js/bun/jsc`. The compiled-executable bytecode paths of #40201 work against it: the aliasing run keeps 12 MB of instruction streams out of anonymous memory and 45 internal modules load from embedded bytecode. The failures on this machine are the DOMJIT hot loops and two `bun-build-compile` tests that exceed their timeouts under debug + ASAN (the compile alone takes 5 to 47 s here), and the nested `node-http-connect.node.mts` run that takes 5.0 s against a 5 s limit. - The `$newPromiseCapability` call in `src/node-fallbacks/events.js` (the browser polyfill, not a JSC builtin) is a pre-existing bug and was reported separately by #40054. </details> <!-- robobun:evidence:begin --> --- **no test proof** · iteration 2 · platform-specific test(s) that do not run on this machine, deferring to CI, which covers all platforms: test/js/node/dgram/node-dgram.test.js <!-- robobun:evidence:end -->
Merges upstream WebKit main at
baf4a9a7ec0b(2026-08-22): 387 commits since the previous merge base47f7250137c6(2026-08-16), 82 of them touching JavaScriptCore, WTF or bmalloc.#455 was squash-merged, so the fork's history no longer contains the upstream commits it merged and
git merge-base origin/main upstream/mainreports the older3722912ff800. The merge was done with the squash commit grafted as a merge of its PR parents (git replace --graft e462c38dd3 a2f8782020 47f7250137c6), which gives the correct base. This merge commit hasbaf4a9a7ec0bas its second parent, so the next upgrade does not need the graft as long as it lands as a merge commit rather than a squash.The fork's main moved while this PR was open (#330 DFG/FTL byte-offset accessors, #450 critical-collection headroom, #491 pending TerminationException in the microtask job). d0fae3b merges it in without conflicts; the 12
buffer-accessor-jit*.jstests pass on the merged debug build with--useDollarVM=1, and a Bun built from bun main (which needs #330) links and passes its Buffer suites against it.Conflict resolutions
yarr/YarrJIT.cpp: kept at the fork's version (Yarr: JIT lookbehinds, first-code-point alternation dispatch, Boyer-Moore and /u·/v spec alignment, RegExp correctness fixes #299 policy, same as Upgrade to upstream WebKit 47f7250137c6 #455). Upstream's01f04c4fb4(JIT lookbehinds that contain backreferences) restructures the backreference codegen that the fork already reworked for mirrored frames; the fork compiles these patterns already. Upstream's three new tests (regexp-lookbehind-jit-backreferences.js,regexp-lookbehind-jit-backreferences-unicode.js,regexp-backreference-greedy-non-bmp-capture-restore-pos.js) pass on this build in JIT and--useRegExpJIT=falsemode.2165451fd3(interpretertryConsumeBackReferenceposition restore) was already in the fork.de9231d86e(FixedVectorovector) merged cleanly.WTF/URLParser.cppand.h: kept at the fork's version. Upstream'seb44b6cfaaSIMD-scans path, query, fragment and opaque-path runs, which the fork's URLParser rewrite (0cbb4a1946,c6cfe90c60,eeab04040f) already does with its own table-driven scanners. Upstream'sCodePointIterator::span()/advanceBy()additions and the two new TestWebKitAPI cases are in.03e836de2fvs the fork's [JSC] Atomics.wait / memory.atomic.wait: wake up for a termination requested from another thread #432):WaiterListManager::waitSyncImplkeeps the fork's version (termination wake-up delivered under the waiter list lock, deferred termination respected, trap consumed and the TerminationException thrown before returningTerminated). The two callers take upstream'svm.throwTerminationExceptionIfNeeded(), which is a no-op when the exception is already pending.throwWasmToJSException's early-out for a pending TerminationException is in.f324cca020): upstream no longer registers a module entry for a fetch failure and evicts aFetchFailedentry on the nextloadModule. The fork's ModuleLoader: record a non-Error fetch rejection as a fetch failure #262 (setFetchErrorfor a non-ErrorInstancefetch rejection inmoduleLoadTopSettled) is dropped: that path no longer registers anything for any fetch failure, so the poisonedEvaluationFailedentry ModuleLoader: record a non-Error fetch rejection as a fetch failure #262 fixed cannot be created. Verified ModuleLoader: record a non-Error fetch rejection as a fetch failure #262's repro (import a file with a parse error, then import a file that statically imports it) completes on a Bun built against this tree.JSModuleLoader.h/.cpp: both sides' additions kept (removeFailedFetchEntry, publicgetRegisteredMayBeNull, the fork'sregistryEntry/removeEntry/clearAll/loadModuleSync).CodeCache.cpp: upstream'sc823243598generatesCodeForConstructfor class constructors viaUnlinkedFunctionExecutable::isClassConstructorFunction(). The fork's "NOTE: We changed this in Bun" loop calledisConstructor()on theUnlinkedFunctionExecutable, which resolves toJSCell::isConstructor()and is always false for a non-object cell, so it never generated anything butCodeForCall. Upstream's version replaces it. The fork'srecordParseFromUnlinkedCodeBlocknow takes anUnlinkedGlobalCodeBlock*because3d0e6c14b1moved the parse results offUnlinkedCodeBlock(follow-up commit d7ff6be).CachedTypes.cpp:3d0e6c14b1movesm_features/m_lexicallyScopedFeaturesinto the newCachedGlobalCodeBlock; the fork'sunsigned : Nbitfields (fix: use unsigned bitfields for portable bytecode cache struct layout #141, portable layout across MSVC and Itanium) are kept for the fields that stay inCachedCodeBlock(m_parseMode,m_codeGenerationMode). The newCachedGlobalCodeBlockfields are plain (non-bitfield) members, which lay out the same on both ABIs.SyntheticModuleRecord:db2d849cbechangestryCreateWithExportNamesAndValuesto takeArgList; the fork's lazy-export overloads (SyntheticModuleRecord: exports whose values are produced on first binding #408) follow.MarkedArgumentBufferconverts implicitly.ThreadingPOSIX.cpp(9a18171a13, RT threads removed, per-QOSsched_setattron Linux): the fork's!USE(BUN_JSC_ADDITIONS)main-thread detection branch keeps its guard and takes the newThread(QOS, SchedulingPolicy, IsMain)constructor.Thread::updateSchedulingAttributesis a no-op underUSE(BUN_JSC_ADDITIONS)on Linux: upstream now resets every WTF thread toSCHED_OTHERnice 0 with a 100% utilization clamp and puts JIT/Wasm compiler threads onSCHED_BATCHnice 10 when the host has 4 or fewer cores. Bun's threads keep inheriting the process's scheduling policy, nice level and clamps, as they did before this merge. Drop that hunk if following upstream is preferred.RealTimeThreads.cppis deleted (the fork only added an include to it).Options.h,JSWebAssemblyInstance.h: upstream's new includes (OSCheck.h,WasmLimits.h,<wtf/BitSet.h>) added in the fork's quoted-include style.JSType.h,.github/workflowsand the release tarball names are unchanged.PromiseOperations.jsis gone upstream (see38027ff0ecbelow): Bun's six$newPromiseCapabilitycall sites move to$newPromise()plus$resolvePromise/$rejectPromise(or the...WithFirstResolvingFunctionCallCheckvariants) in the Bun PR.Verification
bun run jsc:build:debug(Linux x64, debug + ASAN): builds,jscshell runs.regexp*/string-*/yarr*stress tests (including the three regexp tests upstream added in this range), each in JIT and--useRegExpJIT=falsemode: 890 of 928 runs pass as-is. The rest: 4 files need--useDollarVM=1(pass with it), 2 need the--useRegExpBufferBoundariesoption the fork does not have (\A/\z, same as Upgrade to upstream WebKit 47f7250137c6 #455),regexp-unicode-code-unit-read-for-bmp-terms.jsis the Yarr: JIT lookbehinds, first-code-point alternation dispatch, Boyer-Moore and /u·/v spec alignment, RegExp correctness fixes #299 match-start behaviour documented in Upgrade to upstream WebKit 47f7250137c6 #455, 4 are//@ skipupstream (too-long-rope, memory hog), 1 needs the//@ runDefault(--watchdog)options (an infinite loop by design), 3 need ICU locale data the bundledlibicudataonly exposes through Bun's decompress hook (toLocaleString,localeCompare; they pass when run through Bun), and 2 exceed a 600 s limit under ASAN (string-substring-jit.js,string-iterator-surrogate-pairs.js: identical timings on the current pin and on this tree at a reduced loop count).bun run build:local: Bun links and runs against this tree. Bun'stest/js/bun/jsc,node/vm,node/module,bun/resolve,node/worker_threads,bun/wasm,node/util,node/events,node/dgram,web/url,web/atomics,node/http/node-http-connect,node/async_hooks,node/string_decodersuites: the only failures are 5-second-timeout tests, an IPv6 multicastENODEV, and a Valkey clientdebug_assertthat a Bun debug build on the current WebKit pin fails the same way on this (shared, debug + ASAN) machine.Atomics.waitterminates in under 100 ms onworker.terminate().Upstream changes
Each remaining commit appears once, under the most specific heading that applies. The 17 commits in the range whose only engine-side footprint is a WebCore/WebKit preference entry, a WTF build-file list change, or Cocoa/GTK/WPE-only code the JSCOnly port does not compile are omitted (
7d86b2c8a0,94f879afe6,2f072fbfec,3dfdbed8e4,86a8860a42,0c33544154,722d0b38a9,cc7a6821b7,d8ad5b5f9a,b66aab8e21,5e3cb10ac4,c2b3e55128,2dce2395a4,d27b7fd89e,6248fa7145,8bd2ba0d3e,f0a1fd2b32).API and ABI changes
cffd5ed032— [API][PERF]WTF::PriorityQueuenow followsstd::priority_queueconventions: the template takes a less-than functor type (defaultstd::less<T>, function pointers are rejected bystatic_assert) instead of anisHigherPriorityfunction pointer and serves the greatest element first; theisLessThan/isLessThanEqual/isGreaterThan/isGreaterThanEqualhelpers were removed fromwtf/MathExtras.h. This fixesWasm::Worklist, whose comparator was never flipped when it moved offstd::priority_queue(present in Bun's previous WebKit): compilation plans were served in reverse priority (Preparation before Compilation before Synchronous before Shutdown) and newest-first within a priority, andcompletePlanSynchronouslybumped the plan withdecreaseKeyinstead ofincreaseKey, so synchronousWebAssembly.Module/Instancecompiles could wait behind queued async work. DFG inlining, Wasm inlining and the greedy register allocator were adapted to the new convention with no change in ordering; Bun has no directPriorityQueueusage.9a18171a13— [API][PERF] Linux thread scheduling in WTF is reworked: theRealTimeThreads/SCHED_RRmachinery is removed (wtf/linux/RealTimeThreads.hrenamed toHighPriorityThreads.h, rtkit nice-boosting only underUSE(GLIB)), and everyWTF::Threadnow applies its QOS from its own entry point viasched_setattr: the defaultUserInitiatedQOS maps toSCHED_OTHER, nice 0 plusSCHED_FLAG_UTIL_CLAMP_MIN= 1024 (a 100% DVFS frequency floor, with automatic fallback on kernels that reject uclamp),Defaultgets a 20% floor,UtilitygetsSCHED_BATCH/nice 10 andBackgroundgetsSCHED_IDLE/nice 19. JIT and Wasm worklist threads now passcompilerThreadQOS(), which isUtilityon Linux hosts with <= 4 cores, so concurrent compilation is deprioritized on small machines/containers. API surface: the protectedThreadctor is nowThread(QOS, SchedulingPolicy, IsMain),AutomaticThreadgains aThreadQOSctor overload,Thread::qos()is added andisRealtime()is derived from the scheduling policy, andThreadingEnums.haddsThreadSchedulingState,defaultThreadQOS,defaultThreadSchedulingPolicy,compilerThreadQOS(); Darwin and Windows behaviour is unchanged.e1fdc80a34— [API]WTF::weekDay(int32_t days)inwtf/DateMath.his rewritten as a branchless unsigned multiply-and-shift (Ben Joffe's method) that is well-defined for the wholeint32_trange (the old(days + 4) % 7was signed overflow fordays > INT32_MAX - 4, unreachable from JS since day counts are clipped to +-1e8), and the unusedWTF::msToWeekDay(double)is removed.ISO8601::dayOfWeek(TemporalPlainDate/PlainDateTimedayOfWeek) drops its privateInt128copy of the modulo and usesdaysFromYearMonth+WTF::weekDay. Results are unchanged (upstream checked all 2^32 inputs); authored by Bun's Sosuke Suzuki.75a9d414a4— [API] (additive) Correctness fix forVM::deleteAllCode/Heap::deleteAllCodeBlocks: the VM-levelm_syncResumeCallCache(theMicrotaskCallCacheused to resume async functions/async generators from the microtask queue) lives outside anyVMEntryScopeand kept stale Executable->CodeBlock entry points after all code was detached, so a later resumption could call into a detached CodeBlock. AddsMicrotaskCall::clear(),MicrotaskCallCache::clear()and publicVM::clearMicrotaskCallCaches(), whichHeap::deleteAllCodeBlocksnow calls;CodeCache::clear()also now callswrite()first. Directly relevant to Bun, which callsvm.deleteAllCode(...)inWebWorker__teardownJSCVM,JSC__VM__deleteAllCode, and via the debugger'srecompileAllJSFunctionspath while async work may still be pending.3302d7a455— [PERF][API]SourceProviderCachenow pre-reserves itsm_maphash map from the source length (sourceLength / 512entries, capped at 64K) to avoid repeated rehash/realloc while a large script is parsed. The public default constructor is replaced by a privateexplicit SourceProviderCache(unsigned sourceLength)plusstatic Ref<SourceProviderCache> create(unsigned);VM::addSourceProviderCacheis updated. Bun only includes the header (src/jsc/modules/BunJSCModule.h) and never constructs one directly, so no Bun changes are needed.1450e69522— [API] WTFDequeIteratorandDequeConstIteratorgain defaulted default constructors (required by the C++20bidirectional_iteratorconcept, and by MSVC's STLstd::reverse_iterator, which value-initializes its stored iterator). Purely additive; Bun's manyWTF::Dequeuses (streams,JSBufferList, worker queues) are unaffected and this may help MSVC-STL builds that instantiateDeque::rbegin().f2d69489c6— Removes the unusedtryAllocateBufferhelper fromVectorBufferBase/VectorBufferinwtf/Vector.h;allocateBuffer<FailureAction::Report>remains for the same purpose. [API] Technically a public-header removal, but Bun'ssrc/has no references to it, so no action needed.03e836de2f— [BEHAVIOR] Fixes a thread blocked inAtomics.wait/ Wasmmemory.atomic.waitnever unblocking afterVM::notifyNeedTermination():WaiterListManager::waitSyncImplnow also observes the pendingNeedTerminationtrap (not justhasTerminationRequest()), dequeues the waiter and returnsTerminated, and the newVM::throwTerminationExceptionIfNeeded()materializes the TerminationException throughhandleTraps. This directly affects Bun, whoseVmHandle::request_termination(used byworker.terminate()) fires exactly that trap, so a worker parked inAtomics.waitnow terminates instead of hanging. [API] AddsVM::throwTerminationExceptionIfNeeded();throwWasmToJSExceptionnow early-outs whenever a TerminationException is already pending.88b46e6bc7— [API]wtf/BorrowedBytes.his deleted and replaced bywtf/EscapableByteSpan.h:BorrowedBytes/BorrowedSpanScope/BorrowedVectorScopeare gone, replaced by a stack-only, non-refcountedEscapableByteSpan(plusescapableSpan()helper andSpanUInt8/MutableSpanUInt8/VectorUInt8aliases) thatRELEASE_ASSERTs if a copy outlives the borrow. This is a Swift-interop type used only by PAL crypto on Cocoa; Bun has no references to either header, so no impact beyond the header rename inWTF_PUBLIC_HEADERS.f324cca020— [BEHAVIOR] [API] The module loader stops caching fetch failures:JSModuleLoader::loadModulenow evicts aFetchFailedregistry entry (newremoveFailedFetchEntry) and re-fetches instead of re-rejecting with a duplicated copy of the old error, and the top-level rejection paths inJSMicrotask.cppno longer callensureRegisteredjust to stash an error (evaluation errors are still cached;maybeDuplicateFetchErroris no longer used on that path). For Bun this means a secondimport()of a specifier whose fetch previously rejected (e.g. a missing file or failed loader) will invoke Bun's module-loader fetch hook again rather than rejecting immediately from the cache, so anything that relied on the cached rejection (tests, error identity) may see different behavior.JSModuleLoader::getRegisteredMayBeNullis also moved from private to public.905a225671— [API]wtf/UniStdExtras.his now wrapped in#if OS(UNIX), sosetCloseOnExec/unsetCloseOnExec/dupCloseOnExec/closeWithRetry/setNonBlockare no longer declared on Windows (done to keep the Windows Swift C++ importer happy). Only matters if the embedder includes that header on Windows; Bun's bindings do not reference it.76b474b322— [API] RefactorsJSC::Wasm::TypeKind: the type-section formsFunc,Struct,Array,Rec,Sub,Subfinalare removed fromTypeKindand moved to a new generatedWasm::DefinedTypeKindenum (withisValidDefinedTypeKind/makeString(DefinedTypeKind)), and the section parser dispatches on that. Pure cleanup that removes dummy switch cases; no behavior change. Bun does not reference these enumerators, so nothing to update.218421554b— [PERF] [API]JSON.parsenow buffers array elements on aMarkedArgumentBufferelement stack and allocates eachJSArrayonce at its final length and indexing type (Int32/Double/Contiguous) instead of growing the butterfly viaputDirectIndexper element; also skips two Structure loads foroutOfLineCapacitywhen a property offset is still inline. Drive-by change to the inlinedMarkedVector::appendfast path (stays inline once heap-allocated and registered with a mark set, rather than callingslowAppendon every append) and an additiveMarkedVector::shrink(size_t)— both are inlined into Bun's manyMarkedArgumentBufferusers, but no signature changes. Also speeds up Bun's nativeJSONParse/JSONParseWithExceptioncallers (JSON module loading,.json(), SQL client, etc.).6446fdc8e0— WebCore ISO-BMFF box serialization work; the only engine touch isJSC::DataView::get<T>()andDataView::read<T>()inruntime/DataView.hbecomingconstmember functions. [API] Source-compatible (header-only inline templates, only adds const), so no embedder action needed.38027ff0ec— Removes the@newPromiseCapabilityprivate builtin/link-time constant from JSC (builtins/BuiltinNames.h,bytecode/LinkTimeConstant.h, host function inruntime/JSGlobalObject.cpp), since upstream builtins now use@newPromise+@resolvePromiseWithFirstResolvingFunctionCallCheck/@rejectPromiseWithFirstResolvingFunctionCallCheck(no tuple object allocation, no property lookups). [API] After this upgrade@newPromiseCapabilityno longer resolves as a private name. Bun's bundled modules called$newPromiseCapability(Promise)insrc/js/node/dgram.ts,events.ts,_http_server.ts(3 sites) andutil.ts; the Bun PR rewrites them to$newPromise()plus the$resolvePromise/$rejectPromisefamily. Note the preceding upstream commit7f38ebbabfhad already deletedbuiltins/PromiseOperations.js(the JS implementation); the C++JSPromise::createNewPromiseCapability()used bysrc/jsc/bindings/JSMockFunction.cppis unaffected.0b92c2bcd0— [PERF] DeletesUnlinkedCodeBlock::m_jumpTargets(a per-label offset list that nothing in a shipping configuration read; DFG/liveness already recompute targets viacomputePreciseJumpTargets()), saving 4 bytes per label (~38 KB after loading typescript.js), shrinkingUnlinkedFunctionCodeBlockfrom 216 to 208 bytes (GC cell 224 -> 208), and cutting the serialized bytecode cache by ~1.4%. [API] RemovesCodeBlock::numberOfJumpTargets()/jumpTarget(),UnlinkedCodeBlock::numberOfJumpTargets()/jumpTarget()/lastJumpTarget(),UnlinkedCodeBlockGenerator::addJumpTarget()etc., andrecomputePreciseJumpTargets(), adding acomputePreciseJumpTargets(UnlinkedCodeBlock*, ...)overload — Bun's bindings use none of these. TheCachedCodeBlocklayout changes (field dropped fromruntime/CachedTypes.cpp), butbun build --bytecodeoutput is already keyed to the build viacomputeJSCBytecodeCacheVersion(), so old caches are rejected rather than misread.3d0e6c14b1— [PERF][API] Memory: movesm_features,m_lexicallyScopedFeatures,m_hasCapturedVariables,m_lineCount,m_endColumnand the sourceURL/sourceMappingURL directive pointers fromUnlinkedCodeBlockdown toUnlinkedGlobalCodeBlock(only Program/Eval/Module code uses them), shrinkingUnlinkedFunctionCodeBlockfrom 216 to 192 bytes (cell 224 -> 192; ~53 KB saved after loading typescript.js). The accessorscodeFeatures(),allowDirectEvalCache(),lexicallyScopedFeatures(),hasCapturedVariables(),lineCount(),endColumn(),sourceURLDirective(),sourceMappingURLDirective()andrecordParse()are removed fromUnlinkedCodeBlockand now exist only onUnlinkedGlobalCodeBlock;UnlinkedCodeBlock::usesImportMeta()is deleted outright (Bun's bindings use none of these; Bun'ssourceURLDirective()calls are onSourceProvider). The serializedCachedCodeBlocklayout for the bytecode cache also changes (split intoCachedCodeBlock+CachedGlobalCodeBlock), which is covered by Bun keying the cache version onBUN_WEBKIT_VERSION.0bbbac7b52— [BEHAVIOR] [API] Wasm memory64 now works together with multi-memory: theWasmSectionParsercheck that rejected any module combining a 64-bit memory with multiple memories ("if using memory64 then multiple memories are illegal for now") is removed, so such modules now validate/compile/run instead of failing withCompileError. IPInt decides whether to zero-extend an i32 address per accessed memory using a newWTF::BitSet<Wasm::maxMemories>(JSWebAssemblyInstance::m_memoryIsMemory64Bits) instead of a single memory-0 flag.JSWebAssemblyInstance::cachedMemory0IsMemory64()andoffsetOfCachedMemory0IsMemory64()are removed (replaced byoffsetOfMemoryIsMemory64Bits()); Bun does not reference them.71144530c1— [API] Bumps the vendoredwtf/simdutfsingle-header from 8.2.0 to 9.0.0 (now requires C++17):simdutf::to_string(encoding_type)andimplementation::name()/description()returnstd::string_viewinstead ofstd::string,full_resultgains apadding_errorfield and the base64 decoders now report the=position as the error location for padding errors, theSIMDUTF_FEATURE_*macros become#ifndef-overridable, and the icelake (AVX-512)simdutf::findnow masks its tail load so searching for NUL no longer false-matches past the end of the input.error_codevalues,struct result, and every function Bun'ssrc/simdutf_sysshim (bun-simdutf.cpp,simdutf.rsStatusconstants) calls are unchanged, and Bun falls back to its scalar decoder on any base64 error rather than reading the error offset, so no Bun-side change is needed.ee4b208267— [PERF] [API] Generator/async function bodies whose wrapper has no parameters no longer allocate a 64-byteUnlinkedFunctionExecutable::RareDatajust to hold an empty parameter-name list (everyasync () => {...},async function f() {},function* g() {}paid this; ~6.4 MB saved per 100k such functions).UnlinkedFunctionExecutable::createand theBytecodeGeneratornow takeVector<Identifier>&&instead ofstd::optional<Vector<Identifier>>&&; Bun does not callUnlinkedFunctionExecutable::createdirectly, so no action needed.b1701b3489— [BEHAVIOR] [API]Uint8Array.prototype.setFromBase64on a zero-length target now returns{ read: 0, written: 0 }without inspecting the input at all (even an invalid base64 string is accepted), matching step 3 of the proposal spec;Uint8Array.fromBase64is unchanged.WTF::fromBase64()gains a required fifth parameterOutputSizeIsMaxLength(new enum inwtf/text/Base64.h); Bun does not callWTF::fromBase64directly, so no source change is needed.870de4ab77— WTF fix inwtf/text/TextBreakIterator.{h,cpp}:NonSharedCharacterBreakIteratorandNonSharedSentenceBreakIteratorleaked their ICUUBreakIteratorwhensetTextForIterator()failed (reachable via a nullStringView), and the 8-bit path skippedutext_close()onubrk_setUText()failure. Ownership is now expressed with a newWTF::UBreakIteratorPtr(std::unique_ptr<UBreakIterator, ICUDeleter<ubrk_close>>) andm_iteratorbecomes that smart pointer; the publicoperator UBreakIterator*()is unchanged. [API] Only the private member type and the file-static helpers changed, so this is source-compatible for embedders, and Bun does not use these classes at all (JSC only references them from the offlineCharacterPropertyDataGeneratortool), so it is a no-op for Bun in practice.Behavior changes
3b9afb2b4f— [BEHAVIOR] Wasm correctness fix in BBQ and OMG (B3 lowering):ref.cast/ref.teston a nullable reference now only elides the explicit null check whenOptions::useWasmFaultSignalHandler()is on, so configurations running without the fault handler (e.g. Bun's Linux ASAN builds, whereOptions.cppturns it off unlessASAN_OPTIONScontainsallow_user_segv_handler=1) get a proper Wasm trap instead of dereferencing null. In signaling-memory mode, the decision to emit an explicit bounds check for large constant offsets now uses the last accessed byte (offset + size - 1) rather than the base offset; the old computation was slightly off but always still trapped via the PROT_NONE redzone.b74760b182— [BEHAVIOR] The non-ARM64WTF::roundeven/roundevenfpolyfill returned +0.0 for the tie that rounds to zero (roundeven(-0.5)gave +0.0 instead of -0.0); the result is now wrapped incopysign. In JSC this feeds BBQ's constant folding of Wasmf32.nearest/f64.nearest, so on x86_64 a constant-0.5operand folded to the wrong sign of zero; ARM64 uses__builtin_roundeven(frintn) and was already correct.3c0f403d81— [PERF] [BEHAVIOR] WasmGCarray.fill/array.copyare reworked in BBQ and OMG: null and bounds checks are now emitted inline in JIT code, the runtime call is skipped entirely whensize == 0(observed to be very common), non-refarray.copyuses B3MemoryCopy, and non-refarray.fillusesMemoryFillor newoperationWasmArrayFill{2B,4B,8B,16B}(memset_pattern* on Darwin,std::ranges::fillelsewhere), while ref-typed arrays keep GC-safe loops (operationWasmArrayFillRefs/operationWasmArrayCopyRefsviagcSafeMemmove). Observable change: the trap message for a null array in these ops becomes the generic"access to a null reference"instead of"array.fill to a null reference"/"array.copy to a null reference"(theNullArrayFill/NullArrayCopyenumerators were removed from the internalWasm::ExceptionTypeenum, which Bun does not reference). OldoperationWasmArrayFill{,Vector}/operationWasmArrayCopyJIT operations are removed.2165451fd3— [BEHAVIOR] Correctness fix in the YARR interpreter'stryConsumeBackReference: in Forward direction it speculatively advanced the input bymatchSizebefore comparing, and when the captured character was non-BMP and the input at that offset was not a valid surrogate pair, the earlyerrorCodePointreturn only restored the position for Backward, so a failed greedy iteration consumed input. Fixes wrong results like/(\u{1F601})\1*$/u.exec("\u{1F601}ab")matching instead of returningnull, and/(\u{1F601})(\1*)?/usplitting a surrogate pair; the check now falls through to the common mismatch path which restores the position in both directions. Only affects patterns that run in the interpreter (authored by Sosuke Suzuki from Bun).e88b92e29f— [BEHAVIOR] (bug fix) Fixes a BBQ-tier miscompile of Wasmi64.mul_wide_s/i64.mul_wide_uon x86_64: the 128-bit product comes back inrdx:rax, and if the register allocator handed outrax/rdxas the result or scratch registers the halves were clobbered, producing wrong results. Now uses the samePREPARE_FOR_MOD_OR_DIVpattern as div/mod (clobber + lockrax/rdx). Only reachable whenOptions::useWasmWideArithmeticis on (default off, Bun does not enable it), so this matters only for users opting in viaBUN_JSC_useWasmWideArithmetic=1.5cfff9fe44— [BEHAVIOR] In JSC's Wasm ESM integration (WebAssemblyModuleRecord), immutable exported globals are now exposed in the module namespace as plain JS values instead ofWebAssembly.Globalwrappers, per the esm-integration spec/WPT; v128 and exnref globals stay TDZ,Instance.exportsis unchanged, and wasm-to-wasm ESM imports fall back to theInstance.exportswrapper when the namespace binding is empty. No Bun-visible change today because Bun's.wasmloader (src/runtime/jsc_hooks.rs,L::Wasmarm) returns a file path / wasi-runner instead of creating a JSC Wasm module record; it would matter if Bun ever adopts JSC's native Wasm ESM path.b7afce9416— [BEHAVIOR] When several Wasm functions fail validation during concurrent compilation, theWebAssembly.CompileErrormessage now deterministically reports the lowest-index failing function instead of whichever worker thread finished first; non-function failures (OOM/parse/cancel) still take precedence. Adds protectedPlan::failAtFunction/EntryPlan::failFunctionCompilationand anm_errorFunctionIndexfield; error messages become stable across runs (useful for snapshot tests).010e57fb4b— [BEHAVIOR]WebAssembly.Module.imports()/WebAssembly.Module.exports()descriptors no longer include the non-standard js-types-proposaltypefield unlessOptions::useWasmJSTypes()is enabled (default false, and Bun does not set it). At the merge base this field was emitted unconditionally and could throw for unrepresentable ref types; descriptors now have the spec shape{module, name, kind}/{name, kind}, matching V8/Node. Also tweaks theWasmJSTypesEnableddescription inUnifiedWebPreferences.yaml.20c0bd7d62— [BEHAVIOR] Wasm JS API spec fix: re-exporting an imported immutableWebAssembly.Globalnow yields the same JS object that was imported (instance.exports.g === importedGlobal), matching the WPTconstructor-cachingexpectations; previously a fresh wrapper was created each time (mutable globals already preserved identity).JSWebAssemblyInstancegains anm_importedGlobalWrappersmap (newsetImportedGlobalWrapper/importedGlobalWrappermethods, visited by GC). Plain-number global imports still get a new wrapper.39de2d4eea— [BEHAVIOR] Wasm: importing aWebAssembly.Tagand re-exporting it now yields the same JS object (previously a freshJSWebAssemblyTagwrapper was created on every export, so===identity failed), and locally defined tags are cached on first export so two export names share one wrapper. Implemented via a newm_tagWrappersmap onJSWebAssemblyInstancethat is visited by GC; no embedder-facing API change.7f38ebbabf— [BEHAVIOR]Promise.tryfollows the updated spec (Normative: make Promise.try use PromiseResolve in non-error case tc39/ecma262#3883): the result comes fromPromiseResolve(C, value)/PromiseReject(C, error)instead ofNewPromiseCapability(C), soPromise.try(() => p)now returnspitself whenpis a native Promise, and a subclass constructor is invoked after the callback runs rather than before.builtins/PromiseOperations.jsis deleted (@newPromiseCapabilitySlowgone) and@newPromiseCapabilitybecomes a C++ link-time constant wrappingJSPromise::createNewPromiseCapability. Heads-up: follow-up upstream commit38027ff0ec(also in this range) removes@newPromiseCapabilityentirely; see that entry under "API and ABI changes" for the Bun$newPromiseCapability(Promise)call sites that must be rewritten.Performance
958a13ecad— [PERF] Wasm BBQemitIndirectCallcomputed the CallProfile address withaddPtr(TrustedImm32, ...), which on large offsets (functions with many call profiles) silently spills throughscratchRegister, clobbering the profile value loaded just before; it now doesmove+ registeraddPtr. No observable behavior change, but affectedcall_indirectsites were left permanently un-optimized (polymorphic-callee detection never kicked in), so this restores expected tiering for large wasm functions.01f04c4fb4— [PERF] YARR JIT now compiles backreferences inside lookbehinds (e.g./(?<=(a)\1)b/); previously any such pattern forced the entire regex to the interpreter. The backward match compares the capture from its end down to its start, withcheckNotEnoughInputbecomingindex >= lengthin Backward mode and case-insensitive, duplicate-named-group and surrogate-pair handling reused with the index direction flipped; forward codegen is unchanged. ~10.8x faster on the newregexp-lookbehind-backreferencemicrobenchmark, no intended change in match results (authored by Sosuke Suzuki from Bun).7ef4708559— [PERF] Parser: whenparseFunctionInfohas already computed a function's free-variable list for theSourceProviderCacheentry, that span is now handed topopScope, soScope::collectFreeVariablesFrom(renamed fromcollectFreeVariables, internal toparser/Parser.h) no longer re-derives it by re-walking used/declared/lexical sets. Pure parse-time speedup for cacheable (>=16/8 byte) function bodies;SourceProviderCacheItemCreationParametersgains afreeVariableCountfield andfreeVariables()accessor. No behavior change.0ca8f08b89— [PERF]Lexer::shiftdrops the 14-year-old "unconditionally zerom_currentthen overwrite" micro-optimization in favor of a plain if/else, which measures faster on current hardware. Semantics are identical; lexer hot-path only.24a6944b57— [PERF] InParser::parseMemberExpression, when the TreeBuilder isSyntaxChecker(the pre-parse/syntax-only pass), thenewtoken start positions are now tracked by a counting placeholder instead of aVector<JSTextPosition, 4>, sinceSyntaxChecker::createNewExprignores them anyway. Saves allocation/copy work for nestednewchains during syntax checking; no behavior change.a5fa580c84— [PERF] B3 LICM (hoistLoopInvariantValues) can now hoist trapping loads (plainLoad*,WasmStructGet,WasmArrayLengthwithout fences) and control-dependent values out of loops that contain side exits, as long as no earlier "trap barrier" (write/fence/side-exit) precedes the value on the path from the loop header. Previously any side exit in the loop disabled hoisting of control-dependent values entirely; mainly benefits Wasm OMG and FTL code with bounds/null checks in loops. AddsEffects::isWrite()/isTrapBarrier().6fbae40455— [PERF] FTLswitchon a string that is an unresolved concatenation rope now calls a new noexcept operation (operationSwitchStringResolveRopeAndGetCharacters8) to resolve the rope, and if the result is 8-bit uses the inline binary-search StringSwitch on the resolved characters instead of falling back to the generic slow path. Resolution usestryGetValue()so an OOM falls through to the slow path rather than throwing from the JIT operation.de9231d86e— [PERF]RegExp::m_ovectorandRegExp::RareData::m_captureGroupNamesswitch fromVectortoFixedVector, shrinking theRegExpGC cell from 96 to 80 bytes and allocating exactlyoffsetVectorSizeints instead ofVector::resize's 16-element minimum capacity (64 bytes). Upstream measured per-RegExp cell+ovector going from 160 to 96 bytes and max RSS with 200k live RegExps dropping from 137.5 MB to 115.0 MB;estimatedSizenow reports the exact ovectorbyteSize(). Authored by a Bun contributor.1c2c282d06— [PERF]Options::computeNumberOfWorkerThreadsnow caps its result at 32 on non-Darwin platforms; in practice this only affects the defaultnumberOfWasmCompilerThreads(previouslycores - 1with no cap; other callers already pass caps of 3 or 8), limiting it to 31 on Linux/Windows machines with more than 32 cores. Motivated by Wasm compilation OOMs on high-core-count, low-memory hosts; Bun does not override this option (it only setsnumberOfGCMarkers), so large Linux servers will see fewer Wasm compiler threads and lower peak memory.ce878e190f— [PERF]Map.prototype.forEach/Set.prototype.forEachget inline DFG and FTL lowering forMapIterationNext/MapIterationEntry/MapIterationEntryKey/MapIterationEntryValue, scanning the ordered hash table directly instead of making four C++ operation calls per element (the for-ofMapIterator*nodes already did this and now shareloadMapEntryData). Upstream microbenchmarks show 1.23x-1.65x speedups on forEach-heavy loops; the now-unreachableoperationMap/SetIterationEntry*JIT operations are removed and the remainingoperationMap/SetIterationNextbecome noexcept and only handle obsolete tables. Internal DFG operations only, no embedder-facing API or JS-visible behavior change (new stress tests cover mutation during iteration).c823243598— [PERF] The bytecode cache (generateUnlinkedCodeBlockForFunctionsinCodeCache.cpp) now emitsCodeForConstructinstead ofCodeForCallfor class constructors, so cached programs no longer reparse every class constructor body (and its nested functions) on the firstnew C(); upstream measured 253 -> 4 parses constructing 182 three.js classes and 133 -> 9 parses for babylon.js startup. Cache output grows by the previously missing constructor bodies (three.js +10.8%, a 50 MB bundle +0.5%), which is relevant to Bun's--bytecodebuilds andnode:vmcached-data paths that usegenerateProgramBytecode/generateModuleBytecode. No API or JS behavior change.9516ed8a4f— [PERF] DFG/FTLswitchon strings now handles 8-bit substring ropes inline by reading the base string's buffer at the substring offset, instead of bailing to the slowoperationSwitchStringcall (which resolves the rope). Previously only flat 8-bit strings took the inline binary-switch path, so JIT'd code doingswitch (s.slice(...))/switch (s.substring(...))gets faster. Internal-only signature rename inDFGSpeculativeJIT.h; no public API change.a7a9e233ce— [PERF] TheJSON.parselexer accumulates the int32 value while scanning the digit run instead of re-walking the digits a second time inlexNumber; micro-optimization for integer-heavy JSON. No API or behavior change.6b13bfa7ba— [PERF]TypedArray.prototype.sort()without a comparator now uses an LSD radix sort (8-bit digits, stable passes, skipping digits with a single bucket) for 2/4/8-byte element types above measured thresholds (128 / 512 / 8192 elements), with a SIMD already-sorted pre-scan and a sampled few-distinct-values check that falls back tostd::sort; upstream reports 2.3-4.6x on large Int16/Uint16/Int32/Uint32/Float32/Float64 arrays and 6.7x on presorted Int32 (geomean 1.5x). It temporarily allocates an O(n) scratch buffer (plus a snapshot copy for shared buffers) and falls back tostd::sorton allocation failure; results are unchanged (NaN canonicalization matches the oldsortFloatpath). Also addsWTF::SIMD::bitXor/bitXor2helpers toSIMDHelpers.h.db2d849cbe— [PERF] Replaces heap-registeringMarkedArgumentBufferwith a stackstd::array<EncodedJSValue, N>wrapped inArgListat every call site where the argument count is statically known (37 files: Promise resolve/reject/then/finally and microtask jobs,VM::callPromiseRejectionCallback, Proxy traps, JSONtoJSON/reviver, RegExp/StringSymbol.*protocol, iterator protocol, typed-array callbacks, Map/Set/WeakMap constructors, DFG slow paths). This trims per-call overhead and removes the never-hithasOverflowed()/OOM checks whenever the engine calls back into JS from C++. No public API or JS-visible behavior change; the only signature change (SyntheticModuleRecord::tryCreateWithExportNamesAndValuesnow takesArgList) is a private method Bun does not call.eb44b6cfaa— [PERF]WTF::URLParsernow SIMD-scans the path, opaque-path, query, and fragment states (viaSIMD::findfromwtf/SIMDHelpers.h) for the first delimiter, encode-set member, control, or non-ASCII code point and consumes the whole preceding run at once (skipped for canonical input, bulk-appended when building the output buffer) instead of looping per code point; upstream measures ~1.33x on 82k real-world URLs and 3-4x on ~100-char components. This directly speeds up everyWTF::URLparse in Bun (new URL(),URLPattern,Request/fetchURL handling, module URL resolution). Additive-only header changes:CodePointIterator::span()/advanceBy()and a privateURLParser::appendToASCIIBuffer(std::span<const char16_t>)overload; aconstevalstatic_assertverifies each stop-character set covers its percent-encode set, so no parsing behavior changes.70eb5015ae— [PERF] Memory: the buffered-structures set, its lock andbufferingCountdownmove from thePropertyInlineCachebase class intoRepatchingPropertyInlineCache, since handler ICs never buffer;sizeof(HandlerPropertyInlineCache)drops 112 -> 88 bytes per IC site in Baseline/DFG JITData (about -1.27 MB on Octane typescript). Side effect: handler ICs that fail to cache a structure now retrytryCacheon the next few visits instead of skipping them; repatching ICs are unchanged. Internal JIT data structure only, not referenced by Bun.1969cf2d9e— [PERF]StringImpl::replace(char16_t, char16_t)(behindString::replace(char, char)) now finds the first occurrence with SIMDWTF::find()instead of a scalar byte-at-a-time loop, for both 8-bit and 16-bit strings; same fix already applied tomakeStringByReplacingAll. No behavior change.2d0855229c— [PERF]WTF::copyElements(used throughout string building/concatenation) now handles 2..32-byte copies with inlined overlapping unaligned loads/stores instead of calling libcmemcpy, whose size dispatch costs more than the copy itself for short runs. The B3operationMemoryCopyfast path is hoisted into new WTF helperscopySmallMemory<min,max>(),copyOverlappingEnds,copyOverlappingEndPairs,WidestUnalignedUnitandmaxSmallCopySizeinwtf/UnalignedAccess.h, available for Bun's own C++ to use; no behavior change.7375405d8e— [PERF]base64EncodeInternal()/base64DecodeInternal()in WTF bound the chosen lookup table withauto, copying the whole 64-byte encode map or 128-byte decode map onto the stack on every call; nowauto&references the constexpr table directly. Affects Bun's uses ofWTF::base64Decode/base64URLDecode/base64URLEncode(WebCrypto JWK import/export insrc/jsc/bindings/webcrypto/CryptoKey*.cpp); no behavior change.Wasm
ce60d5d618— WasmGC concurrent-GC correctness fix in the BBQ tier:struct.new/struct.new_defaultskipped the mutator fence when every stored field was a constant, but a struct with reference fields still needs the store-store fence before the new object is published to the concurrent marker. BBQ now emitsemitMutatorFence()whenever the struct type has ref fields, matching IPInt/OMG; the fence is a no-op on x86_64, so this matters on ARM64.c25fbbd346— Debug-only: fixes a copy-paste typo in anASSERTin Wasm BBQemitModOrDiv(x64) that testedlhsLocationtwice instead ofrhsLocation != edx. No release-build or behavior impact.4cc12fa76b— Debug-build-only fix:assertCalleeIsReferencedinWasmOperations.cppnow returns early when the frame's callee is not aNativeCallee, which happens when a stack overflow during a JS↔Wasm transition reachesoperationWasmToJSExceptionwith a JS callee still in the frame. Fixes a spuriousasNativeCallee()crash underASSERT_ENABLED; no release behavior change.3400ff6aa7— Wasm:ModuleInformationnow stores theimportedStringConstants/qualifiedBuiltinSetNamescompile options as UTF-8 byte vectors (Wasm::Name) instead ofisolatedCopy()'dWTF::Strings, so noStringImplis ever shared between the main thread and Wasm compiler threads (not allStringImplfields are atomic). Import-name matching now compares raw bytes directly, dropping amakeStringper import. InternalimportedStringConstantsEquals()/builtinSetsInclude()signatures change toconst Name&(Bun does not call them); only affects modules compiled with JS string builtins / importedStringConstants options.20d622b6d6— Build fix:Wasm::CalleeGroup::BBQCalleeReference::operator=is replaced with a namedset()method so clang 18's-Wthread-safety-preciseanalyzer can see theWTF_REQUIRES_LOCKrequirement. No runtime behavior change; internal type only.Other JSC
9d03f48340— Removes the deadCallLinkInfo::m_slowPathCountfield (plusoffsetOfSlowPathCount()/slowPathCount()) and its increments in the LLInt and JIT virtual-call thunks;CallLinkStatus::computeFromCallLinkInfoalready bailed viatakesSlowPath()for anym_clearedByVirtualsite, so the reads always saw zero. Minor: one fewer memory increment per virtual call and 4 bytes less inCallLinkInfo. Internal-only, not used by Bun.3ddc7045b7— DFG OSR-exit correctness fix:SpeculativeJIT::emitSwitchChar'sStringUsepath calledop1.use()beforespeculateString(), so the operand's death preceded the BadType exit and baseline re-executedop_switch_charon a dead/poisoned scrutinee value when the speculation failed (e.g. aswitchwith single-character string cases later fed a non-string). Now speculates before releasing the operand, matchingemitSwitchString; fixes a potential crash/miscompile in optimized code, no API change.bdb7246737— Adds an opt-in DFG/FTL "global inlining planner" (Options::useGlobalInliningPlanner, default false) that surveys and ranks all inlining candidates of a compilation up front (weighted by callee tier and inline depth) and spends a single compilation-wide budget, instead of deciding per call site in bytecode order. Adds nine newOptionsknobs (globalInliningPlanBudgetForDFG/FTL,maximumGlobalInliningPlanSites,inliningPlanTierBonus*,inliningPlanDepthPenalty). No effect unless enabled; upstream notes the current budget is high enough that it barely changes inlining decisions yet.WTF and bmalloc
386c27f080— Build-only tweak: theALWAYS_INLINEfast path ofWTFCrashWithInfo(Darwin/PlayStation on x86_64/ARM64) is additionally disabled when compiling under the clang static analyzer (__clang_analyzer__) so the analyzer sees the out-of-line no-return version. No effect on normal Bun builds.390e2c91dc— Only engine-side change is a one-line#import→#includeof<wtf/Platform.h>inwtf/MachSendRightAnnotated.h(a Cocoa-only header); the rest is WebKit modulemap hygiene for Swift/Windows. No effect on Bun's JSCOnly build.1f7ab2fec8— FixesWTF::symbolize()inwtf/StackTrace.cppunderUSE(LIBBACKTRACE): consults the symbol table (mangled names) before DWARF so clang debug builds get fully-qualified frame names, initializes the symbol pointer (previously read uninitialized on lookup miss), and passes a non-null error callback (libbacktrace always invokes it, so null crashed on the first failed lookup). No effect on Bun:USE_LIBBACKTRACEdefaults to OFF for the JSCOnly port and Bun's build does not enable it.f0148cf5ab— ChangesSource/WTF/wtf/module.modulemapso the WTFCoreclang module declaresrequires cplusplus23instead ofcplusplus, and bumps the module-cache touch count to force a rebuild. Only affects builds that consume WTF as a clang module (-fmodules, Apple/Swift-interop builds); Bun's build already uses-std=c++23and does not enable clang modules, so no effect on Bun.