Skip to content

Remove dead code from jsc FFI glue, C++ bindings, bun_core, http_types, and bunfig - #37012

Open
robobun wants to merge 11 commits into
mainfrom
claude/farm/e120a58d/dead-code-jsc-http-core-misc
Open

Remove dead code from jsc FFI glue, C++ bindings, bun_core, http_types, and bunfig#37012
robobun wants to merge 11 commits into
mainfrom
claude/farm/e120a58d/dead-code-jsc-http-core-misc

Conversation

@robobun

@robobun robobun commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Dead-code sweep across crates not covered by the other open dead-code PRs (#36237, #35775, #36970, #36115, #35437, #35880). Net -2419 lines. Every removal was verified to have zero references across src/, scripts/, and freshly regenerated build/debug/codegen output, then validated by cargo check on all 10 CI target triples and a full debug build.

Removed

bun_jsc FFI glue

  • DeprecatedStrong::unref: never called; the sole user (test_runner/Collection.rs) uses init + Drop only, per the file's own audit note
  • Unused extern "C" imports JSCommonJSExtensions__{appendFunction,setFunction,swapRemove} in NodeModuleModule.rs: zero Rust call sites
  • ZigString__free: exported fn whose only cross-reference was its prototype in headers-handwritten.h; no C++ caller (helpers.h frees via ZigString__freeGlobal, which stays)
  • Zig__GlobalObject__reportUncaughtException: exported fn with no C++ caller; the internal safe wrapper report_uncaught_exception stays
  • AbortSignal__Timeout__run: orphaned wrapper; AbortSignal.cpp calls only __create/__deinit, and the timeout actually fires through the Rust timer dispatch (EventLoopTimerTag::AbortSignalTimeout)
  • Resolver__propForRequireMainPaths: no caller; removed together with its stale extern decl in JSCommonJSModule.cpp (getterPaths uses Resolver__nodeModulePathsJSValue)

C++ bindings

  • The JSCommonJSExtensions::m_registeredFunctions vector mechanism: with the Rust imports above gone, its three extern "C" writers had zero callers, so the member and its GC-visit loop were dead with them (custom require.extensions functions are stored in Rust-side Strongs)
  • Stale header prototypes for the removed exports in headers.h and headers-handwritten.h

bun_core

  • fmt::raw: shorthand constructor duplicating s(), zero callers (the Raw struct stays, it is constructed via s)
  • The schema wrapper module in lib.rs: zero users; everyone imports the flattened bun_core::StringPointer
  • NAPI_MODULE_REGISTER feature counter: never incremented, and bun_analytics has no mapping for it

bun_http_types

  • mime_type_list.txt (2309 lines): orphan data file fully duplicated by the hand-maintained table in mime_type_list_enum.rs; not read by any build step (absent from cargo dep-info), referenced only by two doc comments, both updated
  • FrameType::HTTP_FRAME_ALTSVC / HTTP_FRAME_ORIGIN: the enum is used only for outbound frame construction (inbound dispatch is on raw u8 per the file comment) and a client never sends these frames

websocket client

  • CompressError::OutOfMemory / DecompressError::OutOfMemory: never constructed (compress returns only DeflateFailed; decompress only InflateFailed/TooLarge), plus the unreachable match arm in websocket_client.rs

bun_runtime

  • ReadableStream::detach_if_possible: no-op vestige whose body was emptied in 8553428; removed with its sole call in done()
  • image/mod.rs: trimmed the flattened re-export list to the two names actually addressed via crate::image:: (Image, AsyncImageTask)

options / bunfig

  • The write-only [bundle].packages cluster: BundlePackage enum, DebugOptions::package_bundle_map, the bunfig parse block that populated it, and two re-exports. The map had zero readers; the key is undocumented and now falls through bunfig's per-key lookup like any other unknown key

bun_perf

  • Timer::lap: existed only in the WASM stub impl; the real Timer never defined it, so no portable caller can exist

Verification

  • rg -w for every symbol across src/, scripts/, cmake/, and regenerated build/debug/codegen: zero references outside the definition sites
  • bun run rust:check-all: 10/10 triples pass (this caught and reverted two candidates that grep missed: zig_hash_map keys/values_mut used inside the allow(dead_code) h2 file, and file_poll::Pollable used by the darwin ParentDeathWatchdog path)
  • Full bun bd debug build passes
  • Smoke tests pass: require-extensions (43), websocket permessage-deflate + abort (10), web streams (161), bunfig options (5)

Noted but not removed

  • The legacy inbound half of h2_frame_parser.rs (~1770 lines) is provably unreachable, but the file header documents it as intentionally parked until the outbound h2 migration lands, so it is left for that migration to delete
  • DebugOptions::editor and DebugOptions::output_file are write-only (bunfig [debug].editor and --output-file parse into them, nothing reads them); they look like unported feature hooks rather than leftovers, so they are flagged here instead of deleted
  • bun_resolver::Error::{MissingResolveDir,InvalidResolveDir} are never constructed, but the surrounding commented-out block is an intentional TODO referencing Missing Esbuild plugin API options (resolveDir, pluginData) #8994

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

fails on main (without fix)
ASAN without fix: 3 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-jsc-http-core.test.ts
bun test v1.4.0 (2b0a08d92)

test/internal/source-lints/dead-symbols-jsc-http-core.test.ts:
63 |     ["src/jsc/JSGlobalObject.rs", /\bZig__GlobalObject__reportUncaughtException\b/],
64 |     ["src/jsc/AbortSignal.rs", /\bAbortSignal__Timeout__run\b/],
65 |     ["src/jsc/resolver_jsc.rs", /\bResolver__propForRequireMainPaths\b/],
66 |   ];
67 |   for (const [file, re] of checks) {
68 |     expect(src(file)).not.toMatch(re);
                               ^
error: expect(received).not.toMatch(expected)

Expected substring or pattern: not /pub fn unref\b/
Received: "#[cfg(debug_assertions)]\nuse core::mem::ManuallyDrop;\n#[cfg(debug_assertions)]\nuse core::ptr::NonNull;\n\nuse crate::JSValue;\n\n// Refcount contract (load-bearing): `ref()`/`unref()` calls must be balanced\n// in pairs; Drop is the release for the `init()` protect. In debug builds a\n// final `unref()` (ref_count 1 → 0) additionally frees the canary, zeroes\n// `raw`, and clears `_safety` so a subsequent Drop 
... (truncated)

release without fix: 3 FAILED
bun test v1.4.0-canary.1 (830d03788)

test/internal/source-lints/dead-symbols-jsc-http-core.test.ts:
63 |     ["src/jsc/JSGlobalObject.rs", /\bZig__GlobalObject__reportUncaughtException\b/],
64 |     ["src/jsc/AbortSignal.rs", /\bAbortSignal__Timeout__run\b/],
65 |     ["src/jsc/resolver_jsc.rs", /\bResolver__propForRequireMainPaths\b/],
66 |   ];
67 |   for (const [file, re] of checks) {
68 |     expect(src(file)).not.toMatch(re);
                               ^
error: expect(received).not.toMatch(expected)

Expected substring or pattern: not /pub fn unref\b/
Received: "#[cfg(debug_assertions)]\nuse core::mem::ManuallyDrop;\n#[cfg(debug_assertions)]\nuse core::ptr::NonNull;\n\nuse crate::JSValue;\n\n// Refcount contract (load-bearing): `ref()`/`unref()` calls must be balanced\n// in pairs; Drop is the release for the `init()` protect. In debug builds a\n// final `unref()` (ref_count 1 → 0) additionally frees the canary, zeroes\n// `raw`, and clears `_safety` so a subsequent Drop is a no-op. Release builds\n// have no ref_count, so an unref-used-as-release followed by Drop would\n// double-unprotect — callers must never use `unref()` as the release.\n// (Audite
... (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-jsc-http-core.test.ts
bun test v1.4.0 (2b0a08d92)

test/internal/source-lints/dead-symbols-jsc-http-core.test.ts:
(pass) dead Rust symbols (bun_jsc FFI glue) do not reappear [18.97ms]
(pass) dead Rust symbols (bun_core, http_types, websocket, webcore, perf) do not reappear [13.21ms]
(pass) write-only [bundle].packages bunfig cluster does not reappear [6.77ms]
(pass) dead C++ symbols and stale header prototypes do not reappear (HEAD) [27.36ms]
(pass) orphan data file stays deleted (HEAD) [488.42ms]

 5 pass
 0 fail
 24 expect() calls
Ran 5 tests across 1 file. [2.69s]
__F:0:S:0

release with fix: all passed
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped) in 675ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/124] gen generated_host_exports.rs
generated_host_exports.rs: 92 exports (host=3, lazy=10, generic=79, rust=0); 238 extern-C blocks audited
[2/124] gen cpp.rs (cppbind)
[2/124] 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^[[92m   Compiling^[[0m bun_zlib_sys v0.0.0 (/workspace/bun/src/zlib_sys)
^[[1m^[[92m   Compiling^[[0m bun_cares_sys v0.0.0 (/workspace/bun/src/cares_sys)
^[[1m^[[92m   Compiling^[[0m bun_zstd v0.0.0 (/workspace/bun/src/zstd)
^[[1m^[[92m   Compiling^[[0m bun_picohttp v0.0.0 (/workspace/bun/src/picohttp)
^[[1m^[
... (truncated)
diff hotspot
src/bun_core/Global.rs                             |    2 +-
 src/bun_core/fmt.rs                                |    8 +-
 src/bun_core/lib.rs                                |    8 -
 src/bundler/options.rs                             |    2 -
 src/bunfig/bunfig.rs                               |   51 -
 src/http_jsc/websocket_client.rs                   |    1 -
 src/http_jsc/websocket_client/WebSocketDeflate.rs  |    4 -
 src/http_types/MimeType.rs                         |    3 +-
 src/http_types/h2.rs                               |    4 -
 src/http_types/mime_type_list.txt                  | 2310 --------------------
 src/http_types/mime_type_list_enum.rs              |    2 +-
 src/jsc/AbortSignal.rs                             |    9 -
 src/jsc/DeprecatedStrong.rs                        |   58 +-
 src/jsc/JSGlobalObject.rs                          |   11 -
 src/jsc/NodeModuleModule.rs                        |   18 -
 src/jsc/ZigString.rs                               |   24 -
 src/jsc/bindings/JSCommonJSExtensions.cpp          |   47 -
 src/jsc/bindings/JSCommonJSExtensions.h            |    9 +-
 src/jsc/bindings/JSCommonJSModule.cpp              |    2 -
 src/jsc/bindings/headers-handwritten.h             |    2 -
 src/jsc/bindings/headers.h                         |    1 -
 src/jsc/resolver_jsc.rs                            |    8 -
 src/options_types/bundle_enums.rs                  |    7 -
 src/options_types/context.rs                       |    2 -
 src/options_types/lib.rs                           |    4 +-
 src/perf/system_timer.rs                           |    8 +-
 src/resolver/resolver.rs                           |    3 +-
 src/runtime/image/mod.rs                           |    5 +-
 src/runtime/server/RequestContext.rs               |   10 +-
 src/runtime/webcore/Blob.rs                        |    4 +-
 src/runtime/webcore/Body.rs                        |    2 +-
 src/runtime/webcore/FileSink.rs                    |    6 +-

... (truncated)

gate history · 7 passed · 0 rejected · iteration 1

evidence per changed file
file                                               reads  edits  tests
src/bun_core/Global.rs                                 1      1      0
src/bun_core/fmt.rs                                    2      3      0
src/bun_core/lib.rs                                    1      1      0
src/bundler/options.rs                                 1      1      0
src/bunfig/bunfig.rs                                   1      1      0
src/http_jsc/websocket_client.rs                       1      2      0
src/http_jsc/websocket_client/WebSocketDeflate.rs      1      1      0
src/http_types/MimeType.rs                             1      2      0
src/http_types/h2.rs                                   1      1      0
src/http_types/mime_type_list.txt                      0      0      0
src/http_types/mime_type_list_enum.rs                  1      1      0
src/jsc/AbortSignal.rs                                 1      1      0
src/jsc/DeprecatedStrong.rs                            4      5      0
src/jsc/JSGlobalObject.rs                              1      1      0
src/jsc/NodeModuleModule.rs                            2      3      0
src/jsc/ZigString.rs                                   1      1      0
(+ 18 more files)

…s, options, and bunfig

Every symbol was verified to have zero references across src/, scripts/,
and freshly regenerated build/debug/codegen output, then validated by
cargo check on all 10 CI target triples plus a full debug build.

- bun_jsc: DeprecatedStrong::unref, unused extern imports of
  JSCommonJSExtensions__{appendFunction,setFunction,swapRemove},
  ZigString__free, Zig__GlobalObject__reportUncaughtException,
  AbortSignal__Timeout__run, Resolver__propForRequireMainPaths
- C++ bindings: the now-unreferenced JSCommonJSExtensions
  m_registeredFunctions vector (writers, GC visit loop, member) and the
  stale header prototypes for the removed Rust exports
- bun_core: fmt::raw, the schema wrapper module, NAPI_MODULE_REGISTER
  feature counter
- bun_http_types: orphan mime_type_list.txt (fully duplicated by the
  hand-maintained table, not read by any build step), outbound-only
  FrameType ALTSVC/ORIGIN variants a client never sends
- websocket deflate: never-constructed OutOfMemory error variants and
  their unreachable match arm
- webcore: ReadableStream::detach_if_possible no-op vestige
- options/bunfig: the write-only [bundle].packages cluster
  (BundlePackage enum, DebugOptions::package_bundle_map, parser block)
- perf: WASM-stub-only Timer::lap
- runtime/image: re-export names with no external users

Adds a source lint guarding against reintroduction.
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This change removes obsolete public APIs, FFI symbols, configuration types, runtime exports, and WebSocket error variants. It simplifies ReadableStream::done, updates its callers, revises MIME documentation, and adds source-lint checks.

Changes

Dead symbol cleanup

Layer / File(s) Summary
Public API and runtime cleanup
src/bun_core/*, src/http_types/*, src/perf/system_timer.rs, src/resolver/resolver.rs, src/runtime/image/mod.rs
Removes unused constructors, enum variants, timer methods, image re-exports, and stale documentation references.
Bundle configuration cleanup
src/bundler/options.rs, src/options_types/*
Removes BundlePackage, its re-exports, and package_bundle_map.
JSC FFI and binding cleanup
src/jsc/*, src/jsc/bindings/*
Removes obsolete Rust exports, C++ declarations, registered-function storage, string deallocation, resolver bindings, CommonJS extension declarations, and DeprecatedStrong::unref.
WebSocket error cleanup
src/http_jsc/websocket_client.rs, src/http_jsc/websocket_client/WebSocketDeflate.rs
Removes compression OutOfMemory variants and their WebSocket error mapping.
ReadableStream completion API
src/runtime/webcore/ReadableStream.rs, src/runtime/server/RequestContext.rs, src/runtime/webcore/{Blob,Body,FileSink}.rs
Changes ReadableStream::done to a parameterless method, removes detachment handling, and updates callers.
Dead symbol regression checks
test/internal/source-lints/dead-symbols-jsc-http-core.test.ts
Adds working-tree and committed-tree checks for removed Rust, C++, configuration, and MIME symbols.

Possibly related PRs

Suggested reviewers: jarred-sumner

🚥 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 change as dead-code removal across the main affected components.
Description check ✅ Passed The description explains the changes and provides detailed verification results, covering both required template topics.

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

@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.

Beyond the inline nits, I checked that the FrameType::HTTP_FRAME_{ALTSVC,ORIGIN} removal from http_types/h2.rs does not affect runtime/api/bun/h2_frame_parser.rs — that file defines its own local FrameType enum (line 241) rather than importing the bun_http_types one. Also confirmed the removed #[no_mangle] FFI exports (ZigString__free, Zig__GlobalObject__reportUncaughtException, AbortSignal__Timeout__run, Resolver__propForRequireMainPaths) and m_registeredFunctions have no remaining references anywhere under src/jsc/bindings/.

Extended reasoning...

Large 30-file dead-code sweep touching Rust↔C++ FFI export surface, a JSC GC visitChildren loop, and bunfig parsing — worth a human confirming the m_registeredFunctions WriteBarrier-vector removal and the bunfig [bundle].packages drop. The three inline findings are cosmetic nits only; spot-checks of the riskier removals (h2 FrameType variants, FFI exports, analytics counter) held up.

Comment thread src/jsc/DeprecatedStrong.rs Outdated
Comment thread src/runtime/webcore/ReadableStream.rs Outdated
Comment thread src/jsc/NodeModuleModule.rs Outdated
- ReadableStream::done: drop the now-unused JSGlobalObject parameter
  (its only use was the deleted detach_if_possible call) and update all
  17 call sites
- DeprecatedStrong: drop SafetyData::ref_count, which became a
  write-once constant with a vacuous debug_assert once unref was removed
- NodeModuleModule: replace the comment describing the deleted C++
  WriteBarrier vector with one matching the Strong-based storage
Comment thread src/jsc/DeprecatedStrong.rs Outdated
Comment thread src/jsc/NodeModuleModule.rs Outdated
@robobun

robobun commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the three review findings in 1d44393 and trimmed the two flagged comments in 410121e:

  • ReadableStream::done now takes no JSGlobalObject; the compiler found 17 call sites (the 12 listed plus 5 in server/RequestContext.rs), all updated
  • SafetyData::ref_count and its vacuous assert are gone; the struct is just the canary pointer now
  • The stale WriteBarrier comment in NodeModuleModule.rs is removed

Re-verified: cargo check on all 10 triples, full debug build, and the streams/require-extensions/source-lint suites (176 tests) pass.

A stash round-trip restored the deleted file in the working tree and a
blanket git add swept it back into the previous commit.
Comment thread src/jsc/bindings/JSCommonJSExtensions.cpp Outdated
With m_registeredFunctions gone the override visited nothing custom;
the method table inherits Base::visitChildren without it.
Comment thread src/jsc/bindings/JSCommonJSExtensions.h Outdated
With no data members left it has nothing to destruct: the declared
destructor was never defined (nothing odr-used it), and subspaceForImpl
selects the non-destructible cell type from the base automatically.
@robobun

robobun commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 4:57 AM PT - Aug 6th, 2026

@Jarred-Sumner, your commit 8041adce46f8f28e9e35774bda8b3b2cc60b5404 passed in Build #89595! 🎉


🧪   To try this PR locally:

bunx bun-pr 37012

That installs a local version of the PR into your bun-37012 executable, so you can run:

bun-37012 --bun

Comment thread src/jsc/DeprecatedStrong.rs Outdated
Comment thread src/perf/system_timer.rs Outdated
…signature

enable_safety's only invocation was the const that suppressed its own
unused-macro warning. The WASM reset stub returned u64 while the real
impl returns unit, so no portable caller could use the value.
Comment thread src/bun_core/fmt.rs
Comment thread src/bun_core/fmt.rs Outdated
Comment thread test/internal/source-lints/dead-symbols-jsc-http-core.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.

No issues found in this pass — all six earlier nits have been addressed. I'm deferring rather than approving because the sweep is broad (34 files, −2.4k lines) and several removals sit on load-bearing boundaries: the JSCommonJSExtensions base-class change to JSNonFinalObject (subspace/GC), six #[no_mangle] extern "C" exports at the Rust↔C++ FFI edge, and the [bundle].packages bunfig parse block (write-only and undocumented, but previously validated its inputs). Worth a human sanity-check.

What was reviewed

  • Confirmed zero remaining references in src/ to the six removed FFI exports and the three JSCommonJSExtensions__* C++ writers.
  • Verified h2_frame_parser.rs has its own local FrameType enum, so removing HTTP_FRAME_ALTSVC/ORIGIN from http_types/h2.rs is isolated.
  • Checked [bundle].packages is absent from docs/runtime/bunfig.mdx — undocumented as claimed.
  • ReadableStream::done() signature change: the removed detach_if_possible body was already empty, so dropping the global_this param across 17 call sites is behavior-preserving.
Extended reasoning...

Overview

Dead-code sweep across 34 files (net −2419 lines): removes uncalled #[no_mangle] FFI exports (ZigString__free, Zig__GlobalObject__reportUncaughtException, AbortSignal__Timeout__run, Resolver__propForRequireMainPaths), unused Rust extern imports of JSCommonJSExtensions__{append,set,swapRemove}Function and the C++ m_registeredFunctions WriteBarrier vector they wrote, orphan mime_type_list.txt (2310 lines), the write-only [bundle].packages bunfig cluster, never-constructed websocket-deflate OutOfMemory variants, unused h2 FrameType variants, fmt::raw, the bun_core::schema shim module, an unused analytics counter, the WASM-only Timer::lap, unused image:: re-exports, and the no-op ReadableStream::detach_if_possible (with done() losing its global_this param across 17 call sites). Follow-up commits (in response to earlier review rounds) additionally changed JSCommonJSExtensions's base from JSDestructibleObject to JSNonFinalObject, dropped its visitChildren override and never-defined destructor, removed DeprecatedStrong's ref_count/enable_safety! machinery, and aligned the WASM Timer::reset signature.

Security risks

None identified. The changes are pure removals of unreferenced code plus mechanical signature updates; no auth, crypto, input parsing, or trust-boundary logic is touched. The only user-visible behavior change is that an undocumented [bundle].packages bunfig key no longer validates package-name shape (it previously emitted "Expected package name" for non-package keys but never used the result) — now it falls through like any other unknown key.

Level of scrutiny

Moderate-to-high. Individually most hunks are trivially verifiable deletions, and the PR's verification is thorough (rg across src/scripts/codegen, 10-triple cargo check, full debug build, targeted smoke suites, plus a source-lint guard test). But the aggregate touches memory-safety-adjacent surfaces the REVIEW.md flags as the most-blocked category: a JSC cell's base class and subspace selection, removal of a GC-visited WriteBarrier vector, and six extern "C" symbols at the Rust/C++ ABI seam. Each removal's correctness depends on a negative claim ("nothing calls this") that codegen or a platform-gated path could invalidate; the PR description notes two such near-misses caught only by the multi-triple check. The JSNonFinalObject change relies on subspaceForImpl keying off is_base_of_v<JSDestructibleObject, T> — sound per robobun's follow-up, but structural enough to merit a maintainer glance.

Other factors

I have already reviewed this PR across six prior passes, each surfacing a nit that was promptly fixed (vestigial visitChildren, the JSDestructibleObject base, the self-suppressing enable_safety! macro, the WASM reset signature mismatch, a broken [\raw`]intra-doc link, and a stale audit-note citation). All are resolved at HEAD (2b0a08d9). This run I spot-checked the FFI-export removals (zero residual references insrc/), confirmed h2_frame_parser.rsdefines its ownFrameTypeso thehttp_typesvariant removal is isolated, and verified[bundle].packages` is absent from the bunfig docs. Given the breadth and the FFI/GC surface, deferring for a human review rather than approving.

@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.

No issues found this pass — every prior nit is addressed and resolved. Deferring to a human because of scope: 33 files across FFI exports, JSC C++ bindings (JSCommonJSExtensions base-class change), bunfig parsing, and the ReadableStream::done() signature fan-out.

What was reviewed:

  • Grepped src/ for every removed #[no_mangle]/extern-"C" symbol (ZigString__free, Zig__GlobalObject__reportUncaughtException, AbortSignal__Timeout__run, Resolver__propForRequireMainPaths, JSCommonJSExtensions__*) — zero remaining references.
  • Verified the JSDestructibleObject → JSNonFinalObject switch against WebCore::subspaceForImpl in BunClientData.h — the is_base_of_v branch selects cellHeapCellType and the needsDestruction static_assert holds.
  • Confirmed BundlePackage / package_bundle_map / detach_if_possible / NAPI_MODULE_REGISTER have no remaining readers; the removed detach_if_possible was already an empty body, so done() is behavior-preserving.
Extended reasoning...

Overview

Dead-code sweep removing ~2.4k lines across 33 files: unused #[no_mangle] FFI exports and their C++ header prototypes, the JSCommonJSExtensions::m_registeredFunctions WriteBarrier vector plus its extern-C writers, the write-only [bundle].packages bunfig cluster, an orphan 2310-line MIME data file, never-constructed error variants, a WASM-only Timer::lap, the no-op ReadableStream::detach_if_possible, and assorted stale re-exports. Follow-up commits addressed cascading dead code my earlier passes flagged (empty visitChildren, JSDestructibleObject base, self-suppressing enable_safety!, WASM reset() signature, stale intra-doc links). The final commit (8041adc, pushed by a maintainer) deletes the source-lint test file per REVIEW.md's "do not add tests to check dead code stays dead".

Security risks

None identified. No auth, crypto, path-handling, or input-validation logic is touched; removals are orphaned symbols and no-op call chains. The bunfig [bundle].packages block that is removed only populated a map nothing ever read, so dropping it cannot weaken any check.

Level of scrutiny

High. This is not a mechanical rename or config tweak — it removes #[no_mangle] exports whose only consumers would be C++ or generated code (grep is necessary but not sufficient), changes a JSC cell's base class and therefore its heap subspace, drops an undocumented-but-user-reachable bunfig key, and rewrites a ReadableStream method signature across 17 call sites in server/webcore hot paths. Each removal looks correct on inspection and the author's verification (10-triple cargo check, full debug build, targeted test suites) is thorough, but the blast radius warrants a maintainer's eyes.

Other factors

I spot-checked the highest-risk items: (1) WebCore::subspaceForImpl in BunClientData.h keys the heap-cell type on std::is_base_of_v<JSDestructibleObject, T> with a needsDestruction static_assert, so the JSNonFinalObject base compiles to the non-destructible cell type as claimed; (2) none of the removed extern-C symbols appear anywhere in src/; (3) detach_if_possible already had an empty body, so removing it and the done() parameter is behavior-preserving. All eight of my prior inline findings were nits and are resolved. A maintainer has already pushed a commit to this branch, so they are aware of it — I'm deferring rather than approving given the breadth and the GC-adjacent C++ change.

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