diff --git a/.github/workflows/build-reusable.yml b/.github/workflows/build-reusable.yml index 1c71527296e0..e87041bb28fa 100644 --- a/.github/workflows/build-reusable.yml +++ b/.github/workflows/build-reusable.yml @@ -32,6 +32,8 @@ jobs: name: Linux runs-on: ${{matrix.os}} strategy: + # One variant's failure shouldn't cancel the others. + fail-fast: false matrix: include: - lto_flag: "" @@ -344,6 +346,8 @@ jobs: name: Linux musl runs-on: ${{matrix.os}} strategy: + # One variant's failure shouldn't cancel the others. + fail-fast: false matrix: include: - lto_flag: "" @@ -445,6 +449,8 @@ jobs: # mac-release.bash remains for building on a real Mac locally. runs-on: linux-x64-gh strategy: + # One variant's failure shouldn't cancel the others. + fail-fast: false matrix: include: - label: bun-webkit-macos-arm64 @@ -539,6 +545,8 @@ jobs: # so all FreeBSD targets build on x64 regardless of target arch. runs-on: linux-x64-gh strategy: + # One variant's failure shouldn't cancel the others. + fail-fast: false matrix: include: - label: bun-webkit-freebsd-amd64 @@ -596,6 +604,8 @@ jobs: # cross-compile from x64 regardless of target arch. runs-on: linux-x64-gh strategy: + # One variant's failure shouldn't cancel the others. + fail-fast: false matrix: include: - label: bun-webkit-linux-arm64-android diff --git a/Dockerfile b/Dockerfile index 2d57157dc9a0..16c33406eaf9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,15 +31,20 @@ ENV DEBIAN_FRONTEND=noninteractive # Both archive.ubuntu.com and azure.archive.ubuntu.com have intermittently # timed out from inside the GitHub-hosted docker-buildx network at different -# times. Prefer Azure (faster on Azure-hosted runners) but fall back to the -# canonical mirror if `apt-get update` can't reach it. arm64 uses -# ports.ubuntu.com which has been reachable, so leave it alone. -RUN sed -i 's|http://archive.ubuntu.com/ubuntu|http://azure.archive.ubuntu.com/ubuntu|g' /etc/apt/sources.list +# times, and ports.ubuntu.com (arm64) has gone fully dark for hours at a +# stretch. Prefer Azure on amd64 (faster on Azure-hosted runners). On any +# failed attempt, swap to a fallback mirror before retrying: amd64 falls back +# to the canonical archive, arm64 falls back to a Launchpad-registered +# ubuntu-ports mirror. +RUN sed -i 's|http://archive.ubuntu.com/ubuntu|http://azure.archive.ubuntu.com/ubuntu|g' /etc/apt/sources.list \ + && echo 'Acquire::Retries "5";' > /etc/apt/apt.conf.d/99-retries -# Install basic build dependencies -RUN ( apt-get update || \ - ( sed -i 's|http://azure.archive.ubuntu.com/ubuntu|http://archive.ubuntu.com/ubuntu|g' /etc/apt/sources.list && apt-get update ) \ - ) && apt-get install -y \ +# Install basic build dependencies. `apt-get update` exits 0 on partial index +# fetch failure (only W:, not E:), which then makes the install fail with +# "no installation candidate"; retry the whole update+install, swapping to a +# fallback mirror after the first failure. +RUN for attempt in 1 2 3; do \ + apt-get update && apt-get install -y \ wget \ curl \ git \ @@ -52,6 +57,15 @@ RUN ( apt-get update || \ ca-certificates \ gnupg \ lsb-release \ + && break || { \ + echo "apt attempt $attempt failed, swapping mirrors and retrying"; \ + sed -i -e 's|http://azure.archive.ubuntu.com/ubuntu|http://archive.ubuntu.com/ubuntu|g' \ + -e 's|http://ports.ubuntu.com/ubuntu-ports|http://mirrors.ocf.berkeley.edu/ubuntu-ports|g' \ + /etc/apt/sources.list; \ + sleep 15; \ + }; \ + done \ + && dpkg -l wget curl git python3 ninja-build lsb-release >/dev/null \ && rm -rf /var/lib/apt/lists/* # Install zstd (for icu/compress-data.ts). Pinned: focal's apt has 1.4.4 which diff --git a/Source/JavaScriptCore/parser/Parser.cpp b/Source/JavaScriptCore/parser/Parser.cpp index a71bce8e4589..5d366c0ce7e1 100644 --- a/Source/JavaScriptCore/parser/Parser.cpp +++ b/Source/JavaScriptCore/parser/Parser.cpp @@ -53,7 +53,10 @@ #define consumeOrFail(tokenType, ...) do { if (!consume(tokenType)) [[unlikely]] { handleErrorToken(); internalFailWithMessage(true, __VA_ARGS__); } } while (0) #define consumeOrFailWithFlags(tokenType, flags, ...) do { if (!consume(tokenType, flags)) [[unlikely]] { handleErrorToken(); internalFailWithMessage(true, __VA_ARGS__); } } while (0) #define matchOrFail(tokenType, ...) do { if (!match(tokenType)) [[unlikely]] { handleErrorToken(); internalFailWithMessage(true, __VA_ARGS__); } } while (0) -#define failIfStackOverflow() do { if (!canRecurse()) [[unlikely]] failWithStackOverflow(); } while (0) +// Once the recursion limit is hit, treat it as sticky: save-point backtracking can clear +// m_errorMessage, and retrying an alternate production (e.g. object literal -> destructuring +// pattern) at each nesting level would otherwise turn a linear failure into an exponential one. +#define failIfStackOverflow() do { if (m_hasStackOverflow || !canRecurse()) [[unlikely]] failWithStackOverflow(); } while (0) #define semanticFail(...) do { internalFailWithMessage(false, __VA_ARGS__); } while (0) #define semanticFailIfTrue(cond, ...) do { if ((cond)) [[unlikely]] internalFailWithMessage(false, __VA_ARGS__); } while (0) #define semanticFailIfFalse(cond, ...) do { if (!(cond)) [[unlikely]] internalFailWithMessage(false, __VA_ARGS__); } while (0)