Skip to content

Disable DOMJIT for crypto.getRandomValues() - #13470

Merged
Jarred-Sumner merged 1 commit into
mainfrom
jarred/disable-domjit-crypto-getrandomValues
Aug 22, 2024
Merged

Jarred-Sumner merged 1 commit into
mainfrom
jarred/disable-domjit-crypto-getrandomValues

Conversation

@Jarred-Sumner

Copy link
Copy Markdown
Collaborator

What does this PR do?

Speculative fix for https://discord.com/channels/876711213126520882/1276103693665828894/1276133319033229363

How did you verify your code works?

Didn't

@dylan-conway dylan-conway left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should have a test calling getRandomValues with the same buffer

@Jarred-Sumner
Jarred-Sumner merged commit dafa994 into main Aug 22, 2024
@Jarred-Sumner
Jarred-Sumner deleted the jarred/disable-domjit-crypto-getrandomValues branch August 22, 2024 22:52
Jarred-Sumner pushed a commit that referenced this pull request Sep 24, 2026
…hs (#43840)

### Problem
- `src/codegen/generate-classes.ts` still has the DOMJIT emitter (C++
signatures, `WithoutTypeChecks` wrappers, result-type asserts, Rust
thunks). None of it can run: `define()` in `class-definitions.ts` has
set `DOMJIT = undefined` on each field since #14005 (2024-09), and all
31 `*.classes.ts` files go through `define()`.
- Nothing is left for it to bind: #35002 deleted each Rust
`*_without_type_checks` fast path, and #36756 and #36903 removed the C++
leftovers.
- A `DOMJIT:` option in a `.classes.ts` file does nothing. Five exist.

### Fix
- Delete the emitter, the option type, the strip in `define()`, the five
ignored blocks, and the stale notes next to them: 6 files, 273 lines
removed.
- The generated output is the same except for 94 empty `#if
BUN_DEBUG`/`#endif` pairs in `ZigGeneratedClasses.h` and three
DOMJIT-only `#include`s in `ZigGeneratedClasses.cpp`.
`generated_classes.rs` is byte-identical.
- Verified: the generator run before and after, `bun bd`, `tsc -p src`,
and the tests in the Notes.
- Self-reviewed: 13 concerns raised, 13 addressed (Notes).

### Background
- DOMJIT is the JavaScriptCore fast path that lets the JIT call a host
function with unboxed, type-checked arguments. The generator could emit
a C++ signature and a Rust thunk for each method.
- The hand-written DOMJIT users (`Buffer.alloc`, `performance.now`,
`bun:ffi`) do not use this generator. They stay.
- Earlier sweeps (#39249, #41169) called this removal a design call.
This PR asks for that call alone.

### Downsides
- To turn generated DOMJIT on again, a person must restore these paths
from git history and write the Rust fast paths again.
- No runtime cost found. Checked: the generated `.cpp`, `.h` and `.rs`
differ only as Fix says.

<details><summary>Notes</summary>

**Removed**
- `generate-classes.ts`: `DOMJITName`, `argTypeName`, `DOMJITType`,
`DOMJITFunctionDeclaration`, `DOMJITFunctionDefinition`,
`domJITTypeCheckFields`, `RustDOMJITArgType`. Also the `DOMJIT` branches
in `zigExportName`, `propRow`, `renderDecls`, the `expectedResultType`
asserts in the host-function wrapper, both Rust thunk loops, and the
`DOMJITAbstractHeap.h`, `FrameTracers.h`, `DFGAbstractHeap.h` includes
of the generated prologue. The destructures that named `DOMJIT` also
lose the unused `cache` and `value` bindings.
- `class-definitions.ts`: the `DOMJIT?:` option type and the two
`.map()` calls in `define()` that erased it.
- Ignored live blocks: `Crypto.randomUUID`, `Crypto.timingSafeEqual`
(`crypto.classes.ts`), `ServerWebSocket.publishText`, `publishBinary`
(`server.classes.ts`), `TextDecoder.decode` (`encoding.classes.ts`).
- Stale notes: the commented-out `// DOMJIT: {` blocks with their crash
notes on `sendText`, `sendBinary` (2023) and `getRandomValues` (#13470,
2024-08), and three orphan "DOMJIT fast path" comments in
`src/runtime/webcore/Crypto.rs` whose functions #35002 deleted.

**Self-review, and what changed because of it**
- The first draft mixed this design call with 22 log scopes and seven
fields. It now ships alone, with its history in the body.
- The leftover DOMJIT notes (`Crypto.rs`, the commented-out blocks) are
folded in.
- Three deletions that open PRs carry were dropped (#40232, #41385).
- Five items that open PRs use were taken out of the held branch
(#43283, #31855, #42819, #39222, #37518). Two `builtins.d.ts` lines were
dropped too: `src/codegen/replacements.ts` defines
`$ImportKindLabelToId`, so that declaration is live.

**History**
- #13470 (2024-08) turned DOMJIT off for `getRandomValues`. #14005
(2024-09) added the strip in `define()` as the repair for the #14001
segfault. #35224 found the cause (the wrappers returned `{ result }`
with a null exception slot) and tried to repair the generated wrappers.
A stale-PR cleanup closed it with no maintainer comment. #35002 deleted
the Rust fast paths, so the option cannot come back without new native
code.

**Kept on purpose**
- The hand-written `DomCall` path for `bun:ffi` (`src/jsc/host_fn.rs`,
`src/runtime/ffi`), the C++ DOMJIT signatures in `JSBuffer.cpp`,
`JSPerformance.cpp`, `NodeVM.cpp`, `JSSQLStatement.cpp`, and
`test/js/bun/jsc/domjit.test.ts`.

**Tests (debug build)**
- `test/js/web/encoding/text-decoder.test.js` 127 pass,
`test/js/web/web-globals.test.js` 23 pass,
`test/js/bun/util/randomUUIDv5.test.ts` 40 pass,
`test/js/bun/websocket/websocket-server.test.ts -t sendBinary` 5 pass.
- `websocket-server.test.ts -t "publish|send"`: 44 pass, 4 time out near
19 s under debug+ASAN. A debug binary built from main fails the same 4.
- `test/js/bun/jsc/domjit.test.ts`: 40 pass, 10 time out at the
100k-iteration sizes. A debug binary built from main gives the same
40/10.

**The rest of this sweep**
- Relink of the debug build with `-Wl,--gc-sections`, then the DWARF
line table of the result: 2,290 of 31,118 Rust `fn`s have no live line.
After `cargo check` on six targets only three `pub fn`s had no caller
anywhere. The 96 trait impls with no caller are the ones #43664 kept on
purpose.
- clang `-fsyntax-only -Wunused-function -Wunused-template
-Wunused-member-function -Wunused-macros` over bun's 177 C/C++
translation units (the build passes `-Wno-unused-function`): ten hits.
Open PRs delete them, or an `#if` uses them.
- oxlint `no-unused-vars` over `src/js`, `src/codegen`, `scripts`,
`packages`. cargo's `unused_dependencies` lint over four targets. A scan
for commented-out blocks (62 lines in the repo). Nothing new that is
certain.
- Each deletion was compared with the diffs of the 36 open dead-code
PRs. Left out because an open PR has it: `Bun__napi_get_version`
(#40232), two unused generator locals (#41385).

**Verified and held for the next run** (branch
`robobun/9a0817f5/dead-code-scopes-fields`, 25 files, 81 lines removed)
- 20 `declare_scope!` scopes that nothing logs to: `JSC`, `STR`,
`Bundle` and `scan_counter` (outer pair), `Store`, `hot_reloader`,
`CLI`, `LibUVBackend`, `ResolveInfoRequest`, `GetHostByAddrInfoRequest`,
`CAresNameInfo`, `GetNameInfoRequest`, `CAresReverse`, `CAresLookup`,
`quic_session`, `PathWatcherManager`, `S3Client`, `S3Stat`, `AWS`, `uws`
(`uws_sys/socket.rs`). rustc does not lint an item that another crate's
macro expands.
- Fields: `Runtime::Features.jsx_optimization_inline` with the local
`can_be_inlined`, `DebugOptions.output_file`, `ArchiveIterator.filter`,
`PackageManager.total_scripts`, `CommandLineArguments.lockfile`,
`ArgumentsSlice::_vm`. Also `struct_Channeldata` and two empty modules
in `napi_body.rs`.
- It passed `rust:check-all` (12 targets), release and `--cfg bun_debug
--cfg bun_asan` checks on linux, windows and darwin, and `cargo check
--tests` before the trim below. The trimmed commit passes `cargo check`
on linux.
- Taken out because an open PR uses the item:
`BundleOptions.code_coverage` (#43283 reads it), scope `ModuleLoader`
(#31855), scope `PROCESS` (#42819, #39222), `impl Clone for JsPoster`
and its vtable slot (#37518 rewrites the vtable).

**Follow-up candidates, not verified dead**
- `Parser Options.preserve_unused_imports_ts` is never `true`. tsconfig
`importsNotUsedAsValues` is parsed into
`preserve_imports_not_used_as_values` but never reaches the parser, in
the released binary too. This looks like a missing feature.
- `completions/bun-cli.json` (4,513 lines) and
`misctools/generate-cli-completions.ts` (728 lines): nothing in the repo
reads the JSON, but feature PRs still edit it by hand.
- `bench/snippets/runner-entrypoint.js` (244 lines): no reference, first
line says "this isn't done yet", last real change 2023-05.
- Ten `impl_timer_owner!` accessors have no caller because `dispatch.rs`
recovers the owner with its own `owner!` macro. Which mechanism stays is
a design call.
- `mordant-baseline.toml` still counts about 170 `unused_pub` findings
(`sys/lib.rs` 56, `libuv_sys/libuv.rs` 41, `errno/windows_errno.rs` 31).
`bun run rust:mordant` names them.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants