Skip to content

Remove dead code from SerializedScriptValue, WebSocket, Performance, JSDOMConvert*, rescle, wasi - #36474

Merged
Jarred-Sumner merged 10 commits into
mainfrom
claude/farm/3e237919/dead-code-ssv-wasi-webcore
Aug 1, 2026
Merged

Remove dead code from SerializedScriptValue, WebSocket, Performance, JSDOMConvert*, rescle, wasi#36474
Jarred-Sumner merged 10 commits into
mainfrom
claude/farm/3e237919/dead-code-ssv-wasi-webcore

Conversation

@robobun

@robobun robobun commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Net: -3673 LOC (30 files, +177 / -3850). No behavior change.

Nothing here overlaps with the other open dead-code PRs (#34965, #34759, #36426, #36178, #36237, #35775, #35559, #36318, #36115, #35437, #35880); every touched file was checked against their file lists.

SerializedScriptValue.cpp / .h (7239 → 5090, 413 → 202)

  • All #if ENABLE(OFFSCREEN_CANVAS_IN_WORKERS), #if ENABLE(WEB_RTC), #if ENABLE(WEB_CODECS), #if ENABLE(PREDEFINED_COLOR_SPACE_DISPLAY_P3) blocks. Bun's JSCOnly cmakeconfig.h sets all four to 0 on every target, and the referenced types (OffscreenCanvas, RTCCertificate, DetachedRTCDataChannel, WebCodecsVideoFrame, ...) have no headers anywhere under src/, so the guarded bodies could not compile if the macros flipped.
  • ~1200 lines of long-commented-out serialization paths for DOM geometry (DOMPoint/DOMRect/DOMMatrix/DOMQuad), ImageBitmap, File/FileList, Blob, ImageData, blob-URL/IDB helpers, and alternate ctors. All date to 2022.
  • Uncalled public methods (rg across src/ and build/debug/codegen/): create(StringView), create(JSContextRef, JSValueRef, JSValueRef*), deserialize(JSContextRef, JSValueRef*), toString(), nullValue(), wireFormatVersion(), and the never-instantiated encode<Encoder>() / decode<Decoder>() templates. Plus their private-only helpers CloneSerializer::serialize(StringView, Vector<uint8_t>&), CloneDeserializer::deserializeString(), blobFilePathForBlobURL(), wrapCryptoKey(), unwrapCryptoKey(), write/read(DestinationColorSpaceTag), the PLATFORM(COCOA) CFDataRef helpers, and the fillTransferMap(const Vector<Ref<T>>&, ...) overload.
  • Orphaned enums PredefinedColorSpaceTag, DestinationColorSpaceTag, ImageDataPoolTag, m_transferredImageBitmaps, and 18 SerializationTag values that are no longer written or read in live code (FileTag, FileListTag, ImageDataTag, BlobTag, DOMPoint*/Rect*/Matrix*/QuadTag, ImageBitmap*Tag, OffscreenCanvasTransferTag, RTC*Tag, WebCodecs*Tag). The grammar-comment documentation block is kept.

Followup note: m_blobURLs / m_blobFilePaths are now write-only (their sole reader blobFilePathForBlobURL is gone), but removing them cascades through the live CloneDeserializer ctor params and the public deserialize(..., blobURLs, blobFilePaths, ...) overload. Left as-is.

WebSocket.cpp / .h (-212)

  • Uncalled create(ctx, url, protocols, headers, bool) 5-arg overload and the three connect(const String&[, ...]) overloads (all JSWebSocket.cpp paths use the 2/3/8/9-arg create and the 4-arg connect).
  • didUpdateBufferedAmount(unsigned), the decl-only didReceiveData(const char*, size_t) and WebSocket(ScriptExecutionContext&, const String&), and the uncalled offerPerMessageDeflate() getter.
  • 2022-era commented-out blocks: CSP/portAllowed, ResourceLoadObserver/MixedContentChecker, ENABLE(INTELLIGENT_TRACKING_PREVENTION), contextDestroyed/suspend/resume/stop/activeDOMObjectName, four ConnectedWebSocketKind::Server case blocks, and the commented #includes.
  • m_dispatchedErrorEvent (only read by the removed suspend/resume block).

JSDOMConvert{Sequences,Strings,Record,Union}.h / .cpp (-381)

  • NumericSequenceConverter and the five SequenceConverter<IDL{Long,Float,UnrestrictedFloat,Double,UnrestrictedDouble}> specializations. IDLSequence<T> is only instantiated with string / enum / interface / dictionary / object element types in Bun (rg 'IDLSequence<IDL(Long|Float|Double|Unrestricted)' src/ build/debug/codegen/ = 0).
  • Converter<IDLFrozenArray<T>> (only the JSConverter side is used), JSConverter<IDLRecord<K,V>> (only the Converter side is used), and the IDLAllowSharedAdaptor<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>> specs (webcrypto uses the un-wrapped union).
  • propertyNameToString / propertyNameToAtomString, the IDLLegacyNullToEmpty{,Atom}StringAdaptor and IDLAtomStringAdaptor<IDL{USV,Byte}String> converters, and valueToByteAtomString / valueToUSVAtomString (their only callers).

windows/rescle.cpp / .h (-278)

The only entry point rescle__setWindowsMetadata (from src/sys/windows/mod.rs) uses Load, SetIcon, SetVersionString, SetFileVersion, SetProductVersion, Commit. Removed SetExecutionLevel, IsExecutionLevelSet, SetApplicationManifest, IsApplicationManifestSet, GetVersionString×2, ChangeString×2, ChangeRcData, GetString×2, OnEnumResourceManifest + its Load() registration, the now-always-false execution-level and manifest branches in Commit(), ReadFileToString, the executionLevel_/originalExecutionLevel_/applicationManifestPath_/manifestString_ members, and five unused RU_VS_* macros.

Followup note: with ChangeString/ChangeRcData gone, stringTableMap_ and rcDataLngMap_ are now populated by Load() and written back unchanged by Commit(). That round-trip was already a semantic no-op on main (the removed mutators had zero callers there too), but removing it touches a live Windows bun build --compile path rather than an unreferenced helper, so it is deferred rather than folded into this sweep.

Performance.cpp / .h + PerformanceObserver.h (-154)

  • addResourceTiming(ResourceTiming&&) (no callers; Bun's fetch produces PerformanceResourceTiming via queueEntry directly), isResourceTimingBufferFull(), m_backupResourceTimingBuffer, m_waitingForBackupBufferToBeProcessed.
  • allowHighPrecisionTime() + highTimePrecision, timeResolution(), relativeTimeFromTimeOriginInReducedResolution(MonotonicTime) (no callers).
  • 2024-era commented-out navigation(), reportFirstContentfulPaint/addNavigationTiming/navigationFinished, resourceTimingBufferFullTimerFired().
  • PerformanceObserver.h: hasNavigationTiming/addedNavigationTiming/m_hasNavigationTiming (only referenced from the commented-out code above).

EventTarget.cpp / .h + EventListenerMap (-51)

  • isPaymentRequest() virtual (no callers, no overriders).
  • legacyType(const Event&) static, which unconditionally returned nullAtom() since 2022, and the legacy-fallback block in fireEventListeners it made unreachable.
  • hasCapturingEventListeners(const AtomString&) (no callers) and its only callee EventListenerMap::containsCapturing.
  • Decl-only invalidateJSEventListeners(JSC::JSObject*).

src/js/node/wasi.ts (-280)

  • The four exports.X = exports.Y = ... = void 0; pre-declaration chains (186 LOC). These are tsc emit artifacts from the original wasi-js npm bundle; every property is re-assigned to its real value immediately after.
  • WASIExitError / WASIKillError classes (the types module is only consumed as types_1.WASIError).
  • exports.SOCKET_DEFAULT_RIGHTS (written once, never read).
  • initWasiFdInfo() (never called; contains five debug console.log calls).
  • if (log.enabled) { ... } blocks and bare log(...) / logOpen(...) calls (log is hard-coded to () => {} and never reassigned).

src/js/thirdparty/ws.js (-19)

  • Long-commented-out secWebSocketExtensions / PerMessageDeflate block (May 2023).

Rust (-22)

  • bun_http: PRINT_EVERY / PRINT_EVERY_I debug scaffolding and the if PRINT_EVERY != 0 { ... } block it made always-dead.
  • bun_threading: drop GuardedBy, RawMutex, RwLockReadGuard, RwLockWriteGuard from the crate re-export list (zero bun_threading::X references; the backing types stay for Guarded's impl).
  • bun_standalone_graph: Error::UnsupportedTarget variant (never constructed; download_to_path returns other variants).
  • bun_bunfig: the unused OfflineMode re-export.

Verification

  • rg -w <symbol> src/ build/debug/codegen/ src/codegen/ returned only the definition for each deleted item.
  • bun bd builds clean.
  • bun run rust:check-all passes on all 10 targets (linux/macos/windows × x64/aarch64, plus musl).
  • Smoke tests pass: structured-clone.test.ts (231/231), structuredClone-classes.test.ts, worker_threads.test.ts (91/91), websocket-client.test.ts, abort.test.ts, performance-entries.test.ts, wasi.test.js, deno/event/event-target.test.ts.
  • New test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts guards against reintroduction: fails (7/7) with src/ at main, passes (7/7) with this diff.

[review] gate passed · iteration 1 · 30 files touched

fails on main (without fix)
ASAN without fix: 7 FAILED
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts
bun test v1.4.0 (e0122fcf0)

test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts:
47 |     ["src/jsc/bindings/webcore/SerializedScriptValue.h", /static Ref<SerializedScriptValue> nullValue\(\)/],
48 |     ["src/jsc/bindings/webcore/SerializedScriptValue.h", /static uint32_t wireFormatVersion\(\)/],
49 |     ["src/jsc/bindings/webcore/SerializedScriptValue.h", /void encode\(Encoder&\) const/],
50 |     ["src/jsc/bindings/webcore/SerializedScriptValue.h", /static RefPtr<SerializedScriptValue> decode\(Decoder&/],
51 |   ];
52 |   expect(resurrected(checks)).toEqual([]);
                                   ^
error: expect(received).toEqual(expected)

- []
+ [
+   "src/jsc/bindings/webcore/SerializedScriptValue.cpp: ENABLE\(OFFSCREEN_CANVAS_IN_WORKERS\)",
+   "src/jsc/bindings/webcore/SerializedScriptValue.cpp: ENABLE\(WEB_RTC\)",
+   "src/jsc/bindings/webcore/SerializedScriptValue.cpp: ENABLE\(WEB_CODECS\)",
+   "src/jsc/bindings/webcore/SerializedScriptValue.cpp:
... (truncated)

release without fix: 7 FAILED
bun test v1.4.0-canary.1 (754b4fe22)

test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts:
47 |     ["src/jsc/bindings/webcore/SerializedScriptValue.h", /static Ref<SerializedScriptValue> nullValue\(\)/],
48 |     ["src/jsc/bindings/webcore/SerializedScriptValue.h", /static uint32_t wireFormatVersion\(\)/],
49 |     ["src/jsc/bindings/webcore/SerializedScriptValue.h", /void encode\(Encoder&\) const/],
50 |     ["src/jsc/bindings/webcore/SerializedScriptValue.h", /static RefPtr<SerializedScriptValue> decode\(Decoder&/],
51 |   ];
52 |   expect(resurrected(checks)).toEqual([]);
                                   ^
error: expect(received).toEqual(expected)

- []
+ [
+   "src/jsc/bindings/webcore/SerializedScriptValue.cpp: ENABLE\(OFFSCREEN_CANVAS_IN_WORKERS\)",
+   "src/jsc/bindings/webcore/SerializedScriptValue.cpp: ENABLE\(WEB_RTC\)",
+   "src/jsc/bindings/webcore/SerializedScriptValue.cpp: ENABLE\(WEB_CODECS\)",
+   "src/jsc/bindings/webcore/SerializedScriptValue.cpp: readRTCCertificate",
+   "src/jsc/bindings/webcore/SerializedScriptValue.cpp: readOffscreenCanvas",
+   "src/jsc/bindings/webcore/SerializedScriptValue.cpp: readWebCodecsVideoFrame",
+   "
... (truncated)
passes on PR (with fix)
ASAN with fix: all passed
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts
bun test v1.4.0 (e0122fcf0)

test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts:
(pass) dead SerializedScriptValue ENABLE() blocks and unused public methods do not reappear [71.54ms]
(pass) dead WebSocket create/connect overloads and commented-out WebKit blocks do not reappear [23.13ms]
(pass) dead Performance/PerformanceObserver/EventTarget members do not reappear [22.29ms]
(pass) dead JSDOMConvert* template specializations do not reappear [16.77ms]
(pass) dead windows/rescle.cpp resource-editing methods do not reappear [19.33ms]
(pass) dead wasi.ts bundle artifacts and debug scaffolding do not reappear [14.77ms]
(pass) dead Rust http/threading/standalone_graph/bunfig items do not reappear [8.79ms]

 7 pass
 0 fail
 7 expect() calls
Ran 7 tests across 1 file. [2.27s]
__F:0:S:0

release with fix: all passed
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped) in 718ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/138] gen ErrorCode+*.h
[2/138] gen bake.{client,server,error}.js
-> bake.client.js, bake.server.js, bake.error.js
[3/138] gen JSEvent.lut.h
Generating /workspace/bun/build/release/codegen/JSEvent.lut.h from /workspace/bun/src/jsc/bindings/webcore/JSEvent.cpp
[4/138] gen JSBuffer.lut.h
Generating /workspace/bun/build/release/codegen/JSBuffer.lut.h from /workspace/bun/src/jsc/bindings/JSBuffer.cpp
[5/138] gen cpp.rs (cppbind)
[6/138] gen JSSink.{cpp,h,lut.h,rs}
generated_jssink.rs: 6 sinks, 72 exported symbols
Generating /workspace/bun/build/release/codegen/JSSink.lut.h from /workspace/bun/build/release/codegen/JSSink.lut.txt
[7/138] gen generated_host_exports.rs
generated_host_exports.rs: 94 exports (host=3, lazy=10, generic=81, rust=0); 239 extern-C blocks audited
[8/138] gen JS modules (bundle-modules)
Preprocess modules (9054ms)
Bundle modules (45ms)
Postprocesss modules (217ms)
Bundle Functions (732ms)
Generate Code (35ms)

[10.10s] Bundled "src/js" for production
  2561 kb
  193 internal modules
  1
... (truncated)
diff hotspot
src/bunfig/bunfig.rs                               |    2 -
 src/http/lib.rs                                    |   12 -
 src/js/node/wasi.ts                                |  282 +--
 src/js/thirdparty/ws.js                            |   19 -
 src/jsc/bindings/IDLTypes.h                        |    8 -
 src/jsc/bindings/webcore/Event.h                   |    1 -
 src/jsc/bindings/webcore/EventListenerMap.cpp      |   13 -
 src/jsc/bindings/webcore/EventListenerMap.h        |    1 -
 src/jsc/bindings/webcore/EventTarget.cpp           |   29 +-
 src/jsc/bindings/webcore/EventTarget.h             |    9 -
 src/jsc/bindings/webcore/JSDOMConvertNumbers.h     |   30 -
 src/jsc/bindings/webcore/JSDOMConvertRecord.h      |   31 -
 src/jsc/bindings/webcore/JSDOMConvertSequences.h   |  209 --
 src/jsc/bindings/webcore/JSDOMConvertStrings.cpp   |   25 -
 src/jsc/bindings/webcore/JSDOMConvertStrings.h     |   95 -
 src/jsc/bindings/webcore/JSDOMConvertUnion.h       |   21 -
 src/jsc/bindings/webcore/Performance.cpp           |  165 +-
 src/jsc/bindings/webcore/Performance.h             |   27 +-
 src/jsc/bindings/webcore/PerformanceObserver.cpp   |    2 +-
 src/jsc/bindings/webcore/PerformanceObserver.h     |    4 -
 src/jsc/bindings/webcore/SerializedScriptValue.cpp | 2163 +-------------------
 src/jsc/bindings/webcore/SerializedScriptValue.h   |  213 +-
 src/jsc/bindings/webcore/WebSocket.cpp             |  197 --
 src/jsc/bindings/webcore/WebSocket.h               |   15 -
 src/jsc/bindings/windows/rescle.cpp                |  261 ---
 src/jsc/bindings/windows/rescle.h                  |   21 -
 src/standalone_graph/StandaloneModuleGraph.rs      |    4 -
 src/standalone_graph/error.rs                      |    3 -
 src/threading/lib.rs                               |    5 +-
 .../dead-symbols-ssv-wasi-webcore.test.ts          |  160 ++
 30 files changed, 177 insertions(+), 3850 deletions(-)

gate history · 7 passed · 0 rejected · iteration 1

evidence per changed file
file                                              reads  edits  tests
src/bunfig/bunfig.rs                                  0      0      0
src/http/lib.rs                                       0      0      0
src/js/node/wasi.ts                                   0      0      0
src/js/thirdparty/ws.js                               0      0      0
src/jsc/bindings/IDLTypes.h                           1      1      0
src/jsc/bindings/webcore/Event.h                      1      1      0
src/jsc/bindings/webcore/EventListenerMap.cpp         1      1      0
src/jsc/bindings/webcore/EventListenerMap.h           1      1      0
src/jsc/bindings/webcore/EventTarget.cpp              0      0      0
src/jsc/bindings/webcore/EventTarget.h                0      0      0
src/jsc/bindings/webcore/JSDOMConvertNumbers.h        2      1      0
src/jsc/bindings/webcore/JSDOMConvertRecord.h         0      0      0
src/jsc/bindings/webcore/JSDOMConvertSequences.h      0      0      0
src/jsc/bindings/webcore/JSDOMConvertStrings.cpp      0      0      0
src/jsc/bindings/webcore/JSDOMConvertStrings.h        0      0      0
src/jsc/bindings/webcore/JSDOMConvertUnion.h          0      0      0
(+ 14 more files)

…JSDOMConvert*, rescle, wasi

SerializedScriptValue.cpp/.h (-2360 LOC): delete all #if ENABLE(WEB_RTC),
ENABLE(WEB_CODECS), ENABLE(OFFSCREEN_CANVAS_IN_WORKERS),
ENABLE(PREDEFINED_COLOR_SPACE_DISPLAY_P3) blocks (all =0 in Bun's JSCOnly
cmakeconfig.h; the guarded types have no headers under src/). Delete ~1200
lines of long-commented-out DOM geometry / ImageBitmap / File / Blob /
ImageData serialization paths. Delete uncalled public methods
create(StringView), create(JSContextRef,...), deserialize(JSContextRef,...),
toString(), nullValue(), wireFormatVersion(), encode<>/decode<>() and their
private-only helpers (CloneSerializer::serialize(StringView,...),
CloneDeserializer::deserializeString, blobFilePathForBlobURL, wrapCryptoKey,
unwrapCryptoKey, write/read(DestinationColorSpaceTag), PLATFORM(COCOA)
CFDataRef helpers). Delete orphaned enums PredefinedColorSpaceTag,
DestinationColorSpaceTag, ImageDataPoolTag and 18 never-written
SerializationTag values.

WebSocket.cpp/.h (-212 LOC): delete uncalled create/connect overloads,
didUpdateBufferedAmount, offerPerMessageDeflate getter, and 2022-era
commented-out CSP / MixedContentChecker / suspend/resume /
INTELLIGENT_TRACKING_PREVENTION / ConnectedWebSocketKind::Server blocks.
Remove the now-orphaned m_dispatchedErrorEvent field.

JSDOMConvert*.h/.cpp (-381 LOC): delete NumericSequenceConverter and the five
SequenceConverter<IDL{Long,Float,UnrestrictedFloat,Double,UnrestrictedDouble}>
specializations (IDLSequence<T> is only instantiated with
string/enum/interface/dictionary element types in Bun). Delete
Converter<IDLFrozenArray<T>>, JSConverter<IDLRecord<K,V>>,
IDLAllowSharedAdaptor<IDLUnion<...>> specs, propertyNameTo{,Atom}String,
the IDLLegacyNullToEmpty{,Atom}StringAdaptor and
IDLAtomStringAdaptor<IDL{USV,Byte}String> converters, and
valueTo{Byte,USV}AtomString.

windows/rescle.cpp/.h (-278 LOC): rescle__setWindowsMetadata uses only Load,
SetIcon, SetVersionString, SetFileVersion, SetProductVersion, Commit. Delete
SetExecutionLevel/IsExecutionLevelSet/SetApplicationManifest/
IsApplicationManifestSet, GetVersionString, ChangeString, ChangeRcData,
GetString, OnEnumResourceManifest and its Load() registration, the now
always-empty execution-level/manifest branches in Commit(), ReadFileToString,
and five unused RU_VS_* macros.

Performance.cpp/.h (-150 LOC): delete uncalled addResourceTiming and its
private-only isResourceTimingBufferFull/m_backupResourceTimingBuffer/
m_waitingForBackupBufferToBeProcessed, allowHighPrecisionTime/
highTimePrecision, timeResolution,
relativeTimeFromTimeOriginInReducedResolution, and the long-commented-out
navigation()/addNavigationTiming()/resourceTimingBufferFullTimerFired blocks.

PerformanceObserver.h: delete hasNavigationTiming/addedNavigationTiming/
m_hasNavigationTiming (only referenced by the above commented-out code).

EventTarget.cpp/.h + EventListenerMap (-51 LOC): delete isPaymentRequest()
(no callers, no overriders), hasCapturingEventListeners and its only caller
EventListenerMap::containsCapturing, the decl-only invalidateJSEventListeners,
and the legacyType() static + its fallback block in fireEventListeners
(legacyType unconditionally returned nullAtom() since 2022).

AbortSignal.cpp/.h + JSAbortSignalCustom.cpp (-29 LOC): delete signalFollow
(no callers). It was the only writer of m_followingSignal, so also delete
m_followingSignal, isFollowingSignal(), and its always-false check in
JSAbortSignalOwner::isReachableFromOpaqueRoots.

wasi.ts (-280 LOC): delete the four exports.X = ... = void 0 pre-declaration
chains (tsc emit artifact from the wasi-js bundle; every property is
re-assigned immediately after). Delete WASIExitError/WASIKillError classes,
exports.SOCKET_DEFAULT_RIGHTS, initWasiFdInfo() (unreferenced, contains debug
console.log), and the if(log.enabled){...} blocks (log is hard-coded to
() => {}).

ws.js: delete the long-commented-out secWebSocketExtensions /
PerMessageDeflate block (May 2023).

Rust: delete bun_http's PRINT_EVERY/PRINT_EVERY_I debug scaffolding and its
always-false block; drop the unused GuardedBy/RawMutex/RwLockReadGuard/
RwLockWriteGuard re-exports from bun_threading (the backing types stay);
delete standalone_graph::Error::UnsupportedTarget (never constructed);
delete the unused bunfig::OfflineMode re-export.

Verified: bun bd, bun run rust:check-all (all 10 targets), and smoke tests
for structured-clone, worker_threads, websocket-client, abort,
performance-entries, wasi, event-target all pass.
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Changes

The pull request removes unused APIs and instrumentation across Rust, WASI, WebCore, WebSocket, Windows resource editing, and structured cloning. It also updates HTTP receive pausing, numeric IDL conversion, performance observer plumbing, and dead-symbol source linting.

API and runtime consolidation

Layer / File(s) Summary
Runtime and Rust cleanup
src/http/lib.rs, src/js/node/wasi.ts, src/js/thirdparty/ws.js, src/bunfig/bunfig.rs, src/standalone_graph/..., src/threading/lib.rs
Removes obsolete exports, logging, WASI initialization, and Rust error symbols. HTTP progress updates can pause socket reads when more data is expected.
Event API and dispatch cleanup
src/jsc/bindings/webcore/Event*
Removes event and listener APIs. Trusted-event legacy listener fallback is deleted.
DOM conversion consolidation
src/jsc/bindings/IDLTypes.h, src/jsc/bindings/webcore/JSDOMConvert*
Moves numeric conversion into direct JSValue handling and removes obsolete conversion specializations and adaptors.
Performance observer and timing API reduction
src/jsc/bindings/webcore/Performance*
Simplifies timing precision and resource-buffer state. Buffered entry collection no longer receives a PerformanceObserver.
Structured clone contracts and transfer
src/jsc/bindings/webcore/SerializedScriptValue.*
Reshapes serialization tags, buffer growth, transfer state, deserializer plumbing, supported transfer types, constructors, and public APIs.
WebSocket API narrowing
src/jsc/bindings/webcore/WebSocket.*
Removes connection overloads, callbacks, accessors, state, and inactive code paths.
Windows resource updater reduction
src/jsc/bindings/windows/rescle.*
Removes manifest processing and several version, string, RCDATA, and execution-level APIs.
Dead-symbol regression lint
test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts
Adds source-tree checks for removed symbols across the affected modules.

Possibly related PRs

  • oven-sh/bun#35941: Both changes modify WASI getiovs truncation and logging behavior.
  • oven-sh/bun#36168: Both changes modify structured-clone serialization and cross-process transfer paths.
  • oven-sh/bun#36221: Both changes modify buffered performance-entry delivery.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the primary dead-code cleanup and names the main affected modules.
Description check ✅ Passed The description provides detailed change scope and verification results, although it does not use the template headings exactly.

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

Comment thread test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts Outdated
Comment thread src/jsc/bindings/webcore/Performance.cpp Outdated
Source-lint test: three WebSocket.h regexes did not match the pre-PR
signatures (didReceiveData takes named params; connect returns
ExceptionOr<void>), so they were vacuous. Fixed to match the actual removed
declarations; verified all 71 checks now match main and none match this branch.

Finish the one-hop cascade for code this PR made dead:
- Event.h: delete setType() (only callers were the removed legacyType
  fallback in fireEventListeners).
- Performance.cpp: make timePrecision constexpr (only writer
  allowHighPrecisionTime() was removed); delete two commented-out
  hasNavigationTiming/addedNavigationTiming blocks that now referenced methods
  removed from PerformanceObserver.h; drop the now-unused PerformanceObserver&
  param from appendBufferedEntriesByType and update its one caller.
- rescle.cpp: drop <assert.h>, <fstream>, <codecvt>, <algorithm> includes
  whose only consumers were the removed ReadFileToString / ChangeString /
  GetString / ChangeRcData / manifest branches.
Comment thread src/jsc/bindings/webcore/Performance.h Outdated
…TimingBufferFull removal

m_resourceTimingBufferSize and m_resourceTimingBufferFullFlag became
write-only once their sole readers were removed; drop the fields and their
dead stores in clearResourceTimings/setResourceTimingBufferSize. Drop the
ResourceTiming/ResourceResponse/PerformancePaintTiming forward-decls and the
commented-out includes and member decls that were their only remaining
references.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (4)
src/jsc/bindings/webcore/SerializedScriptValue.cpp (3)

2340-2362: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

m_sharedBuffers is left uninitialized by this constructor.

m_sharedBuffers (declared at Line 3941 without an initializer) is only assigned in the longer constructor. Instances created through this overload — e.g. the crypto-key rawKeyDeserializer at Line 3888 — carry an indeterminate pointer, and readTerminal's SharedArrayBufferTag branch tests !m_sharedBuffers before dereferencing it. Not reachable through readCryptoKey today, but it is UB waiting on the next caller.

Same for m_blobURLs/m_blobFilePaths being default-constructed here, which is fine, but the raw pointer needs an explicit default.

🛡️ Proposed fix
-    ArrayBufferContentsArray* m_sharedBuffers;
+    ArrayBufferContentsArray* m_sharedBuffers { nullptr };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/jsc/bindings/webcore/SerializedScriptValue.cpp` around lines 2340 - 2362,
Initialize m_sharedBuffers to nullptr in the shown CloneDeserializer
constructor’s initializer list, matching the default state expected by
readTerminal’s SharedArrayBufferTag handling. Leave m_blobURLs and
m_blobFilePaths unchanged.

183-200: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Tag numbering preserved for retained tags — wire compatibility is intact.

Nit: the serialization grammar comment further down still documents removed terminals (DOMPoint/DOMRect/DOMMatrix/DOMQuad, ImageBitmapTag, OffscreenCanvasTransferTag, RTCDataChannelTransferTag, WebCodecsEncodedVideoChunkTag, DestinationColorSpace, File/FileList/ImageData/Blob) whose tags and read/write paths no longer exist. Worth trimming in the same pass so the grammar stays a usable reference.

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

In `@src/jsc/bindings/webcore/SerializedScriptValue.cpp` around lines 183 - 200,
Update the serialization grammar comment associated with the tag definitions to
remove entries for deleted terminals, including DOM geometry types, ImageBitmap,
OffscreenCanvas, RTCDataChannel, WebCodecsEncodedVideoChunk,
DestinationColorSpace, File/FileList/ImageData, and Blob. Keep the grammar
aligned only with the retained tags and existing read/write paths, including the
current Bun-specific tags.

3886-3893: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Temporary {} bound to the const Vector<RefPtr<MessagePort>>& member outlives its lifetime.

m_messagePorts is a reference member; the {} argument materializes a temporary that dies at the end of this declaration statement, so rawKeyDeserializer holds a dangling reference for the subsequent readCryptoKey call. Harmless only because readCryptoKey never touches message ports. Hoist a named empty vector to make it safe.

🛡️ Proposed fix
             JSValue cryptoKey;
-            CloneDeserializer rawKeyDeserializer(m_lexicalGlobalObject, m_globalObject, {}, nullptr, serializedKey);
+            Vector<RefPtr<MessagePort>> noMessagePorts;
+            CloneDeserializer rawKeyDeserializer(m_lexicalGlobalObject, m_globalObject, noMessagePorts, nullptr, serializedKey);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/jsc/bindings/webcore/SerializedScriptValue.cpp` around lines 3886 - 3893,
In the deserialization block around CloneDeserializer, replace the temporary {}
message-port argument with a named empty Vector<RefPtr<MessagePort>> whose
lifetime covers rawKeyDeserializer and its readCryptoKey call. Pass that named
vector to the constructor while preserving the existing crypto-key handling.
src/js/node/wasi.ts (1)

658-686: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove the unconditional debug logging from getiovs.

Malformed guest iovecs now write debug objects to host stdout in both branches. Keep the clamping behavior, but remove these console.log calls to avoid introducing noisy observable output.

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

In `@src/js/node/wasi.ts` around lines 658 - 686, Remove the unconditional
console.log debug-object calls from both malformed-buffer branches in getiovs,
while preserving the existing bufLen clamping behavior and error handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts`:
- Around line 89-90: Add header-file checks to the dead-symbol test for every
removed AbortSignal and ResourceUpdater declaration, alongside the existing .cpp
definition patterns. Cover the relevant retained API variants identified by
rescle.h so reintroduced declarations in AbortSignal.h or rescle.h cause the
test to fail.

---

Outside diff comments:
In `@src/js/node/wasi.ts`:
- Around line 658-686: Remove the unconditional console.log debug-object calls
from both malformed-buffer branches in getiovs, while preserving the existing
bufLen clamping behavior and error handling.

In `@src/jsc/bindings/webcore/SerializedScriptValue.cpp`:
- Around line 2340-2362: Initialize m_sharedBuffers to nullptr in the shown
CloneDeserializer constructor’s initializer list, matching the default state
expected by readTerminal’s SharedArrayBufferTag handling. Leave m_blobURLs and
m_blobFilePaths unchanged.
- Around line 183-200: Update the serialization grammar comment associated with
the tag definitions to remove entries for deleted terminals, including DOM
geometry types, ImageBitmap, OffscreenCanvas, RTCDataChannel,
WebCodecsEncodedVideoChunk, DestinationColorSpace, File/FileList/ImageData, and
Blob. Keep the grammar aligned only with the retained tags and existing
read/write paths, including the current Bun-specific tags.
- Around line 3886-3893: In the deserialization block around CloneDeserializer,
replace the temporary {} message-port argument with a named empty
Vector<RefPtr<MessagePort>> whose lifetime covers rawKeyDeserializer and its
readCryptoKey call. Pass that named vector to the constructor while preserving
the existing crypto-key handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a3c7ff54-3e4c-4206-a26f-1066def8cd52

📥 Commits

Reviewing files that changed from the base of the PR and between c08f665 and bfd38c6.

📒 Files selected for processing (31)
  • src/bunfig/bunfig.rs
  • src/http/lib.rs
  • src/js/node/wasi.ts
  • src/js/thirdparty/ws.js
  • src/jsc/bindings/webcore/AbortSignal.cpp
  • src/jsc/bindings/webcore/AbortSignal.h
  • src/jsc/bindings/webcore/Event.h
  • src/jsc/bindings/webcore/EventListenerMap.cpp
  • src/jsc/bindings/webcore/EventListenerMap.h
  • src/jsc/bindings/webcore/EventTarget.cpp
  • src/jsc/bindings/webcore/EventTarget.h
  • src/jsc/bindings/webcore/JSAbortSignalCustom.cpp
  • src/jsc/bindings/webcore/JSDOMConvertRecord.h
  • src/jsc/bindings/webcore/JSDOMConvertSequences.h
  • src/jsc/bindings/webcore/JSDOMConvertStrings.cpp
  • src/jsc/bindings/webcore/JSDOMConvertStrings.h
  • src/jsc/bindings/webcore/JSDOMConvertUnion.h
  • src/jsc/bindings/webcore/Performance.cpp
  • src/jsc/bindings/webcore/Performance.h
  • src/jsc/bindings/webcore/PerformanceObserver.cpp
  • src/jsc/bindings/webcore/PerformanceObserver.h
  • src/jsc/bindings/webcore/SerializedScriptValue.cpp
  • src/jsc/bindings/webcore/SerializedScriptValue.h
  • src/jsc/bindings/webcore/WebSocket.cpp
  • src/jsc/bindings/webcore/WebSocket.h
  • src/jsc/bindings/windows/rescle.cpp
  • src/jsc/bindings/windows/rescle.h
  • src/standalone_graph/StandaloneModuleGraph.rs
  • src/standalone_graph/error.rs
  • src/threading/lib.rs
  • test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts
💤 Files with no reviewable changes (22)
  • src/bunfig/bunfig.rs
  • src/jsc/bindings/webcore/EventListenerMap.h
  • src/js/thirdparty/ws.js
  • src/jsc/bindings/webcore/EventListenerMap.cpp
  • src/jsc/bindings/webcore/JSAbortSignalCustom.cpp
  • src/jsc/bindings/webcore/Event.h
  • src/jsc/bindings/webcore/PerformanceObserver.h
  • src/jsc/bindings/webcore/JSDOMConvertRecord.h
  • src/jsc/bindings/webcore/JSDOMConvertUnion.h
  • src/standalone_graph/error.rs
  • src/jsc/bindings/webcore/JSDOMConvertStrings.cpp
  • src/jsc/bindings/webcore/AbortSignal.h
  • src/standalone_graph/StandaloneModuleGraph.rs
  • src/jsc/bindings/webcore/AbortSignal.cpp
  • src/jsc/bindings/windows/rescle.h
  • src/http/lib.rs
  • src/jsc/bindings/webcore/WebSocket.h
  • src/jsc/bindings/webcore/EventTarget.h
  • src/jsc/bindings/webcore/JSDOMConvertStrings.h
  • src/jsc/bindings/webcore/WebSocket.cpp
  • src/jsc/bindings/windows/rescle.cpp
  • src/jsc/bindings/webcore/JSDOMConvertSequences.h

Comment thread test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All three rounds of prior feedback (vacuous test regexes; timePrecision/Event::setType/rescle-includes cascade; Performance.h cascade) are addressed in ae21882 and bfd38c6, and this pass found nothing new. Deferring to a human because of scale: -3.8k LOC across 31 files, including SerializedScriptValue (structuredClone/postMessage wire format), JSAbortSignalOwner::isReachableFromOpaqueRoots (GC reachability), EventTarget::fireEventListeners, and JSDOMConvert* template specializations — worth a human skim to confirm nothing load-bearing was swept up.

What was reviewed: verified legacyType() returned nullAtom() unconditionally so the removed fireEventListeners fallback was unreachable; confirmed signalFollow was the sole writer of m_followingSignal so the removed isFollowingSignal() GC-root check was always false; confirmed setResourceTimingBufferSize becoming a no-op is behavior-preserving (its stored value had no remaining reader); confirmed the removed SerializationTag enum values leave gaps rather than renumbering, so wire-format compatibility is preserved.

Extended reasoning...

Overview

Net -3.8k LOC dead-code sweep across 31 files. The bulk is SerializedScriptValue.cpp/.h (~2.3k lines): always-off #if ENABLE(OFFSCREEN_CANVAS_IN_WORKERS|WEB_RTC|WEB_CODECS) blocks, ~1.2k lines of 2022-era commented-out DOM-geometry/Blob/ImageData serialization, and uncalled public methods (nullValue, toString, wireFormatVersion, encode/decode<T>, create(StringView), the JSContextRef overloads). The rest: WebSocket unused overloads and commented-out WebKit blocks, Performance/PerformanceObserver unreferenced buffer machinery, EventTarget unreachable legacy-type fallback, AbortSignal::signalFollow and its GC-reachability check, JSDOMConvert* numeric-sequence and string-adaptor template specializations, unused rescle.cpp resource-editing methods, wasi.ts tsc emit artifacts and dead debug scaffolding, ws.js commented-out block, and four small Rust items. A source-lint test guards against reintroduction.

I reviewed this PR across three prior iterations: (1) three vacuous regex patterns in the source-lint test that didn't match the pre-PR source; (2) four one-hop cascade orphans (timePrecision mutability, Event::setType, rescle #includes, commented-out hasNavigationTiming blocks); (3) three more Performance.h cascade orphans (ResourceTiming forward-decl, m_resourceTimingBufferSize, m_resourceTimingBufferFullFlag). All were fixed in ae21882 and bfd38c6. This pass found nothing new.

Security risks

None identified. Pure deletions of unreferenced code, commented-out blocks, and always-off #if branches. No new input-handling paths, no auth/crypto/permission surface touched. The removed wrapCryptoKey/unwrapCryptoKey helpers were already dead (the live path skips wrapping per the existing comment). The JSAbortSignalOwner::isReachableFromOpaqueRoots change removes a check that was provably always false (m_followingSignal had no writer), so GC behavior is unchanged.

Level of scrutiny

High — this is why I'm deferring rather than approving. The touched files are load-bearing runtime paths: SerializedScriptValue backs structuredClone/postMessage/worker_threads transfer; EventTarget::fireEventListeners is the DOM event dispatch hot path; isReachableFromOpaqueRoots is GC-safety code; the JSDOMConvert* headers are template specializations whose "used-ness" depends on instantiation across all generated bindings. The build passing on all 10 targets plus the smoke-test suite (structured-clone, worker_threads, websocket-client, abort, performance-entries, wasi) is strong evidence, but a -3.8k sweep of this breadth deserves a human pass — particularly the SerializedScriptValue tag-enum deletions (verified they leave gaps, not renumber) and the JSDOMConvert specializations (verified via build, but a maintainer familiar with which IDL types Bun's codegen emits should confirm).

Other factors

  • The PR description is detailed and names every deletion with its verification method (rg across src/ + build/debug/codegen/, bun bd, rust:check-all on 10 targets, 8 smoke-test files).
  • The author was responsive across three review rounds and applied the cascade principle beyond what I asked (e.g. also removed sibling ResourceResponse/PerformancePaintTiming forward-decls in bfd38c6, ran a one-off verifier confirming all 71 lint patterns match main and none match this branch).
  • The new source-lint test follows the existing test/internal/source-lints/ pattern and each check was verified non-vacuous after ae21882.
  • No overlap with the 11 other open dead-code PRs listed in the description.

Add header-file checks alongside the .cpp checks so a reintroduced
declaration (without the definition) still trips the lint.
@robobun

robobun commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator Author

On the out-of-diff review items:

  • m_sharedBuffers uninitialized in the short CloneDeserializer ctor and temporary {} bound to the m_messagePorts reference at rawKeyDeserializer: both are pre-existing on main (same code at SerializedScriptValue.cpp:5505 on main and the short ctor never initialized m_sharedBuffers before this PR either). This PR only removed commented-out lines adjacent to those call sites; it did not change the live code. Both are real latent-UB concerns but out of scope for a dead-code sweep, and currently harmless because readCryptoKey reads neither member.
  • wasi.ts console.log in getiovs: also pre-existing on main (same lines). This PR removed the no-op log("getiovs: warning...") calls that followed them, leaving the existing console.log unchanged, so the observable behavior is identical to before.
  • Serialization grammar comment still documents removed terminals: intentional. The comment block is the wire-format spec; the removed tag values leave gaps in the enum (not renumbered), and the grammar comment documents what a given tag byte means when encountered in a serialized blob, including historical tags a future decoder might still see in persisted data. Keeping it as-is.

Header-side lint checks added in ba206e3.

Comment thread src/jsc/bindings/windows/rescle.cpp
Comment thread src/jsc/bindings/webcore/JSDOMConvertSequences.h
…enceConverter/LegacyNullToEmpty removal

The five Converter<IDL{Long,Float,UnrestrictedFloat,Double,UnrestrictedDouble}>
convert(JSGlobalObject&, ThrowScope&, double) overloads existed only for the
removed NumericSequenceConverter::convertArray (the removed FIXME above it
documented that contract); the sibling convert(JSGlobalObject&, JSValue)
overloads inline their own logic. IDLLegacyNullToEmpty{,Atom}StringAdaptor
type tags in IDLTypes.h had no remaining references after their
Converter<>/JSConverter<> specializations were removed from
JSDOMConvertStrings.h.
Comment thread src/jsc/bindings/webcore/Performance.h
@Jarred-Sumner

Copy link
Copy Markdown
Collaborator

@robobun lets keep the AbortSignal one we're gonna need that soon

robobun added 2 commits July 31, 2026 10:18
Per review, this will be needed soon. Reverts the AbortSignal.cpp/.h and
JSAbortSignalCustom.cpp changes and drops the corresponding source-lint
checks.
@robobun

robobun commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator Author

Restored in 63bfbb2: AbortSignal::signalFollow, m_followingSignal, isFollowingSignal(), and the JSAbortSignalOwner::isReachableFromOpaqueRoots check are back to their main state. Dropped the corresponding source-lint checks. (754b4fe cleans up a stray Cargo.lock diff that rode along from a container reset.)

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Additional findings (outside current diff — PR may have been updated during review):

  • 🔴 Cargo.lock:289-297 — Commit 63bfbb2 (the AbortSignal restore) accidentally included a 19-line Cargo.lock deletion, dropping declared dependencies from the bun_brotli and bun_safety lockfile entries even though neither crate's Cargo.toml is touched by this PR — both manifests still declare all of them at HEAD. The lockfile is now inconsistent with the workspace: cargo build --locked will fail with "the lock file needs to be updated", and without --locked the next cargo invocation will silently regenerate it and undo this hunk. Please revert the Cargo.lock changes from 63bfbb2 (git checkout c08f6653 -- Cargo.lock).

    Extended reasoning...

    What happened

    Commit 63bfbb2 ("Restore AbortSignal::signalFollow and m_followingSignal") was pushed in response to Jarred's review comment asking to keep the AbortSignal removal. Its commit message and stat show it was intended as a C++-only revert:

     Cargo.lock                                            | 19 -------------------
     src/jsc/bindings/webcore/AbortSignal.cpp              | 19 +++++++++++++++++++
     src/jsc/bindings/webcore/AbortSignal.h                |  4 ++++
     src/jsc/bindings/webcore/JSAbortSignalCustom.cpp      |  6 ++++++
     .../dead-symbols-ssv-wasi-webcore.test.ts             |  9 ++-------
    

    The Cargo.lock hunk removes dependencies from two workspace crate entries:

    • bun_brotli: drops bitflags, bstr, bun_io, const_format, enum-map, enumset, libc, scopeguard, strum (keeps only bun_alloc, bun_brotli_sys, bun_core, thiserror)
    • bun_safety: drops bitflags, bstr, bun_alloc, const_format, enum-map, enumset, libc, scopeguard, strum, thiserror (keeps only bun_core)

    Why this is a desync, not an intentional prune

    Cargo.lock records the dependencies declared in each workspace member's Cargo.toml — it does not prune unused deps. For the lockfile to legitimately drop these entries, the corresponding Cargo.toml files would have to change. But:

    1. Neither manifest is in this PR's changed-files list. git diff c08f6653..HEAD --name-only -- 'src/**/Cargo.toml' Cargo.toml returns nothing.
    2. Both manifests at HEAD still declare every dropped dep. src/brotli/Cargo.toml unconditionally declares all 13 deps (bitflags, bstr, bun_io, const_format, enum-map, enumset, libc, scopeguard, strum, thiserror, bun_alloc, bun_core, bun_brotli_sys). src/safety/Cargo.toml declares all 11. None are feature-gated or cfg-conditional.
    3. This PR's intentional Rust changes don't touch dependency graphs. Per the PR description's Rust section, the only Rust edits are re-export removals in src/threading/lib.rs, src/bunfig/bunfig.rs, src/http/lib.rs, and an enum variant in src/standalone_graph/error.rs. None of those crates are bun_brotli or bun_safety, and none add or remove a [dependencies] entry.

    Step-by-step proof of the failure

    1. At the merge-base c08f665, Cargo.lock lists bun_brotli with 13 deps and bun_safety with 11 deps, matching their manifests.
    2. After 63bfbb2, Cargo.lock lists bun_brotli with 4 deps and bun_safety with 1 dep.
    3. src/brotli/Cargo.toml at HEAD still says bitflags.workspace = true (line 21), strum.workspace = true (line 14), etc. — all unconditional.
    4. When Cargo resolves the workspace, it reads src/brotli/Cargo.toml, sees bitflags declared, and finds the bun_brotli entry in Cargo.lock does not list it.
    5. With --locked: Cargo refuses to update the lockfile and errors with "the lock file /workspace/bun/Cargo.lock needs to be updated but --locked was passed to prevent this".
    6. Without --locked: Cargo silently rewrites the bun_brotli and bun_safety entries back to the full dependency list — undoing this hunk and leaving a dirty working tree for the next contributor.

    Why the PR's own verification didn't catch this

    The evidence block's rust:check-all and release-build verification were both run at commit 071f23d (visible in the console output header bun test v1.4.0 (071f23d7f)), which is the commit before 63bfbb2. The Cargo.lock desync was introduced in the very last commit and was never verified.

    Impact and fix

    Either --locked CI builds fail on this branch/after merge, or (if the build doesn't pass --locked) the lockfile silently regenerates on the next cargo invocation and this hunk becomes 19 lines of merge-conflict noise for whoever touches Cargo.lock next. Either way it is an accidental, unrelated change riding on a dead-code sweep PR.

    Fix: git checkout c08f6653 -- Cargo.lock (or drop Cargo.lock from the diff entirely — nothing in this PR should change it).

@robobun

robobun commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator Author

Re the Cargo.lock finding above: already fixed in 754b4fe (pushed ~1 minute after 63bfbb2). git diff c08f6653..HEAD -- Cargo.lock is empty at the current HEAD.

@robobun

robobun commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator Author

CI status: the diff itself is green. Two full CI runs (builds #86289 and #86351) each failed only on tests unrelated to this diff, all tagged flaky by ci:errors:

  • #86289: napi.test.ts (debian/windows), password.test.ts leak (alpine), plus 13 parallel-batch-only flakes that passed alone.
  • #86351: napi.test.ts (windows, same as before), watch-many-dirs.test.ts (ubuntu aarch64), plus 9 parallel-batch-only flakes that passed alone.

None of those tests touch any file in this diff (SerializedScriptValue, WebSocket, Performance, EventTarget, JSDOMConvert*, rescle, wasi.ts, ws.js, http/threading/standalone_graph/bunfig Rust). Locally, bun bd builds clean, bun run rust:check-all passes on all 10 targets, and the smoke-test suite (structured-clone.test.ts 231/231, worker_threads.test.ts 91/91, websocket-client, abort, performance, wasi, event-target) passes. The new source-lint test fails 7/7 with src/ at the branch base and passes 7/7 with this diff.

Ready for a maintainer to merge.

Jarred-Sumner pushed a commit that referenced this pull request Aug 1, 2026
…n_jsc Rust (#36576)

Net **-1185 lines** (+68 / -1253) across 24 files. Every removed item
was verified to have zero references across `src/` and
`build/debug/codegen/`, then confirmed by a full `bun bd` build and `bun
run rust:check-all`.

No overlap with the 11 open dead-code PRs (checked file lists of #34965
#34759 #36474 #36178 #36237 #35559 #35775 #36318 #36115 #35437 #35880).

### Whole-file deletions (C++, 1107 lines)

| File | LOC | Verification |
|---|---|---|
| `src/jsc/bindings/node/http/llhttp/api.h` | 357 | Never `#include`d.
Vendored upstream copy artifact; all 41 `LLHTTP_EXPORT` decls are
duplicated verbatim in `llhttp.h`, and `api.c` includes `llhttp.h` not
`api.h`. Only mentioned in `llhttp/README.md`. |
| `src/jsc/bindings/webcore/JSDOMConvertWebGL.{h,cpp}` | 317 | Entire
body guarded by `#if ENABLE(WEBGL)`. The .cpp `#include`s ~40 headers
(`JSANGLEInstancedArrays.h` etc.) that don't exist in the repo, so the
guard is provably inactive on every bun target.
`IDLWebGLAny`/`IDLWebGLExtension` used nowhere else. |
| `src/jsc/bindings/headers-cpp.h` | 190 | Only includer is
`headergen/sizegen.cpp`, which isn't in any build rule. File itself has
syntax errors (line 166 `#include ""ConsoleObject.h""`, lines 172-182
`#include ""`), so it cannot be compiling anywhere. |
| `src/jsc/bindings/webcore/HTTPHeaderValues.{h,cpp}` | 108 | Header
only included by its own .cpp; none of the five declared functions
(`textPlainContentType`, `formURLEncodedContentType`,
`applicationJSONContentType`, `noCache`, `maxAge0`) are called anywhere.
|
| `src/jsc/bindings/webcore/JSDOMConvertJSON.h` | 51 | Sole includer is
the umbrella `JSDOMConvert.h`. `IDLJSON` is referenced nowhere outside
`IDLTypes.h` (type decl) and this file. |
| `src/jsc/bindings/ares_build.h` | 42 | Zero `#include`s anywhere under
`src/`. Superseded by the generated
`build/<profile>/deps/cares/ares_build.h` emitted by
`scripts/build/deps/cares.ts`. |
| `src/jsc/bindings/webcore/TaskSource.h` | 29 | Never `#include`d. Only
referenced in commented-out code in `WebSocket.cpp` /
`JSDOMPromiseDeferred.cpp`. |
| `src/jsc/bindings/JSVMClientDataClient.h` | 13 | See `BunClientData`
below. |

### C++ symbol removals

- **`helpers.h`** (38 lines): `Zig::toAtomString(ZigString)`,
`toStringNotConst`, `__dot_char`/`ZigStringCwd`/`BunStringCwd`,
`toZigString(WTF::String*)`, `toZigString(JSC::Identifier&)` +
`(JSC::Identifier*)`, `Zig::toStringView(ZigString)`. rg across src/ and
codegen shows zero callers for each.
- **`headers-handwritten.h`** (22 lines): `WritableEvent` typedef + 8
consts, `ReadableEvent` typedef + 9 consts. Zero references anywhere.
- **`JSDOMWrapper.h`** (8 lines): `JSTextNodeType`,
`JSProcessingInstructionNodeType`, `JSDocumentTypeNodeType`,
`JSDocumentFragmentNodeType`, `JSDocumentWrapperType`,
`JSCommentNodeType`, `JSCDATASectionNodeType`, `JSAttrNodeType`. Only
referenced in commented-out code at `webcore/DOMJITHelpers.h:163-178`.
(`JSNodeType`/`JSNodeTypeMask`/`JSElementType`/`JSAsJSONType` kept.)
- **`BunClientData.{h,cpp}`** (9 lines): `addClient()` is never called,
so `m_clients` is always empty and the `~JSVMClientData`
`forEach`/`clear` loop is a no-op. Removed `addClient`, `m_clients`, the
dtor loop, and the include of `JSVMClientDataClient.h`.
- **`JSDOMConvert.h`** (2 lines): removed `#include` of the two deleted
headers.
- **`headergen/sizegen.cpp`** (2 lines): removed `#include
"headers-cpp.h"`. The file is not in any build rule and was already
uncompilable (its loop references `names[]`/`sizes[]`/`aligns[]`, none
of which were ever fully defined); leaving the loop untouched to
minimise conflict with #36115..

### Rust removals

- **`bun_core::String::github_action` + `StringGithubActionFormatter`**
(22 lines): all four `.github_action()` call sites in
`VirtualMachine.rs` are on `jsc::ZigString`, not `bun_core::String`. The
`ZigString` variant is kept.
- **`bun_jsc::JSUint8Array::ptr()` +
`sizes::BUN_FFI_POINTER_OFFSET_TO_TYPED_ARRAY_VECTOR`** (14 lines): zero
callers.
- **`bun_jsc::RefString::to_js()`** (9 lines): the sole external
`RefString` user (`filesystem_router.rs`) never calls `.to_js()`.
Removed along with now-unused
`JSGlobalObject`/`JSValue`/`JsResult`/`StringJsc` imports.
- **`bun_jsc::Errorable::value()`** (7 lines): identical body to
`Errorable::ok()`; every caller uses `ok()`.

### Verification

- `bun bd` passes
- `bun run rust:check-all` passes on all targets
- `bun bd test test/internal/source-lints/` passes (62 tests)
- `bun bd test test/js/node/inspector/` passes (67 tests; exercises
`BunDebugger.cpp`)
- `bun bd test test/cli/install/bun-install-lifecycle-scripts.test.ts`
passes (3 pre-existing env failures unrelated to this diff, reproduced
on main)

### Followups (not in this diff)

- `src/jsc/bindings/CachedScript.h` is semantically vestigial (empty
class, all callers pass `nullptr`) but removing it requires editing
signatures in `ScriptExecutionContext.h` /
`JSDOMExceptionHandling.{h,cpp}`.
- `src/ast/lib.rs` `StringBuilder` stub + the `count()` method chain is
a no-op cluster but removing it requires dropping the `&mut
StringBuilder` parameter from three `clone_with_builder` signatures.
- `src/runtime/api/bun/h2/connection.rs`
`send_header_block`/`send_push_promise`/`send_data`/`encode_header`/`begin_header_block`
(~173 LOC) are only called from `#[cfg(test)]`; intentionally staged per
the `h2/mod.rs` module doc for a future rewrite, so left alone.

<!-- robobun:evidence:begin -->

---

**[review]** gate passed · iteration 2 · 24 files touched

<details><summary>fails on main (without fix)</summary>

```console
ASAN without fix: 2 FAILED
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/internal/source-lints/dead-symbols-llhttp-helpers-install.test.ts
bun test v1.4.0 (6057ada)

test/internal/source-lints/dead-symbols-llhttp-helpers-install.test.ts:
50 |     ["src/jsc/bindings/webcore/JSDOMConvert.h", /JSDOMConvertWebGL\.h/],
51 |     ["src/jsc/bindings/IDLTypes.h", /\bIDLJSON\b/],
52 |     ["src/jsc/headergen/sizegen.cpp", /headers-cpp\.h/],
53 |   ];
54 |   const resurrected = checks.filter(([file, re]) => re.test(src(file))).map(([file, re]) => `${file}: ${re.source}`);
55 |   expect(resurrected).toEqual([]);
                           ^
error: expect(received).toEqual(expected)

- []
+ [
+   "src/jsc/bindings/helpers.h: static WTF::AtomString toAtomString\(ZigString",
+   "src/jsc/bindings/helpers.h: \btoStringNotConst\b",
+   "src/jsc/bindings/helpers.h: \b__dot_char\b",
+   "src/jsc/bindings/helpers.h: \bZigStringCwd\b",
+   "src/jsc/bindings/helpers.h: \bBunStringCwd\b",
+   "src/jsc/bindings/helpers.h: toZigString\(WTF::String\*",
+   "src/jsc/bindings/helpers.h: toZigString\(JSC::Identifier&",
+   "src/
... (truncated)

release without fix: 2 FAILED
bun test v1.4.0-canary.1 (91f57fe)

test/internal/source-lints/dead-symbols-llhttp-helpers-install.test.ts:
50 |     ["src/jsc/bindings/webcore/JSDOMConvert.h", /JSDOMConvertWebGL\.h/],
51 |     ["src/jsc/bindings/IDLTypes.h", /\bIDLJSON\b/],
52 |     ["src/jsc/headergen/sizegen.cpp", /headers-cpp\.h/],
53 |   ];
54 |   const resurrected = checks.filter(([file, re]) => re.test(src(file))).map(([file, re]) => `${file}: ${re.source}`);
55 |   expect(resurrected).toEqual([]);
                           ^
error: expect(received).toEqual(expected)

- []
+ [
+   "src/jsc/bindings/helpers.h: static WTF::AtomString toAtomString\(ZigString",
+   "src/jsc/bindings/helpers.h: \btoStringNotConst\b",
+   "src/jsc/bindings/helpers.h: \b__dot_char\b",
+   "src/jsc/bindings/helpers.h: \bZigStringCwd\b",
+   "src/jsc/bindings/helpers.h: \bBunStringCwd\b",
+   "src/jsc/bindings/helpers.h: toZigString\(WTF::String\*",
+   "src/jsc/bindings/helpers.h: toZigString\(JSC::Identifier&",
+   "src/jsc/bindings/helpers.h: toZigString\(JSC::Identifier\*",
+   "src/jsc/bindings/helpers.h: static WTF::StringView toStringView\(ZigString",
+   "src/jsc/bindings/headers-handwritten.h: \bWritableE
... (truncated)
```

</details>

<details><summary>passes on PR (with fix)</summary>

```console
ASAN with fix: all passed
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/internal/source-lints/dead-symbols-llhttp-helpers-install.test.ts
bun test v1.4.0 (6057ada)

test/internal/source-lints/dead-symbols-llhttp-helpers-install.test.ts:
(pass) dead C++ symbols in helpers.h / headers-handwritten.h / JSDOMWrapper.h / BunClientData do not reappear [37.66ms]
(pass) dead Rust symbols in bun_core / jsc do not reappear [9.99ms]

 2 pass
 0 fail
 2 expect() calls
Ran 2 tests across 1 file. [2.03s]
__F:0:S:0

release with fix: all passed
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped) in 647ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/122] gen cpp.rs (cppbind)
[2/122] gen generated_host_exports.rs
generated_host_exports.rs: 94 exports (host=3, lazy=10, generic=81, rust=0); 239 extern-C blocks audited
[3/122] gen JS modules (bundle-modules)
Preprocess modules (8812ms)
Bundle modules (38ms)
Postprocesss modules (34ms)
Bundle Functions (748ms)
Generate Code (19ms)

[9.67s] Bundled "src/js" for production
  2569 kb
  193 internal modules
  13 native modules
  90 internal functions across 19 files
[3/121] cargo bun_bin → libbun_rust.a (--target x86_64-unknown-linux-gnu)

  nightly-2026-07-20-x86_64-unknown-linux-gnu unchanged - rustc 1.99.0-nightly (9f36de775 2026-07-19)

�[1m�[92m   Compiling�[0m bun_core v0.0.0 (/workspace/bun/src/bun_core)
�[1m�[92m   Compiling�[0m bun_errno v0.0.0 (/workspace/bun/src/errno)
�[1m�[92m   Compiling�[0m bun_ptr v0.0.0 (/workspace/bun/src/ptr)
�[1m�[92m   Compiling�[0m bun_boringssl_sys v0.0.0 (/workspace/bun/src/boringssl_sys)
�[1m�[92m   Compiling�[0m bun_safety v0.0.0 (/workspace/bun/src/safety)
�[1m�
... (truncated)
```

</details>

<details><summary>diff hotspot</summary>

```
src/bun_core/string/mod.rs                         |  22 --
 src/jsc/Errorable.rs                               |   7 -
 src/jsc/JSUint8Array.rs                            |  13 -
 src/jsc/RefString.rs                               |   9 -
 src/jsc/bindings/BunClientData.cpp                 |   5 -
 src/jsc/bindings/BunClientData.h                   |   5 -
 src/jsc/bindings/IDLTypes.h                        |  12 -
 src/jsc/bindings/JSDOMWrapper.h                    |   8 -
 src/jsc/bindings/JSVMClientDataClient.h            |  13 -
 src/jsc/bindings/ares_build.h                      |  42 ---
 src/jsc/bindings/headers-cpp.h                     | 190 -----------
 src/jsc/bindings/headers-handwritten.h             |  22 --
 src/jsc/bindings/helpers.h                         |  38 ---
 src/jsc/bindings/node/http/llhttp/api.h            | 357 ---------------------
 src/jsc/bindings/webcore/HTTPHeaderValues.cpp      |  68 ----
 src/jsc/bindings/webcore/HTTPHeaderValues.h        |  40 ---
 src/jsc/bindings/webcore/JSDOMConvert.h            |   2 -
 src/jsc/bindings/webcore/JSDOMConvertJSON.h        |  51 ---
 src/jsc/bindings/webcore/JSDOMConvertWebGL.cpp     | 249 --------------
 src/jsc/bindings/webcore/JSDOMConvertWebGL.h       |  68 ----
 src/jsc/bindings/webcore/TaskSource.h              |  29 --
 src/jsc/headergen/sizegen.cpp                      |   2 -
 src/jsc/sizes.rs                                   |   1 -
 .../dead-symbols-llhttp-helpers-install.test.ts    |  68 ++++
 24 files changed, 68 insertions(+), 1253 deletions(-)
```

</details>

**gate history** · 1 passed · 1 rejected · iteration 2

<details><summary>evidence per changed file</summary>

```
file                                           reads  edits  tests
src/bun_core/string/mod.rs                         1      2      0
src/jsc/Errorable.rs                               1      1      0
src/jsc/JSUint8Array.rs                            1      2      0
src/jsc/RefString.rs                               2      2      0
src/jsc/bindings/BunClientData.cpp                 1      1      0
src/jsc/bindings/BunClientData.h                   2      2      0
src/jsc/bindings/IDLTypes.h                        1      1      0
src/jsc/bindings/JSDOMWrapper.h                    1      1      0
src/jsc/bindings/JSVMClientDataClient.h            0      0      0
src/jsc/bindings/ares_build.h                      0      0      0
src/jsc/bindings/headers-cpp.h                     0      0      0
src/jsc/bindings/headers-handwritten.h             1      1      0
src/jsc/bindings/helpers.h                         2      2      0
src/jsc/bindings/node/http/llhttp/api.h            0      0      0
src/jsc/bindings/webcore/HTTPHeaderValues.cpp      0      0      0
src/jsc/bindings/webcore/HTTPHeaderValues.h        0      0      0
(+ 8 more files)
```

</details>

<!-- robobun:evidence:end -->
@robobun

robobun commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator Author

Heads up: the automated gate check bounces this PR with "src/** changed but no test/** files" after 11bdeca removed the source-lint test. I won't re-add it since that was a deliberate push; just flagging in case the gate blocks the merge queue on your end. Happy to add a different style of test if there's one you'd prefer for dead-code sweeps.

@Jarred-Sumner
Jarred-Sumner merged commit df49a6e into main Aug 1, 2026
39 of 53 checks passed
@Jarred-Sumner
Jarred-Sumner deleted the claude/farm/3e237919/dead-code-ssv-wasi-webcore branch August 1, 2026 01:36
@@ -124,14 +109,11 @@ class SerializedScriptValue : public ThreadSafeRefCounted<SerializedScriptValue>
static SYSV_ABI bool isTransferable(JSC::JSGlobalObject* globalObject, JSC::JSValue value);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Commit 11bdeca (HEAD) deletes test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts — the only test this PR added — with a bare commit message and no timeline note, so the diff is now 29 files with no test. The PR description's Verification section and the entire robobun:evidence gate block still claim this test "fails (7/7) with src/ at main, passes (7/7) with this diff", which now overstates what ships. Either restore the test (updating its patterns after 63bfbb2 restored AbortSignal::signalFollow/m_followingSignal), or update the description/evidence block to drop the stale claim and record why the maintainer removed it.

Extended reasoning...

What happened

Commit 11bdeca3 (current HEAD, authored by Jarred Sumner on 2026-07-31 18:26 PDT) deletes test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts (160 lines) with a bare one-line commit message. Nothing in the PR timeline explains the deletion — the last robobun comment ("Ready for a maintainer to merge", 2026-07-31 14:06Z) predates it. The changed-files list is now 29 files with no test file.

Meanwhile, the PR description's Verification section still states:

New test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts guards against reintroduction: fails (7/7) with src/ at main, passes (7/7) with this diff.

And the <!-- robobun:evidence:begin --> gate block still shows the full "fails on main / passes on PR" console output for that test, plus lists dead-symbols-ssv-wasi-webcore.test.ts | 160 ++ in the diff hotspot. Both are now stale — they present evidence for a test that no longer exists in the diff.

Step-by-step proof

  1. git log --oneline shows 11bdeca3 Delete test/internal/source-lints/dead-symbols-ssv-wasi-webcore.test.ts as HEAD.
  2. git show --stat 11bdeca3 shows exactly one change: dead-symbols-ssv-wasi-webcore.test.ts | 160 ---, 1 file changed, 160 deletions.
  3. ls test/internal/source-lints/ confirms the file is absent from disk; sibling dead-symbols-react-compiler.test.ts is present (establishing the convention this file followed, also cited in the CodeRabbit learnings quoted in this PR's own timeline for Remove dead code from js_printer, bundler, js_parser, patch, shell, http #35978/Remove dead code from webcrypto C++, sqlite bindings, and Rust runtime #36178).
  4. The PR's <changed-files count="29"> list contains no test/ file.
  5. Five prior commits on this branch (ae21882, bfd38c6, ba206e3, 071f23d, 63bfbb2) touched or referenced this test file across five review rounds; commit 63bfbb2 restored AbortSignal::signalFollow/m_followingSignal at maintainer request, which would have required updating the test's patterns (ba206e3 had added header-side checks for exactly those symbols).

Why this is worth noting

CLAUDE.md #11: "NEVER overstate what you got done or what actually works in commits, PRs or in messages to the user." The description now claims an automated reversion guard that does not ship, and the machine-generated evidence block presents pass/fail output for a nonexistent file.

REVIEW.md: "Never silently weaken, skip, or delete an existing test or safety net. Every deletion needs a stated reason or replacement." — though this applies weakly here, since the test was both added and removed within this PR (net effect on the test suite is zero) and the deletion was an explicit maintainer action, not accidental.

Why nit, not normal

This is a "no behavior change" dead-code sweep. REVIEW.md's "every behavioral change ships an automated test" does not strictly apply — the deleted file was an accidental-revert source-lint guard, not a behavioral test. The smoke tests listed in the Verification section (structured-clone.test.ts 231/231, worker_threads.test.ts 91/91, websocket-client, abort, performance-entries, wasi, event-target) still ran and passed per the CI status comment, and bun bd / rust:check-all are the primary correctness gates for a pure-deletion diff. Merging as-is causes no runtime failure — the concrete gap is PR-hygiene: the description overstates what ships.

How to fix

Either:

  • Restore the test, updating its patterns to drop the AbortSignal.h signalFollow/m_followingSignal checks that 63bfbb2 made stale (the likely reason it was dropped rather than fixed), or
  • Update the PR description: remove the "New test/internal/source-lints/..." bullet from Verification, regenerate or delete the robobun:evidence block, and add a one-line note recording why the guard was dropped (e.g. "source-lint guard removed by maintainer — smoke tests + build are the reversion gate").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants