Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d9e9626
AOT: module binding, class fields, unused classes, names of modules o…
Jarred-Sumner Oct 28, 2026
5a23339
AOT: the kind of a module goes by its text, getters that read a name …
Jarred-Sumner Oct 28, 2026
0468a4a
AOT: fixes, tests and shorter docs; WebKit d6e9f85e [skip size check]
Jarred-Sumner Oct 28, 2026
6e3f36f
AOT: tests as small files in the ordinary shards; WebKit preview-pr-9…
Jarred-Sumner Oct 28, 2026
380e8dd
[autofix.ci] apply automated fixes
autofix-ci[bot] Oct 28, 2026
361c50d
scripts/runner.node.ts is executable [skip size check]
Jarred-Sumner Oct 28, 2026
43169b1
AOT: library modules held as values, typed parses keep declared types…
Jarred-Sumner Oct 28, 2026
9f3242a
AOT: test programs build at default flags and share builds; a Worker …
Jarred-Sumner Oct 28, 2026
5319f52
[autofix.ci] apply automated fixes
autofix-ci[bot] Oct 28, 2026
b4ba001
AOT: the test driver runs programs before it builds more and removes …
Jarred-Sumner Oct 28, 2026
33622b9
AOT: on Linux the test files that build many executables run on the B…
Jarred-Sumner Oct 28, 2026
04b9307
AOT: the ELF and Linux writers hand out owned parts of a mapping; a f…
Jarred-Sumner Oct 28, 2026
add8dde
[autofix.ci] apply automated fixes
autofix-ci[bot] Oct 28, 2026
184e0b8
AOT: a program is compiled once where library code was lacking; a bui…
Jarred-Sumner Oct 28, 2026
d997b76
AOT: test programs that took long share one library; five sweeps over…
Jarred-Sumner Oct 28, 2026
8b2f312
AOT: native code that lists the environment counts as a caller of its…
Jarred-Sumner Oct 28, 2026
aaab6c8
AOT: each program of an executable holds the module of the library th…
Jarred-Sumner Oct 28, 2026
e522379
AOT: what the table of built-ins only guesses is left to the engine t…
Jarred-Sumner Oct 28, 2026
d78b7d5
AOT: a module object handed to native code is listed among the forms …
Jarred-Sumner Oct 28, 2026
6af52b8
AOT: the options of Bun.spawn, Bun.listen, Bun.connect and fetch are …
Jarred-Sumner Oct 28, 2026
6fd51bb
AOT: the bounds on instructions a turn hold on the lane that counts t…
Jarred-Sumner Oct 28, 2026
8a44e04
AOT: WebKit f495db1d; with AddressSanitizer the test files of the com…
Jarred-Sumner Oct 28, 2026
6e63b62
Merge branch 'main' into claude/compile-aot-on-check [skip size check]
Jarred-Sumner Oct 28, 2026
c5e86e6
AOT tests: one build-scaling shape has its growth in memory in its row
Jarred-Sumner Oct 28, 2026
da05b24
Merge branch 'main' into claude/compile-aot-on-check
Jarred-Sumner Oct 28, 2026
021911d
AOT: exception checks at the call sites in BunProcess.cpp; tests of n…
Jarred-Sumner Oct 28, 2026
92276be
Remove the system CA certificate prefetch from standalone executables
Jarred-Sumner Oct 29, 2026
5f5f865
Remove the macOS tests for the system CA certificate prefetch
Jarred-Sumner Oct 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
310 changes: 91 additions & 219 deletions .buildkite/ci.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .buildkite/update-test-durations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ steps:
# The scripts read BUILDKITE_API_TOKEN. The agent that runs this step has to
# provide it: `pipeline upload` refuses a pipeline with a secret interpolated in.
command: |
bun scripts/update-test-durations.mjs --builds 5
node scripts/update-test-durations.mjs --builds 5
node scripts/update-parallel-allowlist.mjs --builds 300
buildkite-agent artifact upload test/expected-durations.json
buildkite-agent artifact upload test/parallel-allowlist.json
4 changes: 2 additions & 2 deletions .github/actions/rust-lint-setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ runs:

- name: Setup system deps
# cmake/ninja for `--configure-only`; clang for toolchain detection
# (configure resolves cfg.cc/cxx). `engine-test-programs` links with AddressSanitizer.
# (configure resolves cfg.cc/cxx even though nothing here compiles C++).
shell: bash
env:
LLVM_VERSION_MAJOR: ${{ inputs.llvm-version }}
run: |
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc > /dev/null
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-${LLVM_VERSION_MAJOR} main" | sudo tee /etc/apt/sources.list.d/llvm.list > /dev/null
sudo apt-get update -qq
sudo apt-get install -y -qq --no-install-recommends cmake ninja-build nasm clang-${LLVM_VERSION_MAJOR} lld-${LLVM_VERSION_MAJOR} llvm-${LLVM_VERSION_MAJOR} libclang-rt-${LLVM_VERSION_MAJOR}-dev
sudo apt-get install -y -qq --no-install-recommends cmake ninja-build nasm clang-${LLVM_VERSION_MAJOR} lld-${LLVM_VERSION_MAJOR} llvm-${LLVM_VERSION_MAJOR}
- name: Setup Rust
if: inputs.toolchain != ''
Expand Down
19 changes: 9 additions & 10 deletions .github/workflows/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,20 +116,19 @@ export LLVM_VERSION_MAJOR=23

## rust-lints.yml Workflow

Five independent jobs over the Rust workspace. They share `.github/actions/rust-lint-setup`, a composite action that installs LLVM from apt.llvm.org (configure resolves a clang even though nothing here compiles C++), Bun, optionally a pinned Rust toolchain plus components, runs `bun install`, then `bun scripts/build.ts --configure-only` and the ninja targets a job asks for: `clone-lolhtml clone-rust-argon2` (cargo cannot resolve the workspace until the vendored `lol_html` and `rust-argon2` path dependencies exist) and, for jobs that check `bun_runtime`/`bun_jsc`/`bun_core`, `codegen` (their `include!()`d sources under `build/debug/codegen`). `codegen` reads the code generators of the prebuilt WebKit and nothing else of it: a job that links no C++ passes `webkit-generators-only: "1"`, and the build fetches the release's `bun-webkit-aot-sources.tar.gz` (half a megabyte) in place of the tarball (440 MB).
Four independent jobs over the Rust workspace. They share `.github/actions/rust-lint-setup`, a composite action that installs LLVM from apt.llvm.org (configure resolves a clang even though nothing here compiles C++), Bun, optionally a pinned Rust toolchain plus components, runs `bun install`, then `bun scripts/build.ts --configure-only` and the ninja targets a job asks for: `clone-lolhtml clone-rust-argon2` (cargo cannot resolve the workspace until the vendored `lol_html` and `rust-argon2` path dependencies exist) and, for jobs that check `bun_runtime`/`bun_jsc`/`bun_core`, `codegen` (their `include!()`d sources under `build/debug/codegen`). `codegen` reads the code generators of the prebuilt WebKit and nothing else of it: a job that links no C++ passes `webkit-generators-only: "1"`, and the build fetches the release's `bun-webkit-aot-sources.tar.gz` (half a megabyte) in place of the tarball (440 MB).

| Job | Check name | Runs | Blocking |
| ---------------- | --------------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------ |
| `clippy` | `cargo clippy` | `bun run rust:clippy`, then `cargo check --workspace --all-targets` | yes |
| `miri` | `cargo miri test` | `bun run rust:miri` (`scripts/rust-miri.ts`) | yes |
| `lolhtml` | `lol-html cargo test` | `cargo test` in `vendor/lolhtml` | yes |
| `aot-rust-tests` | `AoT cargo test` | the schema's `--check` and tests, `cargo test` of the nine AoT crates | yes |
| `mordant` | `mordant` | `bun run rust:mordant` | advisory (`continue-on-error`) |
| Job | Check name | Runs | Blocking |
| --------- | --------------------- | ------------------------------------------------------------------- | ------------------------------ |
| `clippy` | `cargo clippy` | `bun run rust:clippy`, then `cargo check --workspace --all-targets` | yes |
| `miri` | `cargo miri test` | `bun run rust:miri` (`scripts/rust-miri.ts`) | yes |
| `lolhtml` | `lol-html cargo test` | `cargo test` in `vendor/lolhtml` | yes |
| `mordant` | `mordant` | `bun run rust:mordant` | advisory (`continue-on-error`) |

- `clippy` lints the default targets only (lib and bin): test code was never held to the clippy lint set. Its second step, `cargo check --workspace --all-targets`, type-checks `#[cfg(test)]` code, `tests/` and `benches/` so they keep compiling. Nothing else builds them except the crates `rust:miri` runs.
- `clippy`, `miri`, `lolhtml` and `aot-rust-tests` pin `RUSTUP_TOOLCHAIN` at the workflow level (kept in sync with `channel` in `rust-toolchain.toml`) so rustup does not install that file's cross-target list; the action installs the toolchain with `--profile minimal` plus the components the job names (`clippy`, `miri rust-src`, none, none).
- `clippy`, `miri` and `lolhtml` pin `RUSTUP_TOOLCHAIN` at the workflow level (kept in sync with `channel` in `rust-toolchain.toml`) so rustup does not install that file's cross-target list; the action installs the toolchain with `--profile minimal` plus the components the job names (`clippy`, `miri rust-src`, none).
- `lolhtml` exists because the vendored lol-html is a fork (oven-sh/lol-html, `bun` branch) whose own test suite is the only thing guarding the fork's invariants. It used to trigger only on `scripts/build/deps/lolhtml.ts`; it now shares the workflow's wider path filter.
- `aot-rust-tests` tests the Rust half of the AoT compiler (`bun build --compile --aot`) without linking Bun. Its ninja targets are `codegen engine-test-programs clone-zstd clone-lolhtml clone-rust-argon2`. `codegen` fetches the prebuilt WebKit tarball (about 700 MB) in every job that builds it, because the table of built-ins is generated from the tarball's `Source/JavaScriptCore/aot/builtins/generated` and the schema's Rust files by the tarball's `aot/ir/generator`. `engine-test-programs` (`jsc` and `testaot`) is the only C++ this job compiles and links: the five sources of Bun's table of built-ins, with the tarball's `lib/libjsc-objects.a`, `lib/libtestaot-objects.a` and libraries. The `testaot` in a tarball's `bin/` has another table and reads nothing that Bun's front end writes. `clone-zstd` is for the build script of `bun_sema_standalone`, which compiles zstd's decoder from `vendor/zstd` into the test binaries; the jobs that only check link nothing and do not need it. The tarball is extracted to a cache directory named after the WebKit version and the build configuration, so `bun scripts/build/aot-paths.ts` prints where `testaot`, `jsc`, the schema and the engine's half of the table are, as `NAME=<path>` lines that the job appends to `$GITHUB_ENV`. `bun test test/internal/aot-schema-generator.test.ts` runs here, with `AOT_SCHEMA` set by `aot-paths.ts`: it skips itself without an engine, as on Buildkite's test machines. The Rust files that the schema gives are written by the `codegen` target, by the tarball's generator from the tarball's schema, so they are always those of the **pinned** WebKit. The schema, its generator and its C++ output belong to WebKit, so a schema change is made with `--webkit=local`; it lands in WebKit first, then in Bun as one change: the new `WEBKIT_VERSION` (`scripts/build/deps/webkit.ts`) and the hand-written Rust that follows it.
- `cargo test` is not here: Buildkite runs it on every pull request (`getCargoTestStep()` in `.buildkite/ci.ts`, `bun run rust:test`, `scripts/rust-test.ts`), for the crates whose tests link without JavaScriptCore. `bun test test/internal/aot-schema-generator.test.ts` runs in `lint.yml`, which fetches the engine's code generators anyway: it skips itself without `AOT_SCHEMA`, as on Buildkite's test machines. The Rust files that the schema gives are written by the `codegen` target, by the generator and from the schema of the **pinned** WebKit. The schema, its generator and its C++ output belong to WebKit, so a schema change is made with `--webkit=local`; it lands in WebKit first, then in Bun as one change: the new `WEBKIT_VERSION` (`scripts/build/deps/webkit.ts`) and the hand-written Rust that follows it.
- `mordant` runs the [mordant](https://github.com/scarletindustries/mordant) lint pack as an advisory (`continue-on-error`) job. Mordant ships its own runner, the way clippy does. `cargo mordant` is `cargo check` with `mordant-driver` (rustc with the lints linked in) as `RUSTC_WORKSPACE_WRAPPER`, and it builds into `target/mordant/check`. The shared action installs mordant's nightly (`MORDANT_TOOLCHAIN`) with `rustc-dev` and `llvm-tools-preview`, and every cargo call in the job names it (`cargo +"$MORDANT_TOOLCHAIN" …`): `cargo install --locked --git … --rev "$MORDANT_REV"` builds the two binaries with it, and `scripts/rust-mordant.ts` runs `cargo mordant` under it. It is not spelled `RUSTUP_TOOLCHAIN` because `test/internal/source-lints/ci-image-pins.test.ts` holds every `RUSTUP_TOOLCHAIN: nightly-…` in a workflow to the channel in `rust-toolchain.toml`, and this one moves with mordant instead. One cache covers them: `~/.cargo/bin/{cargo-mordant,mordant-driver}`, keyed on the nightly and the rev. The job restores it with `actions/cache/restore` and saves it with `actions/cache/save` right after the build, because the post step of `actions/cache` does not run in a job that failed, and a pull request with a finding over the baseline would then build mordant again on every push. Because that nightly is older than ours, the script passes `-A unknown_lints` through `MORDANT_RUSTFLAGS`. It is skipped on `merge_group`.
- Mordant's nightly is the compiler that checks this workspace while the lints run, so it must still be able to compile it. When a `rust-toolchain.toml` bump brings in an API that nightly lacks, the job fails on every PR until mordant moves to a newer nightly and the pin here follows. #42851 was one: the job was off from then until mordant moved to 2026-09-01.

Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ jobs:
curl -fsSL --retry 3 -o "$RUNNER_TEMP/engine.tar.gz" "$release/bun-webkit-aot-sources.tar.gz" ||
curl -fsSL --retry 3 -o "$RUNNER_TEMP/engine.tar.gz" "$release/bun-webkit-linux-amd64-lto.tar.gz"
tar -xzf "$RUNNER_TEMP/engine.tar.gz" -C vendor/WebKit --strip-components=1 --exclude=bun-webkit/Source/JavaScriptCore/aot/tests bun-webkit/Source/JavaScriptCore/aot
- name: Check that the engine's generator writes what the build declares
env:
AOT_SCHEMA: ${{ github.workspace }}/vendor/WebKit/Source/JavaScriptCore/aot/ir/AOTSchema.def
run: bun test ./test/internal/aot-schema-generator.test.ts
- name: Typecheck the built-in modules
# The code generators write the types src/js/builtins.d.ts references (build/types) and the enums the dev
# server's sources import (src/runtime/bake/generated.ts). A module with a second text in src/js/ahead-of-time is
Expand All @@ -63,7 +67,7 @@ jobs:
version=$(sed -n 's/^export const WEBKIT_VERSION = "\(.*\)";$/\1/p' scripts/build/deps/webkit.ts)
git init --quiet "$RUNNER_TEMP/WebKit"
git -C "$RUNNER_TEMP/WebKit" remote add origin https://github.com/oven-sh/WebKit.git
git -C "$RUNNER_TEMP/WebKit" sparse-checkout set Source/JavaScriptCore
git -C "$RUNNER_TEMP/WebKit" sparse-checkout set Source/JavaScriptCore Tools/Scripts/aot
git -C "$RUNNER_TEMP/WebKit" fetch --quiet --depth=1 --filter=blob:none origin "refs/tags/autobuild-${version#autobuild-}"
git -C "$RUNNER_TEMP/WebKit" checkout --quiet FETCH_HEAD
BUN_WEBKIT_PATH="$RUNNER_TEMP/WebKit" bun test test/internal/build-aot-codegen-declared-outputs.test.ts -t "finds a use for every name of the schema"
Expand Down
50 changes: 0 additions & 50 deletions .github/workflows/rust-lints.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ on:
- "src/pod/README.md"
- "src/**/*.bind.ts"
- "src/codegen/**"
- "src/trim/features/**"
- "test/aot/ir/**"
# src/aot/report/wording/tests.rs includes it.
- "docs/compiler/explain.mdx"
- "test/internal/aot-schema-generator.test.ts"
- "scripts/build/**"
- "scripts/build.ts"
- "scripts/rust-miri.ts"
Expand Down Expand Up @@ -131,51 +126,6 @@ jobs:
working-directory: vendor/lolhtml
run: cargo test

aot-rust-tests:
name: AoT cargo test
runs-on: ubuntu-latest
timeout-minutes: 90
env:
# Without optimization a frame is several times as large, and the tests
# of the nesting limits reach the end of the stack before the limit.
CARGO_PROFILE_DEV_OPT_LEVEL: 1
# With optimization the frame pointer goes unless it is forced, as
# scripts/build/rust.ts does: `bun_core::return_address()` reads it.
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS: -Cforce-frame-pointers=yes
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Setup
uses: ./.github/actions/rust-lint-setup
with:
bun-version: ${{ env.BUN_VERSION }}
llvm-version: ${{ env.LLVM_VERSION_MAJOR }}
toolchain: ${{ env.RUSTUP_TOOLCHAIN }}
ninja-targets: codegen engine-test-programs clone-zstd clone-lolhtml clone-rust-argon2

- name: Locate the engine's files
run: bun scripts/build/aot-paths.ts >> "$GITHUB_ENV"

- name: The engine's generator writes what the build declares
run: bun test ./test/internal/aot-schema-generator.test.ts

- name: cargo test
# A red step in front of this one does not hide what these tests say.
if: ${{ !cancelled() }}
# ir_tests.rs skips the engine's half of every test when TESTAOT is
# unset or was built from another schema than the codegen. Here a build
# without testaot has to fail the job, and so does such a skip.
# The skipped test of bun_sema_standalone fails without this branch too.
env:
BUN_CODEGEN_DIR: ${{ github.workspace }}/build/debug/codegen
AOT_IR_REQUIRES_ENGINE: 1
run: |
test -x "$TESTAOT"
cargo test --no-fail-fast -p bun_aot -p bun_builtin_sources -p bun_bundler -p bun_sema -p bun_sema_driver -p bun_sema_parser -p bun_sema_standalone -p bun_trim -p bun_removable_features -p bun_exe_format -p bun_crash_handler -p bun_options_types -p bun_resolver -p bun_lint_react_compiler -p bun_sql_jsc -- --skip realpath_under_the_marked_root_stays_under_it
mordant:
name: mordant
runs-on: ubuntu-latest
Expand Down
8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Library/Caches
*.tmp
*.trace
*.wat
!test/aot/programs/**/*.wat
!test/aot/parallel/**/*.wat
*.zip
**/.verdaccio-db.json
**/*.dir
Expand Down Expand Up @@ -97,8 +97,8 @@ misctools/sha
myscript.sh
node_modules
node_modules_*
!test/aot/programs/**/node_modules/
!test/aot/programs/**/dist/
!test/aot/parallel/**/node_modules/
!test/aot/parallel/**/dist/
!test/aot/ir/**/node_modules/
out
out.*
Expand Down Expand Up @@ -223,3 +223,5 @@ src/jsc/bindings/GeneratedBindings.zig
# hawk analysis scaffolding (see tools/hawk/); generated per-run, never committed
src/runtime/hawk_root.rs
__pycache__/
rustc-ice-*.txt
fuzz-out/
8 changes: 2 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"src/bundler",
"src/collections",
"src/css",
"src/errno",

Check warning on line 11 in Cargo.toml

View workflow job for this annotation

GitHub Actions / lol-html cargo test

explicit `package.readme` can be inferred
"src/glob",
"src/http",
"src/install",
Expand Down Expand Up @@ -510,6 +510,10 @@
bun_which = { path = "src/which" }
bun_transpiler = { path = "src/transpiler" }

# It stands in for vector code that every test program runs over each byte it parses.
[profile.dev.package.bun_sema_standalone]
opt-level = 3

[profile.release.package.bun_react_compiler]
opt-level = "s"

Expand Down
Loading
Loading