mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-31 07:23:06 +08:00
Merge the macOS island fixes of ni/1-libnode-loader
The libnode-linux action becomes .github/actions/libnode, which serves the Linux x64 and macOS lanes: the libnode-packs cache for the runner's platform, else the development pack. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
name: libnode pack (Linux x64)
|
||||
name: libnode pack (Linux x64, macOS)
|
||||
description: >-
|
||||
Provide the linux-x64 libnode pack for the Node island tests and export
|
||||
Provide the runner's libnode pack for the Node island tests and export
|
||||
SCRIPTC_LIBNODE. Restores the libnode build that the libnode-packs
|
||||
workflow cached and assembles @scriptc/libnode-linux-x64-gnu from it (the
|
||||
workflow cached and assembles @scriptc/libnode-<platform> from it (the
|
||||
bridge compiles in seconds; Node is never built here). Until that cache
|
||||
exists for this ref, it falls back to the pinned, checksum-verified
|
||||
development pack (packages/libnode-common/dev-pack.json). Fails the job if
|
||||
@@ -10,33 +10,44 @@ description: >-
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Name the runner's pack
|
||||
id: target
|
||||
shell: bash
|
||||
run: |
|
||||
case "$RUNNER_OS-$RUNNER_ARCH" in
|
||||
Linux-X64) platform=linux-x64-gnu toolchain=manylinux_2_28-gcc-toolset-14 bridge=libscr_node_bridge.so ;;
|
||||
macOS-ARM64) platform=darwin-arm64 toolchain=macos-15-xcode-clang bridge=libscr_node_bridge.dylib ;;
|
||||
macOS-X64) platform=darwin-x64 toolchain=macos-15-xcode-clang bridge=libscr_node_bridge.dylib ;;
|
||||
*) echo "::error::no libnode pack for $RUNNER_OS $RUNNER_ARCH"; exit 1 ;;
|
||||
esac
|
||||
printf 'platform=%s\ntoolchain=%s\nbridge=%s\n' "$platform" "$toolchain" "$bridge" >> "$GITHUB_OUTPUT"
|
||||
- name: Compute the libnode cache key
|
||||
id: key
|
||||
shell: bash
|
||||
env:
|
||||
SCRIPTC_LIBNODE_TOOLCHAIN: manylinux_2_28-gcc-toolset-14
|
||||
run: node packages/libnode-common/scripts/cache-key.mjs --platform linux-x64-gnu >> "$GITHUB_OUTPUT"
|
||||
SCRIPTC_LIBNODE_TOOLCHAIN: ${{ steps.target.outputs.toolchain }}
|
||||
run: node packages/libnode-common/scripts/cache-key.mjs --platform ${{ steps.target.outputs.platform }} >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/cache/restore@v4
|
||||
id: libnode
|
||||
with:
|
||||
path: .libnode-cache/${{ steps.key.outputs.path }}
|
||||
key: ${{ steps.key.outputs.key }}
|
||||
- name: Assemble @scriptc/libnode-linux-x64-gnu
|
||||
- name: Assemble @scriptc/libnode-${{ steps.target.outputs.platform }}
|
||||
if: steps.libnode.outputs.cache-hit == 'true'
|
||||
shell: bash
|
||||
env:
|
||||
SCRIPTC_LIBNODE_TOOLCHAIN: manylinux_2_28-gcc-toolset-14
|
||||
SCRIPTC_LIBNODE_TOOLCHAIN: ${{ steps.target.outputs.toolchain }}
|
||||
SCRIPTC_LIBNODE_CACHE: ${{ github.workspace }}/.libnode-cache
|
||||
run: |
|
||||
node packages/libnode-linux-x64-gnu/scripts/build.mjs --from-cache
|
||||
node packages/libnode-common/scripts/verify.mjs packages/libnode-linux-x64-gnu
|
||||
echo "SCRIPTC_LIBNODE=$GITHUB_WORKSPACE/packages/libnode-linux-x64-gnu" >> "$GITHUB_ENV"
|
||||
node packages/libnode-${{ steps.target.outputs.platform }}/scripts/build.mjs --from-cache
|
||||
node packages/libnode-common/scripts/verify.mjs packages/libnode-${{ steps.target.outputs.platform }}
|
||||
echo "SCRIPTC_LIBNODE=$GITHUB_WORKSPACE/packages/libnode-${{ steps.target.outputs.platform }}" >> "$GITHUB_ENV"
|
||||
- uses: actions/cache@v4
|
||||
if: steps.libnode.outputs.cache-hit != 'true'
|
||||
id: devpack
|
||||
with:
|
||||
path: ${{ runner.temp }}/libnode-dev-pack
|
||||
key: libnode-dev-pack-linux-x64-${{ hashFiles('packages/libnode-common/dev-pack.json', 'packages/libnode-common/build-pack.mjs', 'packages/libnode-common/fetch-dev-pack.mjs', 'packages/libnode-common/bridge/**', 'packages/runtime/src/scr_node_bridge.h') }}
|
||||
key: libnode-dev-pack-${{ steps.target.outputs.platform }}-${{ hashFiles('packages/libnode-common/dev-pack.json', 'packages/libnode-common/build-pack.mjs', 'packages/libnode-common/fetch-dev-pack.mjs', 'packages/libnode-common/bridge/**', 'packages/runtime/src/scr_node_bridge.h') }}
|
||||
- name: Assemble the development pack
|
||||
if: steps.libnode.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
@@ -50,4 +61,4 @@ runs:
|
||||
shell: bash
|
||||
run: |
|
||||
test -f "$SCRIPTC_LIBNODE/manifest.json"
|
||||
test -f "$SCRIPTC_LIBNODE/libscr_node_bridge.so"
|
||||
test -f "$SCRIPTC_LIBNODE/${{ steps.target.outputs.bridge }}"
|
||||
@@ -215,7 +215,7 @@ jobs:
|
||||
# Node island tests (`// @requires-libnode` corpus programs and
|
||||
# node-island.test.ts) load Node from a libnode pack, and fail rather
|
||||
# than skip in this lane when none is configured.
|
||||
- uses: ./.github/actions/libnode-linux
|
||||
- uses: ./.github/actions/libnode
|
||||
# Ubuntu pipes core dumps to apport, and RLIMIT_CORE does not limit a
|
||||
# piped dump. The kernel then streams every page of the runtime's
|
||||
# reserved allocator address space through the pipe, so each expected
|
||||
@@ -284,6 +284,9 @@ jobs:
|
||||
path: ${{ runner.temp }}
|
||||
- run: tar -xzf "$RUNNER_TEMP/native-darwin-arm64.tar.gz"
|
||||
- run: pnpm build
|
||||
# Node island tests load Node from a libnode pack, and fail rather
|
||||
# than skip on macOS CI when none is configured.
|
||||
- uses: ./.github/actions/libnode
|
||||
- name: Tests (${{ (github.event_name != 'schedule' && inputs.macos_suite != 'full') && 'darwin suite' || 'corpus and integration suites' }})
|
||||
run: node scripts/ci-test.mjs
|
||||
|
||||
@@ -704,6 +707,12 @@ jobs:
|
||||
path: ${{ runner.temp }}
|
||||
- run: tar -xzf "$RUNNER_TEMP/native-darwin-arm64.tar.gz"
|
||||
- run: pnpm build
|
||||
# Node island tests load Node from a libnode pack, and fail rather
|
||||
# than skip on macOS CI when none is configured.
|
||||
- uses: ./.github/actions/libnode
|
||||
- name: Node island harness
|
||||
if: matrix.shard == 1
|
||||
run: pnpm test tests/harness/node-island packages/libnode-common
|
||||
- name: No-clang assembly/object contract
|
||||
if: matrix.shard == 1
|
||||
run: pnpm test packages/cli/test/native-output.test.ts
|
||||
@@ -761,7 +770,8 @@ jobs:
|
||||
if: ${{ needs.validation_scope.outputs.full == 'true' && needs.lanes.outputs.macos == 'true' }}
|
||||
name: test (macOS x64 LLVM artifacts, no clang)
|
||||
runs-on: macos-15-intel
|
||||
timeout-minutes: 20
|
||||
# The Node island tests take most of it.
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
@@ -776,6 +786,15 @@ jobs:
|
||||
with:
|
||||
target: darwin-x64
|
||||
- run: pnpm build
|
||||
# Node island tests load Node from a libnode pack, and fail rather
|
||||
# than skip on macOS CI when none is configured.
|
||||
- uses: ./.github/actions/libnode
|
||||
- name: Node islands (Intel)
|
||||
run: >-
|
||||
pnpm test tests/harness/node-island packages/libnode-common
|
||||
&& pnpm test tests/harness/differential.test.ts -t ' (68[0-9][0-9]|7661|7662)-'
|
||||
env:
|
||||
SCRIPTC_TEST_WORKERS: "3"
|
||||
- name: Intel Mach-O no-clang object contract
|
||||
run: |
|
||||
mkdir -p "$RUNNER_TEMP/traps"
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ partially published release can be resumed safely.
|
||||
|
||||
The `@scriptc/libnode-<platform>` packs (linux-x64-gnu, linux-arm64-gnu, darwin-arm64, darwin-x64) carry the Node.js shared library that programs with Node islands load in process, plus the scriptc bridge compiled against it. They version in lockstep with the other platform packages (`sync-versions.mjs` stamps them); the Node release they contain is pinned separately in `packages/libnode-common/libnode.json`, which must match `.node-version` and `internal/compatibility/node-v24.json`. Each pack's `manifest.json` records the Node version, `NODE_MODULE_VERSION`, the bridge ABI and the size and SHA-256 of both libraries.
|
||||
|
||||
A Node `--shared` build takes about half an hour on 8 cores, so packs never build in `pnpm -r build`, the test suites or the release job. `.github/workflows/libnode-packs.yml` builds them on matching hosts when the pin, the bridge (`packages/libnode-common/bridge/`, `packages/runtime/src/scr_node_bridge.h`) or the pack packages change, or on manual dispatch. Linux packs build in the `manylinux_2_28` images (glibc 2.28, gcc-toolset-14) on native x64 and arm64 runners; Node disables its startup snapshot when cross-compiling, so arm64 is never cross-built. Each platform's libnode build is cached by Node release, configure flags, platform and toolchain; a bridge-only change restores libnode from the cache and rebuilds only the bridge. Every pack is smoke-tested by `packages/libnode-common/smoke/smoke.c`, which loads it the way the runtime does, and uploaded as the `libnode-<platform>` artifact, with zstd copies of both libraries as `libnode-<platform>-zst`. The Linux test lanes of `ci.yml` restore the cached linux-x64 build through `.github/actions/libnode-linux`, assemble the pack (`build.mjs --from-cache`, which never builds Node) and set `SCRIPTC_LIBNODE`, so the Node island tests run; without a cached build they skip with a warning. `packages/libnode-common/build-pack.mjs` assembles a pack from any matching libnode and headers, the bridge-only rebuild path.
|
||||
A Node `--shared` build takes about half an hour on 8 cores, so packs never build in `pnpm -r build`, the test suites or the release job. `.github/workflows/libnode-packs.yml` builds them on matching hosts when the pin, the bridge (`packages/libnode-common/bridge/`, `packages/runtime/src/scr_node_bridge.h`) or the pack packages change, or on manual dispatch. Linux packs build in the `manylinux_2_28` images (glibc 2.28, gcc-toolset-14) on native x64 and arm64 runners; Node disables its startup snapshot when cross-compiling, so arm64 is never cross-built. Each platform's libnode build is cached by Node release, configure flags, platform and toolchain; a bridge-only change restores libnode from the cache and rebuilds only the bridge. Every pack is smoke-tested by `packages/libnode-common/smoke/smoke.c`, which loads it the way the runtime does, and uploaded as the `libnode-<platform>` artifact, with zstd copies of both libraries as `libnode-<platform>-zst`. The Linux x64 and macOS test lanes of `ci.yml` restore the cached build for their platform through `.github/actions/libnode`, assemble the pack (`build.mjs --from-cache`, which never builds Node) and set `SCRIPTC_LIBNODE`, so the Node island tests run; without a cached build they fall back to the pinned development pack (`packages/libnode-common/dev-pack.json`). `packages/libnode-common/build-pack.mjs` assembles a pack from any matching libnode and headers, the bridge-only rebuild path.
|
||||
|
||||
To build one pack by hand on its own platform (it needs Python 3.9+, Ninja, a C++20 compiler and zstd; on Linux, build in a manylinux_2_28 container for a distributable pack):
|
||||
|
||||
|
||||
@@ -323,7 +323,9 @@ const ScrNodeBridge kBridge = {
|
||||
// libnode's own answer (RTLD_NEXT). Without them a garbage collection that
|
||||
// scans the stack while JavaScript runs on the runtime's stack walks from
|
||||
// that stack up to the main thread's and faults in the unmapped gap.
|
||||
// (macOS binds libnode's calls inside libnode; its packs need another way.)
|
||||
// macOS binds libnode's calls inside libnode instead: there the runtime
|
||||
// points the main thread's pthread stack record at its stack while Node
|
||||
// starts (ni_pthread_stack_enter in scr_node_island.c).
|
||||
#define SCR_V8_STACK_START(fn, symbol) \
|
||||
extern "C" __attribute__((visibility("default"))) void *fn() __asm__(symbol); \
|
||||
extern "C" void *fn() { \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"comment": "Temporary libnode source for CI until the NI-13 packs (@scriptc/libnode-<platform>) exist: the community dockfries/libnode build of Node 24.22.1 and Node's official headers for the bridge. The first URL is scriptc's CI-only mirror (prerelease libnode-dev-24.22.1), the others the original locations; fetch-dev-pack.mjs tries them in order and verifies the sha256.",
|
||||
"comment": "Temporary libnode source for CI until the NI-13 packs (@scriptc/libnode-<platform>) are published. linux-x64: the community dockfries/libnode build of Node 24.22.1. darwin-arm64 and darwin-x64: libnode of the pinned Node 24.22.0 from the libnode-packs workflow (NI-13), mirrored. Each with Node's official headers of the same release for the bridge. The first URL is scriptc's CI-only mirror (prerelease libnode-dev-24.22.1), the others the original locations; fetch-dev-pack.mjs tries them in order and verifies the sha256.",
|
||||
"nodeVersion": "24.22.1",
|
||||
"linux-x64": {
|
||||
"libnode": {
|
||||
@@ -18,5 +18,39 @@
|
||||
"sha256": "322e0a27db9088093ab8347bdc8c7e0aaa21dc9ed548390bf06b394494c09267",
|
||||
"dir": "node-v24.22.1/include/node"
|
||||
}
|
||||
},
|
||||
"darwin-arm64": {
|
||||
"libnode": {
|
||||
"urls": [
|
||||
"https://github.com/vercel-labs/scriptc/releases/download/libnode-dev-24.22.1/libnode-darwin-arm64.tar.gz"
|
||||
],
|
||||
"sha256": "3f06e5d0a0e1054f5fb4aab578a81908b3f94db4c2db64ceb9d3273c69d1ca3e",
|
||||
"file": "libnode.137.dylib"
|
||||
},
|
||||
"headers": {
|
||||
"urls": [
|
||||
"https://github.com/vercel-labs/scriptc/releases/download/libnode-dev-24.22.1/node-v24.22.0-headers.tar.gz",
|
||||
"https://nodejs.org/dist/v24.22.0/node-v24.22.0-headers.tar.gz"
|
||||
],
|
||||
"sha256": "00e9f08b9057f9f5428387a5ffd496e53f274565b40b144b7ba876700755352a",
|
||||
"dir": "node-v24.22.0/include/node"
|
||||
}
|
||||
},
|
||||
"darwin-x64": {
|
||||
"libnode": {
|
||||
"urls": [
|
||||
"https://github.com/vercel-labs/scriptc/releases/download/libnode-dev-24.22.1/libnode-darwin-x64.tar.gz"
|
||||
],
|
||||
"sha256": "17b8ee5bc6610da3b839041a992a4c16dc740d6f256712214d65b696d4a48d39",
|
||||
"file": "libnode.137.dylib"
|
||||
},
|
||||
"headers": {
|
||||
"urls": [
|
||||
"https://github.com/vercel-labs/scriptc/releases/download/libnode-dev-24.22.1/node-v24.22.0-headers.tar.gz",
|
||||
"https://nodejs.org/dist/v24.22.0/node-v24.22.0-headers.tar.gz"
|
||||
],
|
||||
"sha256": "00e9f08b9057f9f5428387a5ffd496e53f274565b40b144b7ba876700755352a",
|
||||
"dir": "node-v24.22.0/include/node"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/* Assembles a development libnode pack from the pinned, checksum-verified
|
||||
* inputs in dev-pack.json: a prebuilt libnode of the repository's Node
|
||||
* release and Node's official headers, with the bridge built against them
|
||||
* by build-pack.mjs. CI's Linux test lanes fall back to it
|
||||
* (.github/actions/libnode-linux) until the libnode-packs workflow has
|
||||
* cached a build of @scriptc/libnode-linux-x64-gnu for their ref.
|
||||
* by build-pack.mjs. CI's Linux x64 and macOS test lanes fall back to it
|
||||
* (.github/actions/libnode) until the libnode-packs workflow has cached a
|
||||
* build of @scriptc/libnode-<platform> for their ref.
|
||||
*
|
||||
* node packages/libnode-common/fetch-dev-pack.mjs --out <pack directory> */
|
||||
import { execFileSync } from "node:child_process";
|
||||
|
||||
@@ -13,6 +13,12 @@
|
||||
#include "scr_node_bridge.h"
|
||||
#include "scr_node_island_host.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define BRIDGE_FILE "libscr_node_bridge.dylib"
|
||||
#else
|
||||
#define BRIDGE_FILE "libscr_node_bridge.so"
|
||||
#endif
|
||||
|
||||
static int settled = 0;
|
||||
|
||||
static void settle(uint32_t id, const char *outcome, size_t len) {
|
||||
@@ -44,7 +50,7 @@ static void call(const ScrNodeBridge *b, uint32_t id, int sync, const char *modu
|
||||
int main(int argc, char **argv) {
|
||||
if (argc != 3) return 2;
|
||||
char path[4096];
|
||||
snprintf(path, sizeof path, "%s/libscr_node_bridge.so", argv[1]);
|
||||
snprintf(path, sizeof path, "%s/" BRIDGE_FILE, argv[1]);
|
||||
void *lib = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
|
||||
if (lib == NULL) {
|
||||
fprintf(stderr, "%s\n", dlerror());
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* The libnode bridge against a real pack, without the compiler: the C host
|
||||
* in bridge-smoke.c loads the pack the way scr_node_island.c does and makes
|
||||
* calls through the bridge with the runtime's embedded bootstrap. Needs a
|
||||
* pack in SCRIPTC_LIBNODE; required in the Linux x64 CI lanes
|
||||
* pack in SCRIPTC_LIBNODE; required in the Linux x64 and macOS CI lanes
|
||||
* (tests/harness/libnode.ts). */
|
||||
import { execFile } from "node:child_process";
|
||||
import { mkdirSync, writeFileSync } from "node:fs";
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ucontext.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#if defined(__linux__)
|
||||
#include <sys/auxv.h>
|
||||
@@ -821,6 +822,28 @@ static const void *ni_caller_bottom = NULL;
|
||||
static size_t ni_caller_size = 0;
|
||||
#endif
|
||||
|
||||
/* A context that runs fn on the stack [lo, lo + size), from its top.
|
||||
* macOS's makecontext clears the whole stack it is given, which costs a
|
||||
* pass over (and commits) every page of it on each call: there it is given
|
||||
* only the top slice. The context starts at the same address either way,
|
||||
* and its frames grow below the slice as they would anywhere on the
|
||||
* stack; nothing reads uc_stack after makecontext, and the stack's bound
|
||||
* is the runtime's stack guard (and the guard page), not uc_stack. */
|
||||
static void ni_make_context(ucontext_t *ctx, char *lo, size_t size, void (*fn)(void)) {
|
||||
if (getcontext(ctx) != 0) scr_trap("scriptc: getcontext failed\n");
|
||||
#if defined(__APPLE__)
|
||||
size_t slice = (size_t)64 * 1024;
|
||||
if (size > slice) {
|
||||
lo += size - slice;
|
||||
size = slice;
|
||||
}
|
||||
#endif
|
||||
ctx->uc_stack.ss_sp = lo;
|
||||
ctx->uc_stack.ss_size = size;
|
||||
ctx->uc_link = NULL;
|
||||
makecontext(ctx, fn, 0);
|
||||
}
|
||||
|
||||
static void ni_trampoline(void) {
|
||||
for (;;) {
|
||||
#ifdef NI_ASAN
|
||||
@@ -854,11 +877,7 @@ static void ni_on_node_stack(void (*job)(void *), void *arg) {
|
||||
#ifdef NI_ASAN
|
||||
if (__lsan_register_root_region) __lsan_register_root_region(ni_stack, NI_STACK);
|
||||
#endif
|
||||
if (getcontext(&ni_node_ctx) != 0) scr_trap("scriptc: getcontext failed\n");
|
||||
ni_node_ctx.uc_stack.ss_sp = ni_stack + NI_GUARD;
|
||||
ni_node_ctx.uc_stack.ss_size = NI_STACK - NI_GUARD;
|
||||
ni_node_ctx.uc_link = NULL;
|
||||
makecontext(&ni_node_ctx, ni_trampoline, 0);
|
||||
ni_make_context(&ni_node_ctx, ni_stack + NI_GUARD, NI_STACK - NI_GUARD, ni_trampoline);
|
||||
}
|
||||
ni_job = job;
|
||||
ni_job_arg = arg;
|
||||
@@ -884,12 +903,61 @@ typedef struct {
|
||||
char *error;
|
||||
} NiStart;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* V8 takes each thread's stack start (v8::base::Stack, the bound of its
|
||||
* conservative stack scan and of its stack limit) from
|
||||
* pthread_get_stackaddr_np the first time it asks, and keeps it for the
|
||||
* thread's life. On Linux the bridge's definitions of those functions
|
||||
* answer for libnode with Node's stack; macOS binds libnode's own calls
|
||||
* inside libnode, so they cannot. While Node starts on its stack (where
|
||||
* V8 first asks, and where every frame of Node runs), the main thread's
|
||||
* pthread record names Node's stack instead: its stack address and the
|
||||
* bottom pthread_get_stacksize_np derives from it, found by value next
|
||||
* to each other in the record and checked through the public accessors.
|
||||
* The record is restored once Node has started. */
|
||||
static void **ni_pthread_stack = NULL;
|
||||
static void *ni_pthread_saved[2];
|
||||
|
||||
static void ni_pthread_stack_enter(uintptr_t start, size_t size) {
|
||||
pthread_t self = pthread_self();
|
||||
void *addr = pthread_get_stackaddr_np(self);
|
||||
void *bottom = (char *)addr - pthread_get_stacksize_np(self);
|
||||
void **record = (void **)(void *)self;
|
||||
for (size_t i = 0; i + 1 < 64; i++) {
|
||||
if (record[i] != addr || record[i + 1] != bottom) continue;
|
||||
ni_pthread_saved[0] = record[i];
|
||||
ni_pthread_saved[1] = record[i + 1];
|
||||
record[i] = (void *)start;
|
||||
record[i + 1] = (void *)(start - size);
|
||||
if (pthread_get_stackaddr_np(self) == (void *)start) {
|
||||
ni_pthread_stack = &record[i];
|
||||
return;
|
||||
}
|
||||
record[i] = ni_pthread_saved[0];
|
||||
record[i + 1] = ni_pthread_saved[1];
|
||||
}
|
||||
}
|
||||
|
||||
static void ni_pthread_stack_leave(void) {
|
||||
if (ni_pthread_stack == NULL) return;
|
||||
ni_pthread_stack[0] = ni_pthread_saved[0];
|
||||
ni_pthread_stack[1] = ni_pthread_saved[1];
|
||||
ni_pthread_stack = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ni_start_job(void *p) {
|
||||
NiStart *a = p;
|
||||
/* JavaScript may use Node's stack down to a reserve above its guard page
|
||||
* (native frames below V8's limit, the runtime's stack guard). */
|
||||
uintptr_t limit = (uintptr_t)(ni_stack + NI_GUARD) + NI_STACK / 8;
|
||||
#if defined(__APPLE__)
|
||||
ni_pthread_stack_enter((uintptr_t)ni_stack + NI_STACK, NI_STACK - NI_GUARD);
|
||||
#endif
|
||||
a->error = ni_bridge->start(&ni_host, a->bootstrap, a->argv0, limit);
|
||||
#if defined(__APPLE__)
|
||||
ni_pthread_stack_leave();
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Node island tests need a libnode pack (SCRIPTC_LIBNODE). The Linux x64 CI
|
||||
* test lanes provide one (.github/actions/libnode-linux) and must run
|
||||
/* Node island tests need a libnode pack (SCRIPTC_LIBNODE). The Linux x64 and
|
||||
* macOS CI test lanes provide one (.github/actions/libnode) and must run
|
||||
* these tests, so there a missing pack is a failure, never a skip. Other
|
||||
* CI platforms do not provision a pack yet, and a local run without a pack
|
||||
* skips. */
|
||||
@@ -17,8 +17,7 @@ export const libnodeRequired =
|
||||
process.env["CI"] !== undefined &&
|
||||
process.env["CI"] !== "" &&
|
||||
process.env["CI"] !== "false" &&
|
||||
process.platform === "linux" &&
|
||||
process.arch === "x64";
|
||||
((process.platform === "linux" && process.arch === "x64") || process.platform === "darwin");
|
||||
|
||||
/** The configured pack, or null. Throws where CI requires one. */
|
||||
export function libnodePack(): string | null {
|
||||
@@ -26,7 +25,7 @@ export function libnodePack(): string | null {
|
||||
if (pack !== undefined && pack !== "") return pack;
|
||||
if (libnodeRequired)
|
||||
throw new Error(
|
||||
"Node island tests need a libnode pack in this CI lane, and SCRIPTC_LIBNODE is not set (.github/actions/libnode-linux provides it)",
|
||||
"Node island tests need a libnode pack in this CI lane, and SCRIPTC_LIBNODE is not set (.github/actions/libnode provides it)",
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user