From 041c0aeab8265275fbbdbcca6f703df2b4f26492 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Thu, 23 Jul 2026 09:14:20 +0000 Subject: [PATCH 01/11] Ban from release builds; drop it from bun-uws A single #include anywhere in the release link pulls libstdc++'s globals_io.o in: its _GLOBAL__sub_I.00090_globals_io.cc static initializer constructs cin/cout/cerr/clog (char and wchar_t) and references the full std::locale facet set, so roughly fifty libstdc++ functions (std::ios_base::Init, std::locale::_S_initialize, std::locale::_Impl, ctype/numpunct/moneypunct/timepunct/messages) run before main on every bun process. There were two sources of the include: the vendored simdutf header in WebKit (Source/WTF/wtf/simdutf/simdutf_impl.h, fixed in oven-sh/WebKit#320) and five bun-uws headers. Three of the bun-uws headers (AsyncSocket.h, HttpRouter.h, Loop.h) included it without using it; App.h, HttpContext.h and TopicTree.h wrote fixed error strings via std::cerr, now fputs(stderr). The new src/banned-includes/iostream shim is prepended to the -I path for release builds only, so any #include resolves to a #error with a pointer to this explanation. This also catches WebKit headers that start including it (SIMDUTF.h etc. are pulled into Bun TUs via helpers.h), so a future WebKit bump that regresses this fails the release compile rather than silently re-adding the initializers. Debug builds keep the real header for ad-hoc printf debugging; -DBUN_ALLOW_IOSTREAM is the opt-out. With both this change and the WebKit patch applied: nm build/release/bun-profile | grep ios_base4Init -> empty _GLOBAL__sub_I.00090_globals_io.cc gone std::locale::_S_initialize / _Impl ctor gone bun-profile: 547 KB smaller The four remaining _GLOBAL__sub_I_*locale_inst.cc stubs are facet-id guard-byte writes (a few dozen movb $1 each) pulled by Int128.cpp's std::ostringstream; those are near-free and does not emit the static Init object. --- packages/bun-uws/src/App.h | 6 +-- packages/bun-uws/src/AsyncSocket.h | 1 - packages/bun-uws/src/HttpContext.h | 4 +- packages/bun-uws/src/HttpRouter.h | 1 - packages/bun-uws/src/Loop.h | 1 - packages/bun-uws/src/TopicTree.h | 4 +- scripts/build/flags.ts | 6 +++ src/banned-includes/iostream | 27 +++++++++++ .../source-lints/no-iostream-include.test.ts | 46 +++++++++++++++++++ 9 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 src/banned-includes/iostream create mode 100644 test/internal/source-lints/no-iostream-include.test.ts diff --git a/packages/bun-uws/src/App.h b/packages/bun-uws/src/App.h index e326e63a6368..7eca10ac278e 100644 --- a/packages/bun-uws/src/App.h +++ b/packages/bun-uws/src/App.h @@ -418,19 +418,19 @@ struct TemplatedApp { /* Terminate on misleading idleTimeout values */ if (behavior.idleTimeout && behavior.idleTimeout < 8) { - std::cerr << "Error: idleTimeout must be either 0 or greater than 8!" << std::endl; + fputs("Error: idleTimeout must be either 0 or greater than 8!\n", stderr); std::terminate(); } /* Maximum idleTimeout is 16 minutes */ if (behavior.idleTimeout > 240 * 4) { - std::cerr << "Error: idleTimeout must not be greater than 960 seconds!" << std::endl; + fputs("Error: idleTimeout must not be greater than 960 seconds!\n", stderr); std::terminate(); } /* Maximum maxLifetime is 4 hours */ if (behavior.maxLifetime > 240) { - std::cerr << "Error: maxLifetime must not be greater than 240 minutes!" << std::endl; + fputs("Error: maxLifetime must not be greater than 240 minutes!\n", stderr); std::terminate(); } diff --git a/packages/bun-uws/src/AsyncSocket.h b/packages/bun-uws/src/AsyncSocket.h index 5e2fafae7eb6..e608eedf98d0 100644 --- a/packages/bun-uws/src/AsyncSocket.h +++ b/packages/bun-uws/src/AsyncSocket.h @@ -27,7 +27,6 @@ * to signal error with -1 (which is how the entire UNIX syscalling is built). */ #include -#include #include "libusockets.h" #include "bun-usockets/src/internal/internal.h" diff --git a/packages/bun-uws/src/HttpContext.h b/packages/bun-uws/src/HttpContext.h index 67d209e5e54f..81f0fdec43b8 100644 --- a/packages/bun-uws/src/HttpContext.h +++ b/packages/bun-uws/src/HttpContext.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "MoveOnlyFunction.h" #include "HttpParser.h" #include @@ -466,7 +466,7 @@ struct HttpContext { /* Returning from a request handler without responding or attaching an onAborted handler is ill-use */ if (!((HttpResponse *) s)->hasResponded() && !httpResponseData->onAborted && !httpResponseData->socketData) { /* Throw exception here? */ - std::cerr << "Error: Returning from a request handler without responding or attaching an abort handler is forbidden!" << std::endl; + fputs("Error: Returning from a request handler without responding or attaching an abort handler is forbidden!\n", stderr); std::terminate(); } diff --git a/packages/bun-uws/src/HttpRouter.h b/packages/bun-uws/src/HttpRouter.h index 2783237a40f1..8a48cd6b8ea7 100644 --- a/packages/bun-uws/src/HttpRouter.h +++ b/packages/bun-uws/src/HttpRouter.h @@ -27,7 +27,6 @@ #include #include #include -#include #include "MoveOnlyFunction.h" diff --git a/packages/bun-uws/src/Loop.h b/packages/bun-uws/src/Loop.h index c33f271f626b..d8d8003c74b5 100644 --- a/packages/bun-uws/src/Loop.h +++ b/packages/bun-uws/src/Loop.h @@ -23,7 +23,6 @@ #include "LoopData.h" #include -#include #include "AsyncSocket.h" extern "C" int bun_is_exiting(); diff --git a/packages/bun-uws/src/TopicTree.h b/packages/bun-uws/src/TopicTree.h index 0df624b04d18..3ebceeb1f6fd 100644 --- a/packages/bun-uws/src/TopicTree.h +++ b/packages/bun-uws/src/TopicTree.h @@ -18,7 +18,7 @@ #pragma once #include #include -#include +#include #include #include #include @@ -108,7 +108,7 @@ struct TopicTree { void checkIteratingSubscriber(Subscriber *s) { /* Notify user that they are doing something wrong here */ if (iteratingSubscriber == s) { - std::cerr << "Error: WebSocket must not subscribe or unsubscribe to topics while iterating its topics!" << std::endl; + fputs("Error: WebSocket must not subscribe or unsubscribe to topics while iterating its topics!\n", stderr); std::terminate(); } } diff --git a/scripts/build/flags.ts b/scripts/build/flags.ts index 2ea21c66e91d..c31aaa2de3c8 100644 --- a/scripts/build/flags.ts +++ b/scripts/build/flags.ts @@ -1512,6 +1512,12 @@ export const stripFlags: Flag[] = [ export function bunIncludes(cfg: Config): string[] { const { cwd, codegenDir, vendorDir } = cfg; const includes: string[] = [ + // Release builds shadow with a #error shim. A single + // include anywhere (our headers, bun-uws, or a WebKit header pulled into a + // Bun TU) drags libstdc++'s globals_io.o into the link and runs + // std::ios_base::Init + the full locale facet set before main. Debug builds + // keep the real header available for ad-hoc printf-debugging. + ...(cfg.release ? [join(cwd, "src/banned-includes")] : []), join(cwd, "packages"), join(cwd, "packages/bun-usockets"), join(cwd, "packages/bun-usockets/src"), diff --git a/src/banned-includes/iostream b/src/banned-includes/iostream new file mode 100644 index 000000000000..dfd898b0077f --- /dev/null +++ b/src/banned-includes/iostream @@ -0,0 +1,27 @@ +// This directory is placed first on the -I search path for Bun's C++ compile +// (release profile), so `#include ` resolves here instead of the +// toolchain header. +// +// is unlike ///: on libstdc++ +// it emits a reference to std::ios_base_library_init (or, on configurations +// without the init-priority attribute, a static `std::ios_base::Init __ioinit` +// object) in every translation unit that includes it. One such reference +// anywhere in the link pulls libstdc++'s globals_io.o in, whose +// _GLOBAL__sub_I.00090_globals_io.cc static initializer constructs +// cin/cout/cerr/clog and their wchar_t siblings before main. That in turn +// references the full std::locale facet set (ctype / numpunct / moneypunct / +// timepunct / messages, for both char and wchar_t), so roughly fifty libstdc++ +// functions run on every Bun process start. +// +// Bun never touches C++ iostreams at runtime. Use fputs/fprintf for error +// output, or WTF's dataLog()/PrintStream in JSC-adjacent code. +// +// Because Bun's own headers include wtf/SIMDUTF.h (and others) from the +// WebKit prebuilt, this shim also catches a WebKit header that starts +// including : it will fail Bun's release build rather than silently +// regressing startup. +#ifndef BUN_ALLOW_IOSTREAM +#error " is banned in Bun release builds: it drags std::ios_base::Init and the full std::locale facet set into pre-main startup. Use fputs/fprintf for stderr output. See src/banned-includes/iostream." +#else +#include_next +#endif diff --git a/test/internal/source-lints/no-iostream-include.test.ts b/test/internal/source-lints/no-iostream-include.test.ts new file mode 100644 index 000000000000..067171339438 --- /dev/null +++ b/test/internal/source-lints/no-iostream-include.test.ts @@ -0,0 +1,46 @@ +import { expect, test } from "bun:test"; +import { Glob } from "bun"; +import { readFileSync } from "node:fs"; +import path from "node:path"; + +// is unique among the C++ stream headers: on libstdc++ it emits a +// reference to std::ios_base_library_init in every TU that includes it, which +// forces libstdc++'s globals_io.o into the link. That object's +// _GLOBAL__sub_I.00090_globals_io.cc initializer constructs cin/cout/cerr/clog +// (and the wchar_t variants) before main, dragging the full std::locale facet +// set (ctype/numpunct/moneypunct/timepunct/messages for char and wchar_t) into +// every Bun process startup. Bun never touches C++ iostreams at runtime. +// +// , , and are fine: they declare the +// stream types but do not emit the static Init object. If you need to print to +// stderr from C++, use fputs/fprintf. +// +// The upstream source of the original leak was the vendored simdutf header +// inside WebKit (Source/WTF/wtf/simdutf/simdutf_impl.h); that is handled by +// the WebKit pin. This test guards Bun's own compiled C++ so the initializer +// cannot creep back in through packages/ or src/. +test("C++ sources compiled into Bun do not include ", async () => { + const repoRoot = path.resolve(import.meta.dir, "..", "..", ".."); + + const roots = ["src", "packages/bun-uws", "packages/bun-usockets"]; + // sizegen.cpp is a build-time code generator, not linked into the bun binary. + const allowlist = new Set(["src/jsc/headergen/sizegen.cpp"]); + + const iostreamInclude = /^\s*#\s*include\s*/m; + const violations: string[] = []; + + for (const root of roots) { + const glob = new Glob("**/*.{h,hpp,hxx,cpp,cc,cxx}"); + for await (const rel of glob.scan({ cwd: path.join(repoRoot, root) })) { + const relFromRepo = path.join(root, rel).replaceAll("\\", "/"); + if (allowlist.has(relFromRepo)) continue; + const source = readFileSync(path.join(repoRoot, root, rel), "utf8"); + if (iostreamInclude.test(source)) { + violations.push(relFromRepo); + } + } + } + + violations.sort(); + expect(violations).toEqual([]); +}); From 54bce8314eec26171dc7b7b55cc7eea9a2422f29 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 23 Jul 2026 09:17:14 +0000 Subject: [PATCH 02/11] [autofix.ci] apply automated fixes --- test/internal/source-lints/no-iostream-include.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/internal/source-lints/no-iostream-include.test.ts b/test/internal/source-lints/no-iostream-include.test.ts index 067171339438..04453c1c39ce 100644 --- a/test/internal/source-lints/no-iostream-include.test.ts +++ b/test/internal/source-lints/no-iostream-include.test.ts @@ -1,5 +1,5 @@ -import { expect, test } from "bun:test"; import { Glob } from "bun"; +import { expect, test } from "bun:test"; import { readFileSync } from "node:fs"; import path from "node:path"; From 18dc9eb7f7e38d0ce9af60712a70acb3cb8ada67 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Thu, 23 Jul 2026 09:57:36 +0000 Subject: [PATCH 03/11] Bump WebKit to 2f7e89c84f (simdutf iostream drop + compile-time ban) Picks up oven-sh/WebKit#320 (removes the stray from the vendored simdutf amalgamation and bans at compile time for non-Debug USE_BUN_JSC_ADDITIONS builds) and oven-sh/WebKit#322 (skip the eager timezone prewarm under USE_BUN_JSC_ADDITIONS). With this bump the release build's src/banned-includes/iostream shim no longer trips on the WebKit simdutf header, and no translation unit in the final link carries a reference to std::ios_base_library_init. --- scripts/build/deps/webkit.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/build/deps/webkit.ts b/scripts/build/deps/webkit.ts index e50f02454d23..11797fc64e9e 100644 --- a/scripts/build/deps/webkit.ts +++ b/scripts/build/deps/webkit.ts @@ -6,9 +6,12 @@ // oven-sh/WebKit main: macOS + Windows artifacts cross-compiled on Linux, // -lto variants built with ThinLTO (per-module summaries for cross-language // importing), every x64 at the nehalem floor (no separate -baseline variant), -// typed-array constructor ClassInfo kept address-unique under LTO, and the -// Windows ICU data table filtered + per-item zstd compressed. -export const WEBKIT_VERSION = "c9296e353e365ecf0de82f273bb0a88a3df465be"; +// typed-array constructor ClassInfo kept address-unique under LTO, the +// Windows ICU data table filtered + per-item zstd compressed, eager timezone +// prewarm skipped under USE_BUN_JSC_ADDITIONS, the stray simdutf scalar/base64 +// include dropped, and banned at compile time for +// non-Debug USE_BUN_JSC_ADDITIONS builds (see src/banned-includes/iostream). +export const WEBKIT_VERSION = "2f7e89c84f818b07b27d4702813a37db543c298a"; /** * WebKit (JavaScriptCore) — the JS engine. From 0179c70dad31ccd94d111ea1592dbe7ac249238d Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Thu, 23 Jul 2026 10:06:24 +0000 Subject: [PATCH 04/11] Bump WebKit to af2e8dc639 (pick up #321 lazy WebAssembly namespace) The 2f7e89c84f autobuild hit a one-lane Windows x64 Release failure on the main push (the PR preview build for the identical change passed all 38 lanes, so this is infrastructure noise). af2e8dc6 is the current oven-sh/WebKit main HEAD and still contains #320 and #322. --- packages/bun-uws/src/App.h | 1 + scripts/build/deps/webkit.ts | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/bun-uws/src/App.h b/packages/bun-uws/src/App.h index 7eca10ac278e..8d5fe6969c0c 100644 --- a/packages/bun-uws/src/App.h +++ b/packages/bun-uws/src/App.h @@ -21,6 +21,7 @@ #include #include #include +#include namespace uWS { /* Safari 15.0 - 15.3 has a completely broken compression implementation (client_no_context_takeover not diff --git a/scripts/build/deps/webkit.ts b/scripts/build/deps/webkit.ts index 11797fc64e9e..d13158c4fdb2 100644 --- a/scripts/build/deps/webkit.ts +++ b/scripts/build/deps/webkit.ts @@ -9,9 +9,10 @@ // typed-array constructor ClassInfo kept address-unique under LTO, the // Windows ICU data table filtered + per-item zstd compressed, eager timezone // prewarm skipped under USE_BUN_JSC_ADDITIONS, the stray simdutf scalar/base64 -// include dropped, and banned at compile time for -// non-Debug USE_BUN_JSC_ADDITIONS builds (see src/banned-includes/iostream). -export const WEBKIT_VERSION = "2f7e89c84f818b07b27d4702813a37db543c298a"; +// include dropped, banned at compile time for non-Debug +// USE_BUN_JSC_ADDITIONS builds (see src/banned-includes/iostream), and the +// WebAssembly namespace object created lazily. +export const WEBKIT_VERSION = "af2e8dc6393ce244eb1865e34e7636225744cfba"; /** * WebKit (JavaScriptCore) — the JS engine. From 76610d36d05fe0c5e6579c12e4fd0f247a778b03 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Thu, 23 Jul 2026 11:00:21 +0000 Subject: [PATCH 05/11] bun-uws: drop the stderr logging from validation terminates Bun validates idleTimeout/maxLifetime and the request-handler contract before calling into uWS, so these paths are programmer errors rather than user-facing conditions; std::terminate is enough. --- packages/bun-uws/src/App.h | 4 ---- packages/bun-uws/src/HttpContext.h | 3 --- packages/bun-uws/src/TopicTree.h | 3 --- 3 files changed, 10 deletions(-) diff --git a/packages/bun-uws/src/App.h b/packages/bun-uws/src/App.h index 8d5fe6969c0c..8b3181eb1d99 100644 --- a/packages/bun-uws/src/App.h +++ b/packages/bun-uws/src/App.h @@ -21,7 +21,6 @@ #include #include #include -#include namespace uWS { /* Safari 15.0 - 15.3 has a completely broken compression implementation (client_no_context_takeover not @@ -419,19 +418,16 @@ struct TemplatedApp { /* Terminate on misleading idleTimeout values */ if (behavior.idleTimeout && behavior.idleTimeout < 8) { - fputs("Error: idleTimeout must be either 0 or greater than 8!\n", stderr); std::terminate(); } /* Maximum idleTimeout is 16 minutes */ if (behavior.idleTimeout > 240 * 4) { - fputs("Error: idleTimeout must not be greater than 960 seconds!\n", stderr); std::terminate(); } /* Maximum maxLifetime is 4 hours */ if (behavior.maxLifetime > 240) { - fputs("Error: maxLifetime must not be greater than 240 minutes!\n", stderr); std::terminate(); } diff --git a/packages/bun-uws/src/HttpContext.h b/packages/bun-uws/src/HttpContext.h index 81f0fdec43b8..6e3bd96fe15d 100644 --- a/packages/bun-uws/src/HttpContext.h +++ b/packages/bun-uws/src/HttpContext.h @@ -30,7 +30,6 @@ #include #include #include -#include #include "MoveOnlyFunction.h" #include "HttpParser.h" #include @@ -465,8 +464,6 @@ struct HttpContext { /* Returning from a request handler without responding or attaching an onAborted handler is ill-use */ if (!((HttpResponse *) s)->hasResponded() && !httpResponseData->onAborted && !httpResponseData->socketData) { - /* Throw exception here? */ - fputs("Error: Returning from a request handler without responding or attaching an abort handler is forbidden!\n", stderr); std::terminate(); } diff --git a/packages/bun-uws/src/TopicTree.h b/packages/bun-uws/src/TopicTree.h index 3ebceeb1f6fd..6a06ef261671 100644 --- a/packages/bun-uws/src/TopicTree.h +++ b/packages/bun-uws/src/TopicTree.h @@ -18,7 +18,6 @@ #pragma once #include #include -#include #include #include #include @@ -106,9 +105,7 @@ struct TopicTree { std::vector outgoingMessages; void checkIteratingSubscriber(Subscriber *s) { - /* Notify user that they are doing something wrong here */ if (iteratingSubscriber == s) { - fputs("Error: WebSocket must not subscribe or unsubscribe to topics while iterating its topics!\n", stderr); std::terminate(); } } From 5d19ebc85cf08bcc6c361a9d34827af89a6567cf Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Thu, 23 Jul 2026 11:15:34 +0000 Subject: [PATCH 06/11] bun-uws: drop stale 'Notify user' comments at checkIteratingSubscriber call sites The stderr message they referred to was removed in the previous commit. --- packages/bun-uws/src/TopicTree.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/bun-uws/src/TopicTree.h b/packages/bun-uws/src/TopicTree.h index 6a06ef261671..ec3a61d1671a 100644 --- a/packages/bun-uws/src/TopicTree.h +++ b/packages/bun-uws/src/TopicTree.h @@ -160,7 +160,6 @@ struct TopicTree { /* Subscribe fails if we already are subscribed */ Topic *subscribe(Subscriber *s, std::string_view topic) { - /* Notify user that they are doing something wrong here */ checkIteratingSubscriber(s); /* Lookup or create new topic */ @@ -184,7 +183,6 @@ struct TopicTree { /* Returns ok, last, newCount */ std::tuple unsubscribe(Subscriber *s, std::string_view topic) { - /* Notify user that they are doing something wrong here */ checkIteratingSubscriber(s); /* Lookup topic */ From a4a7e9ca3143bf4008ba52148ff48426a0721c11 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Thu, 23 Jul 2026 11:25:25 +0000 Subject: [PATCH 07/11] source-lints/no-iostream: guard against a vacuous pass when the glob scans nothing Matches the convention in the sibling lints (shim-stdint-includes, unsound-erased-box, frozen-nonnull-reborrow, expect-call-counter). --- test/internal/source-lints/no-iostream-include.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/internal/source-lints/no-iostream-include.test.ts b/test/internal/source-lints/no-iostream-include.test.ts index 04453c1c39ce..29c86bea2331 100644 --- a/test/internal/source-lints/no-iostream-include.test.ts +++ b/test/internal/source-lints/no-iostream-include.test.ts @@ -28,10 +28,12 @@ test("C++ sources compiled into Bun do not include ", async () => { const iostreamInclude = /^\s*#\s*include\s*/m; const violations: string[] = []; + let scanned = 0; for (const root of roots) { const glob = new Glob("**/*.{h,hpp,hxx,cpp,cc,cxx}"); for await (const rel of glob.scan({ cwd: path.join(repoRoot, root) })) { + scanned++; const relFromRepo = path.join(root, rel).replaceAll("\\", "/"); if (allowlist.has(relFromRepo)) continue; const source = readFileSync(path.join(repoRoot, root, rel), "utf8"); @@ -41,6 +43,9 @@ test("C++ sources compiled into Bun do not include ", async () => { } } + // Guard against repoRoot resolving wrong (test file moved) or a scanned root + // going away, which would make the ban below pass vacuously. + expect(scanned).toBeGreaterThan(0); violations.sort(); expect(violations).toEqual([]); }); From ea56cdc8dea6ab055fae1f69fd0b4b6ba531684c Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Thu, 23 Jul 2026 11:46:29 +0000 Subject: [PATCH 08/11] ci: retrigger From a7bc0c7a882726d97ec832d212079309d7e4c7ce Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Thu, 23 Jul 2026 22:25:26 +0000 Subject: [PATCH 09/11] source-lints/no-iostream: assert scanned > 0 per root, not in aggregate So the guard still trips if one of the three roots is renamed while the others still yield files. --- test/internal/source-lints/no-iostream-include.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/internal/source-lints/no-iostream-include.test.ts b/test/internal/source-lints/no-iostream-include.test.ts index 29c86bea2331..2ef0fa212c33 100644 --- a/test/internal/source-lints/no-iostream-include.test.ts +++ b/test/internal/source-lints/no-iostream-include.test.ts @@ -28,9 +28,9 @@ test("C++ sources compiled into Bun do not include ", async () => { const iostreamInclude = /^\s*#\s*include\s*/m; const violations: string[] = []; - let scanned = 0; for (const root of roots) { + let scanned = 0; const glob = new Glob("**/*.{h,hpp,hxx,cpp,cc,cxx}"); for await (const rel of glob.scan({ cwd: path.join(repoRoot, root) })) { scanned++; @@ -41,11 +41,11 @@ test("C++ sources compiled into Bun do not include ", async () => { violations.push(relFromRepo); } } + // Guard against repoRoot resolving wrong (test file moved) or a scanned + // root going away, which would make the ban below pass vacuously. + expect(scanned).toBeGreaterThan(0); } - // Guard against repoRoot resolving wrong (test file moved) or a scanned root - // going away, which would make the ban below pass vacuously. - expect(scanned).toBeGreaterThan(0); violations.sort(); expect(violations).toEqual([]); }); From 507ab81136eaa98ea9a82d224ed785b343ab06c6 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Thu, 23 Jul 2026 22:40:59 +0000 Subject: [PATCH 10/11] webkit.ts: restore the why-comment dropped by the main merge The merge of main into this branch kept WEBKIT_VERSION = a40d462206 (correct: on oven-sh/WebKit main, a40d462206 is a descendant of 2f7e89c84f and therefore includes #320/#321/#322 as well as #315) but dropped the descriptive comment from both parents. Restore it as the union of the two sides. --- scripts/build/deps/webkit.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scripts/build/deps/webkit.ts b/scripts/build/deps/webkit.ts index 73985fc97c72..a2388b8653a8 100644 --- a/scripts/build/deps/webkit.ts +++ b/scripts/build/deps/webkit.ts @@ -3,6 +3,17 @@ * for local mode. Override via `--webkit-version=` to test a branch. * From https://github.com/oven-sh/WebKit releases. */ +// oven-sh/WebKit main: macOS + Windows artifacts cross-compiled on Linux, +// -lto variants built with ThinLTO (per-module summaries for cross-language +// importing), every x64 at the nehalem floor (no separate -baseline variant), +// typed-array constructor ClassInfo kept address-unique under LTO, the +// Windows ICU data table filtered + per-item zstd compressed, Windows unwind +// info (RtlAddGrowableFunctionTable) registered for the fixed JIT pool (LLInt +// pending offlineasm .seh_* emission), eager timezone prewarm skipped under +// USE_BUN_JSC_ADDITIONS, the stray simdutf scalar/base64 include +// dropped, banned at compile time for non-Debug +// USE_BUN_JSC_ADDITIONS builds (see src/banned-includes/iostream), and the +// WebAssembly namespace object created lazily. export const WEBKIT_VERSION = "a40d462206e1caf8388062120acde61e37a4ae7d"; /** From eba02a1f6597fb60f49d2e29782bb8aa925824be Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Thu, 23 Jul 2026 22:50:26 +0000 Subject: [PATCH 11/11] Revert "webkit.ts: restore the why-comment dropped by the main merge" This reverts commit 507ab81136eaa98ea9a82d224ed785b343ab06c6. --- scripts/build/deps/webkit.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/scripts/build/deps/webkit.ts b/scripts/build/deps/webkit.ts index a2388b8653a8..73985fc97c72 100644 --- a/scripts/build/deps/webkit.ts +++ b/scripts/build/deps/webkit.ts @@ -3,17 +3,6 @@ * for local mode. Override via `--webkit-version=` to test a branch. * From https://github.com/oven-sh/WebKit releases. */ -// oven-sh/WebKit main: macOS + Windows artifacts cross-compiled on Linux, -// -lto variants built with ThinLTO (per-module summaries for cross-language -// importing), every x64 at the nehalem floor (no separate -baseline variant), -// typed-array constructor ClassInfo kept address-unique under LTO, the -// Windows ICU data table filtered + per-item zstd compressed, Windows unwind -// info (RtlAddGrowableFunctionTable) registered for the fixed JIT pool (LLInt -// pending offlineasm .seh_* emission), eager timezone prewarm skipped under -// USE_BUN_JSC_ADDITIONS, the stray simdutf scalar/base64 include -// dropped, banned at compile time for non-Debug -// USE_BUN_JSC_ADDITIONS builds (see src/banned-includes/iostream), and the -// WebAssembly namespace object created lazily. export const WEBKIT_VERSION = "a40d462206e1caf8388062120acde61e37a4ae7d"; /**