BigInt("0x…"/"0b…"/"0o…"): linear-time string parse - #35899
Conversation
Bumps WebKit to pick up the JSBigInt::parseInt power-of-two fast path (oven-sh/WebKit#353). Before: O(n^2) because multiplyAdd runs over the full digit vector for every group of input characters. After: O(n) by packing bits directly into the digit vector, mirroring toStringBasePowerOfTwo. 200k-hex-char string: ~360ms -> ~1ms release. Adds parse correctness coverage for hex/binary/octal at all digit-word alignment boundaries plus a linearity check at 250k hex chars.
|
Warning Review limit reached
Next review available in: 1 minute Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
Comment |
|
Updated 7:13 AM PT - Jul 26th, 2026
❌ @robobun, your commit f7c2ba0 has 2 failures in
Add 🧪 To try this PR locally: bunx bun-pr 35899That installs a local version of the PR into your bun-35899 --bun |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Status: diff is green; waiting on oven-sh/WebKit#353 to merge so Build #82305 (192/196 passed):
Local
|
| * From https://github.com/oven-sh/WebKit releases. | ||
| */ | ||
| export const WEBKIT_VERSION = "549170099226f816a4b204ea1d8fa102fb79eefa"; | ||
| export const WEBKIT_VERSION = "autobuild-preview-pr-353-4b51ec68"; |
There was a problem hiding this comment.
🔴 WEBKIT_VERSION is pointing at autobuild-preview-pr-353-4b51ec68, an ephemeral preview-build release for the still-unmerged oven-sh/WebKit#353. Preview releases are deleted once the upstream PR merges/closes, at which point every fresh prebuilt-mode build (CI and local) will 404 on the WebKit download. Per the description this is a known TODO — flagging so it doesn't slip: bump to the merged commit sha before landing.
Extended reasoning...
What the bug is
scripts/build/deps/webkit.ts:6 sets:
export const WEBKIT_VERSION = "autobuild-preview-pr-353-4b51ec68";replacing the previous 40-hex commit sha. The autobuild-preview-pr-* tag is the CI preview release that oven-sh/WebKit publishes for open PRs so downstream Bun PRs can test against them before the WebKit change lands. These preview releases are ephemeral — they are deleted (or become stale/unreferenced) once the WebKit PR is merged or closed and the real autobuild-<sha> release is published for the merged commit.
Code path that triggers it
prebuiltUrl() in the same file builds the download URL directly from this constant:
const version = cfg.webkitVersion;
const tag = version.startsWith("autobuild-") ? version : `autobuild-${version}`;
return `https://github.com/oven-sh/WebKit/releases/download/${tag}/${name}.tar.gz`;so every cfg.webkit === "prebuilt" build — which is the default for CI and for anyone not running a local WebKit checkout — fetches https://github.com/oven-sh/WebKit/releases/download/autobuild-preview-pr-353-4b51ec68/bun-webkit-<os>-<arch><suffix>.tar.gz. prebuiltDestDir() also keys the cache dir on this string, so there is no fallback to a previously-cached sha.
Why nothing else prevents it
There is no guard in the build system that rejects preview tags or falls back to a pinned release; prebuiltUrl() explicitly accommodates the autobuild- prefix so preview tags work during development. The only thing preventing this from breaking builds today is that oven-sh/WebKit#353 is still open and its preview artifacts still exist.
Impact
If this PR merges as-is and oven-sh/WebKit#353 subsequently merges (which it must, since this PR depends on it), the preview release will be cleaned up. From that point every fresh clone / cache-cold CI runner hits a 404 downloading WebKit and the build fails outright — a regression in something that currently works on main. Even before deletion, pinning main to an unmerged, force-pushable PR branch is fragile.
Step-by-step proof
- Merge this PR with
WEBKIT_VERSION = "autobuild-preview-pr-353-4b51ec68". - JSBigInt::parseInt: O(n) fast path for power-of-two radix WebKit#353 merges; its preview release
autobuild-preview-pr-353-4b51ec68is deleted per the preview-release lifecycle. - A contributor (or CI) with a cold cache runs
bun bd.resolveDepfor WebKit computesprebuiltUrl(cfg)→.../releases/download/autobuild-preview-pr-353-4b51ec68/bun-webkit-linux-amd64.tar.gz. - GitHub returns 404; the fetch step fails; the build aborts before compiling anything.
- Every subsequent PR's CI is red until someone lands a follow-up bumping
WEBKIT_VERSION.
Fix
Before merging, land oven-sh/WebKit#353 first, then update this line to the merged commit's 40-hex sha (matching the autobuild-<sha> release), e.g.:
export const WEBKIT_VERSION = "<merged-commit-sha>";The PR description already states this intent ("will be updated to the merged sha once oven-sh/WebKit#353 lands"); this comment is the merge-blocking reminder so it can't be forgotten.
There was a problem hiding this comment.
Yes, intentional and tracked: PR is in draft until oven-sh/WebKit#353 lands, then this line gets swapped to the merged 40-hex sha. Leaving this thread open as the merge-blocker.
…ty / maxLength boundary / UChar path
Depends on oven-sh/WebKit#353.
Problem
BigInt("0x…"),BigInt("0b…"),BigInt("0o…")parse time is O(n²) in the string length.JSBigInt::parseIntroutes every radix through a loop that callsmultiplyAddover the full preallocated digit vector once perlengthLimitForBigInt32characters (n/k groups × O(n) per group). The output direction,toStringBasePowerOfTwo, is already linear.Sibling of the radix-10 quadratic conversions, split out because the pow-2 fix is trivially linear and independent of any divide-and-conquer work.
Fix
oven-sh/WebKit#353 adds a fast path in
JSBigInt::parseIntfor power-of-two radix that packs each character'sctz(radix)bits directly into the digit vector, carrying across 64-bit word boundaries for octal. No multiplication. Short inputs that fit in int32 fall through to the existing path so they keep returning BigInt32.This PR
WEBKIT_VERSION(currently pointing at the preview build; will be updated to the merged sha once JSBigInt::parseInt: O(n) fast path for power-of-two radix WebKit#353 lands).test/js/bun/jsc/bigint-parse.test.ts: roundtrip correctness for hex/binary/octal at every alignment boundary (1..40 hex, 1..130 binary, 1..70 octal to cover the 3-bit span across 64-bit words), cross-radix agreement, leading-zero/whitespace handling, SyntaxError on bad chars, and a linearity check at 250 000 hex chars (before: ~570 ms release; after: <10 ms debug+ASAN).Verification
Local
debug-localbuild (WebKit from source, ASAN):All 7 tests pass in 160 ms.
[decide:webkit] gate passed · iteration 2 · 2 files touched
passes on PR (with fix)
diff hotspot
gate history · 1 passed · 2 rejected · iteration 2
evidence per changed file