Compare commits

..

1 Commits

Author SHA1 Message Date
Ashcon Partovi
23ea8875ac Test out Amazon Linux 2024-06-27 15:49:40 -07:00
498 changed files with 13429 additions and 32402 deletions

View File

@@ -6,7 +6,7 @@
steps:
- if: "build.pull_request.repository.fork"
block: ":eyes:"
prompt: "Did you review the PR?"
prompt: ":rotating_light: Did you review the PR?"
blocked_state: "running"
- label: ":pipeline:"

View File

@@ -70,7 +70,6 @@ steps:
- key: "darwin-aarch64-build-bun-nolto"
label: ":darwin: aarch64 - build-bun (no-lto)"
if: "build.branch != 'main'"
depends_on:
- "darwin-aarch64-build-deps"
- "darwin-aarch64-build-zig"
@@ -113,8 +112,7 @@ steps:
- key: "darwin-aarch64-test-macos-14"
label: ":darwin: 14 aarch64 - test-bun"
if: "build.branch != 'main'"
parallelism: 3
parallelism: 2
soft_fail:
- exit_status: 2
retry:
@@ -142,8 +140,7 @@ steps:
- key: "darwin-aarch64-test-macos-13"
label: ":darwin: 13 aarch64 - test-bun"
if: "build.branch != 'main'"
parallelism: 3
parallelism: 2
soft_fail:
- exit_status: 2
retry:
@@ -170,7 +167,6 @@ steps:
- key: "darwin-aarch64-test-macos-14-smoke"
label: ":darwin: 14 aarch64 - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 2
@@ -198,7 +194,6 @@ steps:
- key: "darwin-aarch64-test-macos-13-smoke"
label: ":darwin: 13 aarch64 - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 2
@@ -279,7 +274,6 @@ steps:
- key: "darwin-x64-build-bun-nolto"
label: ":darwin: x64 - build-bun (no-lto)"
if: "build.branch != 'main'"
depends_on:
- "darwin-x64-build-deps"
- "darwin-x64-build-zig"
@@ -322,8 +316,7 @@ steps:
- key: "darwin-x64-test-macos-14"
label: ":darwin: 14 x64 - test-bun"
if: "build.branch != 'main'"
parallelism: 3
parallelism: 2
soft_fail:
- exit_status: 2
retry:
@@ -350,8 +343,7 @@ steps:
- key: "darwin-x64-test-macos-13"
label: ":darwin: 13 x64 - test-bun"
if: "build.branch != 'main'"
parallelism: 3
parallelism: 2
soft_fail:
- exit_status: 2
retry:
@@ -378,7 +370,6 @@ steps:
- key: "darwin-x64-test-macos-14-smoke"
label: ":darwin: 14 x64 - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 2
@@ -406,7 +397,6 @@ steps:
- key: "darwin-x64-test-macos-13-smoke"
label: ":darwin: 13 x64 - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 2
@@ -487,7 +477,6 @@ steps:
- key: "linux-aarch64-build-bun-nolto"
label: ":linux: aarch64 - build-bun (no-lto)"
if: "build.branch != 'main'"
depends_on:
- "linux-aarch64-build-deps"
- "linux-aarch64-build-zig"
@@ -530,7 +519,6 @@ steps:
- key: "linux-aarch64-test-debian-12"
label: ":debian: 12 aarch64 - test-bun"
if: "build.branch != 'main'"
parallelism: 5
soft_fail:
- exit_status: 2
@@ -559,7 +547,6 @@ steps:
- key: "linux-aarch64-test-ubuntu-2204"
label: ":ubuntu: 22.04 aarch64 - test-bun"
if: "build.branch != 'main'"
parallelism: 5
soft_fail:
- exit_status: 2
@@ -588,7 +575,6 @@ steps:
- key: "linux-aarch64-test-ubuntu-2004"
label: ":ubuntu: 20.04 aarch64 - test-bun"
if: "build.branch != 'main'"
parallelism: 5
soft_fail:
- exit_status: 2
@@ -615,9 +601,36 @@ steps:
command:
- "./scripts/runner.node.mjs --step linux-aarch64-build-bun-nolto"
- key: "linux-aarch64-test-amazonlinux-2023"
label: ":aws: 2023 aarch64 - test-bun"
parallelism: 5
soft_fail:
- exit_status: 2
retry:
automatic:
- exit_status: 1
limit: 1
- exit_status: -1
limit: 3
- exit_status: 255
limit: 3
- signal_reason: agent_stop
limit: 3
- signal: SIGTERM
limit: 3
depends_on:
- "linux-aarch64-build-bun-nolto"
agents:
robobun: "true"
os: "linux"
arch: "aarch64"
distro: "amazonlinux"
release: "2023"
command:
- "./scripts/runner.node.mjs --step linux-aarch64-build-bun-nolto"
- key: "linux-aarch64-test-debian-12-smoke"
label: ":debian: 12 aarch64 - test-bun-smoke"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 2
@@ -646,7 +659,6 @@ steps:
- key: "linux-aarch64-test-ubuntu-2204-smoke"
label: ":ubuntu: 22.04 aarch64 - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 2
@@ -675,7 +687,6 @@ steps:
- key: "linux-aarch64-test-ubuntu-2004-smoke"
label: ":ubuntu: 20.04 aarch64 - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 2
@@ -702,6 +713,34 @@ steps:
command:
- "./scripts/runner.node.mjs --step linux-aarch64-build-bun --smoke 0.05"
- key: "linux-aarch64-test-amazonlinux-2023-smoke"
label: ":aws: 2023 aarch64 - test-bun (smoke)"
parallelism: 1
soft_fail:
- exit_status: 2
retry:
automatic:
- exit_status: 1
limit: 1
- exit_status: -1
limit: 3
- exit_status: 255
limit: 3
- signal_reason: agent_stop
limit: 3
- signal: SIGTERM
limit: 3
depends_on:
- "linux-aarch64-build-bun"
agents:
robobun: "true"
os: "linux"
arch: "aarch64"
distro: "amazonlinux"
release: "20.04"
command:
- "./scripts/runner.node.mjs --step linux-aarch64-build-bun --smoke 0.05"
# Linux x64
- key: "linux-x64"
group: ":linux: x64"
@@ -757,7 +796,6 @@ steps:
- key: "linux-x64-build-bun-nolto"
label: ":linux: x64 - build-bun (no-lto)"
if: "build.branch != 'main'"
depends_on:
- "linux-x64-build-deps"
- "linux-x64-build-zig"
@@ -800,7 +838,6 @@ steps:
- key: "linux-x64-test-debian-12"
label: ":debian: 12 x64 - test-bun"
if: "build.branch != 'main'"
parallelism: 5
soft_fail:
- exit_status: 2
@@ -829,7 +866,6 @@ steps:
- key: "linux-x64-test-ubuntu-2204"
label: ":ubuntu: 22.04 x64 - test-bun"
if: "build.branch != 'main'"
parallelism: 5
soft_fail:
- exit_status: 2
@@ -858,7 +894,6 @@ steps:
- key: "linux-x64-test-ubuntu-2004"
label: ":ubuntu: 20.04 x64 - test-bun"
if: "build.branch != 'main'"
parallelism: 5
soft_fail:
- exit_status: 2
@@ -885,9 +920,36 @@ steps:
command:
- "./scripts/runner.node.mjs --step linux-x64-build-bun-nolto"
- key: "linux-x64-test-amazonlinux-2023"
label: ":aws: 2023 x64 - test-bun"
parallelism: 5
soft_fail:
- exit_status: 2
retry:
automatic:
- exit_status: 1
limit: 1
- exit_status: -1
limit: 3
- exit_status: 255
limit: 3
- signal_reason: agent_stop
limit: 3
- signal: SIGTERM
limit: 3
depends_on:
- "linux-x64-build-bun-nolto"
agents:
robobun: "true"
os: "linux"
arch: "x64"
distro: "amazonlinux"
release: "2023"
command:
- "./scripts/runner.node.mjs --step linux-x64-build-bun-nolto"
- key: "linux-x64-test-debian-12-smoke"
label: ":debian: 12 x64 - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 2
@@ -916,7 +978,6 @@ steps:
- key: "linux-x64-test-ubuntu-2204-smoke"
label: ":ubuntu: 22.04 x64 - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 2
@@ -945,7 +1006,6 @@ steps:
- key: "linux-x64-test-ubuntu-2004-smoke"
label: ":ubuntu: 20.04 x64 - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 2
@@ -972,6 +1032,34 @@ steps:
command:
- "./scripts/runner.node.mjs --step linux-x64-build-bun --smoke 0.05"
- key: "linux-x64-test-amazonlinux-2023-smoke"
label: ":aws: 2023 x64 - test-bun (smoke)"
parallelism: 1
soft_fail:
- exit_status: 2
retry:
automatic:
- exit_status: 1
limit: 1
- exit_status: -1
limit: 3
- exit_status: 255
limit: 3
- signal_reason: agent_stop
limit: 3
- signal: SIGTERM
limit: 3
depends_on:
- "linux-x64-build-bun"
agents:
robobun: "true"
os: "linux"
arch: "x64"
distro: "amazonlinux"
release: "2023"
command:
- "./scripts/runner.node.mjs --step linux-x64-build-bun --smoke 0.05"
# Linux x64-baseline
- key: "linux-x64-baseline"
group: ":linux: x64-baseline"
@@ -1027,7 +1115,6 @@ steps:
- key: "linux-x64-baseline-build-bun-nolto"
label: ":linux: x64-baseline - build-bun (no-lto)"
if: "build.branch != 'main'"
depends_on:
- "linux-x64-baseline-build-deps"
- "linux-x64-baseline-build-zig"
@@ -1070,7 +1157,6 @@ steps:
- key: "linux-x64-baseline-test-debian-12"
label: ":debian: 12 x64-baseline - test-bun"
if: "build.branch != 'main'"
parallelism: 5
soft_fail:
- exit_status: 2
@@ -1099,7 +1185,6 @@ steps:
- key: "linux-x64-baseline-test-ubuntu-2204"
label: ":ubuntu: 22.04 x64-baseline - test-bun"
if: "build.branch != 'main'"
parallelism: 5
soft_fail:
- exit_status: 2
@@ -1128,7 +1213,6 @@ steps:
- key: "linux-x64-baseline-test-ubuntu-2004"
label: ":ubuntu: 20.04 x64-baseline - test-bun"
if: "build.branch != 'main'"
parallelism: 5
soft_fail:
- exit_status: 2
@@ -1155,9 +1239,36 @@ steps:
command:
- "./scripts/runner.node.mjs --step linux-x64-baseline-build-bun-nolto"
- key: "linux-x64-baseline-test-amazonlinux-2023"
label: ":aws: 2023 x64-baseline - test-bun"
parallelism: 5
soft_fail:
- exit_status: 2
retry:
automatic:
- exit_status: 1
limit: 1
- exit_status: -1
limit: 3
- exit_status: 255
limit: 3
- signal_reason: agent_stop
limit: 3
- signal: SIGTERM
limit: 3
depends_on:
- "linux-x64-baseline-build-bun-nolto"
agents:
robobun: "true"
os: "linux"
arch: "x64"
distro: "amazonlinux"
release: "2023"
command:
- "./scripts/runner.node.mjs --step linux-x64-baseline-build-bun-nolto"
- key: "linux-x64-baseline-test-debian-12-smoke"
label: ":debian: 12 x64-baseline - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 2
@@ -1186,7 +1297,6 @@ steps:
- key: "linux-x64-baseline-test-ubuntu-2204-smoke"
label: ":ubuntu: 22.04 x64-baseline - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 2
@@ -1215,7 +1325,6 @@ steps:
- key: "linux-x64-baseline-test-ubuntu-2004-smoke"
label: ":ubuntu: 20.04 x64-baseline - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 2
@@ -1242,6 +1351,34 @@ steps:
command:
- "./scripts/runner.node.mjs --step linux-x64-baseline-build-bun --smoke 0.05"
- key: "linux-x64-baseline-test-amazonlinux-2023-smoke"
label: ":aws: 2023 x64-baseline - test-bun (smoke)"
parallelism: 1
soft_fail:
- exit_status: 2
retry:
automatic:
- exit_status: 1
limit: 1
- exit_status: -1
limit: 3
- exit_status: 255
limit: 3
- signal_reason: agent_stop
limit: 3
- signal: SIGTERM
limit: 3
depends_on:
- "linux-x64-baseline-build-bun"
agents:
robobun: "true"
os: "linux"
arch: "x64"
distro: "amazonlinux"
release: "2023"
command:
- "./scripts/runner.node.mjs --step linux-x64-baseline-build-bun --smoke 0.05"
# Windows x64
- key: "windows-x64"
group: ":windows: x64"
@@ -1289,7 +1426,6 @@ steps:
- key: "windows-x64-build-bun-nolto"
label: ":windows: x64 - build-bun (no-lto)"
if: "build.branch != 'main'"
depends_on:
- "windows-x64-build-deps"
- "windows-x64-build-zig"
@@ -1332,7 +1468,6 @@ steps:
- key: "windows-x64-test-bun"
label: ":windows: x64 - test-bun"
if: "build.branch != 'main'"
parallelism: 10
soft_fail:
- exit_status: 1
@@ -1357,7 +1492,6 @@ steps:
- key: "windows-x64-test-bun-smoke"
label: ":windows: x64 - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 1
@@ -1431,7 +1565,6 @@ steps:
- key: "windows-x64-baseline-build-bun-nolto"
label: ":windows: x64-baseline - build-bun (no-lto)"
if: "build.branch != 'main'"
depends_on:
- "windows-x64-baseline-build-deps"
- "windows-x64-baseline-build-zig"
@@ -1474,7 +1607,6 @@ steps:
- key: "windows-x64-baseline-test-bun"
label: ":windows: x64-baseline - test-bun"
if: "build.branch != 'main'"
parallelism: 10
soft_fail:
- exit_status: 1
@@ -1499,7 +1631,6 @@ steps:
- key: "windows-x64-baseline-test-bun-smoke"
label: ":windows: x64-baseline - test-bun (smoke)"
if: "build.branch != 'main'"
parallelism: 1
soft_fail:
- exit_status: 1

View File

@@ -3,11 +3,11 @@
set -eo pipefail
function assert_main() {
if [[ "$BUILDKITE_PULL_REQUEST_REPO" && "$BUILDKITE_REPO" != "$BUILDKITE_PULL_REQUEST_REPO" ]]; then
if [ "$BUILDKITE_REPO" != "$BUILDKITE_PULL_REQUEST_REPO" ]; then
echo "error: Cannot upload release from a fork"
exit 1
fi
if [ "$BUILDKITE_PULL_REQUEST" != "false" ]; then
if [ -n "$BUILDKITE_PULL_REQUEST" ]; then
echo "error: Cannot upload release from a pull request"
exit 1
fi

View File

@@ -6,45 +6,112 @@ inputs:
type: string
description: "The version of bun to install: 'latest', 'canary', 'bun-v1.0.0', etc."
default: latest
required: false
workflow-run-id:
type: string
description: "The workflow run ID where to download bun."
baseline:
type: boolean
description: "Whether to use the baseline version of bun."
default: false
required: false
add-to-path:
type: boolean
description: "Whether to add bun to PATH."
default: true
download-url:
type: string
description: "The base URL to download bun from."
default: "https://pub-5e11e972747a44bf9aaf9394f185a982.r2.dev/releases"
required: false
outputs:
os:
description: "Operating system: 'darwin', 'linux', or 'windows'."
value: ${{ steps.setup.outputs.os }}
arch:
description: "Architecture: 'aarch64' or 'x64'."
value: ${{ steps.setup.outputs.arch }}
target:
description: "Target: 'bun-{os}-{arch}-[baseline]'."
value: ${{ steps.setup.outputs.target }}
release:
description: "Release: 'latest', 'canary', or 'bun-v1.x.x'."
value: ${{ steps.setup.outputs.release }}
bun-path:
description: "The path to Bun."
value: ${{ steps.unpack.outputs.bun-path }}
runs:
using: composite
steps:
- name: Setup Bun
- id: setup
name: Setup Bun
shell: bash
run: |
set -x
case "$(uname -s)" in
Linux*) os=linux;;
Darwin*) os=darwin;;
*) os=windows;;
esac
echo "os=${os}" >> $GITHUB_OUTPUT
case "$(uname -m)" in
arm64 | aarch64) arch=aarch64;;
*) arch=x64;;
esac
echo "arch=${arch}" >> $GITHUB_OUTPUT
case "${{ inputs.baseline }}" in
true | 1) target="bun-${os}-${arch}-baseline";;
*) target="bun-${os}-${arch}";;
true | 1) target="bun-${os}-${arch}-baseline" ;;
*) target="bun-${os}-${arch}" ;;
esac
echo "target=${target}" >> $GITHUB_OUTPUT
case "${{ inputs.bun-version }}" in
latest) release="latest";;
canary) release="canary";;
*) release="bun-v${{ inputs.bun-version }}";;
latest) release="latest" ;;
canary) release="canary" ;;
*) release="bun-v${{ inputs.bun-version }}" ;;
esac
curl -LO "${{ inputs.download-url }}/${release}/${target}.zip"
unzip ${target}.zip
mkdir -p ${{ runner.temp }}/.bun/bin
mv ${target}/bun* ${{ runner.temp }}/.bun/bin/
chmod +x ${{ runner.temp }}/.bun/bin/*
echo "${{ runner.temp }}/.bun/bin" >> ${GITHUB_PATH}
if [[ "${{ inputs.workflow-run-id }}" ]]; then
release="workflow-${{ inputs.workflow-run-id }}"
fi
echo "release=${release}" >> $GITHUB_OUTPUT
- if: ${{ inputs.workflow-run-id }}
name: Download Bun from Github Actions
uses: actions/download-artifact@v4
with:
github-token: ${{ github.token }}
run-id: ${{ inputs.workflow-run-id }}
name: ${{ steps.setup.outputs.target }}
- if: ${{ !inputs.workflow-run-id }}
name: Download Bun from URL
shell: bash
run: |
set -x
curl -LO ${{ inputs.download-url }}/${{ steps.setup.outputs.release }}/${{ steps.setup.outputs.target }}.zip
- id: unpack
name: Unpack Bun
shell: bash
run: |
set -x
target="${{ steps.setup.outputs.target }}"
release="${{ steps.setup.outputs.release }}"
mkdir -p ${target}/${release}
unzip ${target}.zip -d ${target}
mv ${target}/${target}/* ${target}/${release}/
rm -rf ${target}/${target}
rm -f ${target}.zip
bin="$(pwd)/${target}/${release}"
path="${bin}/bun"
if [[ "${{ runner.os }}" == "Windows" ]]; then
bin=$(cygpath -w ${bin})
path=$(cygpath -w ${path})
fi
echo "bun-bin=${bin}" >> $GITHUB_OUTPUT
echo "bun-path=${path}" >> ${GITHUB_OUTPUT}
- if: ${{ inputs.add-to-path == 'true' }}
name: Add Bun to Path
shell: bash
run: |
set -x
echo "${{ steps.unpack.outputs.bun-bin }}" >> ${GITHUB_PATH}

131
.github/workflows/build-bun.yml vendored Normal file
View File

@@ -0,0 +1,131 @@
name: Build Bun
permissions:
contents: read
actions: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
workflow_call:
inputs:
no-cache:
type: boolean
canary:
type: boolean
assertions:
type: boolean
zig-optimize:
type: string
workflow_dispatch:
inputs:
no-cache:
type: boolean
canary:
type: boolean
assertions:
type: boolean
zig-optimize:
type: string
jobs:
linux-x64:
name: Build linux-x64
uses: ./.github/workflows/build-linux.yml
secrets: inherit
with:
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-linux-x64' || 'ubuntu-latest' }}
tag: linux-x64
arch: x64
cpu: haswell
no-cache: ${{ inputs.no-cache }}
canary: ${{ inputs.canary }}
assertions: ${{ inputs.assertions }}
zig-optimize: ${{ inputs.zig-optimize }}
linux-x64-baseline:
name: Build linux-x64-baseline
uses: ./.github/workflows/build-linux.yml
secrets: inherit
with:
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-linux-x64' || 'ubuntu-latest' }}
tag: linux-x64-baseline
arch: x64
cpu: nehalem
no-cache: ${{ inputs.no-cache }}
canary: ${{ inputs.canary }}
assertions: ${{ inputs.assertions }}
zig-optimize: ${{ inputs.zig-optimize }}
linux-aarch64:
if: ${{ github.repository_owner == 'oven-sh' }}
name: Build linux-aarch64
uses: ./.github/workflows/build-linux.yml
secrets: inherit
with:
runs-on: namespace-profile-bun-ci-linux-aarch64
tag: linux-aarch64
arch: aarch64
cpu: native
no-cache: ${{ inputs.no-cache }}
canary: ${{ inputs.canary }}
assertions: ${{ inputs.assertions }}
zig-optimize: ${{ inputs.zig-optimize }}
darwin-x64:
name: Build darwin-x64
uses: ./.github/workflows/build-darwin.yml
secrets: inherit
with:
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-12-large' || 'macos-12' }}
tag: darwin-x64
arch: x64
cpu: haswell
no-cache: ${{ inputs.no-cache }}
canary: ${{ inputs.canary }}
assertions: ${{ inputs.assertions }}
zig-optimize: ${{ inputs.zig-optimize }}
darwin-aarch64:
name: Build darwin-aarch64
uses: ./.github/workflows/build-darwin.yml
secrets: inherit
with:
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-darwin-aarch64' || 'macos-12' }}
tag: darwin-aarch64
arch: aarch64
cpu: native
no-cache: ${{ inputs.no-cache }}
canary: ${{ inputs.canary }}
assertions: ${{ inputs.assertions }}
zig-optimize: ${{ inputs.zig-optimize }}
windows-x64:
name: Build windows-x64
uses: ./.github/workflows/build-windows.yml
secrets: inherit
with:
runs-on: windows
tag: windows-x64
arch: x64
cpu: haswell
no-cache: ${{ inputs.no-cache }}
canary: ${{ inputs.canary }}
assertions: ${{ inputs.assertions }}
zig-optimize: ${{ inputs.zig-optimize }}
windows-x64-baseline:
name: Build windows-x64-baseline
uses: ./.github/workflows/build-windows.yml
secrets: inherit
with:
runs-on: windows
tag: windows-x64-baseline
arch: x64
cpu: nehalem
no-cache: ${{ inputs.no-cache }}
canary: ${{ inputs.canary }}
assertions: ${{ inputs.assertions }}
zig-optimize: ${{ inputs.zig-optimize }}

View File

@@ -9,7 +9,7 @@ on:
inputs:
runs-on:
type: string
default: macos-13-large
default: macos-12-large
tag:
type: string
required: true
@@ -21,18 +21,18 @@ on:
required: true
assertions:
type: boolean
zig-optimize:
type: string
canary:
type: boolean
no-cache:
type: boolean
env:
LLVM_VERSION: 18
LLVM_VERSION: 16
BUN_VERSION: 1.1.8
LC_CTYPE: "en_US.UTF-8"
LC_ALL: "en_US.UTF-8"
# LTO is disabled because we cannot use lld on macOS currently
BUN_ENABLE_LTO: "0"
jobs:
build-submodules:
@@ -55,7 +55,16 @@ jobs:
cat $(echo scripts/build*.sh scripts/all-dependencies.sh | tr " " "\n" | sort)
}
echo "hash=$(print_versions | shasum)" >> $GITHUB_OUTPUT
- name: Install Dependencies
- if: ${{ !inputs.no-cache }}
name: Restore Cache
id: cache
uses: actions/cache/restore@v4
with:
path: ${{ runner.temp }}/bun-deps
key: bun-${{ inputs.tag }}-deps-${{ steps.hash.outputs.hash }}
# TODO: Figure out how to cache homebrew dependencies
- if: ${{ inputs.no-cache || !steps.cache.outputs.cache-hit }}
name: Install Dependencies
env:
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
HOMEBREW_NO_AUTO_UPDATE: 1
@@ -79,16 +88,24 @@ jobs:
echo "$(brew --prefix coreutils)/libexec/gnubin" >> $GITHUB_PATH
echo "$(brew --prefix llvm@$LLVM_VERSION)/bin" >> $GITHUB_PATH
brew link --overwrite llvm@$LLVM_VERSION
- name: Clone Submodules
- if: ${{ inputs.no-cache || !steps.cache.outputs.cache-hit }}
name: Clone Submodules
run: |
./scripts/update-submodules.sh
- name: Build Submodules
if: ${{ inputs.no-cache || !steps.cache.outputs.cache-hit }}
env:
CPU_TARGET: ${{ inputs.cpu }}
BUN_DEPS_OUT_DIR: ${{ runner.temp }}/bun-deps
run: |
mkdir -p $BUN_DEPS_OUT_DIR
./scripts/all-dependencies.sh
- name: Save Cache
if: ${{ inputs.no-cache || !steps.cache.outputs.cache-hit }}
uses: actions/cache/save@v4
with:
path: ${{ runner.temp }}/bun-deps
key: ${{ steps.cache.outputs.cache-primary-key }}
- name: Upload bun-${{ inputs.tag }}-deps
uses: actions/upload-artifact@v4
with:
@@ -132,6 +149,14 @@ jobs:
uses: ./.github/actions/setup-bun
with:
bun-version: ${{ env.BUN_VERSION }}
- if: ${{ !inputs.no-cache }}
name: Restore Cache
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/ccache
key: bun-${{ inputs.tag }}-cpp-${{ hashFiles('Dockerfile', 'Makefile', 'CMakeLists.txt', 'build.zig', 'scripts/**', 'src/**', 'packages/bun-usockets/src/**', 'packages/bun-uws/src/**') }}
restore-keys: |
bun-${{ inputs.tag }}-cpp-
- name: Compile
env:
CPU_TARGET: ${{ inputs.cpu }}
@@ -166,6 +191,7 @@ jobs:
arch: ${{ inputs.arch }}
cpu: ${{ inputs.cpu }}
assertions: ${{ inputs.assertions }}
zig-optimize: ${{ inputs.zig-optimize }}
canary: ${{ inputs.canary }}
no-cache: ${{ inputs.no-cache }}
link:
@@ -221,9 +247,18 @@ jobs:
with:
name: bun-${{ inputs.tag }}-zig
path: ${{ runner.temp }}/release
- if: ${{ !inputs.no-cache }}
name: Restore Cache
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/ccache
key: bun-${{ inputs.tag }}-cpp-${{ hashFiles('Dockerfile', 'Makefile', 'CMakeLists.txt', 'build.zig', 'scripts/**', 'src/**', 'packages/bun-usockets/src/**', 'packages/bun-uws/src/**') }}
restore-keys: |
bun-${{ inputs.tag }}-cpp-
- name: Link
env:
CPU_TARGET: ${{ inputs.cpu }}
CCACHE_DIR: ${{ runner.temp }}/ccache
run: |
SRC_DIR=$PWD
mkdir ${{ runner.temp }}/link-build
@@ -244,12 +279,6 @@ jobs:
chmod +x bun-profile bun
mkdir -p bun-${{ inputs.tag }}-profile/ bun-${{ inputs.tag }}/
mv bun-profile bun-${{ inputs.tag }}-profile/bun-profile
if [ -f bun-profile.dSYM || -d bun-profile.dSYM ]; then
mv bun-profile.dSYM bun-${{ inputs.tag }}-profile/bun-profile.dSYM
fi
if [ -f bun.dSYM || -d bun.dSYM ]; then
mv bun.dSYM bun-${{ inputs.tag }}-profile/bun-profile.dSYM
fi
mv bun bun-${{ inputs.tag }}/bun
zip -r bun-${{ inputs.tag }}-profile.zip bun-${{ inputs.tag }}-profile
zip -r bun-${{ inputs.tag }}.zip bun-${{ inputs.tag }}

View File

@@ -43,6 +43,7 @@ jobs:
zig-optimize: ${{ inputs.zig-optimize }}
canary: ${{ inputs.canary }}
no-cache: ${{ inputs.no-cache }}
on-failure:
if: ${{ github.repository_owner == 'oven-sh' && failure() }}
name: On Failure

View File

@@ -21,6 +21,8 @@ on:
required: true
assertions:
type: boolean
zig-optimize:
type: string
canary:
type: boolean
no-cache:
@@ -31,27 +33,24 @@ on:
env:
# Must specify exact version of LLVM for Windows
LLVM_VERSION: 18.1.8
LLVM_VERSION: 16.0.6
BUN_VERSION: ${{ inputs.bun-version }}
BUN_GARBAGE_COLLECTOR_LEVEL: 1
BUN_FEATURE_FLAG_INTERNAL_FOR_TESTING: 1
CI: true
USE_LTO: 1
jobs:
build-submodules:
name: Build Submodules
runs-on: ${{ inputs.runs-on }}
steps:
- name: Install Scoop
run: |
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
Join-Path (Resolve-Path ~).Path "scoop\shims" >> $Env:GITHUB_PATH
- name: Install VS2022 BuildTools 17.9.7
run: choco install -y visualstudio2022buildtools --version=117.9.7.0 --params "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --installChannelUri https://aka.ms/vs/17/release/180911598_-255012421/channel"
- name: Setup Git
run: |
git config --global core.autocrlf false
git config --global core.eol lf
git config --system core.longpaths true
- name: Checkout
uses: actions/checkout@v4
with:
@@ -78,11 +77,14 @@ jobs:
path: bun-deps
key: bun-${{ inputs.tag }}-deps-${{ steps.hash.outputs.hash }}
- if: ${{ inputs.no-cache || !steps.cache.outputs.cache-hit }}
name: Install LLVM and Ninja
name: Install LLVM
uses: KyleMayes/install-llvm-action@8b37482c5a2997a3ab5dbf6561f8109e2eaa7d3b
with:
version: ${{ env.LLVM_VERSION }}
- if: ${{ inputs.no-cache || !steps.cache.outputs.cache-hit }}
name: Install Ninja
run: |
scoop install ninja
scoop install llvm@${{ env.LLVM_VERSION }}
scoop install nasm@2.16.01
choco install -y ninja
- if: ${{ inputs.no-cache || !steps.cache.outputs.cache-hit }}
name: Clone Submodules
run: |
@@ -92,9 +94,9 @@ jobs:
env:
CPU_TARGET: ${{ inputs.cpu }}
CCACHE_DIR: ccache
USE_LTO: 1
run: |
.\scripts\env.ps1 ${{ contains(inputs.tag, '-baseline') && '-Baseline' || '' }}
choco install -y nasm --version=2.16.01
$env:BUN_DEPS_OUT_DIR = (mkdir -Force "./bun-deps")
.\scripts\all-dependencies.ps1
- name: Save Cache
@@ -109,6 +111,7 @@ jobs:
name: bun-${{ inputs.tag }}-deps
path: bun-deps
if-no-files-found: error
codegen:
name: Codegen
runs-on: ubuntu-latest
@@ -117,6 +120,7 @@ jobs:
run: |
git config --global core.autocrlf false
git config --global core.eol lf
git config --system core.longpaths true
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
@@ -137,28 +141,30 @@ jobs:
name: bun-${{ inputs.tag }}-codegen
path: build-codegen-win32-x64
if-no-files-found: error
build-cpp:
name: Build C++
needs: codegen
runs-on: ${{ inputs.runs-on }}
steps:
- name: Install Scoop
run: |
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
Join-Path (Resolve-Path ~).Path "scoop\shims" >> $Env:GITHUB_PATH
- name: Install VS2022 BuildTools 17.9.7
run: choco install -y visualstudio2022buildtools --version=117.9.7.0 --params "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --installChannelUri https://aka.ms/vs/17/release/180911598_-255012421/channel"
- name: Setup Git
run: |
git config --global core.autocrlf false
git config --global core.eol lf
git config --system core.longpaths true
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install LLVM and Ninja
- name: Install LLVM
uses: KyleMayes/install-llvm-action@8b37482c5a2997a3ab5dbf6561f8109e2eaa7d3b
with:
version: ${{ env.LLVM_VERSION }}
- name: Install Ninja
run: |
scoop install ninja
scoop install llvm@${{ env.LLVM_VERSION }}
choco install -y ninja
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
@@ -180,7 +186,6 @@ jobs:
env:
CPU_TARGET: ${{ inputs.cpu }}
CCACHE_DIR: ccache
USE_LTO: 1
run: |
# $CANARY_REVISION = if (Test-Path build/.canary_revision) { Get-Content build/.canary_revision } else { "0" }
$CANARY_REVISION = 0
@@ -190,7 +195,6 @@ jobs:
cd build
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release `
-DNO_CODEGEN=1 `
-DUSE_LTO=1 `
-DNO_CONFIGURE_DEPENDS=1 `
"-DCANARY=${CANARY_REVISION}" `
-DBUN_CPP_ONLY=1 ${{ contains(inputs.tag, '-baseline') && '-DUSE_BASELINE_BUILD=1' || '' }}
@@ -203,19 +207,23 @@ jobs:
name: bun-${{ inputs.tag }}-cpp
path: build/bun-cpp-objects.a
if-no-files-found: error
build-zig:
name: Build Zig
uses: ./.github/workflows/build-zig.yml
with:
os: windows
zig-optimize: ReleaseSafe
only-zig: true
tag: ${{ inputs.tag }}
arch: ${{ inputs.arch }}
cpu: ${{ inputs.cpu }}
assertions: ${{ inputs.assertions }}
zig-optimize: ReleaseSafe
# Windows is always ReleaseSafe for now
# zig-optimize: ${{ inputs.zig-optimize }}
canary: ${{ inputs.canary }}
no-cache: ${{ inputs.no-cache }}
link:
name: Link
runs-on: ${{ inputs.runs-on }}
@@ -225,23 +233,24 @@ jobs:
- build-zig
- codegen
steps:
- name: Install Scoop
run: |
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
Join-Path (Resolve-Path ~).Path "scoop\shims" >> $Env:GITHUB_PATH
- name: Install VS2022 BuildTools 17.9.7
run: choco install -y visualstudio2022buildtools --version=117.9.7.0 --params "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --installChannelUri https://aka.ms/vs/17/release/180911598_-255012421/channel"
- name: Setup Git
run: |
git config --global core.autocrlf false
git config --global core.eol lf
git config --system core.longpaths true
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install LLVM
uses: KyleMayes/install-llvm-action@8b37482c5a2997a3ab5dbf6561f8109e2eaa7d3b
with:
version: ${{ env.LLVM_VERSION }}
- name: Install Ninja
run: |
scoop install ninja
scoop install llvm@${{ env.LLVM_VERSION }}
choco install -y ninja
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
@@ -289,7 +298,6 @@ jobs:
-DNO_CONFIGURE_DEPENDS=1 `
"-DCANARY=${CANARY_REVISION}" `
-DBUN_LINK_ONLY=1 `
-DUSE_LTO=1 `
"-DBUN_DEPS_OUT_DIR=$(Resolve-Path ../bun-deps)" `
"-DBUN_CPP_ARCHIVE=$(Resolve-Path ../bun-cpp/bun-cpp-objects.a)" `
"-DBUN_ZIG_OBJ_DIR=$(Resolve-Path ../bun-zig)" `
@@ -327,6 +335,7 @@ jobs:
path: features.json
if-no-files-found: error
overwrite: true
on-failure:
if: ${{ github.repository_owner == 'oven-sh' && failure() }}
name: On Failure

View File

@@ -1,245 +0,0 @@
name: CI
permissions:
contents: read
actions: write
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'workflow_dispatch' && inputs.run-id || github.ref }}
cancel-in-progress: true
on:
workflow_dispatch:
inputs:
run-id:
type: string
description: The workflow ID to download artifacts (skips the build step)
pull_request:
paths-ignore:
- .vscode/**/*
- docs/**/*
- examples/**/*
push:
branches:
- main
paths-ignore:
- .vscode/**/*
- docs/**/*
- examples/**/*
jobs:
format:
if: ${{ !inputs.run-id }}
name: Format
uses: ./.github/workflows/run-format.yml
secrets: inherit
with:
zig-version: 0.13.0
permissions:
contents: write
lint:
if: ${{ !inputs.run-id }}
name: Lint
uses: ./.github/workflows/run-lint.yml
secrets: inherit
linux-x64:
if: ${{ !inputs.run-id }}
name: Build linux-x64
uses: ./.github/workflows/build-linux.yml
secrets: inherit
with:
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-linux-x64' || 'ubuntu-latest' }}
tag: linux-x64
arch: x64
cpu: haswell
canary: true
no-cache: true
linux-x64-baseline:
if: ${{ !inputs.run-id }}
name: Build linux-x64-baseline
uses: ./.github/workflows/build-linux.yml
secrets: inherit
with:
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-linux-x64' || 'ubuntu-latest' }}
tag: linux-x64-baseline
arch: x64
cpu: nehalem
canary: true
no-cache: true
linux-aarch64:
if: ${{ !inputs.run-id && github.repository_owner == 'oven-sh' }}
name: Build linux-aarch64
uses: ./.github/workflows/build-linux.yml
secrets: inherit
with:
runs-on: namespace-profile-bun-ci-linux-aarch64
tag: linux-aarch64
arch: aarch64
cpu: native
canary: true
no-cache: true
darwin-x64:
if: ${{ !inputs.run-id }}
name: Build darwin-x64
uses: ./.github/workflows/build-darwin.yml
secrets: inherit
with:
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-13-large' || 'macos-13' }}
tag: darwin-x64
arch: x64
cpu: haswell
canary: true
darwin-x64-baseline:
if: ${{ !inputs.run-id }}
name: Build darwin-x64-baseline
uses: ./.github/workflows/build-darwin.yml
secrets: inherit
with:
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-13-large' || 'macos-13' }}
tag: darwin-x64-baseline
arch: x64
cpu: nehalem
canary: true
darwin-aarch64:
if: ${{ !inputs.run-id }}
name: Build darwin-aarch64
uses: ./.github/workflows/build-darwin.yml
secrets: inherit
with:
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-darwin-aarch64' || 'macos-13' }}
tag: darwin-aarch64
arch: aarch64
cpu: native
canary: true
windows-x64:
if: ${{ !inputs.run-id }}
name: Build windows-x64
uses: ./.github/workflows/build-windows.yml
secrets: inherit
with:
runs-on: windows
tag: windows-x64
arch: x64
cpu: haswell
canary: true
windows-x64-baseline:
if: ${{ !inputs.run-id }}
name: Build windows-x64-baseline
uses: ./.github/workflows/build-windows.yml
secrets: inherit
with:
runs-on: windows
tag: windows-x64-baseline
arch: x64
cpu: nehalem
canary: true
linux-x64-test:
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
name: Test linux-x64
needs: linux-x64
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
run-id: ${{ inputs.run-id }}
pr-number: ${{ github.event.number }}
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-linux-x64' || 'ubuntu-latest' }}
tag: linux-x64
linux-x64-baseline-test:
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
name: Test linux-x64-baseline
needs: linux-x64-baseline
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
run-id: ${{ inputs.run-id }}
pr-number: ${{ github.event.number }}
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-linux-x64' || 'ubuntu-latest' }}
tag: linux-x64-baseline
linux-aarch64-test:
if: ${{ inputs.run-id || github.event_name == 'pull_request' && github.repository_owner == 'oven-sh'}}
name: Test linux-aarch64
needs: linux-aarch64
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
run-id: ${{ inputs.run-id }}
pr-number: ${{ github.event.number }}
runs-on: namespace-profile-bun-ci-linux-aarch64
tag: linux-aarch64
darwin-x64-test:
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
name: Test darwin-x64
needs: darwin-x64
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
run-id: ${{ inputs.run-id }}
pr-number: ${{ github.event.number }}
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-13-large' || 'macos-13' }}
tag: darwin-x64
darwin-x64-baseline-test:
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
name: Test darwin-x64-baseline
needs: darwin-x64-baseline
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
run-id: ${{ inputs.run-id }}
pr-number: ${{ github.event.number }}
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-13-large' || 'macos-13' }}
tag: darwin-x64-baseline
darwin-aarch64-test:
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
name: Test darwin-aarch64
needs: darwin-aarch64
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
run-id: ${{ inputs.run-id }}
pr-number: ${{ github.event.number }}
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-darwin-aarch64' || 'macos-13' }}
tag: darwin-aarch64
windows-x64-test:
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
name: Test windows-x64
needs: windows-x64
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
run-id: ${{ inputs.run-id }}
pr-number: ${{ github.event.number }}
runs-on: windows
tag: windows-x64
windows-x64-baseline-test:
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
name: Test windows-x64-baseline
needs: windows-x64-baseline
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
run-id: ${{ inputs.run-id }}
pr-number: ${{ github.event.number }}
runs-on: windows
tag: windows-x64-baseline
cleanup:
if: ${{ always() }}
name: Cleanup
needs:
- linux-x64
- linux-x64-baseline
- linux-aarch64
- darwin-x64
- darwin-x64-baseline
- darwin-aarch64
- windows-x64
- windows-x64-baseline
runs-on: ubuntu-latest
steps:
- name: Cleanup Artifacts
uses: geekyeggo/delete-artifact@v5
with:
name: |
bun-*-cpp
bun-*-zig
bun-*-deps
bun-*-codegen

View File

@@ -90,7 +90,7 @@ jobs:
uses: ./.github/workflows/build-darwin.yml
secrets: inherit
with:
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-13-large' || 'macos-13' }}
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-12-large' || 'macos-12' }}
tag: darwin-x64
arch: x64
cpu: haswell
@@ -100,7 +100,7 @@ jobs:
uses: ./.github/workflows/build-darwin.yml
secrets: inherit
with:
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-13-large' || 'macos-13' }}
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-12-large' || 'macos-12' }}
tag: darwin-x64-baseline
arch: x64
cpu: nehalem
@@ -110,7 +110,7 @@ jobs:
uses: ./.github/workflows/build-darwin.yml
secrets: inherit
with:
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-darwin-aarch64' || 'macos-13' }}
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-darwin-aarch64' || 'macos-12' }}
tag: darwin-aarch64
arch: aarch64
cpu: native

View File

@@ -1,89 +0,0 @@
name: Comment on updated submodule
on:
pull_request_target:
paths:
- "src/generated_versions_list.zig"
- ".github/workflows/on-submodule-update.yml"
jobs:
comment:
name: Comment
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'oven-sh' }}
permissions:
contents: read
pull-requests: write
issues: write
steps:
- name: Checkout current
uses: actions/checkout@v4
with:
sparse-checkout: |
src
- name: Hash generated versions list
id: hash
run: |
echo "hash=$(sha256sum src/generated_versions_list.zig | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT
- name: Checkout base
uses: actions/checkout@v4
with:
ref: ${{ github.base_ref }}
sparse-checkout: |
src
- name: Hash base
id: base
run: |
echo "base=$(sha256sum src/generated_versions_list.zig | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT
- name: Compare
id: compare
run: |
if [ "${{ steps.hash.outputs.hash }}" != "${{ steps.base.outputs.base }}" ]; then
echo "changed=true" >> $GITHUB_OUTPUT
else
echo "changed=false" >> $GITHUB_OUTPUT
fi
- name: Find Comment
id: comment
uses: peter-evans/find-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: github-actions[bot]
body-includes: <!-- generated-comment submodule-updated -->
- name: Write Warning Comment
uses: peter-evans/create-or-update-comment@v4
if: steps.compare.outputs.changed == 'true'
with:
comment-id: ${{ steps.comment.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
edit-mode: replace
body: |
⚠️ **Warning:** @${{ github.actor }}, this PR has changes to submodule versions.
If this change was intentional, please ignore this message. If not, please undo changes to submodules and rebase your branch.
<!-- generated-comment submodule-updated -->
- name: Add labels
uses: actions-cool/issues-helper@v3
if: steps.compare.outputs.changed == 'true'
with:
actions: "add-labels"
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.pull_request.number }}
labels: "changed-submodules"
- name: Remove labels
uses: actions-cool/issues-helper@v3
if: steps.compare.outputs.changed == 'false'
with:
actions: "remove-labels"
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.pull_request.number }}
labels: "changed-submodules"
- name: Delete outdated comment
uses: actions-cool/issues-helper@v3
if: steps.compare.outputs.changed == 'false' && steps.comment.outputs.comment-id != ''
with:
actions: "delete-comment"
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.pull_request.number }}
comment-id: ${{ steps.comment.outputs.comment-id }}

View File

@@ -63,7 +63,7 @@ jobs:
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.20"
bun-version: "1.0.21"
- name: Install Dependencies
run: bun install
- name: Sign Release
@@ -88,7 +88,7 @@ jobs:
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.20"
bun-version: "1.0.21"
- name: Install Dependencies
run: bun install
- name: Release
@@ -117,7 +117,7 @@ jobs:
if: ${{ env.BUN_VERSION != 'canary' }}
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.20"
bun-version: "1.0.21"
- name: Setup Bun
if: ${{ env.BUN_VERSION == 'canary' }}
uses: ./.github/actions/setup-bun
@@ -259,7 +259,7 @@ jobs:
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.20"
bun-version: "1.0.21"
- name: Install Dependencies
run: bun install
- name: Release
@@ -270,24 +270,6 @@ jobs:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
AWS_ENDPOINT: ${{ secrets.AWS_ENDPOINT }}
AWS_BUCKET: bun
notify-sentry:
name: Notify Sentry
runs-on: ubuntu-latest
needs: s3
steps:
- name: Notify Sentry
uses: getsentry/action-release@v1.7.0
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
with:
ignore_missing: true
ignore_empty: true
version: ${{ env.BUN_VERSION }}
environment: production
bump:
name: "Bump version"
runs-on: ubuntu-latest

View File

@@ -29,7 +29,7 @@ jobs:
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.20"
bun-version: "1.1.8"
- name: Setup Zig
uses: goto-bus-stop/setup-zig@c7b6cdd3adba8f8b96984640ff172c37c93f73ee
with:

View File

@@ -17,7 +17,7 @@ on:
jobs:
lint-cpp:
name: Lint C++
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-13-xlarge' || 'macos-13' }}
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-13-xlarge' || 'macos-12' }}
steps:
- name: Checkout
uses: actions/checkout@v4

View File

@@ -13,23 +13,42 @@ on:
tag:
type: string
required: true
pr-number:
github-id:
type: string
required: true
run-id:
release-name:
type: string
buildkite-url:
type: string
default: ${{ github.run_id }}
jobs:
test:
name: Tests
name: ${{ matrix.label }}
runs-on: ${{ inputs.runs-on }}
strategy:
fail-fast: false
matrix:
include:
- label: Bundler tests
include: bundler/,transpiler/
- label: CLI tests
include: cli/
- label: Node tests
include: js/node/
- label: Bun tests
include: js/bun/
- label: Web tests
include: js/web/
- label: Integration tests
include: integration/,third_party/
- label: Other tests
exclude: bundler/,transpiler/,cli/,integration/,third_party/,js/node/,js/bun/,js/web/
steps:
- if: ${{ runner.os == 'Windows' }}
name: Setup Git
run: |
git config --global core.autocrlf false
git config --global core.eol lf
git config --system core.autocrlf false
git config --system core.eol lf
git config --system core.longpaths true
- name: Checkout
uses: actions/checkout@v4
with:
@@ -37,188 +56,122 @@ jobs:
package.json
bun.lockb
test
packages/bun-internal-test
packages/bun-types
- name: Setup Environment
shell: bash
run: |
echo "${{ inputs.pr-number }}" > pr-number.txt
- name: Download Bun
uses: actions/download-artifact@v4
scripts
.github
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
name: bun-${{ inputs.tag }}
path: bun
github-token: ${{ github.token }}
run-id: ${{ inputs.run-id || github.run_id }}
- name: Download pnpm
uses: pnpm/action-setup@v4
bun-version: latest
baseline: ${{ contains(inputs.tag, '-baseline') }}
- id: setup-release
if: ${{ inputs.release-name }}
name: Setup Bun from Release
uses: ./.github/actions/setup-bun
with:
version: 8
- if: ${{ runner.os != 'Windows' }}
name: Setup Bun
shell: bash
run: |
unzip bun/bun-*.zip
cd bun-*
pwd >> $GITHUB_PATH
- if: ${{ runner.os == 'Windows' }}
name: Setup Cygwin
uses: secondlife/setup-cygwin@v3
bun-version: ${{ inputs.release-name }}
baseline: ${{ contains(inputs.tag, '-baseline') }}
add-to-path: false
- id: setup-github
if: ${{ inputs.github-id }}
name: Setup Bun from Github Actions
uses: ./.github/actions/setup-bun
with:
packages: bash
- if: ${{ runner.os == 'Windows' }}
name: Setup Bun (Windows)
run: |
unzip bun/bun-*.zip
cd bun-*
pwd >> $env:GITHUB_PATH
workflow-run-id: ${{ inputs.github-id }}
baseline: ${{ contains(inputs.tag, '-baseline') }}
add-to-path: false
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Dependencies
timeout-minutes: 5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
bun install
- name: Install Dependencies (test)
timeout-minutes: 5
run: |
bun install --cwd test
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install Dependencies (runner)
timeout-minutes: 5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
bun install --cwd packages/bun-internal-test
node-version: 22
- name: Run Tests
id: test
timeout-minutes: 90
shell: bash
timeout-minutes: 30
env:
IS_BUN_CI: 1
TMPDIR: ${{ runner.temp }}
BUN_TAG: ${{ inputs.tag }}
BUN_FEATURE_FLAG_INTERNAL_FOR_TESTING: "true"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SMTP_SENDGRID_SENDER: ${{ secrets.SMTP_SENDGRID_SENDER }}
TLS_MONGODB_DATABASE_URL: ${{ secrets.TLS_MONGODB_DATABASE_URL }}
TLS_POSTGRES_DATABASE_URL: ${{ secrets.TLS_POSTGRES_DATABASE_URL }}
TEST_INFO_STRIPE: ${{ secrets.TEST_INFO_STRIPE }}
TEST_INFO_AZURE_SERVICE_BUS: ${{ secrets.TEST_INFO_AZURE_SERVICE_BUS }}
SHELLOPTS: igncr
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
node packages/bun-internal-test/src/runner.node.mjs $(which bun)
- if: ${{ always() }}
name: Upload Results
uses: actions/upload-artifact@v4
with:
name: bun-${{ inputs.tag }}-tests
path: |
test-report.*
comment.md
pr-number.txt
if-no-files-found: error
overwrite: true
- if: ${{ always() && steps.test.outputs.failing_tests != '' && github.event.pull_request && github.repository_owner == 'oven-sh' }}
name: Send Message
uses: sarisia/actions-status-discord@v1
with:
webhook: ${{ secrets.DISCORD_WEBHOOK }}
nodetail: true
color: "#FF0000"
title: ""
description: |
### ❌ [${{ github.event.pull_request.title }}](${{ github.event.pull_request.html_url }})
node scripts/runner.node.mjs --exec-path "${{ steps.setup-github.outputs.bun-path || steps.setup-release.outputs.bun-path }}" --include "${{ matrix.include }}" --exclude "${{ matrix.exclude }}"
@${{ github.actor }}, there are ${{ steps.test.outputs.failing_tests_count || 'some' }} failing tests on bun-${{ inputs.tag }}.
${{ steps.test.outputs.failing_tests }}
**[View logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})**
- name: Fail
if: ${{ failure() || always() && steps.test.outputs.failing_tests != '' }}
run: |
echo "There are ${{ steps.test.outputs.failing_tests_count || 'some' }} failing tests on bun-${{ inputs.tag }}."
exit 1
test-node:
name: Node.js Tests
# TODO: enable when we start paying attention to the results. In the meantime, this causes CI to queue jobs wasting developer time.
if: 0
runs-on: ${{ inputs.runs-on }}
steps:
- if: ${{ runner.os == 'Windows' }}
name: Setup Git
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checkout
uses: actions/checkout@v4
with:
sparse-checkout: |
test/node.js
- name: Setup Environment
shell: bash
run: |
echo "${{ inputs.pr-number }}" > pr-number.txt
- name: Download Bun
uses: actions/download-artifact@v4
with:
name: bun-${{ inputs.tag }}
path: bun
github-token: ${{ github.token }}
run-id: ${{ inputs.run-id || github.run_id }}
- if: ${{ runner.os != 'Windows' }}
name: Setup Bun
shell: bash
run: |
unzip bun/bun-*.zip
cd bun-*
pwd >> $GITHUB_PATH
- if: ${{ runner.os == 'Windows' }}
name: Setup Cygwin
uses: secondlife/setup-cygwin@v3
with:
packages: bash
- if: ${{ runner.os == 'Windows' }}
name: Setup Bun (Windows)
run: |
unzip bun/bun-*.zip
cd bun-*
pwd >> $env:GITHUB_PATH
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Checkout Tests
shell: bash
working-directory: test/node.js
run: |
node runner.mjs --pull
- name: Install Dependencies
timeout-minutes: 5
shell: bash
working-directory: test/node.js
run: |
bun install
- name: Run Tests
timeout-minutes: 10 # Increase when more tests are added
shell: bash
working-directory: test/node.js
env:
TMPDIR: ${{ runner.temp }}
BUN_GARBAGE_COLLECTOR_LEVEL: "0"
BUN_FEATURE_FLAG_INTERNAL_FOR_TESTING: "true"
run: |
node runner.mjs
- name: Upload Results
uses: actions/upload-artifact@v4
with:
name: bun-${{ inputs.tag }}-node-tests
path: |
test/node.js/summary/*.json
if-no-files-found: error
overwrite: true
# TODO: Enable when we start running the Node.js test suite
# test-node:
# name: Node.js Tests
# runs-on: ${{ inputs.runs-on }}
# steps:
# - if: ${{ runner.os == 'Windows' }}
# name: Setup Git
# run: |
# git config --global core.autocrlf false
# git config --global core.eol lf
# git config --system core.longpaths true
# - name: Checkout
# uses: actions/checkout@v4
# with:
# sparse-checkout: |
# test/node.js
# - name: Setup Environment
# shell: bash
# run: |
# echo "${{ inputs.pr-number }}" > pr-number.txt
# - name: Download Bun
# uses: actions/download-artifact@v4
# with:
# name: bun-${{ inputs.tag }}
# path: bun
# github-token: ${{ github.token }}
# run-id: ${{ inputs.run-id || github.run_id }}
# - if: ${{ runner.os != 'Windows' }}
# name: Setup Bun
# shell: bash
# run: |
# unzip bun/bun-*.zip
# cd bun-*
# pwd >> $GITHUB_PATH
# - if: ${{ runner.os == 'Windows' }}
# name: Setup Cygwin
# uses: secondlife/setup-cygwin@v3
# with:
# packages: bash
# - if: ${{ runner.os == 'Windows' }}
# name: Setup Bun (Windows)
# run: |
# unzip bun/bun-*.zip
# cd bun-*
# pwd >> $env:GITHUB_PATH
# - name: Setup Node.js
# uses: actions/setup-node@v4
# with:
# node-version: 20
# - name: Checkout Tests
# shell: bash
# working-directory: test/node.js
# run: |
# node runner.mjs --pull
# - name: Install Dependencies
# timeout-minutes: 5
# shell: bash
# working-directory: test/node.js
# run: |
# bun install
# - name: Run Tests
# timeout-minutes: 10 # Increase when more tests are added
# shell: bash
# working-directory: test/node.js
# env:
# TMPDIR: ${{ runner.temp }}
# BUN_GARBAGE_COLLECTOR_LEVEL: "0"
# BUN_FEATURE_FLAG_INTERNAL_FOR_TESTING: "true"
# run: |
# node runner.mjs
# - name: Upload Results
# uses: actions/upload-artifact@v4
# with:
# name: bun-${{ inputs.tag }}-node-tests
# path: |
# test/node.js/summary/*.json
# if-no-files-found: error
# overwrite: true

100
.github/workflows/test-bun.yml vendored Normal file
View File

@@ -0,0 +1,100 @@
name: Test Bun
permissions:
contents: read
actions: write
concurrency:
group: ${{ github.workflow }}-${{ inputs.workflow-run-id || inputs.buildkite-url || inputs.bun-version || github.ref }}
cancel-in-progress: true
on:
workflow_dispatch:
inputs:
workflow-run-id:
type: string
buildkite-url:
type: string
bun-version:
type: string
workflow_call:
inputs:
workflow-run-id:
type: string
buildkite-url:
type: string
bun-version:
type: string
jobs:
linux-x64-test:
name: Test linux-x64
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
runs-on: ubuntu-latest
tag: linux-x64
workflow-run-id: ${{ inputs.workflow-run-id }}
buildkite-url: ${{ inputs.buildkite-url }}
bun-version: ${{ inputs.bun-version }}
linux-x64-baseline-test:
name: Test linux-x64-baseline
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
runs-on: ubuntu-latest
tag: linux-x64-baseline
workflow-run-id: ${{ inputs.workflow-run-id }}
buildkite-url: ${{ inputs.buildkite-url }}
bun-version: ${{ inputs.bun-version }}
linux-aarch64-test:
if: ${{ github.repository_owner == 'oven-sh' }}
name: Test linux-aarch64
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
runs-on: namespace-profile-bun-ci-linux-aarch64
tag: linux-aarch64
workflow-run-id: ${{ inputs.workflow-run-id }}
buildkite-url: ${{ inputs.buildkite-url }}
bun-version: ${{ inputs.bun-version }}
darwin-x64-test:
name: Test darwin-x64
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
runs-on: macos-12
tag: darwin-x64
workflow-run-id: ${{ inputs.workflow-run-id }}
buildkite-url: ${{ inputs.buildkite-url }}
bun-version: ${{ inputs.bun-version }}
darwin-aarch64-test:
name: Test darwin-aarch64
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
runs-on: macos-12
tag: darwin-aarch64
workflow-run-id: ${{ inputs.workflow-run-id }}
buildkite-url: ${{ inputs.buildkite-url }}
bun-version: ${{ inputs.bun-version }}
windows-x64-test:
name: Test windows-x64
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
runs-on: windows-latest
tag: windows-x64
workflow-run-id: ${{ inputs.workflow-run-id }}
buildkite-url: ${{ inputs.buildkite-url }}
bun-version: ${{ inputs.bun-version }}
windows-x64-baseline-test:
name: Test windows-x64-baseline
uses: ./.github/workflows/run-test.yml
secrets: inherit
with:
runs-on: windows-latest
tag: windows-x64-baseline
workflow-run-id: ${{ inputs.workflow-run-id }}
buildkite-url: ${{ inputs.buildkite-url }}
bun-version: ${{ inputs.bun-version }}

View File

@@ -80,15 +80,3 @@ jobs:
bun upgrade --canary
# bun upgrade --stable <- to downgrade
```
# If notifying sentry fails, don't fail the rest of the build.
- name: Notify Sentry
uses: getsentry/action-release@v1.7.0
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
with:
ignore_missing: true
ignore_empty: true
version: ${{ github.event.workflow_run.head_sha || github.sha }}-canary
environment: canary

1
.gitignore vendored
View File

@@ -145,4 +145,3 @@ zig-cache
zig-out
test/node.js/upstream
.zig-cache
scripts/env.local

8
.gitmodules vendored
View File

@@ -76,14 +76,6 @@ ignore = dirty
depth = 1
shallow = true
fetchRecurseSubmodules = false
[submodule "src/deps/libuv"]
path = src/deps/libuv
url = https://github.com/libuv/libuv.git
ignore = dirty
depth = 1
shallow = true
fetchRecurseSubmodules = false
branch = v1.48.0
[submodule "zig"]
path = src/deps/zig
url = https://github.com/oven-sh/zig

3
.vscode/launch.json generated vendored
View File

@@ -145,14 +145,13 @@
"request": "launch",
"name": "bun run [file]",
"program": "${workspaceFolder}/build/bun-debug",
"args": ["run", "${file}"],
"args": ["run", "${fileBasename}"],
"cwd": "${fileDirname}",
"env": {
"FORCE_COLOR": "0",
"BUN_DEBUG_QUIET_LOGS": "1",
"BUN_DEBUG_EventLoop": "1",
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
"BUN_DEBUG_ALL": "1",
},
"console": "internalConsole",
},

View File

@@ -2,9 +2,8 @@ cmake_minimum_required(VERSION 3.22)
cmake_policy(SET CMP0091 NEW)
cmake_policy(SET CMP0067 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
set(Bun_VERSION "1.1.21")
set(WEBKIT_TAG 49907bff8781719bc2ded068b0c934f6d0074d1e)
set(Bun_VERSION "1.1.17")
set(WEBKIT_TAG 5bbfe7e880090b9d0b5feaf3563e85957dd7b10d)
set(BUN_WORKDIR "${CMAKE_CURRENT_BINARY_DIR}")
message(STATUS "Configuring Bun ${Bun_VERSION} in ${BUN_WORKDIR}")
@@ -15,6 +14,7 @@ set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD_REQUIRED ON)
# Should not start with v
# Used in process.version, process.versions.node, napi, and elsewhere
set(REPORTED_NODEJS_VERSION "22.3.0")
@@ -22,7 +22,6 @@ set(REPORTED_NODEJS_VERSION "22.3.0")
# If we do not set this, it will crash at startup on the first memory allocation.
if(NOT WIN32 AND NOT APPLE)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_POSITION_INDEPENDENT_CODE FALSE)
endif()
# --- Build Type ---
@@ -39,13 +38,6 @@ else()
message(STATUS "The CMake build type is: ${CMAKE_BUILD_TYPE}")
endif()
if(WIN32 AND NOT CMAKE_CL_SHOWINCLUDES_PREFIX)
# workaround until cmake fix is shipped https://github.com/ninja-build/ninja/issues/2280
# './build/.ninja_deps' may need to be deleted, the bug is "Note: including file: ..." is saved
# as part of some file paths
set(CMAKE_CL_SHOWINCLUDES_PREFIX "Note: including file:")
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(DEBUG ON)
set(DEFAULT_ZIG_OPTIMIZE "Debug")
@@ -58,8 +50,11 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
set(DEFAULT_ZIG_OPTIMIZE "ReleaseFast")
if(WIN32)
# Debug symbols are in a separate file: bun.pdb
# lld-link will strip it for you, so we can build directly to bun.exe
set(bun "bun")
# TODO(@paperdave): Remove this
# it is enabled for the time being to make sure to catch more bugs in the experimental windows builds
set(DEFAULT_ZIG_OPTIMIZE "ReleaseSafe")
else()
if(ZIG_OPTIMIZE STREQUAL "Debug")
@@ -72,7 +67,7 @@ endif()
# --- MacOS SDK ---
if(APPLE AND DEFINED ENV{CI})
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0")
set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0")
endif()
if(APPLE AND NOT CMAKE_OSX_DEPLOYMENT_TARGET)
@@ -116,11 +111,7 @@ endif()
# we do some extra work afterwards to double-check, and we will rerun BUN_FIND_LLVM if the compiler did not match.
#
# If the user passes -DLLVM_PREFIX, most of this logic is skipped, but we still warn if invalid.
if(WIN32 OR APPLE)
set(LLVM_VERSION 18)
else()
set(LLVM_VERSION 16)
endif()
set(LLVM_VERSION 16)
macro(BUN_FIND_LLVM)
find_program(
@@ -154,12 +145,11 @@ macro(BUN_FIND_LLVM)
PATHS ENV PATH ${PLATFORM_LLVM_SEARCH_PATHS}
DOC "Path to LLVM ${LLVM_VERSION}'s llvm-strip binary"
)
find_program(
STRIP
NAMES strip
PATHS ENV PATH ${PLATFORM_LLVM_SEARCH_PATHS}
DOC "Path to strip binary"
DOC "Path to LLVM ${LLVM_VERSION}'s llvm-strip binary"
)
find_program(
DSYMUTIL
@@ -331,16 +321,6 @@ option(USE_STATIC_LIBATOMIC "Statically link libatomic, requires the presence of
option(USE_LTO "Enable Link-Time Optimization" ${DEFAULT_LTO})
if(APPLE AND USE_LTO)
set(USE_LTO OFF)
message(WARNING "Link-Time Optimization is not supported on macOS because it requires -fuse-ld=lld and lld causes many segfaults on macOS (likely related to stack size)")
endif()
if(WIN32 AND USE_LTO)
set(CMAKE_LINKER_TYPE LLD)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF)
endif()
option(BUN_TIDY_ONLY "Only run clang-tidy" OFF)
option(BUN_TIDY_ONLY_EXTRA " Only run clang-tidy, with extra checks for local development" OFF)
@@ -652,6 +632,16 @@ file(GLOB BUN_CPP ${CONFIGURE_DEPENDS}
)
list(APPEND BUN_RAW_SOURCES ${BUN_CPP})
# -- Brotli --
set(BROTLI_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/deps/brotli")
file(GLOB BROTLI_FILES ${CONFIGURE_DEPENDS}
"${BROTLI_SRC}/common/*.c"
"${BROTLI_SRC}/enc/*.c"
"${BROTLI_SRC}/dec/*.c"
)
list(APPEND BUN_RAW_SOURCES ${BROTLI_FILES})
include_directories("${BUN_DEPS_DIR}/brotli/include")
# -- uSockets --
set(USOCKETS_SRC "${CMAKE_CURRENT_SOURCE_DIR}/packages/bun-usockets/src")
file(GLOB USOCKETS_FILES ${CONFIGURE_DEPENDS}
@@ -782,8 +772,6 @@ if(NOT NO_CODEGEN)
"${BUN_SRC}/js/thirdparty/*.ts"
"${BUN_SRC}/js/internal/*.js"
"${BUN_SRC}/js/internal/*.ts"
"${BUN_SRC}/js/internal/util/*.js"
"${BUN_SRC}/js/internal/fs/*.ts"
"${BUN_SRC}/js/node/*.js"
"${BUN_SRC}/js/node/*.ts"
"${BUN_SRC}/js/thirdparty/*.js"
@@ -867,24 +855,13 @@ file(GLOB ZIG_FILES
"${BUN_SRC}/*/*/*/*/*.zig"
)
if(NOT BUN_ZIG_OBJ_FORMAT)
# To use LLVM bitcode from Zig, more work needs to be done. Currently, an install of
# LLVM 18.1.7 does not compatible with what bitcode Zig 0.13 outputs (has LLVM 18.1.7)
# Change to "bc" to experiment, "Invalid record" means it is not valid output.
set(BUN_ZIG_OBJ_FORMAT "obj")
endif()
if(NOT BUN_ZIG_OBJ_DIR)
set(BUN_ZIG_OBJ_DIR "${BUN_WORKDIR}/CMakeFiles")
endif()
get_filename_component(BUN_ZIG_OBJ_DIR "${BUN_ZIG_OBJ_DIR}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
if(WIN32)
set(BUN_ZIG_OBJ "${BUN_ZIG_OBJ_DIR}/bun-zig.o")
else()
set(BUN_ZIG_OBJ "${BUN_ZIG_OBJ_DIR}/bun-zig.o")
endif()
set(BUN_ZIG_OBJ "${BUN_ZIG_OBJ_DIR}/bun-zig.o")
set(USES_TERMINAL_NOT_IN_CI "")
@@ -899,7 +876,6 @@ if(NOT BUN_LINK_ONLY AND NOT BUN_CPP_ONLY)
"${ZIG_COMPILER}" "build" "obj"
"--zig-lib-dir" "${ZIG_LIB_DIR}"
"--prefix" "${BUN_ZIG_OBJ_DIR}"
"--verbose"
"-Dgenerated-code=${BUN_WORKDIR}/codegen"
"-freference-trace=10"
"-Dversion=${Bun_VERSION}"
@@ -909,7 +885,6 @@ if(NOT BUN_LINK_ONLY AND NOT BUN_CPP_ONLY)
"-Dtarget=${ZIG_TARGET}"
"-Denable_logs=${ENABLE_LOGS}"
"-Dreported_nodejs_version=${REPORTED_NODEJS_VERSION}"
"-Dobj_format=${BUN_ZIG_OBJ_FORMAT}"
DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/build.zig"
"${ZIG_FILES}"
@@ -973,15 +948,12 @@ set_target_properties(${bun} PROPERTIES
VISIBILITY_INLINES_HIDDEN YES
)
if(APPLE)
add_compile_definitions("__DARWIN_NON_CANCELABLE=1")
endif()
add_compile_definitions(
# TODO: are all of these variables strictly necessary?
"_HAS_EXCEPTIONS=0"
"LIBUS_USE_OPENSSL=1"
"UWS_HTTPRESPONSE_NO_WRITEMARK=1"
"LIBUS_USE_BORINGSSL=1"
"WITH_BORINGSSL=1"
"STATICALLY_LINKED_WITH_JavaScriptCore=1"
@@ -1086,7 +1058,7 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
if(NOT WIN32)
if(USE_LTO)
list(APPEND LTO_FLAG "-flto=full" "-emit-llvm" "-fwhole-program-vtables" "-fforce-emit-vtables")
list(APPEND LTO_FLAG "-flto=full" "-emit-llvm")
endif()
# Leave -Werror=unused off in release builds so we avoid errors from being used in ASSERT
@@ -1105,38 +1077,13 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
set(LTO_LINK_FLAG "")
if(USE_LTO)
target_compile_options(${bun} PUBLIC -Xclang -emit-llvm-bc)
# -emit-llvm seems to not be supported or under a different name on Windows.
list(APPEND LTO_FLAG "-flto=full")
list(APPEND LTO_LINK_FLAG "-flto=full")
list(APPEND LTO_LINK_FLAG "/LTCG")
list(APPEND LTO_LINK_FLAG "/OPT:REF")
list(APPEND LTO_LINK_FLAG "/OPT:NOICF")
endif()
target_compile_options(${bun} PUBLIC
/O2
${LTO_FLAG}
/Gy
/Gw
/GF
/GA
)
target_link_options(${bun} PUBLIC
${LTO_LINK_FLAG}
/DEBUG:FULL
/delayload:ole32.dll
/delayload:WINMM.dll
/delayload:dbghelp.dll
/delayload:VCRUNTIME140_1.dll
# libuv loads these two immediately, but for some reason it seems to still be slightly faster to delayload them
/delayload:WS2_32.dll
/delayload:WSOCK32.dll
/delayload:ADVAPI32.dll
/delayload:IPHLPAPI.dll
)
target_compile_options(${bun} PUBLIC /O2 ${LTO_FLAG})
target_link_options(${bun} PUBLIC ${LTO_LINK_FLAG} /DEBUG:FULL)
endif()
endif()
@@ -1154,11 +1101,6 @@ else()
# On arm macOS, we can set it to a minimum of the M1 cpu set. this might be the default already.
target_compile_options(${bun} PUBLIC "-mcpu=apple-m1")
endif()
if(NOT WIN32 AND NOT APPLE AND ARCH STREQUAL "aarch64")
# on arm64 linux, we set a minimum of armv8
target_compile_options(${bun} PUBLIC -march=armv8-a+crc -mtune=ampere1)
endif()
endif()
target_compile_options(${bun} PUBLIC -ferror-limit=${ERROR_LIMIT})
@@ -1172,29 +1114,23 @@ if(WIN32)
"BORINGSSL_NO_CXX=1" # lol
)
# set_property(TARGET ${bun} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set_property(TARGET ${bun} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
# set_property(TARGET ${bun} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
set_property(TARGET ${bun} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
target_compile_options(${bun} PUBLIC "/EHsc" "/GR-" -Xclang -fno-c++-static-destructors)
target_link_options(${bun} PUBLIC "/STACK:0x1200000,0x100000" "/DEF:${BUN_SRC}/symbols.def" "/errorlimit:0")
target_compile_options(${bun} PUBLIC "/EHsc" "/GR-")
target_link_options(${bun} PUBLIC "/STACK:0x1200000,0x100000" "/DEF:${BUN_SRC}/symbols.def")
else()
target_compile_options(${bun} PUBLIC
-fPIC
-mtune=${CPU_TARGET}
-fconstexpr-steps=2542484
-fconstexpr-depth=54
-fno-exceptions
-fno-asynchronous-unwind-tables
-fno-unwind-tables
-fno-c++-static-destructors
-fvisibility=hidden
-fvisibility-inlines-hidden
-fno-rtti
-fno-omit-frame-pointer
-mno-omit-leaf-frame-pointer
-fno-pic
-fno-pie
-faddrsig
)
endif()
@@ -1204,18 +1140,17 @@ if(APPLE)
target_link_options(${bun} PUBLIC "-Wl,-stack_size,0x1200000")
target_link_options(${bun} PUBLIC "-exported_symbols_list" "${BUN_SRC}/symbols.txt")
set_target_properties(${bun} PROPERTIES LINK_DEPENDS "${BUN_SRC}/symbols.txt")
target_link_options(${bun} PUBLIC "-fno-keep-static-consts")
target_link_libraries(${bun} PRIVATE "resolv")
endif()
if(UNIX AND NOT APPLE)
target_link_options(${bun} PUBLIC
-fuse-ld=lld
-fno-pic
-static-libstdc++
-static-libgcc
"-Wl,-no-pie"
"-Wl,-icf=safe"
"-fuse-ld=lld"
"-static-libstdc++"
"-static-libgcc"
"-Wl,-z,now"
"-Wl,--as-needed"
"-Wl,--gc-sections"
"-Wl,-z,stack-size=12800000"
@@ -1244,8 +1179,6 @@ if(UNIX AND NOT APPLE)
"-rdynamic"
"-Wl,--dynamic-list=${BUN_SRC}/symbols.dyn"
"-Wl,--version-script=${BUN_SRC}/linker.lds"
-Wl,-z,lazy
-Wl,-z,norelro
)
target_link_libraries(${bun} PRIVATE "c")
@@ -1279,16 +1212,12 @@ endif()
# --- Stripped Binary "bun"
if(CMAKE_BUILD_TYPE STREQUAL "Release" AND NOT WIN32 AND NOT ASSERT_ENABLED)
# if(CI AND APPLE)
if(APPLE)
add_custom_command(
TARGET ${bun}
POST_BUILD
COMMAND ${DSYMUTIL} -o ${BUN_WORKDIR}/${bun}.dSYM ${BUN_WORKDIR}/${bun}
COMMENT "Generating .dSYM"
)
endif()
# add_custom_command(
# TARGET ${bun}
# POST_BUILD
# COMMAND ${DSYMUTIL} -o ${BUN_WORKDIR}/bun.dSYM ${BUN_WORKDIR}/${bun}
# COMMENT "Stripping Symbols"
# )
add_custom_command(
TARGET ${bun}
POST_BUILD
@@ -1456,11 +1385,6 @@ if(USE_STATIC_SQLITE)
"SQLITE_ENABLE_JSON1=1"
"SQLITE_ENABLE_MATH_FUNCTIONS=1"
)
if(WIN32)
target_compile_options(sqlite3 PRIVATE /MT /U_DLL)
endif()
target_link_libraries(${bun} PRIVATE sqlite3)
message(STATUS "Using static sqlite3")
target_compile_definitions(${bun} PRIVATE "LAZY_LOAD_SQLITE=0")
@@ -1469,24 +1393,6 @@ else()
target_compile_definitions(${bun} PRIVATE "LAZY_LOAD_SQLITE=1")
endif()
# -- Brotli --
set(BROTLI_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/deps/brotli")
file(GLOB BROTLI_FILES ${CONFIGURE_DEPENDS}
"${BROTLI_SRC}/common/*.c"
"${BROTLI_SRC}/enc/*.c"
"${BROTLI_SRC}/dec/*.c"
)
add_library(brotli STATIC ${BROTLI_FILES})
target_include_directories(brotli PRIVATE "${BROTLI_SRC}/include")
target_compile_definitions(brotli PRIVATE "BROTLI_STATIC")
if(WIN32)
target_compile_options(brotli PRIVATE /MT /U_DLL)
endif()
target_link_libraries(${bun} PRIVATE brotli)
include_directories("${BUN_DEPS_DIR}/brotli/include")
if(USE_CUSTOM_LSHPACK)
include_directories(${BUN_DEPS_DIR}/ls-hpack)
@@ -1506,6 +1412,7 @@ if(NOT WIN32)
target_link_libraries(${bun} PRIVATE "${WEBKIT_LIB_DIR}/libJavaScriptCore.a")
target_link_libraries(${bun} PRIVATE "${WEBKIT_LIB_DIR}/libbmalloc.a")
else()
target_link_options(${bun} PRIVATE "-static")
target_link_libraries(${bun} PRIVATE
"${WEBKIT_LIB_DIR}/WTF.lib"
"${WEBKIT_LIB_DIR}/JavaScriptCore.lib"
@@ -1515,10 +1422,10 @@ else()
winmm
bcrypt
ntdll
ucrt
userenv
dbghelp
wsock32 # ws2_32 required by TransmitFile aka sendfile on windows
delayimp.lib
)
endif()

View File

@@ -2,11 +2,6 @@ Configuring a development environment for Bun can take 10-30 minutes depending o
If you are using Windows, please refer to [this guide](/docs/project/building-windows)
{% details summary="For Ubuntu users" %}
TL;DR: Ubuntu 22.04 is suggested.
Bun currently requires `glibc >=2.32` in development which means if you're on Ubuntu 20.04 (glibc == 2.31), you may likely meet `error: undefined symbol: __libc_single_threaded `. You need to take extra configurations. Also, according to this [issue](https://github.com/llvm/llvm-project/issues/97314), LLVM 16 is no longer maintained on Ubuntu 24.04 (noble). And instead, you might want `brew` to install LLVM 16 for your Ubuntu 24.04.
{% /details %}
## Install Dependencies
Using your system's package manager, install Bun's dependencies:
@@ -112,7 +107,7 @@ $ export PATH="$PATH:/usr/lib/llvm16/bin"
{% /codetabs %}
> ⚠️ Ubuntu distributions (<= 20.04) may require installation of the C++ standard library independently. See the [troubleshooting section](#span-file-not-found-on-ubuntu) for more information.
> ⚠️ Ubuntu distributions may require installation of the C++ standard library independently. See the [troubleshooting section](#span-file-not-found-on-ubuntu) for more information.
## Building Bun
@@ -316,12 +311,3 @@ $ bun setup -DUSE_STATIC_LIBATOMIC=OFF
```
The built version of Bun may not work on other systems if compiled this way.
## ccache conflicts with building TinyCC on macOS
If you run into issues with `ccache` when building TinyCC, try reinstalling ccache
```bash
brew uninstall ccache
brew install ccache
```

View File

@@ -52,8 +52,11 @@ ENV CI 1
ENV CPU_TARGET=${CPU_TARGET}
ENV BUILDARCH=${BUILDARCH}
ENV BUN_DEPS_OUT_DIR=${BUN_DEPS_OUT_DIR}
ENV BUN_ENABLE_LTO 1
ENV CXX=clang++-${LLVM_VERSION}
ENV CC=clang-${LLVM_VERSION}
ENV AR=/usr/bin/llvm-ar-${LLVM_VERSION}
ENV LD=lld-${LLVM_VERSION}
ENV LC_CTYPE=en_US.UTF-8
ENV LC_ALL=en_US.UTF-8
@@ -90,8 +93,6 @@ RUN install_packages \
clangd-${LLVM_VERSION} \
libc++-${LLVM_VERSION}-dev \
libc++abi-${LLVM_VERSION}-dev \
llvm-${LLVM_VERSION}-runtime \
llvm-${LLVM_VERSION}-dev \
make \
cmake \
ninja-build \
@@ -118,15 +119,6 @@ RUN install_packages \
&& ln -sf /usr/bin/lldb-${LLVM_VERSION} /usr/bin/lldb \
&& ln -sf /usr/bin/clangd-${LLVM_VERSION} /usr/bin/clangd \
&& ln -sf /usr/bin/llvm-ar-${LLVM_VERSION} /usr/bin/llvm-ar \
&& ln -sf /usr/bin/ld.lld /usr/bin/ld \
&& ln -sf /usr/bin/llvm-ranlib-${LLVM_VERSION} /usr/bin/ranlib \
&& ln -sf /usr/bin/clang /usr/bin/cc \
&& ln -sf /usr/bin/clang /usr/bin/c89 \
&& ln -sf /usr/bin/clang /usr/bin/c99 \
&& ln -sf /usr/bin/clang++ /usr/bin/c++ \
&& ln -sf /usr/bin/clang++ /usr/bin/g++ \
&& ln -sf /usr/bin/llvm-ar /usr/bin/ar \
&& ln -sf /usr/bin/clang /usr/bin/gcc \
&& arch="$(dpkg --print-architecture)" \
&& case "${arch##*-}" in \
amd64) variant="x64";; \
@@ -139,7 +131,6 @@ RUN install_packages \
&& ln -s /usr/bin/bun /usr/bin/bunx \
&& rm -rf bun-linux-${variant} bun-linux-${variant}.zip \
&& mkdir -p ${BUN_DIR} ${BUN_DEPS_OUT_DIR}
# && if [ -n "${SCCACHE_BUCKET}" ]; then \
# echo "Setting up sccache" \
# && wget https://github.com/mozilla/sccache/releases/download/v0.5.4/sccache-v0.5.4-${BUILD_MACHINE_ARCH}-unknown-linux-musl.tar.gz \
@@ -176,14 +167,13 @@ ENV CCACHE_DIR=${CCACHE_DIR}
COPY Makefile ${BUN_DIR}/Makefile
COPY src/deps/c-ares ${BUN_DIR}/src/deps/c-ares
COPY scripts ${BUN_DIR}/scripts
WORKDIR $BUN_DIR
RUN --mount=type=cache,target=${CCACHE_DIR} \
cd $BUN_DIR \
&& bash ./scripts/build-cares.sh \
&& rm -rf ${BUN_DIR}/src/deps/c-ares ${BUN_DIR}/Makefile ${BUN_DIR}/scripts
&& make c-ares \
&& rm -rf ${BUN_DIR}/src/deps/c-ares ${BUN_DIR}/Makefile
FROM bun-base as lolhtml
@@ -214,14 +204,13 @@ ENV CPU_TARGET=${CPU_TARGET}
COPY Makefile ${BUN_DIR}/Makefile
COPY src/deps/mimalloc ${BUN_DIR}/src/deps/mimalloc
COPY scripts ${BUN_DIR}/scripts
ARG CCACHE_DIR=/ccache
ENV CCACHE_DIR=${CCACHE_DIR}
RUN --mount=type=cache,target=${CCACHE_DIR} \
cd ${BUN_DIR} \
&& bash ./scripts/build-mimalloc.sh \
&& make mimalloc \
&& rm -rf src/deps/mimalloc Makefile
FROM bun-base as mimalloc-debug
@@ -251,17 +240,14 @@ ARG CCACHE_DIR=/ccache
ENV CCACHE_DIR=${CCACHE_DIR}
COPY Makefile ${BUN_DIR}/Makefile
COPY CMakeLists.txt ${BUN_DIR}/CMakeLists.txt
COPY scripts ${BUN_DIR}/scripts
COPY src/deps/zlib ${BUN_DIR}/src/deps/zlib
COPY package.json bun.lockb Makefile .gitmodules ${BUN_DIR}/
WORKDIR $BUN_DIR
RUN --mount=type=cache,target=${CCACHE_DIR} \
cd $BUN_DIR \
&& bash ./scripts/build-zlib.sh && rm -rf src/deps/zlib scripts
&& make zlib \
&& rm -rf src/deps/zlib Makefile
FROM bun-base as libarchive
@@ -300,7 +286,6 @@ ARG CPU_TARGET
ENV CPU_TARGET=${CPU_TARGET}
COPY Makefile ${BUN_DIR}/Makefile
COPY scripts ${BUN_DIR}/scripts
COPY src/deps/boringssl ${BUN_DIR}/src/deps/boringssl
WORKDIR $BUN_DIR
@@ -310,7 +295,7 @@ ENV CCACHE_DIR=${CCACHE_DIR}
RUN --mount=type=cache,target=${CCACHE_DIR} \
cd ${BUN_DIR} \
&& bash ./scripts/build-boringssl.sh \
&& make boringssl \
&& rm -rf src/deps/boringssl Makefile
@@ -326,14 +311,12 @@ ENV CCACHE_DIR=${CCACHE_DIR}
COPY Makefile ${BUN_DIR}/Makefile
COPY src/deps/zstd ${BUN_DIR}/src/deps/zstd
COPY scripts ${BUN_DIR}/scripts
WORKDIR $BUN_DIR
RUN --mount=type=cache,target=${CCACHE_DIR} \
cd $BUN_DIR \
&& bash ./scripts/build-zstd.sh \
&& rm -rf src/deps/zstd scripts
&& make zstd
FROM bun-base as ls-hpack
@@ -347,14 +330,12 @@ ENV CCACHE_DIR=${CCACHE_DIR}
COPY Makefile ${BUN_DIR}/Makefile
COPY src/deps/ls-hpack ${BUN_DIR}/src/deps/ls-hpack
COPY scripts ${BUN_DIR}/scripts
WORKDIR $BUN_DIR
RUN --mount=type=cache,target=${CCACHE_DIR} \
cd $BUN_DIR \
&& bash ./scripts/build-lshpack.sh \
&& rm -rf src/deps/ls-hpack scripts
&& make lshpack
FROM bun-base-with-zig as bun-identifier-cache
@@ -510,7 +491,6 @@ RUN mkdir -p build bun-webkit
# lol
COPY src/bun.js/bindings/sqlite/sqlite3.c ${BUN_DIR}/src/bun.js/bindings/sqlite/sqlite3.c
COPY src/deps/brotli ${BUN_DIR}/src/deps/brotli
COPY src/symbols.dyn src/linker.lds ${BUN_DIR}/src/
@@ -525,8 +505,7 @@ COPY --from=tinycc ${BUN_DEPS_OUT_DIR}/* ${BUN_DEPS_OUT_DIR}/
COPY --from=c-ares ${BUN_DEPS_OUT_DIR}/* ${BUN_DEPS_OUT_DIR}/
COPY --from=ls-hpack ${BUN_DEPS_OUT_DIR}/* ${BUN_DEPS_OUT_DIR}/
COPY --from=bun-compile-zig-obj /tmp/bun-zig.o ${BUN_DIR}/build/bun-zig.o
COPY --from=bun-cpp-objects ${BUN_DIR}/build/*.a ${BUN_DIR}/build/
COPY --from=bun-cpp-objects ${BUN_DIR}/build/*.o ${BUN_DIR}/build/
COPY --from=bun-cpp-objects ${BUN_DIR}/build/bun-cpp-objects.a ${BUN_DIR}/build/bun-cpp-objects.a
COPY --from=bun-cpp-objects ${BUN_DIR}/bun-webkit/lib ${BUN_DIR}/bun-webkit/lib
WORKDIR $BUN_DIR/build

2
LATEST
View File

@@ -1 +1 @@
1.1.20
1.1.16

View File

@@ -26,11 +26,8 @@ ifeq ($(ARCH_NAME_RAW),arm64)
ARCH_NAME = aarch64
DOCKER_BUILDARCH = arm64
BREW_PREFIX_PATH = /opt/homebrew
DEFAULT_MIN_MACOS_VERSION = 13.0
DEFAULT_MIN_MACOS_VERSION = 11.0
MARCH_NATIVE = -mtune=$(CPU_TARGET)
ifeq ($(OS_NAME),linux)
MARCH_NATIVE = -march=armv8-a+crc -mtune=ampere1
endif
else
ARCH_NAME = x64
DOCKER_BUILDARCH = amd64
@@ -157,12 +154,7 @@ CMAKE_FLAGS_WITHOUT_RELEASE = -DCMAKE_C_COMPILER=$(CC) \
-DCMAKE_OSX_DEPLOYMENT_TARGET=$(MIN_MACOS_VERSION) \
$(CMAKE_CXX_COMPILER_LAUNCHER_FLAG) \
-DCMAKE_AR=$(AR) \
-DCMAKE_RANLIB=$(which llvm-16-ranlib 2>/dev/null || which llvm-ranlib 2>/dev/null) \
-DCMAKE_CXX_STANDARD=20 \
-DCMAKE_C_STANDARD=17 \
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
-DCMAKE_C_STANDARD_REQUIRED=ON \
-DCMAKE_CXX_EXTENSIONS=ON
-DCMAKE_RANLIB=$(which llvm-16-ranlib 2>/dev/null || which llvm-ranlib 2>/dev/null)
@@ -189,8 +181,8 @@ endif
OPTIMIZATION_LEVEL=-O3 $(MARCH_NATIVE)
DEBUG_OPTIMIZATION_LEVEL= -O1 $(MARCH_NATIVE) -gdwarf-4
CFLAGS_WITHOUT_MARCH = $(MACOS_MIN_FLAG) $(OPTIMIZATION_LEVEL) -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pie -fno-pic
BUN_CFLAGS = $(MACOS_MIN_FLAG) $(MARCH_NATIVE) $(OPTIMIZATION_LEVEL) -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pie -fno-pic
CFLAGS_WITHOUT_MARCH = $(MACOS_MIN_FLAG) $(OPTIMIZATION_LEVEL) -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden
BUN_CFLAGS = $(MACOS_MIN_FLAG) $(MARCH_NATIVE) $(OPTIMIZATION_LEVEL) -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden
BUN_TMP_DIR := /tmp/make-bun
CFLAGS=$(CFLAGS_WITHOUT_MARCH) $(MARCH_NATIVE)

Binary file not shown.

View File

@@ -3,7 +3,6 @@
"dependencies": {
"@babel/core": "^7.16.10",
"@babel/preset-react": "^7.16.7",
"@babel/standalone": "^7.24.7",
"@swc/core": "^1.2.133",
"benchmark": "^2.1.4",
"braces": "^3.0.2",

View File

@@ -6,7 +6,6 @@ const App = () => (
<html>
<body>
<h1>Hello World</h1>
<p>This is an example.</p>
</body>
</html>
);

View File

@@ -1,14 +0,0 @@
import { bench, run } from "mitata";
import { join } from "path";
const code = require("fs").readFileSync(
process.argv[2] || join(import.meta.dir, "../node_modules/@babel/standalone/babel.min.js"),
);
const transpiler = new Bun.Transpiler({ minify: true });
bench("transformSync", () => {
transpiler.transformSync(code);
});
await run();

176
build.zig
View File

@@ -33,6 +33,8 @@ comptime {
}
}
const default_reported_nodejs_version = "22.3.0";
const zero_sha = "0000000000000000000000000000000000000000";
const BunBuildOptions = struct {
@@ -46,7 +48,7 @@ const BunBuildOptions = struct {
sha: []const u8,
enable_logs: bool = false,
tracy_callstack_depth: u16,
reported_nodejs_version: Version,
reported_nodejs_version: []const u8 = default_reported_nodejs_version,
generated_code_dir: []const u8,
@@ -71,7 +73,14 @@ const BunBuildOptions = struct {
opts.addOption([:0]const u8, "sha", b.allocator.dupeZ(u8, this.sha) catch @panic("OOM"));
opts.addOption(bool, "baseline", this.isBaseline());
opts.addOption(bool, "enable_logs", this.enable_logs);
opts.addOption([]const u8, "reported_nodejs_version", b.fmt("{}", .{this.reported_nodejs_version}));
opts.addOption([:0]const u8, "reported_nodejs_version", b.allocator.dupeZ(u8, this.reported_nodejs_version) catch @panic("OOM"));
if (this.reported_nodejs_version.len > 0 and this.reported_nodejs_version[0] == 'v') {
@panic("Node.js version should not start with 'v'");
}
if (this.reported_nodejs_version.len == 0) {
@panic("Node.js version should not be empty");
}
const mod = opts.createModule();
this.cached_options_module = mod;
@@ -113,25 +122,8 @@ pub fn getOSGlibCVersion(os: OperatingSystem) ?Version {
};
}
pub fn getCpuModel(os: OperatingSystem, arch: Arch) ?Target.Query.CpuModel {
// https://github.com/oven-sh/bun/issues/12076
if (os == .linux and arch == .aarch64) {
return .{ .explicit = &Target.aarch64.cpu.cortex_a35 };
}
// Be explicit and ensure we do not accidentally target a newer M-series chip
if (os == .mac and arch == .aarch64) {
return .{ .explicit = &Target.aarch64.cpu.apple_m1 };
}
// note: x86_64 is dealt with in the CMake config and passed in.
// the reason for the explicit handling on aarch64 is due to troubles
// passing the exact target in via flags.
return null;
}
pub fn build(b: *Build) !void {
std.log.info("zig compiler v{s}", .{builtin.zig_version_string});
std.debug.print("zig build v{s}\n", .{builtin.zig_version_string});
b.zig_lib_dir = b.zig_lib_dir orelse b.path("src/deps/zig/lib");
@@ -155,14 +147,6 @@ pub fn build(b: *Build) !void {
break :brk .{ os, arch };
};
// target must be refined to support older but very popular devices on
// aarch64, this means moving the minimum supported CPU to support certain
// raspberry PIs. there are also a number of cloud hosts that use virtual
// machines with surprisingly out of date versions of glibc.
if (getCpuModel(os, arch)) |cpu_model| {
target_query.cpu_model = cpu_model;
}
target_query.os_version_min = getOSVersionMin(os);
target_query.glibc_version = getOSGlibCVersion(os);
@@ -179,8 +163,6 @@ pub fn build(b: *Build) !void {
break :ref_trace if (trace == 0) null else trace;
};
const obj_format = b.option(ObjectFormat, "obj_format", "Output file for object files") orelse .obj;
var build_options = BunBuildOptions{
.target = target,
.optimize = optimize,
@@ -196,10 +178,7 @@ pub fn build(b: *Build) !void {
break :canary if (rev == 0) null else rev;
},
.reported_nodejs_version = try Version.parse(
b.option([]const u8, "reported_nodejs_version", "Reported Node.js version") orelse
"0.0.0-unset",
),
.reported_nodejs_version = b.option([]const u8, "reported_nodejs_version", "Reported Node.js version") orelse default_reported_nodejs_version,
.sha = sha: {
const sha = b.option([]const u8, "sha", "Force the git sha") orelse
@@ -245,7 +224,7 @@ pub fn build(b: *Build) !void {
var step = b.step("obj", "Build Bun's Zig code as a .o file");
var bun_obj = addBunObject(b, &build_options);
step.dependOn(&bun_obj.step);
step.dependOn(addInstallObjectFile(b, bun_obj, "bun-zig", obj_format));
step.dependOn(&b.addInstallFile(bun_obj.getEmittedBin(), "bun-zig.o").step);
}
// zig build windows-shim
@@ -273,60 +252,62 @@ pub fn build(b: *Build) !void {
// zig build check-all
{
const step = b.step("check-all", "Check for semantic analysis errors on all supported platforms");
addMultiCheck(b, step, build_options, &.{
var step = b.step("check-all", "Check for semantic analysis errors on all supported platforms");
inline for (.{
.{ .os = .windows, .arch = .x86_64 },
.{ .os = .mac, .arch = .x86_64 },
.{ .os = .mac, .arch = .aarch64 },
.{ .os = .linux, .arch = .x86_64 },
.{ .os = .linux, .arch = .aarch64 },
});
}
}) |check| {
inline for (.{ .Debug, .ReleaseFast }) |mode| {
const check_target = b.resolveTargetQuery(.{
.os_tag = OperatingSystem.stdOSTag(check.os),
.cpu_arch = check.arch,
.os_version_min = getOSVersionMin(check.os),
.glibc_version = getOSGlibCVersion(check.os),
});
// zig build check-windows
{
const step = b.step("check-windows", "Check for semantic analysis errors on Windows");
addMultiCheck(b, step, build_options, &.{
.{ .os = .windows, .arch = .x86_64 },
});
}
}
var options = BunBuildOptions{
.target = check_target,
.os = check.os,
.arch = check_target.result.cpu.arch,
.optimize = mode,
pub inline fn addMultiCheck(
b: *Build,
parent_step: *Step,
root_build_options: BunBuildOptions,
to_check: []const struct { os: OperatingSystem, arch: Arch },
) void {
inline for (to_check) |check| {
inline for (.{ .Debug, .ReleaseFast }) |mode| {
const check_target = b.resolveTargetQuery(.{
.os_tag = OperatingSystem.stdOSTag(check.os),
.cpu_arch = check.arch,
.cpu_model = getCpuModel(check.os, check.arch) orelse .determined_by_cpu_arch,
.os_version_min = getOSVersionMin(check.os),
.glibc_version = getOSGlibCVersion(check.os),
});
var options: BunBuildOptions = .{
.target = check_target,
.os = check.os,
.arch = check_target.result.cpu.arch,
.optimize = mode,
.canary_revision = root_build_options.canary_revision,
.sha = root_build_options.sha,
.tracy_callstack_depth = root_build_options.tracy_callstack_depth,
.version = root_build_options.version,
.reported_nodejs_version = root_build_options.reported_nodejs_version,
.generated_code_dir = root_build_options.generated_code_dir,
};
var obj = addBunObject(b, &options);
obj.generated_bin = null;
parent_step.dependOn(&obj.step);
.canary_revision = build_options.canary_revision,
.sha = build_options.sha,
.tracy_callstack_depth = build_options.tracy_callstack_depth,
.version = build_options.version,
.reported_nodejs_version = build_options.reported_nodejs_version,
.generated_code_dir = build_options.generated_code_dir,
};
var obj = addBunObject(b, &options);
obj.generated_bin = null;
step.dependOn(&obj.step);
}
}
}
// Running `zig build` with no arguments is almost always a mistake.
// TODO: revive this error. cannot right now since ZLS runs zig build without arguments
{
// const mistake_message = b.addSystemCommand(&.{
// "echo",
// \\
// \\To build Bun from source, please use `bun run setup` instead of `zig build`"
// \\For more info, see https://bun.sh/docs/project/contributing
// \\
// \\If you want to build the zig code in isolation, run:
// \\ 'zig build obj -Dgenerated-code=./build/codegen [...opts]'
// \\
// \\If you want to test a compile without emitting an object:
// \\ 'zig build check'
// \\ 'zig build check-all' (run linux+mac+windows)
// \\
// });
// b.default_step.dependOn(&mistake_message.step);
}
}
pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile {
@@ -338,13 +319,10 @@ pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile {
},
.target = opts.target,
.optimize = opts.optimize,
// https://github.com/ziglang/zig/issues/17430
.pic = true,
.omit_frame_pointer = false,
.strip = false, // stripped at the end
});
obj.bundle_compiler_rt = false;
obj.formatted_panics = true;
obj.root_module.omit_frame_pointer = false;
@@ -362,10 +340,9 @@ pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile {
}
if (opts.os == .linux) {
obj.link_emit_relocs = false;
obj.link_eh_frame_hdr = false;
obj.link_emit_relocs = true;
obj.link_eh_frame_hdr = true;
obj.link_function_sections = true;
obj.link_data_sections = true;
if (opts.optimize == .Debug) {
obj.root_module.valgrind = true;
@@ -376,25 +353,6 @@ pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile {
return obj;
}
const ObjectFormat = enum {
bc,
obj,
};
pub fn addInstallObjectFile(
b: *Build,
compile: *Compile,
name: []const u8,
out_mode: ObjectFormat,
) *Step {
// bin always needed to be computed or else the compilation will do nothing. zig build system bug?
const bin = compile.getEmittedBin();
return &b.addInstallFile(switch (out_mode) {
.obj => bin,
.bc => compile.getEmittedLlvmBc(),
}, b.fmt("{s}.o", .{name})).step;
}
fn exists(path: []const u8) bool {
const file = std.fs.openFileAbsolute(path, .{ .mode = .read_only }) catch return false;
file.close();
@@ -455,11 +413,7 @@ fn addInternalPackages(b: *Build, obj: *Compile, opts: *BunBuildOptions) void {
fn validateGeneratedPath(path: []const u8) void {
if (!exists(path)) {
std.debug.panic(
\\Generated file '{s}' is missing!
\\
\\Make sure to use CMake and Ninja, or pass a manual codegen folder with '-Dgenerated-code=...'
, .{path});
std.debug.panic("{s} does not exist in generated code directory!", .{std.fs.path.basename(path)});
}
}

BIN
bun.lockb

Binary file not shown.

View File

@@ -82,7 +82,7 @@ _bun_completions() {
declare -A PACKAGE_OPTIONS;
declare -A PM_OPTIONS;
local SUBCOMMANDS="dev bun create run install add remove upgrade completions discord help init pm x test repl update link unlink build";
local SUBCOMMANDS="dev bun create run install add remove upgrade completions discord help init pm x";
GLOBAL_OPTIONS[LONG_OPTIONS]="--use --cwd --bunfile --server-bunfile --config --disable-react-fast-refresh --disable-hmr --env-file --extension-order --jsx-factory --jsx-fragment --extension-order --jsx-factory --jsx-fragment --jsx-import-source --jsx-production --jsx-runtime --main-fields --no-summary --version --platform --public-dir --tsconfig-override --define --external --help --inject --loader --origin --port --dump-environment-variables --dump-limits --disable-bun-js";
GLOBAL_OPTIONS[SHORT_OPTIONS]="-c -v -d -e -h -i -l -u -p";

View File

@@ -425,7 +425,6 @@ _bun_run_completion() {
'--external[Exclude module from transpilation (can use * wildcards). ex: -e react]:external' \
'-e[Exclude module from transpilation (can use * wildcards). ex: -e react]:external' \
'--loader[Parse files with .ext:loader, e.g. --loader .js:jsx. Valid loaders: js, jsx, ts, tsx, json, toml, text, file, wasm, napi]:loader' \
'--packages[Exclude dependencies from bundle, e.g. --packages external. Valid options: bundle, external]:packages' \
'-l[Parse files with .ext:loader, e.g. --loader .js:jsx. Valid loaders: js, jsx, ts, tsx, json, toml, text, file, wasm, napi]:loader' \
'--origin[Rewrite import URLs to start with --origin. Default: ""]:origin' \
'-u[Rewrite import URLs to start with --origin. Default: ""]:origin' \

View File

@@ -61,7 +61,7 @@ To do anything interesting we need a construct known as a "view". A view is a cl
The `DataView` class is a lower-level interface for reading and manipulating the data in an `ArrayBuffer`.
Below we create a new `DataView` and set the first byte to 3.
Below we create a new `DataView` and set the first byte to 5.
```ts
const buf = new ArrayBuffer(4);
@@ -395,7 +395,7 @@ Bun implements `Buffer`, a Node.js API for working with binary data that pre-dat
```ts
const buf = Buffer.from("hello world");
// => Buffer(11) [ 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100 ]
// => Buffer(16) [ 116, 104, 105, 115, 32, 105, 115, 32, 97, 32, 115, 116, 114, 105, 110, 103 ]
buf.length; // => 11
buf[0]; // => 104, ascii for 'h'

View File

@@ -1,308 +0,0 @@
Bun implements the WHATWG `fetch` standard, with some extensions to meet the needs of server-side JavaScript.
Bun also implements `node:http`, but `fetch` is generally recommended instead.
## Sending an HTTP request
To send an HTTP request, use `fetch`
```ts
const response = await fetch("http://example.com");
console.log(response.status); // => 200
const text = await response.text(); // or response.json(), response.formData(), etc.
```
`fetch` also works with HTTPS URLs.
```ts
const response = await fetch("https://example.com");
```
You can also pass `fetch` a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) object.
```ts
const request = new Request("http://example.com", {
method: "POST",
body: "Hello, world!",
});
const response = await fetch(request);
```
### Sending a POST request
To send a POST request, pass an object with the `method` property set to `"POST"`.
```ts
const response = await fetch("http://example.com", {
method: "POST",
body: "Hello, world!",
});
```
`body` can be a string, a `FormData` object, an `ArrayBuffer`, a `Blob`, and more. See the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/Body/body) for more information.
### Proxying requests
To proxy a request, pass an object with the `proxy` property set to a URL.
```ts
const response = await fetch("http://example.com", {
proxy: "http://proxy.com",
});
```
### Custom headers
To set custom headers, pass an object with the `headers` property set to an object.
```ts
const response = await fetch("http://example.com", {
headers: {
"X-Custom-Header": "value",
},
});
```
You can also set headers using the [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) object.
```ts
const headers = new Headers();
headers.append("X-Custom-Header", "value");
const response = await fetch("http://example.com", {
headers,
});
```
### Response bodies
To read the response body, use one of the following methods:
- `response.text(): Promise<string>`: Returns a promise that resolves with the response body as a string.
- `response.json(): Promise<any>`: Returns a promise that resolves with the response body as a JSON object.
- `response.formData(): Promise<FormData>`: Returns a promise that resolves with the response body as a `FormData` object.
- `response.bytes(): Promise<Uint8Array>`: Returns a promise that resolves with the response body as a `Uint8Array`.
- `response.arrayBuffer(): Promise<ArrayBuffer>`: Returns a promise that resolves with the response body as an `ArrayBuffer`.
- `response.blob(): Promise<Blob>`: Returns a promise that resolves with the response body as a `Blob`.
#### Streaming response bodies
You can use async iterators to stream the response body.
```ts
const response = await fetch("http://example.com");
for await (const chunk of response.body) {
console.log(chunk);
}
```
You can also more directly access the `ReadableStream` object.
```ts
const response = await fetch("http://example.com");
const stream = response.body;
const reader = stream.getReader();
const { value, done } = await reader.read();
```
### Fetching a URL with a timeout
To fetch a URL with a timeout, use `AbortSignal.timeout`:
```ts
const response = await fetch("http://example.com", {
signal: AbortSignal.timeout(1000),
});
```
#### Canceling a request
To cancel a request, use an `AbortController`:
```ts
const controller = new AbortController();
const response = await fetch("http://example.com", {
signal: controller.signal,
});
controller.abort();
```
### Unix domain sockets
To fetch a URL using a Unix domain socket, use the `unix: string` option:
```ts
const response = await fetch("https://hostname/a/path", {
unix: "/var/run/path/to/unix.sock",
method: "POST",
body: JSON.stringify({ message: "Hello from Bun!" }),
headers: {
"Content-Type": "application/json",
},
});
```
### TLS
To use a client certificate, use the `tls` option:
```ts
await fetch("https://example.com", {
tls: {
key: Bun.file("/path/to/key.pem"),
cert: Bun.file("/path/to/cert.pem"),
// ca: [Bun.file("/path/to/ca.pem")],
},
});
```
#### Custom TLS Validation
To customize the TLS validation, use the `checkServerIdentity` option in `tls`
```ts
await fetch("https://example.com", {
tls: {
checkServerIdentity: (hostname, peerCertificate) => {
// Return an error if the certificate is invalid
},
},
});
```
This is similar to how it works in Node's `net` module.
## Debugging
To help with debugging, you can pass `verbose: true` to `fetch`:
```ts
const response = await fetch("http://example.com", {
verbose: true,
});
```
This will print the request and response headers to your terminal:
```sh
[fetch] > HTTP/1.1 GET http://example.com/
[fetch] > Connection: keep-alive
[fetch] > User-Agent: Bun/1.1.21
[fetch] > Accept: */*
[fetch] > Host: example.com
[fetch] > Accept-Encoding: gzip, deflate, br
[fetch] < 200 OK
[fetch] < Content-Encoding: gzip
[fetch] < Age: 201555
[fetch] < Cache-Control: max-age=604800
[fetch] < Content-Type: text/html; charset=UTF-8
[fetch] < Date: Sun, 21 Jul 2024 02:41:14 GMT
[fetch] < Etag: "3147526947+gzip"
[fetch] < Expires: Sun, 28 Jul 2024 02:41:14 GMT
[fetch] < Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
[fetch] < Server: ECAcc (sac/254F)
[fetch] < Vary: Accept-Encoding
[fetch] < X-Cache: HIT
[fetch] < Content-Length: 648
```
Note: `verbose: boolean` is not part of the Web standard `fetch` API and is specific to Bun.
## Performance
Before an HTTP request can be sent, the DNS lookup must be performed. This can take a significant amount of time, especially if the DNS server is slow or the network connection is poor.
After the DNS lookup, the TCP socket must be connected and the TLS handshake might need to be performed. This can also take a significant amount of time.
After the request completes, consuming the response body can also take a significant amount of time and memory.
At every step of the way, Bun provides APIs to help you optimize the performance of your application.
### DNS prefetching
To prefetch a DNS entry, you can use the `dns.prefetch` API. This API is useful when you know you'll need to connect to a host soon and want to avoid the initial DNS lookup.
```ts
import { dns } from "bun";
dns.prefetch("bun.sh", 443);
```
#### DNS caching
By default, Bun caches and deduplicates DNS queries in-memory for up to 30 seconds. You can see the cache stats by calling `dns.getCacheStats()`:
To learn more about DNS caching in Bun, see the [DNS caching](/docs/api/dns) documentation.
### Preconnect to a host
To preconnect to a host, you can use the `fetch.preconnect` API. This API is useful when you know you'll need to connect to a host soon and want to start the initial DNS lookup, TCP socket connection, and TLS handshake early.
```ts
import { fetch } from "bun";
fetch.preconnect("https://bun.sh");
```
Note: calling `fetch` immediately after `fetch.preconnect` will not make your request faster. Preconnecting only helps if you know you'll need to connect to a host soon, but you're not ready to make the request yet.
#### Preconnect at startup
To preconnect to a host at startup, you can pass `--fetch-preconnect`:
```sh
$ bun --fetch-preconnect https://bun.sh ./my-script.ts
```
This is sort of like `<link rel="preconnect">` in HTML.
This feature is not implemented on Windows yet. If you're interested in using this feature on Windows, please file an issue and we can implement support for it on Windows.
### Connection pooling & HTTP keep-alive
Bun automatically reuses connections to the same host. This is known as connection pooling. This can significantly reduce the time it takes to establish a connection. You don't need to do anything to enable this; it's automatic.
#### Simultaneous connection limit
By default, Bun limits the maximum number of simultaneous `fetch` requests to 256. We do this for several reasons:
- It improves overall system stability. Operating systems have an upper limit on the number of simultaneous open TCP sockets, usually in the low thousands. Nearing this limit causes your entire computer to behave strangely. Applications hang and crash.
- It encourages HTTP Keep-Alive connection reuse. For short-lived HTTP requests, the slowest step is often the initial connection setup. Reusing connections can save a lot of time.
When the limit is exceeded, the requests are queued and sent as soon as the next request ends.
You can increase the maximum number of simultaneous connections via the `BUN_CONFIG_MAX_HTTP_REQUESTS` environment variable:
```sh
$ BUN_CONFIG_MAX_HTTP_REQUESTS=512 bun ./my-script.ts
```
The max value for this limit is currently set to 65,336. The maximum port number is 65,535, so it's quite difficult for any one computer to exceed this limit.
### Response buffering
Bun goes to great lengths to optimize the performance of reading the response body. The fastest way to read the response body is to use one of these methods:
- `response.text(): Promise<string>`
- `response.json(): Promise<any>`
- `response.formData(): Promise<FormData>`
- `response.bytes(): Promise<Uint8Array>`
- `response.arrayBuffer(): Promise<ArrayBuffer>`
- `response.blob(): Promise<Blob>`
You can also use `Bun.write` to write the response body to a file on disk:
```ts
import { write } from "bun";
await write("output.txt", response);
```

View File

@@ -756,25 +756,6 @@ $ bun build ./index.tsx --outdir ./out --external '*'
{% /codetabs %}
### `packages`
Control whatever package dependencies are included to bundle or not. Possible values: `bundle` (default), `external`. Bun threats any import which path do not start with `.`, `..` or `/` as package.
{% codetabs group="a" %}
```ts#JavaScript
await Bun.build({
entrypoints: ['./index.ts'],
packages: 'external',
})
```
```bash#CLI
$ bun build ./index.ts --packages external
```
{% /codetabs %}
### `naming`
Customizes the generated file names. Defaults to `./[dir]/[name].[ext]`.

View File

@@ -94,8 +94,8 @@ In Bun's CLI, simple boolean flags like `--minify` do not accept an argument. Ot
---
- `--packages`
- `--packages`
- No differences
- n/a
- Not supported
---

View File

@@ -35,10 +35,6 @@ $ bun add --optional lodash
## `--exact`
{% callout %}
**Alias**`-E`
{% /callout %}
To add a package and pin to the resolved version, use `--exact`. This will resolve the version of the package and add it to your `package.json` with an exact version number instead of a version range.
```bash

View File

@@ -15,7 +15,7 @@ To _containerize_ our application, we define a `Dockerfile`. This file contains
```docker#Dockerfile
# use the official Bun image
# see all versions at https://hub.docker.com/r/oven/bun/tags
FROM oven/bun:1 AS base
FROM oven/bun:1 as base
WORKDIR /usr/src/app
# install dependencies into temp directory

View File

@@ -69,7 +69,7 @@ export const movies = sqliteTable("movies", {
We can use the `drizzle-kit` CLI to generate an initial SQL migration.
```sh
$ bunx drizzle-kit generate --dialect sqlite --schema ./schema.ts
$ bunx drizzle-kit generate:sqlite --schema ./schema.ts
```
---

View File

@@ -13,7 +13,7 @@ console.log(Bun.argv);
Running this file with arguments results in the following:
```sh
$ bun run cli.ts --flag1 --flag2 value
$ bun run cli.tsx --flag1 --flag2 value
[ '/path/to/bun', '/path/to/cli.ts', '--flag1', '--flag2', 'value' ]
```
@@ -47,7 +47,7 @@ console.log(positionals);
then it outputs
```
$ bun run cli.ts --flag1 --flag2 value
$ bun run cli.tsx --flag1 --flag2 value
{
flag1: true,
flag2: "value",

View File

@@ -13,7 +13,7 @@ jobs:
steps:
# ...
- uses: actions/checkout@v4
+ - uses: oven-sh/setup-bun@v2
+ - uses: oven-sh/setup-bun@v1
# run any `bun` or `bunx` command
+ - run: bun install
@@ -33,7 +33,7 @@ jobs:
runs-on: ubuntu-latest
steps:
# ...
- uses: oven-sh/setup-bun@v2
- uses: oven-sh/setup-bun@v1
+ with:
+ bun-version: 1.0.11 # or "latest", "canary", <sha>
```

View File

@@ -52,7 +52,7 @@ Different thresholds can be set for line-level and function-level coverage.
```toml
[test]
# to set different thresholds for lines and functions
coverageThreshold = { lines = 0.5, functions = 0.7 }
coverageThreshold = { line = 0.5, function = 0.7 }
```
---

View File

@@ -1,6 +1,6 @@
All packages downloaded from the registry are stored in a global cache at `~/.bun/install/cache`. They are stored in subdirectories named like `${name}@${version}`, so multiple versions of a package can be cached.
{% details summary="Configuring cache behavior (bunfig.toml)" %}
{% details summary="Configuring cache behavior" (bunfig.toml) %}
```toml
[install.cache]
@@ -15,6 +15,8 @@ disable = false
disableManifest = false
```
{% /details %}
## Minimizing re-downloads
Bun strives to avoid re-downloading packages multiple times. When installing a package, if the cache already contains a version in the range specified by `package.json`, Bun will use the cached package instead of downloading it again.

View File

@@ -1,75 +0,0 @@
Bun supports loading configuration options from [`.npmrc`](https://docs.npmjs.com/cli/v10/configuring-npm/npmrc) files, allowing you to reuse existing registry/scope configurations.
{% callout %}
**NOTE**: We recommend migrating your `.npmrc` file to Bun's [`bunfig.toml`](/docs/runtime/bunfig) format, as it provides more flexible options and can let you configure Bun-specific options.
{% /callout %}
# Supported options
### `registry`: Set the default registry
The default registry is used to resolve packages, it's default value is `npm`'s official registry (`https://registry.npmjs.org/`).
To change it, you can set the `registry` option in `.npmrc`:
```ini
registry=http://localhost:4873/
```
The equivalent `bunfig.toml` option is [`install.registry`](/docs/runtime/bunfig#install-registry):
```toml
install.registry = "http://localhost:4873/"
```
### `@<scope>:registry`: Set the registry for a specific scope
Allows you to set the registry for a specific scope:
```ini
@myorg:registry=http://localhost:4873/
```
The equivalent `bunfig.toml` option is to add a key in [`install.scopes`](/docs/runtime/bunfig#install-registry):
```toml
[install.scopes]
myorg = "http://localhost:4873/"
```
### `//<registry_url>/:<key>=<value>`: Confgure options for a specific registry
Allows you to set options for a specific registry:
```ini
# set an auth token for the registry
# ${...} is a placeholder for environment variables
//http://localhost:4873/:_authToken=${NPM_TOKEN}
# or you could set a username and password
# note that the password is base64 encoded
//http://localhost:4873/:username=myusername
//http://localhost:4873/:_password=${NPM_PASSWORD}
# or use _auth, which is your username and password
# combined into a single string, which is then base 64 encoded
//http://localhost:4873/:_auth=${NPM_AUTH}
```
The following options are supported:
- `_authToken`
- `username`
- `_password` (base64 encoded password)
- `_auth` (base64 encoded username:password, e.g. `btoa(username + ":" + password)`)
The equivalent `bunfig.toml` option is to add a key in [`install.scopes`](/docs/runtime/bunfig#install-registry):
```toml
[install.scopes]
myorg = { url = "http://localhost:4873/", username = "myusername", password = "$NPM_PASSWORD" }
```

View File

@@ -30,6 +30,10 @@ $ docker pull oven/bun
$ docker run --rm --init --ulimit memlock=-1:-1 oven/bun
```
```bash#Proto
$ proto install bun
```
{% /codetabs %}
### Windows
@@ -142,6 +146,7 @@ $ bun upgrade
**Scoop users** — To avoid conflicts with Scoop, use `scoop update bun` instead.
**proto users** - Use `proto install bun --pin` instead.
{% /callout %}
## Canary builds
@@ -286,4 +291,8 @@ $ npm uninstall -g bun
$ brew uninstall bun
```
```bash#Proto
$ proto uninstall bun
```
{% /codetabs %}

View File

@@ -197,9 +197,6 @@ export default {
description:
"Patch dependencies in your project to fix bugs or add features without vendoring the entire package.",
}),
page("install/npmrc", ".npmrc support", {
description: "Bun supports loading some configuration options from .npmrc",
}),
// page("install/utilities", "Utilities", {
// description: "Use `bun pm` to introspect your global module cache or project dependency tree.",
// }),
@@ -287,11 +284,8 @@ export default {
divider("API"),
page("api/http", "HTTP server", {
description: `Bun implements a fast HTTP server built on Request/Response objects, along with supporting node:http APIs.`,
description: `Bun implements Web-standard fetch, plus a Bun-native API for building fast HTTP servers.`,
}), // "`Bun.serve`"),
page("api/fetch", "HTTP client", {
description: `Bun implements Web-standard fetch with some Bun-native extensions.`,
}), // "fetch"),
page("api/websockets", "WebSockets", {
description: `Bun supports server-side WebSockets with on-the-fly compression, TLS support, and a Bun-native pubsub API.`,
}), // "`Bun.serve`"),

View File

@@ -60,7 +60,7 @@ Visual Studio can be installed graphically using the wizard or through WinGet:
After Visual Studio, you need the following:
- LLVM 18.1.8
- LLVM 16
- Go
- Rust
- NASM
@@ -78,14 +78,14 @@ After Visual Studio, you need the following:
```ps1#WinGet
## Select "Add LLVM to the system PATH for all users" in the LLVM installer
> winget install -i LLVM.LLVM -v 18.1.8 && winget install GoLang.Go Rustlang.Rustup NASM.NASM StrawberryPerl.StrawberryPerl RubyInstallerTeam.Ruby.3.2 OpenJS.NodeJS.LTS
> winget install -i LLVM.LLVM -v 16.0.6 && winget install GoLang.Go Rustlang.Rustup NASM.NASM StrawberryPerl.StrawberryPerl RubyInstallerTeam.Ruby.3.2 OpenJS.NodeJS.LTS
```
```ps1#Scoop
> irm https://get.scoop.sh | iex
> scoop install nodejs-lts go rust nasm ruby perl
# scoop seems to be buggy if you install llvm and the rest at the same time
> scoop install llvm@18.1.8
> scoop install llvm@16.0.6
```
{% /codetabs %}

View File

@@ -179,7 +179,7 @@ These environment variables are read by Bun and configure aspects of its behavio
---
- `BUN_CONFIG_NO_CLEAR_TERMINAL_ON_RELOAD`
- If `BUN_CONFIG_NO_CLEAR_TERMINAL_ON_RELOAD=true`, then `bun --watch` will not clear the console on reload
- If `BUN_CONFIG_NO_CLEAR_TERMINAL_ON_RELOAD=1`, then `bun --watch` will not clear the console on reload
---

View File

@@ -48,6 +48,14 @@ In this case, we are importing from `./hello`, a relative path with no extension
- `./hello/index.cjs`
- `./hello/index.json`
Import paths are case-insensitive, meaning these are all valid imports:
```ts#index.ts
import { hello } from "./hello";
import { hello } from "./HELLO";
import { hello } from "./hElLo";
```
Import paths can optionally include extensions. If an extension is present, Bun will only check for a file with that exact extension.
```ts#index.ts

View File

@@ -193,7 +193,7 @@ The table below lists all globals implemented by Node.js and Bun's current compa
### [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer)
🟢 Fully implemented.
🟡 Incomplete implementation of `base64` and `base64url` encodings.
### [`ByteLengthQueuingStrategy`](https://developer.mozilla.org/en-US/docs/Web/API/ByteLengthQueuingStrategy)

View File

@@ -196,41 +196,3 @@ As of Bun v1.0.19, Bun automatically resolves the `specifier` argument to `mock.
After resolution, the mocked module is stored in the ES Module registry **and** the CommonJS require cache. This means that you can use `import` and `require` interchangeably for mocked modules.
The callback function is called lazily, only if the module is imported or required. This means that you can use `mock.module()` to mock modules that don't exist yet, and it means that you can use `mock.module()` to mock modules that are imported by other modules.
## Restore all function mocks to their original values with `mock.restore()`
Instead of manually restoring each mock individually with `mockFn.mockRestore()`, restore all mocks with one command by calling `mock.restore()`. Doing so does not reset the value of modules overridden with `mock.module()`.
Using `mock.restore()` can reduce the amount of code in your tests by adding it to `afterEach` blocks in each test file or even in your [test preload code](https://bun.sh/docs/runtime/bunfig#test-preload).
```ts
import { expect, mock, spyOn, test } from "bun:test";
import * as fooModule from './foo.ts';
import * as barModule from './bar.ts';
import * as bazModule from './baz.ts';
test('foo, bar, baz', () => {
const fooSpy = spyOn(fooModule, 'foo');
const barSpy = spyOn(barModule, 'bar');
const bazSpy = spyOn(bazModule, 'baz');
expect(fooSpy).toBe('foo');
expect(barSpy).toBe('bar');
expect(bazSpy).toBe('baz');
fooSpy.mockImplementation(() => 42);
barSpy.mockImplementation(() => 43);
bazSpy.mockImplementation(() => 44);
expect(fooSpy).toBe(42);
expect(barSpy).toBe(43);
expect(bazSpy).toBe(44);
mock.restore();
expect(fooSpy).toBe('foo');
expect(barSpy).toBe('bar');
expect(bazSpy).toBe('baz');
});
```

View File

@@ -182,7 +182,7 @@ pub fn main() anyerror!void {
try channel.buffer.ensureTotalCapacity(1);
HTTPThread.init();
try HTTPThread.init();
var ctx = try default_allocator.create(HTTP.HTTPChannelContext);
ctx.* = .{

View File

@@ -4,7 +4,7 @@
"workspaces": [
"./packages/bun-types"
],
"devDependencies": {
"dependencies": {
"@vscode/debugadapter": "^1.65.0",
"esbuild": "^0.21.4",
"eslint": "^9.4.0",
@@ -15,7 +15,9 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"source-map-js": "^1.2.0",
"typescript": "^5.4.5",
"typescript": "^5.4.5"
},
"devDependencies": {
"@types/bun": "^1.1.3",
"@types/react": "^18.3.3",
"@typescript-eslint/eslint-plugin": "^7.11.0",
@@ -32,7 +34,6 @@
"build:tidy": "BUN_SILENT=1 cmake --log-level=WARNING . -DZIG_OPTIMIZE=Debug -DUSE_DEBUG_JSC=ON -DBUN_TIDY_ONLY=ON -DCMAKE_BUILD_TYPE=Debug -GNinja -Bbuild-tidy >> ${GITHUB_STEP_SUMMARY:-/dev/stdout} && BUN_SILENT=1 ninja -Cbuild-tidy >> ${GITHUB_STEP_SUMMARY:-/dev/stdout}",
"build:tidy-extra": "cmake . -DZIG_OPTIMIZE=Debug -DUSE_DEBUG_JSC=ON -DBUN_TIDY_ONLY_EXTRA=ON -DCMAKE_BUILD_TYPE=Debug -GNinja -Bbuild-tidy && ninja -Cbuild-tidy",
"build:release": "cmake . -DCMAKE_BUILD_TYPE=Release -GNinja -Bbuild-release && ninja -Cbuild-release",
"build:release:local": "cmake . -DCMAKE_BUILD_TYPE=Release -DWEBKIT_DIR=$(pwd)/src/bun.js/WebKit/WebKitBuild/Release -GNinja -Bbuild-release-local && ninja -Cbuild-release-local",
"build:release:with_logs": "cmake . -DCMAKE_BUILD_TYPE=Release -DENABLE_LOGS=true -GNinja -Bbuild-release && ninja -Cbuild-release",
"build:debug-zig-release": "cmake . -DCMAKE_BUILD_TYPE=Release -DZIG_OPTIMIZE=Debug -GNinja -Bbuild-debug-zig-release && ninja -Cbuild-debug-zig-release",
"build:safe": "cmake . -DZIG_OPTIMIZE=ReleaseSafe -DUSE_DEBUG_JSC=ON -DCMAKE_BUILD_TYPE=Release -GNinja -Bbuild-safe && ninja -Cbuild-safe",
@@ -44,10 +45,8 @@
"lint:fix": "eslint './**/*.d.ts' --cache --fix",
"test": "node scripts/runner.node.mjs ./build/bun-debug",
"test:release": "node scripts/runner.node.mjs ./build-release/bun",
"banned": "bun packages/bun-internal-test/src/linter.ts",
"zig-check": ".cache/zig/zig.exe build check --summary new",
"zig-check-all": ".cache/zig/zig.exe build check-all --summary new",
"zig-check-windows": ".cache/zig/zig.exe build check-windows --summary new",
"zig": ".cache/zig/zig.exe "
}
}

View File

@@ -5,13 +5,9 @@
"std.debug.assert": "Use bun.assert instead",
"std.debug.dumpStackTrace": "Use bun.handleErrorReturnTrace or bun.crash_handler.dumpStackTrace instead",
"std.debug.print": "Don't let this be committed",
"std.mem.indexOfAny(u8": "Use bun.strings.indexOfAny",
"std.mem.indexOfAny": "Use bun.strings.indexAny or bun.strings.indexAnyComptime",
"undefined != ": "This is by definition Undefined Behavior.",
"undefined == ": "This is by definition Undefined Behavior.",
"bun.toFD(std.fs.cwd().fd)": "Use bun.FD.cwd()",
"std.StringArrayHashMapUnmanaged(": "bun.StringArrayHashMapUnmanaged has a faster `eql`",
"std.StringArrayHashMap(": "bun.StringArrayHashMap has a faster `eql`",
"std.StringHashMapUnmanaged(": "bun.StringHashMapUnmanaged has a faster `eql`",
"std.StringHashMap(": "bun.StringHashMaphas a faster `eql`",
"": ""
}

View File

@@ -19,7 +19,9 @@ for (const [banned, suggestion] of Object.entries(BANNED)) {
if (banned.length === 0) continue;
// Run git grep to find occurrences of std.debug.assert in .zig files
// .nothrow() is here since git will exit with non-zero if no matches are found.
let stdout = await $`git grep -n -F "${banned}" "src/**.zig" | grep -v -F '//' | grep -v -F bench`.nothrow().text();
let stdout = await $`git grep -n -F "${banned}" "src/**/**.zig" | grep -v -F '//' | grep -v -F bench`
.nothrow()
.text();
stdout = stdout.trim();
if (stdout.length === 0) continue;

View File

@@ -1,606 +0,0 @@
import * as action from "@actions/core";
import { spawn, spawnSync } from "child_process";
import { rmSync, writeFileSync, readFileSync, mkdirSync, openSync, closeSync } from "fs";
import { readdirSync } from "node:fs";
import { resolve, basename } from "node:path";
import { cpus, hostname, tmpdir, totalmem, userInfo } from "os";
import { join, normalize, posix, relative } from "path";
import { fileURLToPath } from "url";
import PQueue from "p-queue";
const run_start = new Date();
const TIMEOUT_DURATION = 1000 * 60 * 5;
const SHORT_TIMEOUT_DURATION = Math.ceil(TIMEOUT_DURATION / 5);
function defaultConcurrency() {
// This causes instability due to the number of open file descriptors / sockets in some tests
// Windows has higher limits
if (process.platform !== "win32") {
return 1;
}
return Math.min(Math.floor((cpus().length - 2) / 2), 2);
}
const windows = process.platform === "win32";
const nativeMemory = totalmem();
const force_ram_size_input = parseInt(process.env["BUN_JSC_forceRAMSize"] || "0", 10);
let force_ram_size = Number(BigInt(nativeMemory) >> BigInt(2)) + "";
if (!(Number.isSafeInteger(force_ram_size_input) && force_ram_size_input > 0)) {
force_ram_size = force_ram_size_input + "";
}
function uncygwinTempDir() {
if (process.platform === "win32") {
for (let key of ["TMPDIR", "TEMP", "TEMPDIR", "TMP"]) {
let TMPDIR = process.env[key] || "";
if (!/^\/[a-zA-Z]\//.test(TMPDIR)) {
continue;
}
const driveLetter = TMPDIR[1];
TMPDIR = path.win32.normalize(`${driveLetter.toUpperCase()}:` + TMPDIR.substring(2));
process.env[key] = TMPDIR;
}
}
}
uncygwinTempDir();
const cwd = resolve(fileURLToPath(import.meta.url), "../../../../");
process.chdir(cwd);
const ci = !!process.env["GITHUB_ACTIONS"];
const enableProgressBar = false;
const dirPrefix = "bun-test-tmp-" + ((Math.random() * 100_000_0) | 0).toString(36) + "_";
const run_concurrency = Math.max(Number(process.env["BUN_TEST_CONCURRENCY"] || defaultConcurrency(), 10), 1);
const queue = new PQueue({ concurrency: run_concurrency });
var prevTmpdir = "";
function maketemp() {
prevTmpdir = join(
tmpdir(),
dirPrefix + (Date.now() | 0).toString() + "_" + ((Math.random() * 100_000_0) | 0).toString(36),
);
mkdirSync(prevTmpdir, { recursive: true });
return prevTmpdir;
}
const extensions = [".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs", ".mts", ".cts", ".mjsx", ".cjsx", ".mtsx", ".ctsx"];
const git_sha =
process.env["GITHUB_SHA"] ?? spawnSync("git", ["rev-parse", "HEAD"], { encoding: "utf-8" }).stdout.trim();
const TEST_FILTER = process.env.BUN_TEST_FILTER;
function isTest(path) {
if (!basename(path).includes(".test.") || !extensions.some(ext => path.endsWith(ext))) {
return false;
}
if (TEST_FILTER) {
if (!path.includes(TEST_FILTER)) {
return false;
}
}
return true;
}
function* findTests(dir, query) {
for (const entry of readdirSync(resolve(dir), { encoding: "utf-8", withFileTypes: true })) {
const path = resolve(dir, entry.name);
if (entry.isDirectory() && entry.name !== "node_modules" && entry.name !== ".git") {
yield* findTests(path, query);
} else if (isTest(path)) {
yield path;
}
}
}
let bunExe = "bun";
if (process.argv.length > 2) {
bunExe = resolve(process.argv.at(-1));
} else if (process.env.BUN_PATH) {
const { BUN_PATH_BASE, BUN_PATH } = process.env;
bunExe = resolve(normalize(BUN_PATH_BASE), normalize(BUN_PATH));
}
const { error, stdout: revision_stdout } = spawnSync(bunExe, ["--revision"], {
env: { ...process.env, BUN_DEBUG_QUIET_LOGS: 1 },
});
if (error) {
if (error.code !== "ENOENT") throw error;
console.error(`\x1b[31merror\x1b[0;2m:\x1b[0m Could not find Bun executable at '${bunExe}'`);
process.exit(1);
}
const revision = revision_stdout.toString().trim();
const { error: error2, stdout: argv0_stdout } = spawnSync(bunExe, ["-e", "console.log(process.argv[0])"], {
env: { ...process.env, BUN_DEBUG_QUIET_LOGS: 1 },
});
if (error2) throw error2;
const argv0 = argv0_stdout.toString().trim();
console.log(`Testing ${argv0} v${revision}`);
const ntStatusPath = "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\shared\\ntstatus.h";
let ntstatus_header_cache = null;
function lookupWindowsError(code) {
if (ntstatus_header_cache === null) {
try {
ntstatus_header_cache = readFileSync(ntStatusPath, "utf-8");
} catch {
console.error(`could not find ntstatus.h to lookup error code: ${ntStatusPath}`);
ntstatus_header_cache = "";
}
}
const match = ntstatus_header_cache.match(new RegExp(`(STATUS_\\w+).*0x${code.toString(16)}`, "i"));
if (match) {
return match[1];
}
return null;
}
const failing_tests = [];
const passing_tests = [];
let maxFd = -1;
function getMaxFileDescriptor(path) {
if (process.platform === "win32") {
return -1;
}
hasInitialMaxFD = true;
if (process.platform === "linux" || process.platform === "darwin") {
try {
readdirSync(process.platform === "darwin" ? "/dev/fd" : "/proc/self/fd").forEach(name => {
const fd = parseInt(name.trim(), 10);
if (Number.isSafeInteger(fd) && fd >= 0) {
maxFd = Math.max(maxFd, fd);
}
});
return maxFd;
} catch {}
}
const devnullfd = openSync("/dev/null", "r");
closeSync(devnullfd);
maxFd = devnullfd + 1;
return maxFd;
}
let hasInitialMaxFD = false;
const activeTests = new Map();
let slowTestCount = 0;
function checkSlowTests() {
const now = Date.now();
const prevSlowTestCount = slowTestCount;
slowTestCount = 0;
for (const [path, { start, proc }] of activeTests) {
if (proc && now - start >= TIMEOUT_DURATION) {
console.error(
`\x1b[31merror\x1b[0;2m:\x1b[0m Killing test ${JSON.stringify(path)} after ${Math.ceil((now - start) / 1000)}s`,
);
proc?.stdout?.destroy?.();
proc?.stderr?.destroy?.();
proc?.kill?.(9);
} else if (now - start > SHORT_TIMEOUT_DURATION) {
console.error(
`\x1b[33mwarning\x1b[0;2m:\x1b[0m Test ${JSON.stringify(path)} has been running for ${Math.ceil(
(now - start) / 1000,
)}s`,
);
slowTestCount++;
}
}
if (slowTestCount > prevSlowTestCount && queue.concurrency > 1) {
queue.concurrency += 1;
}
}
setInterval(checkSlowTests, SHORT_TIMEOUT_DURATION).unref();
var currentTestNumber = 0;
async function runTest(path) {
const pathOnDisk = resolve(path);
const thisTestNumber = currentTestNumber++;
const testFileName = posix.normalize(relative(cwd, path).replaceAll("\\", "/"));
let exitCode, signal, err, output;
const start = Date.now();
const activeTestObject = { start, proc: undefined };
activeTests.set(testFileName, activeTestObject);
try {
await new Promise((finish, reject) => {
const chunks = [];
process.stderr.write(
`
at ${((start - run_start.getTime()) / 1000).toFixed(2)}s, file ${thisTestNumber
.toString()
.padStart(total.toString().length, "0")}/${total}, ${failing_tests.length} failing files
Starting "${testFileName}"
`,
);
const TMPDIR = maketemp();
const proc = spawn(bunExe, ["test", pathOnDisk], {
stdio: ["ignore", "pipe", "pipe"],
env: {
...process.env,
FORCE_COLOR: "1",
BUN_GARBAGE_COLLECTOR_LEVEL: "1",
BUN_JSC_forceRAMSize: force_ram_size,
BUN_RUNTIME_TRANSPILER_CACHE_PATH: "0",
GITHUB_ACTIONS: process.env.GITHUB_ACTIONS ?? "true",
BUN_DEBUG_QUIET_LOGS: "1",
BUN_INSTALL_CACHE_DIR: join(TMPDIR, ".bun-install-cache"),
BUN_ENABLE_CRASH_REPORTING: "1",
[windows ? "TEMP" : "TMPDIR"]: TMPDIR,
},
});
activeTestObject.proc = proc;
proc.stdout.once("end", () => {
done();
});
let doneCalls = 0;
var done = () => {
// TODO: wait for stderr as well
// spawn.test currently causes it to hang
if (doneCalls++ === 1) {
actuallyDone();
}
};
var actuallyDone = function () {
actuallyDone = done = () => {};
proc?.stderr?.unref?.();
proc?.stdout?.unref?.();
proc?.unref?.();
output = Buffer.concat(chunks).toString();
finish();
};
// if (!KEEP_TMPDIR)
// proc.once("close", () => {
// rm(TMPDIR, { recursive: true, force: true }).catch(() => {});
// });
proc.stdout.on("data", chunk => {
chunks.push(chunk);
if (run_concurrency === 1) process.stdout.write(chunk);
});
proc.stderr.on("data", chunk => {
chunks.push(chunk);
if (run_concurrency === 1) process.stderr.write(chunk);
});
proc.once("close", () => {
activeTestObject.proc = undefined;
});
proc.once("exit", (code_, signal_) => {
activeTestObject.proc = undefined;
exitCode = code_;
signal = signal_;
if (signal || exitCode !== 0) {
actuallyDone();
} else {
done();
}
});
proc.once("error", err_ => {
activeTestObject.proc = undefined;
err = err_;
actuallyDone();
});
});
} finally {
activeTests.delete(testFileName);
}
if (!hasInitialMaxFD) {
getMaxFileDescriptor();
} else if (maxFd > 0) {
const prevMaxFd = maxFd;
maxFd = getMaxFileDescriptor();
if (maxFd > prevMaxFd + queue.concurrency * 2) {
process.stderr.write(
`\n\x1b[31mewarn\x1b[0;2m:\x1b[0m file descriptor leak in ${testFileName}, delta: ${
maxFd - prevMaxFd
}, current: ${maxFd}, previous: ${prevMaxFd}\n`,
);
}
}
const passed = exitCode === 0 && !err && !signal;
let reason = "";
if (!passed) {
let match;
if (err && err.message.includes("timed")) {
reason = "hang";
} else if ((match = output && output.match(/thread \d+ panic: (.*)\n/))) {
reason = 'panic "' + match[1] + '"';
} else if (err) {
reason = (err.name || "Error") + ": " + err.message;
} else if (signal) {
reason = signal;
} else if (exitCode === 1) {
const failMatch = output.match(/\x1b\[31m\s(\d+) fail/);
if (failMatch) {
reason = failMatch[1] + " failing";
} else {
reason = "code 1";
}
} else {
const x = windows && lookupWindowsError(exitCode);
if (x) {
if (x === "STATUS_BREAKPOINT") {
if (output.includes("Segmentation fault at address")) {
reason = "STATUS_ACCESS_VIOLATION";
}
}
reason = x;
} else {
reason = "code " + exitCode;
}
}
}
const duration = (Date.now() - start) / 1000;
if (run_concurrency !== 1 && enableProgressBar) {
// clear line
process.stdout.write("\x1b[2K\r");
}
console.log(
`\x1b[2m${formatTime(duration).padStart(6, " ")}\x1b[0m ${
passed ? "\x1b[32m✔" : "\x1b[31m✖"
} ${testFileName}\x1b[0m${reason ? ` (${reason})` : ""}`,
);
finished++;
if (run_concurrency !== 1 && enableProgressBar) {
writeProgressBar();
}
if (run_concurrency > 1 && ci) {
process.stderr.write(output);
}
if (!passed) {
failing_tests.push({ path: testFileName, reason, output });
process.exitCode = 1;
if (err) console.error(err);
} else {
passing_tests.push(testFileName);
}
return passed;
}
var finished = 0;
function writeProgressBar() {
const barWidth = Math.min(process.stdout.columns || 40, 80) - 2;
const percent = (finished / total) * 100;
const bar = "=".repeat(Math.floor(percent / 2));
const str1 = `[${finished}/${total}] [${bar}`;
process.stdout.write(`\r${str1}${" ".repeat(barWidth - str1.length)}]`);
}
const allTests = [...findTests(resolve(cwd, "test"))];
console.log(`Starting ${allTests.length} tests with ${run_concurrency} concurrency...`);
let total = allTests.length;
for (const path of allTests) {
queue.add(
async () =>
await runTest(path).catch(e => {
console.error("Bug in bun-internal-test");
console.error(e);
process.exit(1);
}),
);
}
await queue.onIdle();
console.log(`
Completed ${total} tests with ${failing_tests.length} failing tests
`);
console.log("\n");
function linkToGH(linkTo) {
return `https://github.com/oven-sh/bun/blob/${git_sha}/${linkTo}`;
}
failing_tests.sort((a, b) => a.path.localeCompare(b.path));
passing_tests.sort((a, b) => a.localeCompare(b));
const failingTestDisplay = failing_tests.map(({ path, reason }) => `- \`${path}\` ${reason}`).join("\n");
// const passingTestDisplay = passing_tests.map(path => `- \`${path}\``).join("\n");
rmSync("report.md", { force: true });
const uptime = process.uptime();
function formatTime(seconds) {
if (seconds < 60) {
return seconds.toFixed(1) + "s";
} else if (seconds < 60 * 60) {
return (seconds / 60).toFixed(0) + "m " + formatTime(seconds % 60);
} else {
return (seconds / 60 / 60).toFixed(0) + "h " + formatTime(seconds % (60 * 60));
}
}
const header = `
host: ${process.env["GITHUB_RUN_ID"] ? "GitHub Actions: " : ""}${userInfo().username}@${hostname()}
platform: ${process.platform} ${process.arch}
bun: ${argv0}
version: v${revision}
date: ${run_start.toISOString()}
duration: ${formatTime(uptime)}
total: ${total} files
failing: ${failing_tests.length} files
passing: ${passing_tests.length} files
percent: ${((passing_tests.length / total) * 100).toFixed(2)}%
`.trim();
console.log("\n" + "-".repeat(Math.min(process.stdout.columns || 40, 80)) + "\n");
console.log(header);
console.log("\n" + "-".repeat(Math.min(process.stdout.columns || 40, 80)) + "\n");
let report = `# bun test on ${
process.env["GITHUB_REF"] ??
spawnSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], { encoding: "utf-8" }).stdout.trim()
}
\`\`\`
${header}
\`\`\`
`;
if (failingTestDisplay.length > 0) {
report += `## Failing tests\n\n`;
report += failingTestDisplay;
report += "\n\n";
}
// if(passingTestDisplay.length > 0) {
// report += `## Passing tests\n\n`;
// report += passingTestDisplay;
// report += "\n\n";
// }
if (failing_tests.length) {
report += `## Failing tests log output\n\n`;
for (const { path, output, reason } of failing_tests) {
report += `### ${path}\n\n`;
report += "[Link to file](" + linkToGH(path) + ")\n\n";
report += `${reason}\n\n`;
report += "```\n";
let failing_output = output
.replace(/\x1b\[[0-9;]*m/g, "")
.replace(/^::(group|endgroup|error|warning|set-output|add-matcher|remove-matcher).*$/gm, "");
if (failing_output.length > 1024 * 64) {
failing_output = failing_output.slice(0, 1024 * 64) + `\n\n[truncated output (length: ${failing_output.length})]`;
}
report += failing_output;
report += "```\n\n";
}
}
writeFileSync("test-report.md", report);
writeFileSync(
"test-report.json",
JSON.stringify({
failing_tests,
passing_tests,
}),
);
function mabeCapitalize(str) {
str = str.toLowerCase();
if (str.includes("arm64") || str.includes("aarch64")) {
return str.toUpperCase();
}
if (str.includes("x64")) {
return "x64";
}
if (str.includes("baseline")) {
return str;
}
return str[0].toUpperCase() + str.slice(1);
}
console.log("-> test-report.md, test-report.json");
function linkify(text, url) {
if (url?.startsWith?.("https://")) {
return `[${text}](${url})`;
}
return text;
}
if (ci) {
if (failing_tests.length > 0) {
action.setFailed(`${failing_tests.length} files with failing tests`);
}
action.setOutput("failing_tests", failingTestDisplay);
action.setOutput("failing_tests_count", failing_tests.length);
if (failing_tests.length) {
const { env } = process;
const tag = process.env.BUN_TAG || "unknown";
const url = `${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}`;
let comment = `## ${linkify(`${emojiTag(tag)}${failing_tests.length} failing tests`, url)} ${tag
.split("-")
.map(mabeCapitalize)
.join(" ")}
${failingTestDisplay}
`;
writeFileSync("comment.md", comment);
}
let truncated_report = report;
if (truncated_report.length > 512 * 1000) {
truncated_report = truncated_report.slice(0, 512 * 1000) + "\n\n...truncated...";
}
action.summary.addRaw(truncated_report);
await action.summary.write();
}
function emojiTag(tag) {
let emojiText = "";
tag = tag.toLowerCase();
if (tag.includes("win32") || tag.includes("windows")) {
emojiText += "🪟";
}
if (tag.includes("linux")) {
emojiText += "🐧";
}
if (tag.includes("macos") || tag.includes("darwin")) {
emojiText += "";
}
if (tag.includes("x86") || tag.includes("x64") || tag.includes("_64") || tag.includes("amd64")) {
if (!tag.includes("linux")) {
emojiText += "💻";
} else {
emojiText += "🖥";
}
}
if (tag.includes("arm64") || tag.includes("aarch64")) {
emojiText += "💪";
}
if (emojiText) {
emojiText += " ";
}
return emojiText;
}
process.exit(failing_tests.length ? 1 : process.exitCode);

View File

@@ -290,7 +290,7 @@ function formatBody(body?: string, isBase64Encoded?: boolean): string | null {
if (!isBase64Encoded) {
return body;
}
return Buffer.from(body, "base64").toString("utf8");
return Buffer.from(body).toString("base64");
}
type HttpEventV1 = {

View File

@@ -22,10 +22,10 @@ bun upgrade
- [Linux, arm64](https://www.npmjs.com/package/@oven/bun-linux-aarch64)
- [Linux, x64](https://www.npmjs.com/package/@oven/bun-linux-x64)
- [Linux, x64 (without AVX2 instructions)](https://www.npmjs.com/package/@oven/bun-linux-x64-baseline)
- [Windows](https://www.npmjs.com/package/@oven/bun-windows-x64)
- [Windows (without AVX2 instructions)](https://www.npmjs.com/package/@oven/bun-windows-x64-baseline)
- [Windows (using Windows Subsystem for Linux, aka. "WSL")](https://relatablecode.com/how-to-set-up-bun-on-a-windows-machine)
### Future Platforms
- [Windows](https://github.com/oven-sh/bun/issues/43)
- Unix-like variants such as FreeBSD, OpenBSD, etc.
- Android and iOS

View File

@@ -1455,7 +1455,7 @@ declare module "bun" {
* ```js
* const {imports, exports} = transpiler.scan(`
* import {foo} from "baz";
* export const hello = "hi!";
* const hello = "hi!";
* `);
*
* console.log(imports); // ["baz"]
@@ -1516,7 +1516,6 @@ declare module "bun" {
plugins?: BunPlugin[];
// manifest?: boolean; // whether to return manifest
external?: string[];
packages?: "bundle" | "external";
publicPath?: string;
define?: Record<string, string>;
// origin?: string; // e.g. http://mydomain.com
@@ -2969,7 +2968,7 @@ declare module "bun" {
* Returns 0 if the versions are equal, 1 if `v1` is greater, or -1 if `v2` is greater.
* Throws an error if either version is invalid.
*/
order(this: void, v1: StringLike, v2: StringLike): -1 | 0 | 1;
order(v1: StringLike, v2: StringLike): -1 | 0 | 1;
}
var semver: Semver;
@@ -3100,10 +3099,6 @@ declare module "bun" {
*/
function openInEditor(path: string, options?: EditorOptions): void;
const fetch: typeof globalThis.fetch & {
preconnect(url: string): void;
};
interface EditorOptions {
editor?: "vscode" | "subl";
line?: number;

View File

@@ -907,42 +907,26 @@ declare global {
new (): ShadowRealm;
};
interface Fetch {
/**
* Send a HTTP(s) request
*
* @param request Request object
* @param init A structured value that contains settings for the fetch() request.
*
* @returns A promise that resolves to {@link Response} object.
*/
(request: Request, init?: RequestInit): Promise<Response>;
/**
* Send a HTTP(s) request
*
* @param request Request object
* @param init A structured value that contains settings for the fetch() request.
*
* @returns A promise that resolves to {@link Response} object.
*/
/**
* Send a HTTP(s) request
*
* @param url URL string
* @param init A structured value that contains settings for the fetch() request.
*
* @returns A promise that resolves to {@link Response} object.
*/
(url: string | URL | Request, init?: FetchRequestInit): Promise<Response>;
(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>;
/**
* Start the DNS resolution, TCP connection, and TLS handshake for a request
* before the request is actually sent.
*
* This can reduce the latency of a request when you know there's some
* long-running task that will delay the request starting.
*
* This is a bun-specific API and is not part of the Fetch API specification.
*/
preconnect(url: string | URL): void;
}
var fetch: Fetch;
// tslint:disable-next-line:unified-signatures
function fetch(request: Request, init?: RequestInit): Promise<Response>;
/**
* Send a HTTP(s) request
*
* @param url URL string
* @param init A structured value that contains settings for the fetch() request.
*
* @returns A promise that resolves to {@link Response} object.
*/
function fetch(url: string | URL | Request, init?: FetchRequestInit): Promise<Response>;
function queueMicrotask(callback: (...args: any[]) => void): void;
/**

View File

@@ -78,7 +78,21 @@ declare module "bun:jsc" {
*/
function setTimeZone(timeZone: string): string;
interface SamplingProfile {
/**
* Run JavaScriptCore's sampling profiler for a particular function
*
* This is pretty low-level.
*
* Things to know:
* - LLint means "Low Level Interpreter", which is the interpreter that runs before any JIT compilation
* - Baseline is the first JIT compilation tier. It's the least optimized, but the fastest to compile
* - DFG means "Data Flow Graph", which is the second JIT compilation tier. It has some optimizations, but is slower to compile
* - FTL means "Faster Than Light", which is the third JIT compilation tier. It has the most optimizations, but is the slowest to compile
*/
function profile(
callback: CallableFunction,
sampleInterval?: number,
): {
/**
* A formatted summary of the top functions
*
@@ -169,24 +183,7 @@ declare module "bun:jsc" {
* Stack traces of the top functions
*/
stackTraces: string[];
}
/**
* Run JavaScriptCore's sampling profiler for a particular function
*
* This is pretty low-level.
*
* Things to know:
* - LLint means "Low Level Interpreter", which is the interpreter that runs before any JIT compilation
* - Baseline is the first JIT compilation tier. It's the least optimized, but the fastest to compile
* - DFG means "Data Flow Graph", which is the second JIT compilation tier. It has some optimizations, but is slower to compile
* - FTL means "Faster Than Light", which is the third JIT compilation tier. It has the most optimizations, but is the slowest to compile
*/
function profile<T extends (...args: any[]) => any>(
callback: T,
sampleInterval?: number,
...args: Parameters<T>
): ReturnType<T> extends Promise<infer U> ? Promise<SamplingProfile> : SamplingProfile;
};
/**
* This returns objects which native code has explicitly protected from being

View File

@@ -36,7 +36,7 @@ declare module "bun:sqlite" {
* ```ts
* const db = new Database("mydb.sqlite");
* db.run("CREATE TABLE foo (bar TEXT)");
* db.run("INSERT INTO foo VALUES (?)", ["baz"]);
* db.run("INSERT INTO foo VALUES (?)", "baz");
* console.log(db.query("SELECT * FROM foo").all());
* ```
*
@@ -47,7 +47,7 @@ declare module "bun:sqlite" {
* ```ts
* const db = new Database(":memory:");
* db.run("CREATE TABLE foo (bar TEXT)");
* db.run("INSERT INTO foo VALUES (?)", ["hiiiiii"]);
* db.run("INSERT INTO foo VALUES (?)", "hiiiiii");
* console.log(db.query("SELECT * FROM foo").all());
* ```
*
@@ -158,7 +158,7 @@ declare module "bun:sqlite" {
* @example
* ```ts
* db.run("CREATE TABLE foo (bar TEXT)");
* db.run("INSERT INTO foo VALUES (?)", ["baz"]);
* db.run("INSERT INTO foo VALUES (?)", "baz");
* ```
*
* Useful for queries like:
@@ -268,9 +268,9 @@ declare module "bun:sqlite" {
* @example
* ```ts
* db.run("CREATE TABLE foo (bar TEXT)");
* db.run("INSERT INTO foo VALUES (?)", ["baz"]);
* db.run("INSERT INTO foo VALUES (?)", "baz");
* db.run("BEGIN");
* db.run("INSERT INTO foo VALUES (?)", ["qux"]);
* db.run("INSERT INTO foo VALUES (?)", "qux");
* console.log(db.inTransaction());
* ```
*/

View File

@@ -42,7 +42,6 @@
#define HAS_MSGX
#endif
/* We need to emulate sendmmsg, recvmmsg on platform who don't have it */
int bsd_sendmmsg(LIBUS_SOCKET_DESCRIPTOR fd, struct udp_sendbuf* sendbuf, int flags) {
#if defined(_WIN32)// || defined(__APPLE__)
@@ -398,9 +397,7 @@ int bsd_addr_get_port(struct bsd_addr_t *addr) {
// called by dispatch_ready_poll
LIBUS_SOCKET_DESCRIPTOR bsd_accept_socket(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd_addr_t *addr) {
LIBUS_SOCKET_DESCRIPTOR accepted_fd;
while (1) {
addr->len = sizeof(addr->mem);
addr->len = sizeof(addr->mem);
#if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
// Linux, FreeBSD
@@ -408,18 +405,12 @@ LIBUS_SOCKET_DESCRIPTOR bsd_accept_socket(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd
#else
// Windows, OS X
accepted_fd = accept(fd, (struct sockaddr *) addr, &addr->len);
#endif
if (UNLIKELY(IS_EINTR(accepted_fd))) {
continue;
}
/* We cannot rely on addr since it is not initialized if failed */
if (accepted_fd == LIBUS_SOCKET_ERROR) {
return LIBUS_SOCKET_ERROR;
}
break;
/* We cannot rely on addr since it is not initialized if failed */
if (accepted_fd == LIBUS_SOCKET_ERROR) {
return LIBUS_SOCKET_ERROR;
}
internal_finalize_bsd_addr(addr);
@@ -432,22 +423,14 @@ LIBUS_SOCKET_DESCRIPTOR bsd_accept_socket(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd
#endif
}
ssize_t bsd_recv(LIBUS_SOCKET_DESCRIPTOR fd, void *buf, int length, int flags) {
while (1) {
ssize_t ret = recv(fd, buf, length, flags);
if (UNLIKELY(IS_EINTR(ret))) {
continue;
}
return ret;
}
int bsd_recv(LIBUS_SOCKET_DESCRIPTOR fd, void *buf, int length, int flags) {
return recv(fd, buf, length, flags);
}
#if !defined(_WIN32)
#include <sys/uio.h>
ssize_t bsd_write2(LIBUS_SOCKET_DESCRIPTOR fd, const char *header, int header_length, const char *payload, int payload_length) {
int bsd_write2(LIBUS_SOCKET_DESCRIPTOR fd, const char *header, int header_length, const char *payload, int payload_length) {
struct iovec chunks[2];
chunks[0].iov_base = (char *)header;
@@ -455,21 +438,13 @@ ssize_t bsd_write2(LIBUS_SOCKET_DESCRIPTOR fd, const char *header, int header_le
chunks[1].iov_base = (char *)payload;
chunks[1].iov_len = payload_length;
while (1) {
ssize_t written = writev(fd, chunks, 2);
if (UNLIKELY(IS_EINTR(written))) {
continue;
}
return written;
}
return writev(fd, chunks, 2);
}
#else
ssize_t bsd_write2(LIBUS_SOCKET_DESCRIPTOR fd, const char *header, int header_length, const char *payload, int payload_length) {
ssize_t written = bsd_send(fd, header, header_length, 0);
int bsd_write2(LIBUS_SOCKET_DESCRIPTOR fd, const char *header, int header_length, const char *payload, int payload_length) {
int written = bsd_send(fd, header, header_length, 0);
if (written == header_length) {
ssize_t second_write = bsd_send(fd, payload, payload_length, 0);
int second_write = bsd_send(fd, payload, payload_length, 0);
if (second_write > 0) {
written += second_write;
}
@@ -478,28 +453,26 @@ ssize_t bsd_write2(LIBUS_SOCKET_DESCRIPTOR fd, const char *header, int header_le
}
#endif
ssize_t bsd_send(LIBUS_SOCKET_DESCRIPTOR fd, const char *buf, int length, int msg_more) {
while (1) {
int bsd_send(LIBUS_SOCKET_DESCRIPTOR fd, const char *buf, int length, int msg_more) {
// MSG_MORE (Linux), MSG_PARTIAL (Windows), TCP_NOPUSH (BSD)
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
#ifdef MSG_MORE
// for Linux we do not want signals
ssize_t rc = send(fd, buf, length, ((msg_more != 0) * MSG_MORE) | MSG_NOSIGNAL | MSG_DONTWAIT);
#else
// use TCP_NOPUSH
ssize_t rc = send(fd, buf, length, MSG_NOSIGNAL | MSG_DONTWAIT);
#endif
#ifdef MSG_MORE
if (UNLIKELY(IS_EINTR(rc))) {
continue;
}
// for Linux we do not want signals
return send(fd, buf, length, ((msg_more != 0) * MSG_MORE) | MSG_NOSIGNAL | MSG_DONTWAIT);
return rc;
}
#else
// use TCP_NOPUSH
return send(fd, buf, length, MSG_NOSIGNAL | MSG_DONTWAIT);
#endif
}
int bsd_would_block() {
@@ -510,23 +483,6 @@ int bsd_would_block() {
#endif
}
static int us_internal_bind_and_listen(LIBUS_SOCKET_DESCRIPTOR listenFd, struct sockaddr *listenAddr, socklen_t listenAddrLength, int backlog) {
int result;
do
result = bind(listenFd, listenAddr, listenAddrLength);
while (IS_EINTR(result));
if (result == -1) {
return -1;
}
do
result = listen(listenFd, backlog);
while (IS_EINTR(result));
return result;
}
inline __attribute__((always_inline)) LIBUS_SOCKET_DESCRIPTOR bsd_bind_listen_fd(
LIBUS_SOCKET_DESCRIPTOR listenFd,
struct addrinfo *listenAddr,
@@ -556,7 +512,7 @@ inline __attribute__((always_inline)) LIBUS_SOCKET_DESCRIPTOR bsd_bind_listen_fd
setsockopt(listenFd, IPPROTO_IPV6, IPV6_V6ONLY, (void *) &disabled, sizeof(disabled));
#endif
if (us_internal_bind_and_listen(listenFd, listenAddr->ai_addr, (socklen_t) listenAddr->ai_addrlen, 512)) {
if (bind(listenFd, listenAddr->ai_addr, (socklen_t) listenAddr->ai_addrlen) || listen(listenFd, 512)) {
return LIBUS_SOCKET_ERROR;
}
@@ -734,7 +690,7 @@ static LIBUS_SOCKET_DESCRIPTOR internal_bsd_create_listen_socket_unix(const char
unlink(path);
#endif
if (us_internal_bind_and_listen(listenFd, (struct sockaddr *) server_address, (socklen_t) addrlen, 512)) {
if (bind(listenFd, (struct sockaddr *)server_address, addrlen) || listen(listenFd, 512)) {
#if defined(_WIN32)
int shouldSimulateENOENT = WSAGetLastError() == WSAENETDOWN;
#endif
@@ -882,7 +838,7 @@ int bsd_connect_udp_socket(LIBUS_SOCKET_DESCRIPTOR fd, const char *host, int por
}
freeaddrinfo(result);
return (int)LIBUS_SOCKET_ERROR;
return LIBUS_SOCKET_ERROR;
}
int bsd_disconnect_udp_socket(LIBUS_SOCKET_DESCRIPTOR fd) {
@@ -969,7 +925,7 @@ static int bsd_do_connect_raw(LIBUS_SOCKET_DESCRIPTOR fd, struct sockaddr *addr,
do {
errno = 0;
r = connect(fd, (struct sockaddr *)addr, namelen);
} while (IS_EINTR(r));
} while (r == -1 && errno == EINTR);
// connect() can return -1 with an errno of 0.
// the errno is the correct one in that case.

View File

@@ -1740,20 +1740,15 @@ void us_internal_ssl_socket_shutdown(struct us_internal_ssl_socket_t *s) {
loop_ssl_data->ssl_socket = &s->s;
loop_ssl_data->msg_more = 0;
// sets SSL_SENT_SHUTDOWN no matter what (not actually true if error!)
int ret = SSL_shutdown(s->ssl);
if (ret == 0) {
ret = SSL_shutdown(s->ssl);
}
if (SSL_in_init(s->ssl) || SSL_get_quiet_shutdown(s->ssl)) {
// when SSL_in_init or quiet shutdown in BoringSSL, we call shutdown
// directly
us_socket_shutdown(0, &s->s);
return;
}
if (ret < 0) {
int err = SSL_get_error(s->ssl, ret);
if (err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL) {
// clear

View File

@@ -109,51 +109,6 @@ struct us_loop_t *us_timer_loop(struct us_timer_t *t) {
return internal_cb->loop;
}
#if defined(LIBUS_USE_EPOLL)
#include <sys/syscall.h>
static int has_epoll_pwait2 = -1;
#ifndef SYS_epoll_pwait2
// It's consistent on multiple architectures
// https://github.com/torvalds/linux/blob/9d1ddab261f3e2af7c384dc02238784ce0cf9f98/include/uapi/asm-generic/unistd.h#L795
// https://github.com/google/gvisor/blob/master/test/syscalls/linux/epoll.cc#L48C1-L50C7
#define SYS_epoll_pwait2 441
#endif
static ssize_t sys_epoll_pwait2(int epfd, struct epoll_event *events, int maxevents, const struct timespec *timeout, const sigset_t *sigmask, size_t sigsetsize) {
return syscall(SYS_epoll_pwait2, epfd, events, maxevents, timeout, sigmask, sigsetsize);
}
static int bun_epoll_pwait2(int epfd, struct epoll_event *events, int maxevents, const struct timespec *timeout) {
int ret;
if (has_epoll_pwait2 != 0) {
do {
ret = sys_epoll_pwait2(epfd, events, maxevents, timeout, NULL, 0);
} while (IS_EINTR(ret));
if (LIKELY(ret != -1 || errno != ENOSYS)) {
return ret;
}
has_epoll_pwait2 = 0;
}
int timeoutMs = -1;
if (timeout) {
timeoutMs = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000;
}
do {
ret = epoll_wait(epfd, events, maxevents, timeoutMs);
} while (IS_EINTR(ret));
return ret;
}
#endif
/* Loop */
struct us_loop_t *us_create_loop(void *hint, void (*wakeup_cb)(struct us_loop_t *loop), void (*pre_cb)(struct us_loop_t *loop), void (*post_cb)(struct us_loop_t *loop), unsigned int ext_size) {
struct us_loop_t *loop = (struct us_loop_t *) us_calloc(1, sizeof(struct us_loop_t) + ext_size);
@@ -184,11 +139,9 @@ void us_loop_run(struct us_loop_t *loop) {
/* Fetch ready polls */
#ifdef LIBUS_USE_EPOLL
loop->num_ready_polls = bun_epoll_pwait2(loop->fd, loop->ready_polls, 1024, NULL);
loop->num_ready_polls = epoll_wait(loop->fd, loop->ready_polls, 1024, -1);
#else
do {
loop->num_ready_polls = kevent64(loop->fd, NULL, 0, loop->ready_polls, 1024, 0, NULL);
} while (IS_EINTR(loop->num_ready_polls));
loop->num_ready_polls = kevent64(loop->fd, NULL, 0, loop->ready_polls, 1024, 0, NULL);
#endif
/* Iterate ready polls, dispatching them by type */
@@ -230,6 +183,12 @@ void us_loop_run(struct us_loop_t *loop) {
}
}
#if defined(LIBUS_USE_EPOLL)
// static int has_epoll_pwait2 = 0;
// TODO:
#endif
void us_loop_run_bun_tick(struct us_loop_t *loop, const struct timespec* timeout) {
if (loop->num_polls == 0)
@@ -248,12 +207,13 @@ void us_loop_run_bun_tick(struct us_loop_t *loop, const struct timespec* timeout
/* Fetch ready polls */
#ifdef LIBUS_USE_EPOLL
loop->num_ready_polls = bun_epoll_pwait2(loop->fd, loop->ready_polls, 1024, timeout);
int timeoutMs = -1;
if (timeout) {
timeoutMs = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000;
}
loop->num_ready_polls = epoll_wait(loop->fd, loop->ready_polls, 1024, timeoutMs);
#else
do {
loop->num_ready_polls = kevent64(loop->fd, NULL, 0, loop->ready_polls, 1024, 0, timeout);
} while (IS_EINTR(loop->num_ready_polls));
loop->num_ready_polls = kevent64(loop->fd, NULL, 0, loop->ready_polls, 1024, 0, timeout);
#endif
/* Iterate ready polls, dispatching them by type */
@@ -336,10 +296,7 @@ int kqueue_change(int kqfd, int fd, int old_events, int new_events, void *user_d
EV_SET64(&change_list[change_length++], fd, EVFILT_WRITE, (new_events & LIBUS_SOCKET_WRITABLE) ? EV_ADD : EV_DELETE, 0, 0, (uint64_t)(void*)user_data, 0, 0);
}
int ret;
do {
ret = kevent64(kqfd, change_list, change_length, change_list, change_length, KEVENT_FLAG_ERROR_EVENTS, NULL);
} while (IS_EINTR(ret));
int ret = kevent64(kqfd, change_list, change_length, change_list, change_length, KEVENT_FLAG_ERROR_EVENTS, NULL);
// ret should be 0 in most cases (not guaranteed when removing async)
@@ -375,10 +332,7 @@ void us_poll_start(struct us_poll_t *p, struct us_loop_t *loop, int events) {
struct epoll_event event;
event.events = events;
event.data.ptr = p;
int ret;
do {
ret = epoll_ctl(loop->fd, EPOLL_CTL_ADD, p->state.fd, &event);
} while (IS_EINTR(ret));
epoll_ctl(loop->fd, EPOLL_CTL_ADD, p->state.fd, &event);
#else
kqueue_change(loop->fd, p->state.fd, 0, events, p);
#endif
@@ -394,10 +348,7 @@ void us_poll_change(struct us_poll_t *p, struct us_loop_t *loop, int events) {
struct epoll_event event;
event.events = events;
event.data.ptr = p;
int rc;
do {
rc = epoll_ctl(loop->fd, EPOLL_CTL_MOD, p->state.fd, &event);
} while (IS_EINTR(rc));
epoll_ctl(loop->fd, EPOLL_CTL_MOD, p->state.fd, &event);
#else
kqueue_change(loop->fd, p->state.fd, old_events, events, p);
#endif
@@ -411,10 +362,7 @@ void us_poll_stop(struct us_poll_t *p, struct us_loop_t *loop) {
int new_events = 0;
#ifdef LIBUS_USE_EPOLL
struct epoll_event event;
int rc;
do {
rc = epoll_ctl(loop->fd, EPOLL_CTL_DEL, p->state.fd, &event);
} while (IS_EINTR(rc));
epoll_ctl(loop->fd, EPOLL_CTL_DEL, p->state.fd, &event);
#else
if (old_events) {
kqueue_change(loop->fd, p->state.fd, old_events, new_events, NULL);
@@ -425,14 +373,12 @@ void us_poll_stop(struct us_poll_t *p, struct us_loop_t *loop) {
us_internal_loop_update_pending_ready_polls(loop, p, 0, old_events, new_events);
}
size_t us_internal_accept_poll_event(struct us_poll_t *p) {
unsigned int us_internal_accept_poll_event(struct us_poll_t *p) {
#ifdef LIBUS_USE_EPOLL
int fd = us_poll_fd(p);
uint64_t buf;
ssize_t read_length = 0;
do {
read_length = read(fd, &buf, 8);
} while (IS_EINTR(read_length));
int read_length = read(fd, &buf, 8);
(void)read_length;
return buf;
#else
/* Kqueue has no underlying FD for timers or user events */
@@ -521,11 +467,7 @@ void us_timer_close(struct us_timer_t *timer, int fallthrough) {
struct kevent64_s event;
EV_SET64(&event, (uint64_t) (void*) internal_cb, EVFILT_TIMER, EV_DELETE, 0, 0, (uint64_t)internal_cb, 0, 0);
int ret;
do {
ret = kevent64(internal_cb->loop->fd, &event, 1, &event, 1, KEVENT_FLAG_ERROR_EVENTS, NULL);
} while (IS_EINTR(ret));
kevent64(internal_cb->loop->fd, &event, 1, &event, 1, KEVENT_FLAG_ERROR_EVENTS, NULL);
/* (regular) sockets are the only polls which are not freed immediately */
if(fallthrough){
@@ -544,11 +486,7 @@ void us_timer_set(struct us_timer_t *t, void (*cb)(struct us_timer_t *t), int ms
struct kevent64_s event;
uint64_t ptr = (uint64_t)(void*)internal_cb;
EV_SET64(&event, ptr, EVFILT_TIMER, EV_ADD | (repeat_ms ? 0 : EV_ONESHOT), 0, ms, (uint64_t)internal_cb, 0, 0);
int ret;
do {
ret = kevent64(internal_cb->loop->fd, &event, 1, &event, 1, KEVENT_FLAG_ERROR_EVENTS, NULL);
} while (IS_EINTR(ret));
kevent64(internal_cb->loop->fd, &event, 1, &event, 1, KEVENT_FLAG_ERROR_EVENTS, NULL);
}
#endif
@@ -643,11 +581,7 @@ void us_internal_async_close(struct us_internal_async *a) {
struct kevent64_s event;
uint64_t ptr = (uint64_t)(void*)internal_cb;
EV_SET64(&event, ptr, EVFILT_MACHPORT, EV_DELETE, 0, 0, (uint64_t)(void*)internal_cb, 0,0);
int ret;
do {
ret = kevent64(internal_cb->loop->fd, &event, 1, &event, 1, KEVENT_FLAG_ERROR_EVENTS, NULL);
} while (IS_EINTR(ret));
kevent64(internal_cb->loop->fd, &event, 1, &event, 1, KEVENT_FLAG_ERROR_EVENTS, NULL);
mach_port_deallocate(mach_task_self(), internal_cb->port);
us_free(internal_cb->machport_buf);
@@ -675,10 +609,7 @@ void us_internal_async_set(struct us_internal_async *a, void (*cb)(struct us_int
event.ext[1] = MACHPORT_BUF_LEN;
event.udata = (uint64_t)(void*)internal_cb;
int ret;
do {
ret = kevent64(internal_cb->loop->fd, &event, 1, &event, 1, KEVENT_FLAG_ERROR_EVENTS, NULL);
} while (IS_EINTR(ret));
int ret = kevent64(internal_cb->loop->fd, &event, 1, &event, 1, KEVENT_FLAG_ERROR_EVENTS, NULL);
if (UNLIKELY(ret == -1)) {
abort();

View File

@@ -125,7 +125,7 @@ int us_poll_events(struct us_poll_t *p) {
((p->poll_type & POLL_TYPE_POLLING_OUT) ? LIBUS_SOCKET_WRITABLE : 0);
}
size_t us_internal_accept_poll_event(struct us_poll_t *p) { return 0; }
unsigned int us_internal_accept_poll_event(struct us_poll_t *p) { return 0; }
int us_internal_poll_type(struct us_poll_t *p) { return p->poll_type & POLL_TYPE_KIND_MASK; }

View File

@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#ifndef INTERNAL_H
#define INTERNAL_H
@@ -22,10 +22,6 @@
#ifndef __cplusplus
#define alignas(x) __declspec(align(x))
#endif
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#else
#include <stdalign.h>
#endif
@@ -56,17 +52,6 @@ void us_internal_loop_update_pending_ready_polls(struct us_loop_t *loop,
#include "internal/eventing/libuv.h"
#endif
#ifndef LIKELY
#define LIKELY(cond) __builtin_expect((_Bool)(cond), 1)
#define UNLIKELY(cond) __builtin_expect((_Bool)(cond), 0)
#endif
#ifdef _WIN32
#define IS_EINTR(rc) (rc == SOCKET_ERROR && WSAGetLastError() == WSAEINTR)
#else
#define IS_EINTR(rc) (rc == -1 && errno == EINTR)
#endif
/* Poll type and what it polls for */
enum {
/* Three first bits */
@@ -133,7 +118,7 @@ void us_internal_async_set(struct us_internal_async *a,
void us_internal_async_wakeup(struct us_internal_async *a);
/* Eventing related */
size_t us_internal_accept_poll_event(struct us_poll_t *p);
unsigned int us_internal_accept_poll_event(struct us_poll_t *p);
int us_internal_poll_type(struct us_poll_t *p);
void us_internal_poll_set_type(struct us_poll_t *p, int poll_type);

View File

@@ -134,9 +134,9 @@ int bsd_addr_get_port(struct bsd_addr_t *addr);
// called by dispatch_ready_poll
LIBUS_SOCKET_DESCRIPTOR bsd_accept_socket(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd_addr_t *addr);
ssize_t bsd_recv(LIBUS_SOCKET_DESCRIPTOR fd, void *buf, int length, int flags);
ssize_t bsd_send(LIBUS_SOCKET_DESCRIPTOR fd, const char *buf, int length, int msg_more);
ssize_t bsd_write2(LIBUS_SOCKET_DESCRIPTOR fd, const char *header, int header_length, const char *payload, int payload_length);
int bsd_recv(LIBUS_SOCKET_DESCRIPTOR fd, void *buf, int length, int flags);
int bsd_send(LIBUS_SOCKET_DESCRIPTOR fd, const char *buf, int length, int msg_more);
int bsd_write2(LIBUS_SOCKET_DESCRIPTOR fd, const char *header, int header_length, const char *payload, int payload_length);
int bsd_would_block();
// return LIBUS_SOCKET_ERROR or the fd that represents listen socket

View File

@@ -75,6 +75,14 @@ public:
void writeMark() {
/* Date is always written */
writeHeader("Date", std::string_view(((LoopData *) us_loop_ext(us_socket_context_loop(SSL, (us_socket_context(SSL, (us_socket_t *) this)))))->date, 29));
/* You can disable this altogether */
// #ifndef UWS_HTTPRESPONSE_NO_WRITEMARK
// if (!Super::getLoopData()->noMark) {
// /* We only expose major version */
// writeHeader("uWebSockets", "20");
// }
// #endif
}
/* Returns true on success, indicating that it might be feasible to write more data.
@@ -580,19 +588,7 @@ public:
httpResponseData->onAborted = std::move(handler);
return this;
}
HttpResponse* clearOnWritableAndAborted() {
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
httpResponseData->onWritable = nullptr;
httpResponseData->onAborted = nullptr;
return this;
}
HttpResponse* clearOnAborted() {
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
httpResponseData->onAborted = nullptr;
return this;
}
/* Attach a read handler for data sent. Will be called with FIN set true if last segment. */
void onData(MoveOnlyFunction<void(std::string_view, bool)> &&handler) {
HttpResponseData<SSL> *data = getHttpResponseData();

View File

@@ -95,14 +95,13 @@ private:
// This is both a performance thing, and also to prevent freeing some things which are not meant to be freed
// such as uv_tty_t
if(loop && cleanMe && !bun_is_exiting()) {
cleanMe = false;
loop->free();
}
}
Loop *loop = nullptr;
bool cleanMe = false;
};
static LoopCleaner &getLazyLoop() {
static thread_local LoopCleaner lazyLoop;
return lazyLoop;
@@ -127,12 +126,6 @@ public:
return getLazyLoop().loop;
}
static void clearLoopAtThreadExit() {
if (getLazyLoop().cleanMe) {
getLazyLoop().loop->free();
}
}
/* Freeing the default loop should be done once */
void free() {
LoopData *loopData = (LoopData *) us_loop_ext((us_loop_t *) this);

View File

@@ -6,7 +6,7 @@ cd $BUN_DEPS_DIR/boringssl
mkdir -p build
cd build
cmake "${CMAKE_FLAGS[@]}" -GNinja ..
cmake "${CMAKE_FLAGS[@]}" -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" -GNinja ..
ninja libcrypto.a libssl.a libdecrepit.a
cp **/libcrypto.a $BUN_DEPS_OUT_DIR/libcrypto.a

View File

@@ -1,12 +1,10 @@
#!/usr/bin/env bash
set -exo pipefail
export FORCE_PIC=1
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
cd $BUN_DEPS_DIR/c-ares
rm -rf build CMakeCache.txt CMakeFiles
rm -rf build
mkdir -p build
cd build
@@ -14,9 +12,8 @@ cd build
cmake "${CMAKE_FLAGS[@]}" .. \
-DCMAKE_INSTALL_LIBDIR=lib \
-DCARES_STATIC=ON \
-DCARES_STATIC_PIC=OFF \
-DCARES_STATIC_PIC=ON \
-DCARES_SHARED=OFF \
-DCARES_BUILD_TOOLS=ON \
-G "Ninja"
ninja

View File

@@ -1,6 +1,5 @@
#!/usr/bin/env bash
set -exo pipefail
export FORCE_PIC=1
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
mkdir -p $BUN_DEPS_OUT_DIR

View File

@@ -2,11 +2,11 @@
set -exo pipefail
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
rm -rf CMakeFiles CMakeCache build.ninja
mkdir -p $BUN_DEPS_OUT_DIR
cd $BUN_DEPS_DIR/ls-hpack
rm -rf CMakeCache* CMakeFiles
cmake "${CMAKE_FLAGS[@]}" . \
@@ -15,6 +15,6 @@ cmake "${CMAKE_FLAGS[@]}" . \
-DSHARED=0 \
-GNinja
ninja libls-hpack.a
ninja
cp ./libls-hpack.a $BUN_DEPS_OUT_DIR/liblshpack.a

View File

@@ -22,8 +22,9 @@ try {
$Baseline = $env:BUN_DEV_ENV_SET -eq "Baseline=True"
Run clang-cl @($env:CFLAGS -split ' ') libtcc.c -o tcc.obj "-DTCC_TARGET_PE" "-DTCC_TARGET_X86_64" "-O2" "-W2" "-Zi" "-MD" "-GS-" "-c" "-MT"
Run llvm-lib "tcc.obj" "-OUT:tcc.lib"
# TODO: -MT
Run clang-cl @($env:CFLAGS -split ' ') libtcc.c -o tcc.obj "-DTCC_TARGET_PE" "-DTCC_TARGET_X86_64" "-O2" "-W2" "-Zi" "-MD" "-GS-" "-c"
Run lib "tcc.obj" "-OUT:tcc.lib"
Copy-Item tcc.obj $BUN_DEPS_OUT_DIR/tcc.lib

View File

@@ -4,9 +4,10 @@ source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
mkdir -p $BUN_DEPS_OUT_DIR
cd $BUN_DEPS_DIR/zlib
rm -rf build
mkdir build
cd build
cmake $CMAKE_FLAGS -G Ninja -DCMAKE_BUILD_TYPE=Release ..
ninja
export CFLAGS="-O3"
if [[ $(uname -s) == 'Darwin' ]]; then
export CFLAGS="$CFLAGS -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}"
fi
CFLAGS="${CFLAGS}" ./configure --static
make -j${CPUS}
cp ./libz.a $BUN_DEPS_OUT_DIR/libz.a

View File

@@ -3,10 +3,9 @@ $ErrorActionPreference = 'Stop' # Setting strict mode, similar to 'set -euo pip
Push-Location (Join-Path $BUN_DEPS_DIR 'zstd')
try {
Remove-Item CMakeCache.txt, CMakeFiles -Recurse -ErrorAction SilentlyContinue
Remove-Item CMakeCache.txt -ErrorAction SilentlyContinue
# CL_SHOWINCLUDES_PREFIX is workaround for cmake bug in 3.28. .ninja_deps still needs to be deleted. Bug is fixed in 3.30
Run cmake -S "build/cmake" @CMAKE_FLAGS -DZSTD_BUILD_STATIC=ON -DCMAKE_CL_SHOWINCLUDES_PREFIX="Note: including file:"
Run cmake -S "build/cmake" @CMAKE_FLAGS -DZSTD_BUILD_STATIC=ON
Run cmake --build . --clean-first --config Release
Copy-Item lib/zstd_static.lib $BUN_DEPS_OUT_DIR/zstd.lib

View File

@@ -7,5 +7,5 @@ mkdir -p $BUN_DEPS_OUT_DIR
cd $BUN_DEPS_DIR/zstd
rm -rf Release CMakeCache.txt CMakeFiles
cmake "${CMAKE_FLAGS[@]}" -DZSTD_BUILD_STATIC=ON -B Release -S build/cmake -G Ninja
ninja libzstd_static -C Release
ninja -C Release
cp Release/lib/libzstd.a $BUN_DEPS_OUT_DIR/libzstd.a

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,9 @@ if ($env:VSINSTALLDIR -eq $null) {
}
Push-Location $vsDir
try {
Import-Module 'C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\Tools\Microsoft.VisualStudio.DevShell.dll'
Enter-VsDevShell -VsInstallPath 'C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools' -DevCmdArguments '-arch=x64 -host_arch=x64'
} catch {
$launchps = (Join-Path -Path $vsDir -ChildPath "Common7\Tools\Launch-VsDevShell.ps1")
. $launchps -Arch amd64 -HostArch amd64
} finally { Pop-Location }
@@ -49,13 +52,10 @@ $CPUS = if ($env:CPUS) { $env:CPUS } else { (Get-CimInstance -Class Win32_Proces
$CC = "clang-cl"
$CXX = "clang-cl"
$CFLAGS = '/O2 /Z7 /MT /O2 /Ob2 /DNDEBUG /U_DLL'
$CXXFLAGS = '/O2 /Z7 /MT /O2 /Ob2 /DNDEBUG /U_DLL'
if ($env:USE_LTO -eq "1") {
$CXXFLAGS += " -fuse-ld=lld -flto -Xclang -emit-llvm-bc"
$CFLAGS += " -fuse-ld=lld -flto -Xclang -emit-llvm-bc"
}
$CFLAGS = '/O2 /Zi'
# $CFLAGS = '/O2 /Z7 /MT'
$CXXFLAGS = '/O2 /Zi'
# $CXXFLAGS = '/O2 /Z7 /MT'
$CPU_NAME = if ($Baseline) { "nehalem" } else { "haswell" };
$env:CPU_TARGET = $CPU_NAME
@@ -69,20 +69,8 @@ $CMAKE_FLAGS = @(
"-DCMAKE_C_COMPILER=$CC",
"-DCMAKE_CXX_COMPILER=$CXX",
"-DCMAKE_C_FLAGS=$CFLAGS",
"-DCMAKE_CXX_FLAGS=$CXXFLAGS",
"-DCMAKE_C_FLAGS_RELEASE=$CFLAGS",
"-DCMAKE_CXX_FLAGS_RELEASE=$CXXFLAGS",
"-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded"
"-DCMAKE_CXX_FLAGS=$CXXFLAGS"
)
if ($env:USE_LTO -eq "1") {
if (Get-Command lld-lib -ErrorAction SilentlyContinue) {
$AR = Get-Command lld-lib -ErrorAction SilentlyContinue
$env:AR = $AR
$CMAKE_FLAGS += "-DCMAKE_AR=$AR"
}
}
$env:CC = "clang-cl"
$env:CXX = "clang-cl"
$env:CFLAGS = $CFLAGS

View File

@@ -7,12 +7,6 @@ if [[ "${CI:-}" == "1" || "${CI:-}" == "true" ]]; then
fi
fi
if [[ $(uname -s) == 'Darwin' ]]; then
export LLVM_VERSION=18
else
export LLVM_VERSION=16
fi
# this is the environment script for building bun's dependencies
# it sets c compiler and flags
export SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
@@ -24,74 +18,17 @@ export BUN_DEPS_OUT_DIR=${BUN_DEPS_OUT_DIR:-$BUN_BASE_DIR/build/bun-deps}
export LC_CTYPE="en_US.UTF-8"
export LC_ALL="en_US.UTF-8"
if [[ "$CI" != "1" && "$CI" != "true" ]]; then
if [ -f $SCRIPT_DIR/env.local ]; then
echo "Sourcing $SCRIPT_DIR/env.local"
source $SCRIPT_DIR/env.local
fi
elif [[ $(uname -s) == 'Darwin' ]]; then
export CXX="$(brew --prefix llvm)@$LLVM_VERSION/bin/clang++"
export CC="$(brew --prefix llvm)@$LLVM_VERSION/bin/clang"
export AR="$(brew --prefix llvm)@$LLVM_VERSION/bin/llvm-ar"
export RANLIB="$(brew --prefix llvm)@$LLVM_VERSION/bin/llvm-ranlib"
export LIBTOOL="$(brew --prefix llvm)@$LLVM_VERSION/bin/llvm-libtool-darwin"
export PATH="$(brew --prefix llvm)@$LLVM_VERSION/bin:$PATH"
ln -sf $LIBTOOL "$(brew --prefix llvm)@$LLVM_VERSION/bin/libtool" || true
fi
# this compiler detection could be better
export CC=${CC:-$(which clang-$LLVM_VERSION || which clang || which cc)}
export CXX=${CXX:-$(which clang++-$LLVM_VERSION || which clang++ || which c++)}
export CC=${CC:-$(which clang-16 || which clang || which cc)}
export CXX=${CXX:-$(which clang++-16 || which clang++ || which c++)}
export AR=${AR:-$(which llvm-ar || which ar)}
export CPUS=${CPUS:-$(nproc || sysctl -n hw.ncpu || echo 1)}
export RANLIB=${RANLIB:-$(which llvm-ranlib-$LLVM_VERSION || which llvm-ranlib || which ranlib)}
# on Linux, force using lld as the linker
if [[ $(uname -s) == 'Linux' ]]; then
export LD=${LD:-$(which ld.lld-$LLVM_VERSION || which ld.lld || which ld)}
export LDFLAGS="${LDFLAGS} -fuse-ld=lld "
fi
export CMAKE_CXX_COMPILER=${CXX}
export CMAKE_C_COMPILER=${CC}
export CFLAGS='-O3 -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables '
export CXXFLAGS='-O3 -fno-exceptions -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-c++-static-destructors '
# Add flags for LTO
# We cannot enable LTO on macOS for dependencies because it requires -fuse-ld=lld and lld causes many segfaults on macOS (likely related to stack size)
if [ "$BUN_ENABLE_LTO" == "1" ]; then
export CFLAGS="$CFLAGS -flto=full "
export CXXFLAGS="$CXXFLAGS -flto=full -fwhole-program-vtables -fforce-emit-vtables "
export LDFLAGS="$LDFLAGS -flto=full -fwhole-program-vtables -fforce-emit-vtables "
fi
if [[ $(uname -s) == 'Linux' ]]; then
export CFLAGS="$CFLAGS -ffunction-sections -fdata-sections -faddrsig "
export CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections -faddrsig "
export LDFLAGS="${LDFLAGS} -Wl,-z,norelro"
fi
# Clang 18 on macOS needs to have -fno-define-target-os-macros to fix a zlib build issue
# https://gitlab.kitware.com/cmake/cmake/-/issues/25755
if [[ $(uname -s) == 'Darwin' && $LLVM_VERSION == '18' ]]; then
export CFLAGS="$CFLAGS -fno-define-target-os-macros "
export CXXFLAGS="$CXXFLAGS -fno-define-target-os-macros "
fi
# libarchive needs position-independent executables to compile successfully
if [ -n "$FORCE_PIC" ]; then
export CFLAGS="$CFLAGS -fPIC "
export CXXFLAGS="$CXXFLAGS -fPIC "
elif [[ $(uname -s) == 'Linux' ]]; then
export CFLAGS="$CFLAGS -fno-pie -fno-pic "
export CXXFLAGS="$CXXFLAGS -fno-pie -fno-pic "
fi
if [[ $(uname -s) == 'Linux' && ($(uname -m) == 'aarch64' || $(uname -m) == 'arm64') ]]; then
export CFLAGS="$CFLAGS -march=armv8-a+crc -mtune=ampere1 "
export CXXFLAGS="$CXXFLAGS -march=armv8-a+crc -mtune=ampere1 "
fi
export CFLAGS='-O3 -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer'
export CXXFLAGS='-O3 -fno-exceptions -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer'
export CMAKE_FLAGS=(
-DCMAKE_C_COMPILER="${CC}"
@@ -106,7 +43,7 @@ export CMAKE_FLAGS=(
)
CCACHE=$(which ccache || which sccache || echo "")
if [ -f "$CCACHE" ]; then
if [ -n "$CCACHE" ]; then
CMAKE_FLAGS+=(
-DCMAKE_C_COMPILER_LAUNCHER="$CCACHE"
-DCMAKE_CXX_COMPILER_LAUNCHER="$CCACHE"
@@ -119,22 +56,22 @@ if [[ $(uname -s) == 'Linux' ]]; then
fi
if [[ $(uname -s) == 'Darwin' ]]; then
export CMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET:-13.0}
export CMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET:-12.0}
CMAKE_FLAGS+=(-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET})
export CFLAGS="$CFLAGS -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -D__DARWIN_NON_CANCELABLE=1 "
export CXXFLAGS="$CXXFLAGS -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -D__DARWIN_NON_CANCELABLE=1 "
CMAKE_FLAGS+=(-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET})
export CFLAGS="$CFLAGS -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}"
export CXXFLAGS="$CXXFLAGS -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}"
fi
mkdir -p $BUN_DEPS_OUT_DIR
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
echo "C Compiler: ${CC}"
echo "C++ Compiler: ${CXX}"
if [ -n "$CCACHE" ]; then
echo "Ccache: ${CCACHE}"
fi
if [[ $(uname -s) == 'Darwin' ]]; then
echo "OSX Deployment Target: ${CMAKE_OSX_DEPLOYMENT_TARGET}"
fi
echo "C Compiler: ${CC}"
echo "C++ Compiler: ${CXX}"
if [ -n "$CCACHE" ]; then
echo "Ccache: ${CCACHE}"
fi
if [[ $(uname -s) == 'Darwin' ]]; then
echo "OSX Deployment Target: ${CMAKE_OSX_DEPLOYMENT_TARGET}"
fi
fi

View File

@@ -5,20 +5,11 @@ $npm_client = "npm"
$root = Join-Path (Split-Path -Path $MyInvocation.MyCommand.Definition -Parent) "..\"
# search for .cmd or .exe
function Get-Esbuild-Path {
param(
$Path
)
$Result = Join-Path $Path "node_modules\.bin\esbuild.cmd"
if (Test-Path $Result) {
return $Result
}
return Join-Path $Path "node_modules\.bin\esbuild.exe"
$esbuild = Join-Path $root "node_modules\.bin\esbuild.cmd"
if (!(Test-Path $esbuild)) {
$esbuild = Join-Path $root "node_modules\.bin\esbuild.exe"
}
$esbuild = Get-Esbuild-Path $root
$env:NODE_ENV = "production"
@@ -43,5 +34,5 @@ Pop-Location
# node-fallbacks
Push-Location src\node-fallbacks
& ${npm_client} install
& (Get-Esbuild-Path (Get-Location)) --bundle @(Get-Item .\*.js) --outdir=out --format=esm --minify --platform=browser
& ${esbuild} --bundle @(Get-Item .\*.js) --outdir=out --format=esm --minify --platform=browser
Pop-Location

View File

@@ -15,35 +15,12 @@ fail() {
printf "${C_RED}setup error${C_RESET}: %s\n" "$@"
}
if [[ $(uname -s) == 'Darwin' ]]; then
export LLVM_VERSION=18
LLVM_VERSION=16
# Use from brew --prefix if available
if has_exec brew; then
export PKG_CONFIG_PATH=$(brew --prefix)/lib/pkgconfig:$PKG_CONFIG_PATH
# if llvm@18/bin/clang exists, use it
if [ -x "$(brew --prefix)/opt/llvm@$LLVM_VERSION/bin/clang" ]; then
export PATH=$(brew --prefix)/opt/llvm@$LLVM_VERSION/bin:$PATH
export CC=$(brew --prefix)/opt/llvm@$LLVM_VERSION/bin/clang
export CXX=$(brew --prefix)/opt/llvm@$LLVM_VERSION/bin/clang++
export AR=$(brew --prefix)/opt/llvm@$LLVM_VERSION/bin/llvm-ar
else
export CC=$(which clang-$LLVM_VERSION || which clang || which cc)
export CXX=$(which clang++-$LLVM_VERSION || which clang++ || which c++)
export AR=$(which llvm-ar-$LLVM_VERSION || which llvm-ar || which ar)
fi
fi
test -n "$CC" || fail "missing LLVM $LLVM_VERSION (could not find clang)"
test -n "$CXX" || fail "missing LLVM $LLVM_VERSION (could not find clang++)"
else
export LLVM_VERSION=16
export CC=$(which clang-$LLVM_VERSION || which clang || which cc)
export CXX=$(which clang++-$LLVM_VERSION || which clang++ || which c++)
export AR=$(which llvm-ar-$LLVM_VERSION || which llvm-ar || which ar)
fi
# this compiler detection could be better
# it is copy pasted from ./env.sh
CC=${CC:-$(which clang-16 || which clang || which cc)}
CXX=${CXX:-$(which clang++-16 || which clang++ || which c++)}
test -n "$CC" || fail "missing LLVM $LLVM_VERSION (could not find clang)"
test -n "$CXX" || fail "missing LLVM $LLVM_VERSION (could not find clang++)"
@@ -59,9 +36,9 @@ has_exec "bun" || fail "you need an existing copy of 'bun' in your path to build
has_exec "cmake" || fail "'cmake' is missing"
has_exec "ninja" || fail "'ninja' is missing"
$(
has_exec "rustc" &&
(test $(cargo --version | awk '{print $2}' | cut -d. -f2) -gt 57) &&
has_exec "cargo"
has_exec "rustc" \
&& (test $(cargo --version | awk '{print $2}' | cut -d. -f2) -gt 57) \
&& has_exec "cargo"
) || fail "Rust and Cargo version must be installed (minimum version 1.57)"
has_exec "go" || fail "'go' is missing"
@@ -82,15 +59,6 @@ printf "C Compiler for dependencies: ${CC}\n"
printf "C++ Compiler for dependencies: ${CXX}\n"
cd "$(dirname "${BASH_SOURCE[0]}")"
rm -rf env.local
echo "# Environment variables as of last setup.sh run at $(date)" >env.local
echo "export CC=\"${CC}\"" >>env.local
echo "export CXX\"=${CXX}\"" >>env.local
echo "export AR=\"${AR}\"" >>env.local
echo "export PATH=\"${PATH}\"" >>env.local
echo "Saved environment variables to $(pwd)/env.local"
bash ./update-submodules.sh
bash ./all-dependencies.sh
@@ -99,9 +67,7 @@ cd ../
# Install bun dependencies
bun i
# Install test dependencies
cd test
bun i
cd ..
cd test; bun i; cd ..
# TODO(@paperdave): do not use the Makefile please
has_exec "make" || fail "'make' is missing"
@@ -115,7 +81,7 @@ cmake -B build -S . \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_CXX_COMPILER="$CXX" \
-UZIG_COMPILER "$*"
-UZIG_COMPILER "$*" \
ninja -C build

View File

@@ -1,7 +1,7 @@
#!/bin/bash
set -exo pipefail
WEBKIT_VERSION=$(grep 'set(WEBKIT_TAG' "CMakeLists.txt" | awk '{print $2}' | cut -f 1 -d ')')
WEBKIT_VERSION=$(git rev-parse HEAD:./src/bun.js/WebKit)
MIMALLOC_VERSION=$(git rev-parse HEAD:./src/deps/mimalloc)
LIBARCHIVE_VERSION=$(git rev-parse HEAD:./src/deps/libarchive)
PICOHTTPPARSER_VERSION=$(git rev-parse HEAD:./src/deps/picohttpparser)

View File

@@ -1,6 +1,5 @@
const std = @import("std");
const bun = @import("root").bun;
const assert = bun.assert;
const assert = @import("root").bun.assert;
const mem = std.mem;
const Allocator = std.mem.Allocator;

View File

@@ -171,7 +171,18 @@ pub inline fn configureAllocator(_: AllocatorConfiguration) void {
// if (!config.long_running) Mimalloc.mi_option_set(Mimalloc.mi_option_reset_delay, 0);
}
pub const panic = Output.panic; // deprecated
pub fn panic(comptime fmt: string, args: anytype) noreturn {
@setCold(true);
if (comptime Environment.isWasm) {
Output.printErrorln(fmt, args);
Output.flush();
@panic(fmt);
} else {
Output.prettyErrorln(fmt, args);
Output.flush();
std.debug.panic(fmt, args);
}
}
pub fn notimpl() noreturn {
@setCold(true);

View File

@@ -18,7 +18,7 @@ const std = @import("std");
const builtin = @import("builtin");
const windows = std.os.windows;
const testing = std.testing;
const assert = (std.debug).assert;
const assert = std.debug.assert;
const Progress = @This();
/// `null` if the current node (and its children) should
@@ -246,7 +246,7 @@ fn clearWithHeldLock(p: *Progress, end_ptr: *usize) void {
end += (std.fmt.bufPrint(p.output_buffer[end..], "\x1b[{d}D", .{p.columns_written}) catch unreachable).len;
end += (std.fmt.bufPrint(p.output_buffer[end..], "\x1b[0K", .{}) catch unreachable).len;
} else if (builtin.os.tag == .windows) winapi: {
assert(p.is_windows_terminal);
std.debug.assert(p.is_windows_terminal);
var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE) {
@@ -357,7 +357,7 @@ fn refreshWithHeldLock(self: *Progress) void {
pub fn log(self: *Progress, comptime format: []const u8, args: anytype) void {
const file = self.terminal orelse {
(std.debug).print(format, args);
std.debug.print(format, args);
return;
};
self.refresh();

View File

@@ -74,30 +74,31 @@ pub const StandaloneModuleGraph = struct {
loader: bun.options.Loader,
contents: []const u8 = "",
sourcemap: LazySourceMap,
cached_blob: ?*bun.JSC.WebCore.Blob = null,
blob_: ?*bun.JSC.WebCore.Blob = null,
pub fn blob(this: *File, globalObject: *bun.JSC.JSGlobalObject) *bun.JSC.WebCore.Blob {
if (this.cached_blob == null) {
if (this.blob_ == null) {
var store = bun.JSC.WebCore.Blob.Store.init(@constCast(this.contents), bun.default_allocator);
// make it never free
store.ref();
const b = bun.JSC.WebCore.Blob.initWithStore(store, globalObject).new();
b.allocator = bun.default_allocator;
var blob_ = bun.default_allocator.create(bun.JSC.WebCore.Blob) catch bun.outOfMemory();
blob_.* = bun.JSC.WebCore.Blob.initWithStore(store, globalObject);
blob_.allocator = bun.default_allocator;
if (bun.http.MimeType.byExtensionNoDefault(bun.strings.trimLeadingChar(std.fs.path.extension(this.name), '.'))) |mime| {
store.mime_type = mime;
b.content_type = mime.value;
b.content_type_was_set = true;
b.content_type_allocated = false;
blob_.content_type = mime.value;
blob_.content_type_was_set = true;
blob_.content_type_allocated = false;
}
store.data.bytes.stored_name = bun.PathString.init(this.name);
this.cached_blob = b;
this.blob_ = blob_;
}
return this.cached_blob.?;
return this.blob_.?;
}
};

View File

@@ -6,8 +6,7 @@ const mem = std.mem;
const math = std.math;
const testing = std.testing;
const bun = @import("root").bun;
const assert = bun.assert;
const assert = @import("root").bun.assert;
pub fn AutoHashMap(comptime K: type, comptime V: type, comptime max_load_percentage: comptime_int) type {
return HashMap(K, V, std.hash_map.AutoContext(K), max_load_percentage);

View File

@@ -101,6 +101,7 @@ pub const Features = struct {
pub var loaders: usize = 0;
pub var lockfile_migration_from_package_lock: usize = 0;
pub var macros: usize = 0;
pub var origin: usize = 0;
pub var shell: usize = 0;
pub var spawn: usize = 0;
pub var standalone_shell: usize = 0;
@@ -109,9 +110,7 @@ pub const Features = struct {
pub var tsconfig: usize = 0;
pub var virtual_modules: usize = 0;
pub var WebSocket: usize = 0;
pub var no_avx: usize = 0;
pub var no_avx2: usize = 0;
pub var binlinks: usize = 0;
pub var builtin_modules = std.enums.EnumSet(bun.JSC.HardcodedModule).initEmpty();
pub fn formatter() Formatter {

View File

@@ -1,6 +1,5 @@
const std = @import("std");
const bun = @import("root").bun;
const js_ast = bun.JSAst;
pub const Reader = struct {
const Self = @This();
@@ -1684,9 +1683,6 @@ pub const Api = struct {
/// conditions
conditions: []const []const u8,
/// packages
packages: ?PackagesMode = null,
pub fn decode(reader: anytype) anyerror!TransformOptions {
var this = std.mem.zeroes(TransformOptions);
@@ -1774,9 +1770,6 @@ pub const Api = struct {
26 => {
this.conditions = try reader.readArray([]const u8);
},
27 => {
this.packages = try reader.readValue(PackagesMode);
},
else => {
return error.InvalidMessage;
},
@@ -1892,11 +1885,6 @@ pub const Api = struct {
try writer.writeArray([]const u8, conditions);
}
if (this.packages) |packages| {
try writer.writeFieldID(27);
try writer.writeValue([]const u8, packages);
}
try writer.endMessage();
}
};
@@ -1919,20 +1907,6 @@ pub const Api = struct {
}
};
pub const PackagesMode = enum(u8) {
/// bundle
bundle,
/// external
external,
_,
pub fn jsonStringify(self: @This(), writer: anytype) !void {
return try writer.write(@tagName(self));
}
};
pub const FileHandle = struct {
/// path
path: []const u8,
@@ -2757,27 +2731,6 @@ pub const Api = struct {
/// token
token: []const u8,
pub fn dupe(this: NpmRegistry, allocator: std.mem.Allocator) NpmRegistry {
const buf = allocator.alloc(u8, this.url.len + this.username.len + this.password.len + this.token.len) catch bun.outOfMemory();
var out: NpmRegistry = .{
.url = "",
.username = "",
.password = "",
.token = "",
};
var i: usize = 0;
inline for (std.meta.fields(NpmRegistry)) |field| {
const field_value = @field(this, field.name);
@memcpy(buf[i .. i + field_value.len], field_value);
@field(&out, field.name) = buf[i .. i + field_value.len];
i += field_value.len;
}
return out;
}
pub fn decode(reader: anytype) anyerror!NpmRegistry {
var this = std.mem.zeroes(NpmRegistry);
@@ -2794,101 +2747,14 @@ pub const Api = struct {
try writer.writeValue(@TypeOf(this.password), this.password);
try writer.writeValue(@TypeOf(this.token), this.token);
}
pub const Parser = struct {
log: *bun.logger.Log,
source: *const bun.logger.Source,
allocator: std.mem.Allocator,
fn addError(this: *Parser, loc: bun.logger.Loc, comptime text: []const u8) !void {
this.log.addError(this.source, loc, text) catch unreachable;
return error.ParserError;
}
fn expectString(this: *Parser, expr: js_ast.Expr) !void {
switch (expr.data) {
.e_string, .e_utf8_string => {},
else => {
this.log.addErrorFmt(this.source, expr.loc, this.allocator, "expected string but received {}", .{
@as(js_ast.Expr.Tag, expr.data),
}) catch unreachable;
return error.ParserError;
},
}
}
pub fn parseRegistryURLString(this: *Parser, str: *js_ast.E.String) !Api.NpmRegistry {
return try this.parseRegistryURLStringImpl(str.data);
}
pub fn parseRegistryURLStringImpl(this: *Parser, str: []const u8) !Api.NpmRegistry {
const url = bun.URL.parse(str);
var registry = std.mem.zeroes(Api.NpmRegistry);
// Token
if (url.username.len == 0 and url.password.len > 0) {
registry.token = url.password;
registry.url = try std.fmt.allocPrint(this.allocator, "{s}://{}/{s}/", .{ url.displayProtocol(), url.displayHost(), std.mem.trim(u8, url.pathname, "/") });
} else if (url.username.len > 0 and url.password.len > 0) {
registry.username = url.username;
registry.password = url.password;
registry.url = try std.fmt.allocPrint(this.allocator, "{s}://{}/{s}/", .{ url.displayProtocol(), url.displayHost(), std.mem.trim(u8, url.pathname, "/") });
} else {
// Do not include a trailing slash. There might be parameters at the end.
registry.url = url.href;
}
return registry;
}
fn parseRegistryObject(this: *Parser, obj: *js_ast.E.Object) !Api.NpmRegistry {
var registry = std.mem.zeroes(Api.NpmRegistry);
if (obj.get("url")) |url| {
try this.expectString(url);
const href = url.asString(this.allocator).?;
// Do not include a trailing slash. There might be parameters at the end.
registry.url = href;
}
if (obj.get("username")) |username| {
try this.expectString(username);
registry.username = username.asString(this.allocator).?;
}
if (obj.get("password")) |password| {
try this.expectString(password);
registry.password = password.asString(this.allocator).?;
}
if (obj.get("token")) |token| {
try this.expectString(token);
registry.token = token.asString(this.allocator).?;
}
return registry;
}
pub fn parseRegistry(this: *Parser, expr: js_ast.Expr) !Api.NpmRegistry {
switch (expr.data) {
.e_string => |str| {
return this.parseRegistryURLString(str);
},
.e_object => |obj| {
return this.parseRegistryObject(obj);
},
else => {
try this.addError(expr.loc, "Expected registry to be a URL string or an object");
return std.mem.zeroes(Api.NpmRegistry);
},
}
}
};
};
pub const NpmRegistryMap = struct {
scopes: bun.StringArrayHashMapUnmanaged(NpmRegistry) = .{},
/// scopes
scopes: []const []const u8,
/// registries
registries: []const NpmRegistry,
pub fn decode(reader: anytype) anyerror!NpmRegistryMap {
var this = std.mem.zeroes(NpmRegistryMap);
@@ -2899,8 +2765,8 @@ pub const Api = struct {
}
pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
try writer.writeArray([]const u8, this.scopes.keys());
try writer.writeArray(NpmRegistry, this.scopes.values());
try writer.writeArray([]const u8, this.scopes);
try writer.writeArray(NpmRegistry, this.registries);
}
};

View File

@@ -2,10 +2,27 @@ const std = @import("std");
const bun = @import("root").bun;
const unicode = std.unicode;
pub const JavascriptString = []u16;
pub fn newJavascriptString(comptime text: []const u8) JavascriptString {
return unicode.utf8ToUtf16LeStringLiteral(text);
}
pub const NodeIndex = u32;
pub const NodeIndexNone = 4294967293;
// TODO: figure out if we actually need this
// -- original comment --
// Files are parsed in parallel for speed. We want to allow each parser to
// generate symbol IDs that won't conflict with each other. We also want to be
// able to quickly merge symbol tables from all files into one giant symbol
// table.
//
// We can accomplish both goals by giving each symbol ID two parts: a source
// index that is unique to the parser goroutine, and an inner index that
// increments as the parser generates new symbol IDs. Then a symbol map can
// be an array of arrays indexed first by source index, then by inner index.
// The maps can be merged quickly by creating a single outer array containing
// all inner arrays from all parsed files.
pub const RefHashCtx = struct {
pub fn hash(_: @This(), key: Ref) u32 {
@@ -27,6 +44,89 @@ pub const RefCtx = struct {
}
};
/// Sets the range of bits starting at `start_bit` upto and excluding `start_bit` + `number_of_bits`
/// to be specific, if the range is N bits long, the N lower bits of `value` will be used; if any of
/// the other bits in `value` are set to 1, this function will panic.
///
/// ```zig
/// var val: u8 = 0b10000000;
/// setBits(&val, 2, 4, 0b00001101);
/// try testing.expectEqual(@as(u8, 0b10110100), val);
/// ```
///
/// ## Panics
/// This method will panic if the `value` exceeds the bit range of the type of `target`
pub fn setBits(
comptime TargetType: type,
target: TargetType,
comptime start_bit: comptime_int,
comptime number_of_bits: comptime_int,
value: TargetType,
) TargetType {
const end_bit = start_bit + number_of_bits;
comptime {
if (number_of_bits == 0) @compileError("non-zero number_of_bits must be provided");
if (@typeInfo(TargetType) == .Int) {
if (@typeInfo(TargetType).Int.signedness != .unsigned) {
@compileError("requires an unsigned integer, found " ++ @typeName(TargetType));
}
if (start_bit >= @bitSizeOf(TargetType)) {
@compileError("start_bit index is out of bounds of the bit field");
}
if (end_bit > @bitSizeOf(TargetType)) {
@compileError("start_bit + number_of_bits is out of bounds of the bit field");
}
} else if (@typeInfo(TargetType) == .ComptimeInt) {
@compileError("comptime_int is unsupported");
} else {
@compileError("requires an unsigned integer, found " ++ @typeName(TargetType));
}
}
if (comptime std.debug.runtime_safety) {
if (getBits(TargetType, value, 0, (end_bit - start_bit)) != value) @panic("value exceeds bit range");
}
const bitmask: TargetType = comptime blk: {
var bitmask = ~@as(TargetType, 0);
bitmask <<= (@bitSizeOf(TargetType) - end_bit);
bitmask >>= (@bitSizeOf(TargetType) - end_bit);
bitmask >>= start_bit;
bitmask <<= start_bit;
break :blk ~bitmask;
};
return (target & bitmask) | (value << start_bit);
}
pub inline fn getBits(comptime TargetType: type, target: anytype, comptime start_bit: comptime_int, comptime number_of_bits: comptime_int) TargetType {
comptime {
if (number_of_bits == 0) @compileError("non-zero number_of_bits must be provided");
if (@typeInfo(TargetType) == .Int) {
if (@typeInfo(TargetType).Int.signedness != .unsigned) {
@compileError("requires an unsigned integer, found " ++ @typeName(TargetType));
}
if (start_bit >= @bitSizeOf(TargetType)) {
@compileError("start_bit index is out of bounds of the bit field");
}
if (start_bit + number_of_bits > @bitSizeOf(TargetType)) {
@compileError("start_bit + number_of_bits is out of bounds of the bit field");
}
} else if (@typeInfo(TargetType) == .ComptimeInt) {
if (target < 0) {
@compileError("requires an unsigned integer, found " ++ @typeName(TargetType));
}
} else {
@compileError("requires an unsigned integer, found " ++ @typeName(TargetType));
}
}
return @as(TargetType, @truncate(target >> start_bit));
}
/// In some parts of Bun, we have many different IDs pointing to different things.
/// It's easy for them to get mixed up, so we use this type to make sure we don't.
///
@@ -86,19 +186,6 @@ pub const Index = packed struct(u32) {
}
};
/// -- original comment from esbuild --
///
/// Files are parsed in parallel for speed. We want to allow each parser to
/// generate symbol IDs that won't conflict with each other. We also want to be
/// able to quickly merge symbol tables from all files into one giant symbol
/// table.
///
/// We can accomplish both goals by giving each symbol ID two parts: a source
/// index that is unique to the parser goroutine, and an inner index that
/// increments as the parser generates new symbol IDs. Then a symbol map can
/// be an array of arrays indexed first by source index, then by inner index.
/// The maps can be merged quickly by creating a single outer array containing
/// all inner arrays from all parsed files.
pub const Ref = packed struct(u64) {
inner_index: Int = 0,
@@ -111,9 +198,6 @@ pub const Ref = packed struct(u64) {
source_index: Int = 0,
/// Represents a null state without using an extra bit
pub const None = Ref{ .inner_index = 0, .source_index = 0, .tag = .invalid };
pub inline fn isEmpty(this: Ref) bool {
return this.asU64() == 0;
}
@@ -138,7 +222,7 @@ pub const Ref = packed struct(u64) {
pub fn format(ref: Ref, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
try std.fmt.format(
writer,
"Ref[inner={d}, src={d}, .{s}]",
"Ref[{d}, {d}, {s}]",
.{
ref.sourceIndex(),
ref.innerIndex(),
@@ -151,6 +235,9 @@ pub const Ref = packed struct(u64) {
return this.tag != .invalid;
}
// 2 bits of padding for whatever is the parent
pub const None = Ref{ .inner_index = 0, .source_index = 0, .tag = .invalid };
pub inline fn sourceIndex(this: Ref) Int {
return this.source_index;
}
@@ -166,7 +253,10 @@ pub const Ref = packed struct(u64) {
pub fn init(inner_index: Int, source_index: usize, is_source_contents_slice: bool) Ref {
return .{
.inner_index = inner_index,
.source_index = @intCast(source_index),
// if we overflow, we want a panic
.source_index = @as(Int, @intCast(source_index)),
.tag = if (is_source_contents_slice) .source_contents_slice else .allocated_name,
};
}
@@ -188,10 +278,9 @@ pub const Ref = packed struct(u64) {
return bun.hash(&@as([8]u8, @bitCast(key.asU64())));
}
pub fn eql(ref: Ref, other: Ref) bool {
return ref.asU64() == other.asU64();
pub fn eql(ref: Ref, b: Ref) bool {
return asU64(ref) == b.asU64();
}
pub inline fn isNull(self: Ref) bool {
return self.tag == .invalid;
}

View File

@@ -34,16 +34,6 @@ pub fn decode(destination: []u8, source: []const u8) bun.simdutf.SIMDUTFResult {
return result;
}
pub fn decodeAlloc(allocator: std.mem.Allocator, input: []const u8) ![]u8 {
var dest = try allocator.alloc(u8, decodeLen(input));
const result = decode(dest, input);
if (!result.isSuccessful()) {
allocator.free(dest);
return error.DecodingFailed;
}
return dest[0..result.count];
}
pub fn encode(destination: []u8, source: []const u8) usize {
return bun.simdutf.base64.encode(source, destination, false);
}
@@ -64,11 +54,7 @@ pub fn decodeLen(source: anytype) usize {
}
pub fn encodeLen(source: anytype) usize {
return encodeLenFromSize(source.len);
}
pub fn encodeLenFromSize(source: usize) usize {
return zig_base64.standard.Encoder.calcSize(source);
return zig_base64.standard.Encoder.calcSize(source.len);
}
pub fn urlSafeEncodeLen(source: anytype) usize {

View File

@@ -0,0 +1,64 @@
const strings = bun.strings;
const std = @import("std");
pub fn main() anyerror!void {
const args = try std.process.argsAlloc(std.heap.c_allocator);
const filepath = args[args.len - 3];
const find = args[args.len - 2];
const amount = try std.fmt.parseInt(usize, args[args.len - 1], 10);
var file = try std.fs.cwd().openFile(filepath, .{ .mode = .read_only });
var contents = try file.readToEndAlloc(std.heap.c_allocator, std.math.maxInt(usize));
var list = try std.ArrayList(u8).initCapacity(std.heap.c_allocator, contents.len);
var duped = list.items.ptr[0..contents.len];
{
var timer = try std.time.Timer.start();
var index: usize = std.math.maxInt(usize);
var j: usize = 0;
var i: usize = 0;
while (j < amount) : (j += 1) {
i = 0;
strings.copy(duped, contents);
}
if (index == std.math.maxInt(usize)) {
std.debug.print("manual [{d} byte file] {s} NOT found in {}\n", .{ contents.len, find, std.fmt.fmtDuration(timer.read()) });
} else {
std.debug.print("manual [{d} byte file] {s} found at {d} in {}\n", .{ contents.len, find, index, std.fmt.fmtDuration(timer.read()) });
}
}
{
var timer = try std.time.Timer.start();
var index: usize = std.math.maxInt(usize);
var j: usize = 0;
var i: usize = 0;
while (j < amount) : (j += 1) {
i = 0;
@memcpy(duped[0..contents.len], contents);
}
if (index == std.math.maxInt(usize)) {
std.debug.print("memcpy [{d} byte file] {s} NOT found in {}\n", .{ contents.len, find, std.fmt.fmtDuration(timer.read()) });
} else {
std.debug.print("memcpy [{d} byte file] {s} found at {d} in {}\n", .{ contents.len, find, index, std.fmt.fmtDuration(timer.read()) });
}
}
{
var timer = try std.time.Timer.start();
var index: usize = std.math.maxInt(usize);
var j: usize = 0;
var i: usize = 0;
while (j < amount) : (j += 1) {
i = 0;
list.clearRetainingCapacity();
list.appendSliceAssumeCapacity(contents);
}
if (index == std.math.maxInt(usize)) {
std.debug.print("ArrayList [{d} byte file] {s} NOT found in {}\n", .{ contents.len, find, std.fmt.fmtDuration(timer.read()) });
} else {
std.debug.print("ArrayList [{d} byte file] {s} found at {d} in {}\n", .{ contents.len, find, index, std.fmt.fmtDuration(timer.read()) });
}
}
}

View File

@@ -517,16 +517,6 @@ pub fn ArrayBitSet(comptime MaskIntType: type, comptime size: usize) type {
}
}
/// Sets all bits
pub fn setAll(self: *Self, value: bool) void {
@memset(&self.masks, if (value) std.math.maxInt(MaskInt) else 0);
// Zero the padding bits
if (num_masks > 0) {
self.masks[num_masks - 1] &= last_item_mask;
}
}
/// Performs a union of two bit sets, and stores the
/// result in the first one. Bits in the result are
/// set if the corresponding bits were set in either input.
@@ -1256,12 +1246,6 @@ pub const AutoBitSet = union(enum) {
};
}
pub fn setAll(this: *AutoBitSet, value: bool) void {
switch (this.*) {
inline else => |*bitset| bitset.setAll(value),
}
}
pub fn deinit(this: *AutoBitSet, allocator: std.mem.Allocator) void {
switch (std.meta.activeTag(this.*)) {
.static => {},

View File

@@ -11,17 +11,17 @@ const mimalloc = bun.Mimalloc;
const BrotliAllocator = struct {
pub fn alloc(_: ?*anyopaque, len: usize) callconv(.C) *anyopaque {
if (bun.heap_breakdown.enabled) {
const zone = bun.heap_breakdown.getZone(BrotliAllocator);
return zone.malloc_zone_malloc(len) orelse bun.outOfMemory();
if (comptime bun.is_heap_breakdown_enabled) {
const zone = bun.HeapBreakdown.malloc_zone_t.get(BrotliAllocator);
return zone.malloc_zone_malloc(len).?;
}
return mimalloc.mi_malloc(len) orelse bun.outOfMemory();
return mimalloc.mi_malloc(len) orelse unreachable;
}
pub fn free(_: ?*anyopaque, data: ?*anyopaque) callconv(.C) void {
if (bun.heap_breakdown.enabled) {
const zone = bun.heap_breakdown.getZone(BrotliAllocator);
if (comptime bun.is_heap_breakdown_enabled) {
const zone = bun.HeapBreakdown.malloc_zone_t.get(BrotliAllocator);
zone.malloc_zone_free(data);
return;
}

View File

@@ -22,12 +22,12 @@ pub const BuildMessage = struct {
pub fn constructor(
globalThis: *JSC.JSGlobalObject,
_: *JSC.CallFrame,
) ?*BuildMessage {
) callconv(.C) ?*BuildMessage {
globalThis.throw("BuildMessage is not constructable", .{});
return null;
}
pub fn getNotes(this: *BuildMessage, globalThis: *JSC.JSGlobalObject) JSC.JSValue {
pub fn getNotes(this: *BuildMessage, globalThis: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue {
const notes: []const logger.Data = this.msg.notes orelse &[_]logger.Data{};
const array = JSC.JSValue.createEmptyArray(globalThis, notes.len);
for (notes, 0..) |note, i| {
@@ -53,7 +53,7 @@ pub const BuildMessage = struct {
var str = ZigString.init(text);
str.setOutputEncoding();
if (str.isUTF8()) {
const out = str.toJS(globalThis);
const out = str.toValueGC(globalThis);
default_allocator.free(text);
return out;
}
@@ -81,7 +81,7 @@ pub const BuildMessage = struct {
this: *BuildMessage,
globalThis: *JSC.JSGlobalObject,
_: *JSC.CallFrame,
) JSC.JSValue {
) callconv(.C) JSC.JSValue {
return this.toStringFn(globalThis);
}
@@ -89,7 +89,7 @@ pub const BuildMessage = struct {
this: *BuildMessage,
globalThis: *JSC.JSGlobalObject,
callframe: *JSC.CallFrame,
) JSC.JSValue {
) callconv(.C) JSC.JSValue {
const args_ = callframe.arguments(1);
const args = args_.ptr[0..args_.len];
if (args.len > 0) {
@@ -110,9 +110,9 @@ pub const BuildMessage = struct {
this: *BuildMessage,
globalThis: *JSC.JSGlobalObject,
_: *JSC.CallFrame,
) JSC.JSValue {
) callconv(.C) JSC.JSValue {
var object = JSC.JSValue.createEmptyObject(globalThis, 4);
object.put(globalThis, ZigString.static("name"), ZigString.init("BuildMessage").toJS(globalThis));
object.put(globalThis, ZigString.static("name"), ZigString.init("BuildMessage").toValueGC(globalThis));
object.put(globalThis, ZigString.static("position"), this.getPosition(globalThis));
object.put(globalThis, ZigString.static("message"), this.getMessage(globalThis));
object.put(globalThis, ZigString.static("level"), this.getLevel(globalThis));
@@ -126,17 +126,17 @@ pub const BuildMessage = struct {
object.put(
globalThis,
ZigString.static("lineText"),
ZigString.init(location.line_text orelse "").toJS(globalThis),
ZigString.init(location.line_text orelse "").toValueGC(globalThis),
);
object.put(
globalThis,
ZigString.static("file"),
ZigString.init(location.file).toJS(globalThis),
ZigString.init(location.file).toValueGC(globalThis),
);
object.put(
globalThis,
ZigString.static("namespace"),
ZigString.init(location.namespace).toJS(globalThis),
ZigString.init(location.namespace).toValueGC(globalThis),
);
object.put(
globalThis,
@@ -163,7 +163,7 @@ pub const BuildMessage = struct {
}
// https://github.com/oven-sh/bun/issues/2375#issuecomment-2121530202
pub fn getColumn(this: *BuildMessage, _: *JSC.JSGlobalObject) JSC.JSValue {
pub fn getColumn(this: *BuildMessage, _: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue {
if (this.msg.data.location) |location| {
return JSC.JSValue.jsNumber(@max(location.column - 1, 0));
}
@@ -171,7 +171,7 @@ pub const BuildMessage = struct {
return JSC.JSValue.jsNumber(@as(i32, 0));
}
pub fn getLine(this: *BuildMessage, _: *JSC.JSGlobalObject) JSC.JSValue {
pub fn getLine(this: *BuildMessage, _: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue {
if (this.msg.data.location) |location| {
return JSC.JSValue.jsNumber(@max(location.line - 1, 0));
}
@@ -182,25 +182,25 @@ pub const BuildMessage = struct {
pub fn getPosition(
this: *BuildMessage,
globalThis: *JSC.JSGlobalObject,
) JSC.JSValue {
) callconv(.C) JSC.JSValue {
return BuildMessage.generatePositionObject(this.msg, globalThis);
}
pub fn getMessage(
this: *BuildMessage,
globalThis: *JSC.JSGlobalObject,
) JSC.JSValue {
return ZigString.init(this.msg.data.text).toJS(globalThis);
) callconv(.C) JSC.JSValue {
return ZigString.init(this.msg.data.text).toValueGC(globalThis);
}
pub fn getLevel(
this: *BuildMessage,
globalThis: *JSC.JSGlobalObject,
) JSC.JSValue {
return ZigString.init(this.msg.kind.string()).toJS(globalThis);
) callconv(.C) JSC.JSValue {
return ZigString.init(this.msg.kind.string()).toValueGC(globalThis);
}
pub fn finalize(this: *BuildMessage) void {
pub fn finalize(this: *BuildMessage) callconv(.C) void {
this.msg.deinit(bun.default_allocator);
}
};

View File

@@ -87,7 +87,7 @@ pub fn messageWithTypeAndLevel(
global: *JSGlobalObject,
vals: [*]const JSValue,
len: usize,
) callconv(JSC.conv) void {
) callconv(.C) void {
if (comptime is_bindgen) {
return;
}
@@ -3191,7 +3191,7 @@ pub fn count(
ptr: [*]const u8,
// len
len: usize,
) callconv(JSC.conv) void {
) callconv(.C) void {
var this = globalThis.bunVM().console;
const slice = ptr[0..len];
const hash = bun.hash(slice);
@@ -3217,7 +3217,7 @@ pub fn countReset(
ptr: [*]const u8,
// len
len: usize,
) callconv(JSC.conv) void {
) callconv(.C) void {
var this = globalThis.bunVM().console;
const slice = ptr[0..len];
const hash = bun.hash(slice);
@@ -3237,7 +3237,7 @@ pub fn time(
_: *JSGlobalObject,
chars: [*]const u8,
len: usize,
) callconv(JSC.conv) void {
) callconv(.C) void {
const id = bun.hash(chars[0..len]);
if (!pending_time_logs_loaded) {
pending_time_logs = PendingTimers.init(default_allocator);
@@ -3257,7 +3257,7 @@ pub fn timeEnd(
_: *JSGlobalObject,
chars: [*]const u8,
len: usize,
) callconv(JSC.conv) void {
) callconv(.C) void {
if (!pending_time_logs_loaded) {
return;
}
@@ -3288,7 +3288,7 @@ pub fn timeLog(
// args
args: [*]JSValue,
args_len: usize,
) callconv(JSC.conv) void {
) callconv(.C) void {
if (!pending_time_logs_loaded) {
return;
}
@@ -3335,7 +3335,7 @@ pub fn profile(
_: [*]const u8,
// len
_: usize,
) callconv(JSC.conv) void {}
) callconv(.C) void {}
pub fn profileEnd(
// console
_: ConsoleObject.Type,
@@ -3345,7 +3345,7 @@ pub fn profileEnd(
_: [*]const u8,
// len
_: usize,
) callconv(JSC.conv) void {}
) callconv(.C) void {}
pub fn takeHeapSnapshot(
// console
_: ConsoleObject.Type,
@@ -3355,7 +3355,7 @@ pub fn takeHeapSnapshot(
_: [*]const u8,
// len
_: usize,
) callconv(JSC.conv) void {
) callconv(.C) void {
// TODO: this does an extra JSONStringify and we don't need it to!
var snapshot: [1]JSValue = .{globalThis.generateHeapSnapshot()};
ConsoleObject.messageWithTypeAndLevel(undefined, MessageType.Log, MessageLevel.Debug, globalThis, &snapshot, 1);
@@ -3367,7 +3367,7 @@ pub fn timeStamp(
_: *JSGlobalObject,
// args
_: *ScriptArguments,
) callconv(JSC.conv) void {}
) callconv(.C) void {}
pub fn record(
// console
_: ConsoleObject.Type,
@@ -3375,7 +3375,7 @@ pub fn record(
_: *JSGlobalObject,
// args
_: *ScriptArguments,
) callconv(JSC.conv) void {}
) callconv(.C) void {}
pub fn recordEnd(
// console
_: ConsoleObject.Type,
@@ -3383,7 +3383,7 @@ pub fn recordEnd(
_: *JSGlobalObject,
// args
_: *ScriptArguments,
) callconv(JSC.conv) void {}
) callconv(.C) void {}
pub fn screenshot(
// console
_: ConsoleObject.Type,
@@ -3391,20 +3391,62 @@ pub fn screenshot(
_: *JSGlobalObject,
// args
_: *ScriptArguments,
) callconv(JSC.conv) void {}
) callconv(.C) void {}
pub const Export = shim.exportFunctions(.{
.messageWithTypeAndLevel = messageWithTypeAndLevel,
.count = count,
.countReset = countReset,
.time = time,
.timeLog = timeLog,
.timeEnd = timeEnd,
.profile = profile,
.profileEnd = profileEnd,
.takeHeapSnapshot = takeHeapSnapshot,
.timeStamp = timeStamp,
.record = record,
.recordEnd = recordEnd,
.screenshot = screenshot,
});
comptime {
@export(messageWithTypeAndLevel, .{ .name = shim.symbolName("messageWithTypeAndLevel") });
@export(count, .{ .name = shim.symbolName("count") });
@export(countReset, .{ .name = shim.symbolName("countReset") });
@export(time, .{ .name = shim.symbolName("time") });
@export(timeLog, .{ .name = shim.symbolName("timeLog") });
@export(timeEnd, .{ .name = shim.symbolName("timeEnd") });
@export(profile, .{ .name = shim.symbolName("profile") });
@export(profileEnd, .{ .name = shim.symbolName("profileEnd") });
@export(takeHeapSnapshot, .{ .name = shim.symbolName("takeHeapSnapshot") });
@export(timeStamp, .{ .name = shim.symbolName("timeStamp") });
@export(record, .{ .name = shim.symbolName("record") });
@export(recordEnd, .{ .name = shim.symbolName("recordEnd") });
@export(screenshot, .{ .name = shim.symbolName("screenshot") });
@export(messageWithTypeAndLevel, .{
.name = Export[0].symbol_name,
});
@export(count, .{
.name = Export[1].symbol_name,
});
@export(countReset, .{
.name = Export[2].symbol_name,
});
@export(time, .{
.name = Export[3].symbol_name,
});
@export(timeLog, .{
.name = Export[4].symbol_name,
});
@export(timeEnd, .{
.name = Export[5].symbol_name,
});
@export(profile, .{
.name = Export[6].symbol_name,
});
@export(profileEnd, .{
.name = Export[7].symbol_name,
});
@export(takeHeapSnapshot, .{
.name = Export[8].symbol_name,
});
@export(timeStamp, .{
.name = Export[9].symbol_name,
});
@export(record, .{
.name = Export[10].symbol_name,
});
@export(recordEnd, .{
.name = Export[11].symbol_name,
});
@export(screenshot, .{
.name = Export[12].symbol_name,
});
}

View File

@@ -21,12 +21,12 @@ pub const ResolveMessage = struct {
pub fn constructor(
globalThis: *JSC.JSGlobalObject,
_: *JSC.CallFrame,
) ?*ResolveMessage {
) callconv(.C) ?*ResolveMessage {
globalThis.throw("ResolveMessage is not constructable", .{});
return null;
}
pub fn getCode(this: *ResolveMessage, globalObject: *JSC.JSGlobalObject) JSC.JSValue {
pub fn getCode(this: *ResolveMessage, globalObject: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue {
switch (this.msg.metadata) {
.resolve => |resolve| {
const label: []const u8 = brk: {
@@ -49,7 +49,7 @@ pub const ResolveMessage = struct {
}
// https://github.com/oven-sh/bun/issues/2375#issuecomment-2121530202
pub fn getColumn(this: *ResolveMessage, _: *JSC.JSGlobalObject) JSC.JSValue {
pub fn getColumn(this: *ResolveMessage, _: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue {
if (this.msg.data.location) |location| {
return JSC.JSValue.jsNumber(@max(location.column - 1, 0));
}
@@ -57,7 +57,7 @@ pub const ResolveMessage = struct {
return JSC.JSValue.jsNumber(@as(i32, 0));
}
pub fn getLine(this: *ResolveMessage, _: *JSC.JSGlobalObject) JSC.JSValue {
pub fn getLine(this: *ResolveMessage, _: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue {
if (this.msg.data.location) |location| {
return JSC.JSValue.jsNumber(@max(location.line - 1, 0));
}
@@ -98,7 +98,7 @@ pub const ResolveMessage = struct {
var str = ZigString.init(text);
str.setOutputEncoding();
if (str.isUTF8()) {
const out = str.toJS(globalThis);
const out = str.toValueGC(globalThis);
default_allocator.free(text);
return out;
}
@@ -111,7 +111,7 @@ pub const ResolveMessage = struct {
this: *ResolveMessage,
globalThis: *JSC.JSGlobalObject,
_: *JSC.CallFrame,
) JSC.JSValue {
) callconv(.C) JSC.JSValue {
return this.toStringFn(globalThis);
}
@@ -119,7 +119,7 @@ pub const ResolveMessage = struct {
this: *ResolveMessage,
globalThis: *JSC.JSGlobalObject,
callframe: *JSC.CallFrame,
) JSC.JSValue {
) callconv(.C) JSC.JSValue {
const args_ = callframe.arguments(1);
const args = args_.ptr[0..args_.len];
if (args.len > 0) {
@@ -140,9 +140,9 @@ pub const ResolveMessage = struct {
this: *ResolveMessage,
globalThis: *JSC.JSGlobalObject,
_: *JSC.CallFrame,
) JSC.JSValue {
) callconv(.C) JSC.JSValue {
var object = JSC.JSValue.createEmptyObject(globalThis, 7);
object.put(globalThis, ZigString.static("name"), ZigString.init("ResolveMessage").toJS(globalThis));
object.put(globalThis, ZigString.static("name"), ZigString.init("ResolveMessage").toValueGC(globalThis));
object.put(globalThis, ZigString.static("position"), this.getPosition(globalThis));
object.put(globalThis, ZigString.static("message"), this.getMessage(globalThis));
object.put(globalThis, ZigString.static("level"), this.getLevel(globalThis));
@@ -170,44 +170,44 @@ pub const ResolveMessage = struct {
pub fn getPosition(
this: *ResolveMessage,
globalThis: *JSC.JSGlobalObject,
) JSC.JSValue {
) callconv(.C) JSC.JSValue {
return JSC.BuildMessage.generatePositionObject(this.msg, globalThis);
}
pub fn getMessage(
this: *ResolveMessage,
globalThis: *JSC.JSGlobalObject,
) JSC.JSValue {
return ZigString.init(this.msg.data.text).toJS(globalThis);
) callconv(.C) JSC.JSValue {
return ZigString.init(this.msg.data.text).toValueGC(globalThis);
}
pub fn getLevel(
this: *ResolveMessage,
globalThis: *JSC.JSGlobalObject,
) JSC.JSValue {
return ZigString.init(this.msg.kind.string()).toJS(globalThis);
) callconv(.C) JSC.JSValue {
return ZigString.init(this.msg.kind.string()).toValueGC(globalThis);
}
pub fn getSpecifier(
this: *ResolveMessage,
globalThis: *JSC.JSGlobalObject,
) JSC.JSValue {
return ZigString.init(this.msg.metadata.resolve.specifier.slice(this.msg.data.text)).toJS(globalThis);
) callconv(.C) JSC.JSValue {
return ZigString.init(this.msg.metadata.resolve.specifier.slice(this.msg.data.text)).toValueGC(globalThis);
}
pub fn getImportKind(
this: *ResolveMessage,
globalThis: *JSC.JSGlobalObject,
) JSC.JSValue {
return ZigString.init(this.msg.metadata.resolve.import_kind.label()).toJS(globalThis);
) callconv(.C) JSC.JSValue {
return ZigString.init(this.msg.metadata.resolve.import_kind.label()).toValueGC(globalThis);
}
pub fn getReferrer(
this: *ResolveMessage,
globalThis: *JSC.JSGlobalObject,
) JSC.JSValue {
) callconv(.C) JSC.JSValue {
if (this.referrer) |referrer| {
return ZigString.init(referrer.text).toJS(globalThis);
return ZigString.init(referrer.text).toValueGC(globalThis);
} else {
return JSC.JSValue.jsNull();
}

Some files were not shown because too many files have changed in this diff Show More