Repository navigation
Conversation
|
Status: ready for review. Rebased on main 3bf1a06 on 2026-11-03. The conflict is gone.
|
8e71cc6 to
c5633b3
Compare
|
No actionable comments were generated in the recent review. WalkthroughThe PR removes the file-write encoding field and updates its callers. It also changes code generation, JavaScriptCore prototype subspace declarations, path separator handling, JSON5 error mapping, and several C++ and Rust APIs. ChangesFile write arguments
Code generation
JavaScriptCore prototype subspaces
Path separator options
JSON5 parser errors
AES-CBC platform methods
Stream and message-port contracts
StringBuilder implementation and documentation
Suggested reviewers: Merge Risk:
|
…the JSON5 parser, and two code generators
- src/jsc/bindings: remove the subspaceFor member template of 72 classes
that allocate with Bun::allocatePlainObjectCell. Nothing instantiates
it. 15 classes had their only STATIC_ASSERT_ISO_SUBSPACE_SHARABLE in
the template and get it at file scope.
- WebCrypto and WebCore: remove the ignored Padding parameter of
CryptoAlgorithmAES_CBC::platformEncrypt and platformDecrypt,
MessagePortPipe::operator==, StreamQueue::first() const, and the empty
analyzeEntry overload for ByteQueueEntry.
- bun_sys, bun_bundler: remove WriteFileEncoding and WriteFileArgs.encoding.
- bun_paths: remove PathSeparators::{Posix, Windows} and sep_dispatch!.
- bun_parsers: remove the JSON5 out-of-memory error variants that
nothing constructs.
- bun_semver: remove impl StringBuilder for semver_string::Builder.
- cppbind.ts, generate-host-exports.ts: remove a branch and a filter
that cannot apply.
c5633b3 to
df07855
Compare
There was a problem hiding this comment.
I reviewed the updated push and didn't find any bugs. Because this touches 82 files including GC subspace declarations across the JSC prototype classes and a WebCrypto signature, a human look would still be worthwhile, mainly to confirm the build on all platforms.
What was reviewed:
- All 72 classes losing
subspaceFor: each is allocated viaBun::allocatePlainObjectCell(vm, sizeof(T))and noallocateCell<T>/tryAllocateCell<T>for any of them exists in src/; the re-emitted file-scopeSTATIC_ASSERT_ISO_SUBSPACE_SHARABLElines match the deleted ones. PathSeparators::{Posix,Windows}removal: everySEP_OPTin src/ isANYorAUTO(no numeric 2/3 orinto_septo those), so collapsing the matches toSEP/platform::Autois behavior-preserving.CryptoAlgorithmAES_CBC::Padding: both callers in CryptoAlgorithmAES_CBC.cpp pass three args and the OpenSSL impl never read the parameter; json5 OOM variants had no constructor (no fallible allocation in the parser) and the one external match arm in JSON5Object.rs is removed;semver_string::Buildercallers all use inherent methods, not the deleted trait impl;MessagePortPipecomparisons use raw pointers, not the deletedoperator==.
Extended reasoning...
The change is a single commit of pure deletions (+40/-564) across 82 files: the subspaceFor member template on 72 JSC prototype/plain-object classes, dead Rust enum variants and fields (bun_sys WriteFileEncoding, PathSeparators Posix/Windows, json5 OOM variants, semver StringBuilder impl), an ignored Padding parameter on AES-CBC platformEncrypt/platformDecrypt, and two codegen guards. The only security-adjacent surface is the AES-CBC signature, where the removed parameter was never read, so no crypto behavior changes. I grepped every removed item for remaining users and found none, and confirmed every affected C++ class allocates through allocatePlainObjectCell. Deferring rather than approving because the size (82 files, GC class definitions) and the webcrypto touch exceed the bar for an unassisted approve, and compilation cannot be verified in this environment.
|
On the build for all platforms:
|
Problem
src/jsc/bindingsdefine asubspaceFormember template. Since Trim ~2 MB from the release binary without touching hot paths #39770 they allocate withBun::allocatePlainObjectCell, so nothing instantiates it.WriteFileArgs.encoding. No path type selectsPathSeparators::PosixorPathSeparators::Windows. Nothing constructs the JSON5 parser's out-of-memory errors.Fix
STATIC_ASSERT_ISO_SUBSPACE_SHARABLEinside the template, where nothing evaluated it. It now follows the class, so the check runs.bun bd,bun run rust:check-all(12 targets),cargo clippy, unchanged generator output, 20 test files (Notes).Background
subspaceFortellsJSC::allocateCell<T>which GC subspace holds aT. A class that allocates withBun::allocatePlainObjectCellnever asks.Downsides
--compile --aothello world maps 8,192 bytes less, and 4,096 more with--trim.Behaviour change: none
Notes
Removed
src/jsc/bindings(67 files, 443 lines): thesubspaceFormember template of 72 classes. Each class allocates withBun::allocatePlainObjectCell(vm, sizeof(T)), and noallocateCell<T>ortryAllocateCell<T>of these classes exists in the tree or in the generated code. The-O0debug binary of main 6f58f6b, linked without--gc-sections, had noT::subspaceFor<...>symbol for them, and had one for each class that still callsallocateCell.JSNonFinalObjecthas no such template in the pinned WebKit, so a laterallocateCell<T>of one of these classes does not compile until the template is back.Paddingparameter ofCryptoAlgorithmAES_CBC::platformEncryptandplatformDecrypt(ignored, both callers pass three arguments),MessagePortPipe::operator==,StreamQueue::first() const, and the emptyanalyzeEntryoverload forByteQueueEntry.src/sys,src/bundler,build_command.rs(14 lines):WriteFileEncodingandWriteFileArgs.encoding. Four writers, no reader.src/paths/Path.rs(38 lines):PathSeparators::{Posix, Windows}. EverySEP_OPTin the workspace isANYorAUTO, and no constant exists for the other two. Thesep_dispatch!macro had one arm left, so its four uses callpath::<fn>::<path::platform::Auto>directly.src/parsers/json5.rs,JSON5Object.rs(16 lines):ParseError::OutOfMemory,Error::Oom,AddToLogError::OutOfMemory,ExternalError::OutOfMemory. The parser has no fallible allocation, so nothing constructs the first one, and each of the others comes only from the one before.src/semver/lib.rs,Scripts.rs(16 lines):impl StringBuilder for semver_string::Builder. Every generic caller gets the lockfile'sStringBuilder.bindings/filter ingenerate-host-exports.tsthat matches no file, and theif (!tree)block incppbind.ts(Parser.parseof@lezer/commonalways returns a tree).Verification (this branch on main 3bf1a06)
bun bd(debug, ASAN) builds.bun run rust:check-all: 12 of 12 targets pass.cargo clippy --no-depsfor the seven changed crates: no finding.rustfmt,clang-formatandprettierreport no change.cpp.rsandgenerated_host_exports.rsare identical.streams.test.js727 pass,headers.test.ts142,fetch_headers.test.js10,web-crypto.test.ts178,json5.test.ts325,message-channel.test.ts17,message-event.test.ts10,string-decoder.test.js143,mock-fn.test.js848,fs-stats-constructor.test.ts7,sqlite.test.js671,node-sqlite.test.ts154,vm.test.ts372,module-graph-callbacks.test.ts1,bun-build-api.test.ts91,path/basename.test.js4,path/dirname.test.js3,path/join.test.js1,path/resolve.test.js6,process.test.js197.process.test.js"should be the node version on the host that we expect" compares with thenodebinary of the machine, v26.3.0 here where the test expects v26.12.1. The release build of main fails it the same way.Size (release builds of CI: main 3bf1a06 in build 137162, this branch in build 137225)
test/bundler/compile-aot-size.test.tson Ubuntu 25.04 x64 prints the numbers. Abun build --compile --aothello world maps 68,134,014 bytes on main and 68,125,822 with this branch (8,192 less). With--trimit maps 25,961,598 and 25,965,694 (4,096 more, one page). "The compiler takes" 23,663,481 and 23,663,546 bytes (65 more).--trimits bound is 25,880,000 bytes.bun-linux-x64.zipis 8,956 bytes smaller,bun-linux-aarch64.zip5,532 andbun-windows-aarch64.zip6,883. The other seven differ by less than 750 bytes. The archives are compressed. The binaries inside were not compared withsizeorbloaty: the machine for this work cannot reach the artifact store.Open pull requests (compared on 2026-11-03 with the heads of the 6,021 other open pull requests)
WriteFileEncodinglines, so it removes six of the same lines. It conflicts with main already. No other head removes a line that this pull request removes.git merge-tree) of each of the 164 with this branch is clean.Left out after the rebase on 2026-11-03
bun_brotli::DecoderOptions(one value): Replace the brotli C library with safe Rust #47073 removes it.NODE_BUILTIN_PATTERNS_RAWandBUN_NODE_BUILTIN_PATTERNS_COMPAT(no reader): resolver: match exactexternalnames before any lookup #47455 adds lines next to the re-export inoptions.rs, so a change there gives it a conflict.src/libarchive,generate-jssink.tsandgenerate-js2native.ts: main deleted or rewrote those files (Replace libarchive with a tar reader and writer in safe Rust #46638, bindgen: move the stream sinks to a schema and deletegenerate-jssink.ts#46641, bindgen: move every Rust function that takes aCallFrameto schemas and delete#[host_fn],$rustand$newRustFunction#46540).Same template, left alone
JSStatFSPrototypeandJSBigIntStatFSPrototype(node:fs: build statfs results with one reachable StatFs class #42554 removes the lines),ImportMetaObjectPrototype(Make import.meta members discoverable as own properties #32248 removes the lines),TTYWrapPrototype(tty: native TTY handle, ReadStream extends net.Socket #41495 removes the lines),JSSharedEnvMap(fix(worker): preserve process.env identity when sharing environments #44371 moves the class),ImportMetaEnv(new on main since the scan, bun test: Vitest compatibility #44833).Bun::allocatePlainObjectCell<T>(vm)that holds the assert can check every class in one place. That is a separate change.allocateCell<T>, for exampleRequireFunctionPrototype,NodeVMModulePrototypeand theProcessBindingobjects. Their template is live.Found dead on 2026-10-21, and left alone (not checked again after the rebase)
max_output_sizeof the brotli, zstd and zlib decoders isusize::MAXin every instance. Issue Bun.zstdDecompress lacks decompressed size limit #28162 asks for an output cap forBun.zstdDecompress, which this field can carry, and http: judge the byte after a gzip member once #45715 and zstd: delete ZstdReaderArrayList in favour of StreamingDecoder #37555 edit the same lines. Needs a decision.bun_md::Options::BOOL_FIELD_SETTERSthat the only reader on main skips: feat(mdx): add native compilation, loading, and direct serving #27047 reads them inMdxObject.rs.ResetEventtimeout (bun test: count code that runs in a Worker under --coverage #43283),Channelclose path (threading: publish into a Channel without holding a reference into it past the release #38358),MemfdFlags::Executable(napi: stub link slots for post-compile .node injection #30033).generate-string-map.ts(Remove the unused options of generate-string-map.ts #46162),Parsed.has_choiceinbun_glob(Remove dead code from bun_glob and bun_css #46196).ErrorCode.tsthat no code reaches through the table,ThreadPool.needs_stack_bounds(alwaystrue, its doc asks callers to clear it),bun_alloc::MaxHeapAllocator(a type with no allocation method, Windows AddressSanitizer build target #35480 and riscv64 target: cross-compiles and runs, looking for guidance rather than a merge #42801 use itsMAX_ALIGN_T), 12 overrides inhawk.tomlfor enum variants that no longer exist (they sit next to the lines Remove dead code from libtcc1.c, four C++ preprocessor conditions, JSPropertyIterator, and hawk.toml #44126 removes), and the prototype classes themselves: most can be built byBun::Bindgen::createClassPrototype, which is visible throughbun:jscheap statistics and is a behaviour change.oom_from_alloc!stamps insrc/parsers/yaml.rs.Self-review (of the larger diff before the rebase)
max_output_sizeandBOOL_FIELD_SETTERSremovals are out.ModuleGraph.cpp,NodeVMScript.cpp,JSCommonJSModule.cppandJSEnvironmentVariableMap.hare in. The lists above were derived again from the final head.subspaceForpart alone is 67 files.