Skip to content

9.0.0 — Host objects across all engines, C++ workers, DevTools & build modernization#43

Open
ammarahm-ed wants to merge 69 commits into
mainfrom
updates
Open

9.0.0 — Host objects across all engines, C++ workers, DevTools & build modernization#43
ammarahm-ed wants to merge 69 commits into
mainfrom
updates

Conversation

@ammarahm-ed

@ammarahm-ed ammarahm-ed commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator
  1. Port all commits and updates from https://github.com/NativeScript/android/ excluding ESM support since hermes does not have support for esm yet and node-api doesn't expose a unified API to load esm modules.
  2. Update JSC, Hermes, QuickJS, PrimJS to latest versions available
  3. Remove Old Hermes engine and make Hermes V1 the default when selecting Hermes
  4. Updated host objects API and added support for host objects in all JS engines including Hermes and JSC
  5. Many small but important performance improvements making the runtime 2x faster in many cases.

ammarahm-ed and others added 30 commits July 1, 2026 20:23
Port of upstream nativescript/android-runtime #1826 (2bab8f5).

URL::New unconditionally string-read argv[1] whenever argc > 1, which
threw for new URL(x, undefined) / new URL(x, null). Gate the base-URL
branch on argv[1] being neither undefined nor null (napi_util::is_of_type),
falling through to the no-base parse otherwise. Ports the expanded
testURLImpl.js suite (engine-agnostic JS) and adds the migration ledger.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime #1820 (94ddb15).

Use _Exit(0) instead of exit(0) on the locked-screen/direct-boot metadata
path so we skip atexit handlers and destructors (a destroyed mutex during
exit(0) was causing an ANR). In the napi runtime this error path lives in
MetadataBuilder.cpp rather than MetadataNode.cpp.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime #1825 (a983931).

compileSdk/targetSdk provided via -P arrive as String; cast them to int in
computeCompileSdkVersion/computeTargetSdkVersion so the Android DSL accepts
them instead of erroring.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime #1818 (3423e6f).

Add -Wl,-z,max-page-size=16384 link option for arm64-v8a/x86_64 so the
runtime .so is compatible with 16 KB page-size devices. Also bump default
compileSdk and build-tools to 35.

Skipped from the upstream commit: the gradle 8.4->8.7 wrapper and AGP
8.3.2->8.5.0 bumps (this fork is already on gradle 8.14.3 / AGP 8.12.1),
and the c++_shared->c++_static STL switch (the napi multi-engine build
relies on shared libc++ alongside the engine .so files).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime Ada v3 chain (#1830, #1832,
#1835, #1884: b31fc5f, 3633aed, 83f611b, 3513ce7, 45fb275). Ada is a vendored
single-file library, so the intermediate version bumps collapse into one
upgrade to the final 3.3.0.

- Upgrade vendored ada.{h,cpp} 2.9.0 -> 3.3.0 (no API breaks in URL/URLSearchParams).
- Port the URLPattern API from V8 to Node-API: new modules/url/URLPattern.{cpp,h}
  backed by ada's url_pattern with a napi RegExp provider (RegExp built via the
  global constructor and driven through .exec; a move-only NapiRegex wraps the
  napi_ref; a thread-local env lets create_instance reach the current env). Wire
  URLPattern::Init into NSRuntimeModules so it is installed as a global.
- Register the property as the spec-correct hasRegExpGroups (the original V8
  impl exposed a typo'd hasRegexpGroups).
- Port testURLPattern.js and register it in mainpage.js.

Verified: native build across all ABIs (V8-13) exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of the portable parts of upstream nativescript/android-runtime #1819
(bec401c, 'NDK 27 and Support for Java 21').

- NanoWSD.java: explicit (byte) casts on compound-assignment (Java 21 rejects
  the implicit narrowing).
- NativeScriptAbstractMap: bound SimpleEntry/SimpleImmutableEntry type params
  with 'extends Serializable' to satisfy Java 21's serializable checks.
- android-metadata-generator / runtime-binding-generator: use
  JavaVersion.VERSION_17 instead of the '17' string.
- runtime: add explicit compileOptions VERSION_17.

Skipped from upstream: CI workflows, gradlew/wrapper and root package.json
version bumps (this fork is already on newer gradle/NDK), and the NDK-27
android_support/FLEXIBLE_PAGE_SIZES bits (already present here).

Verified: :runtime:compileDebugJavaWithJavac under JDK 21, exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime #1845 (87f7f9c).

Replace the vendored libzip headers (cpp/zip/include/{zip.h,zipconf.h}) and
the four prebuilt static libs (libs/common/<abi>/libzip.a) with 1.11.4. The
only consumer, AssetExtractor.cpp, uses stable libzip API unaffected by the
bump. Verified: native compile+link across all ABIs (V8-13) exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime #1848 (78589fd).

Bump ns_default_kotlin_version / ns_default_kotlinx_metadata_jvm_version to
2.2.20 and adapt KotlinClassDescriptor to the kotlinx-metadata 2.2.x API:
metaClass.enumEntries was replaced by kmEnumEntries (a list of entries), so
map it to names before passing to getEnumEntriesAsFields.

Verified: metadata-generator compiles under kotlin 2.2.20 and :app:buildMetadata
runs it successfully.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime #1868 (f033061).

Register a global queueMicrotask(callback). The V8 original called
isolate->EnqueueMicrotask; Node-API has no equivalent, so schedule the
callback via Promise.resolve().then(callback), which enqueues a real
microtask on every engine the runtime targets and preserves ordering with
Promise microtasks (running before timers). Throws TypeError when the
argument is not a function.

Ports testQueueMicrotask.js and registers it in mainpage.js.

Verified: native compile across ABIs exit 0 (on-device ordering asserts not run).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime #1881 (5cb66ee).

A weak global ref cached in the ObjectManager LRUCache can end up pointing
to a collected Java object; reusing it crashes. Add an optional cache-validity
callback to LRUCache that is consulted on lookup — ObjectManager supplies
ValidateWeakGlobalRefCallback (IsSameObject(obj, NULL)) so stale weak refs are
evicted and re-created instead of returned. Adds JEnv::isSameObject and
LRUCache::evictKey.

Verified: native compile across ABIs exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime #1886 (c05e283).

Make ObjectManager::GetClassName (and the JAVA_LANG_CLASS / GET_NAME_METHOD_ID
JNI ids it uses) static, so NativeScriptException can resolve a Java class name
during a rethrow without going through Runtime::GetRuntime(env)->GetObjectManager().
That retrieval can throw when the env/runtime is unavailable mid-exception, which
is exactly when rethrow runs. GetJavaExceptionFromEnv keeps the instance (it needs
GetOrCreateObjectId/CreateJSWrapper). The runtime-lookup robustness from the
upstream commit is already present in the napi GetRuntime(env).

Verified: native compile+link across ABIs exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime #1887 (3ecd707).

- Stop finalizing buildMetadata by the R8 minify task (the ordering caused
  proguard build failures).
- Ship consumer proguard rules from the runtime library (consumerProguardFiles
  + consumer-rules.pro) that keep com.tns.*, generated bindings (com.tns.gen.**),
  internal classes, and RuntimeVisibleAnnotations so reflection/metadata survive
  minification.

Verified: gradle config evaluation exit 0 (full effect requires a release
R8 build).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of the remaining gap from upstream nativescript/android-runtime #1895
(3e61cef). The napi ForEach already used the spec callback order
(value, key, searchParams), the optional thisArg, and stopped on a thrown
callback. It still iterated via get_keys()+get(key), which returns the first
value for a repeated key, so ?a=1&a=2 reported (1) twice. Switch to
get_entries() so each entry yields its own value. Adds the forEach unit tests.

Verified: native compile across ABIs exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Partial port of upstream nativescript/android-runtime #1908 (e924542).

Install a std::terminate handler (LogAndAbortUncaught) in Runtime::Init that
logs the in-flight native exception's message before _Exit, so an uncaught
NativeScriptException/std::exception is diagnosable instead of a bare abort.
Adds NativeScriptException::what() to expose the stored message.

The upstream commit's larger NativeScriptException logging rewrite is V8-stack
specific and does not map onto this fork's napi exception path (which already
builds its own messages/stack traces); not ported.

Verified: native compile across ABIs exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime #1920 (1fd144f).

When multithreaded JS is enabled the runtime's instance maps are accessed from
multiple threads, so back them with thread-safe maps. Widen the field types to
the Map<> interface (only Map methods are used) and, when
getEnableMultithreadedJavascript() is set, initialize them as ConcurrentHashMap /
Collections.synchronizedMap. loadedJavaScriptExtends stays a synchronized
HashMap because it stores null values.

Adds ConcurrentAccessTest.java + testConcurrentAccess.js.

Verified: :runtime: and :app: Java compile exit 0 (concurrency behavior is
device-only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Record 085bc4f + 3c956cf as deferred — a JNI perf optimization that must be
ported together and device-validated across Android 8-11+ (ART calling-convention
crash risk), which can't be verified in this environment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime #1906 (df4e81b).

In callJSMethod, re-resolve the owning runtime not just when the runtime id
misses the cache but also when the resolved runtime does not actually own the
target object (getJavaObjectID == null). This happens when a worker fires a JS
method on an object created in the main thread or another worker.

Also surface a clearer error from ObjectManager::GetJavaObjectByJsObject when
GetJavaObjectByID fails (includes the object id), which usually indicates the id
belongs to a different runtime/thread.

Verified: native + Java compile exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…dentifier .extend keys

Batches three upstream jsparser fixes (build/ is gitignored, rebuilt on demand):
- 54185ff (#1796): webpack devtool:false (we don't use the sourcemap).
- e963d6c (#1797): traverseFiles throws when no files are found, so a broken
  webpack build fails loudly instead of silently succeeding.
- dd2984b (#1950): _getIdentifierKeyName guards the .extend({}) property walk
  against spreads, computed keys, and non-Identifier keys, which can't map to a
  Java binding and previously crashed the parser (e.g. bundled Zod schemas).

Verified: jsparser 'npm run build' (webpack) compiles cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime #1910 (49da71b).

Drop the buildMetadata task's dependsOn on compile*ArtProfile and
optimize*Resources — under proguard/R8 these created a circular task
dependency that broke the build.

Verified: :app: config evaluation exit 0 (full effect requires a release R8 build).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port of upstream nativescript/android-runtime #1938 (2b6cb03).

Harden dex directory setup: create code_cache/secondary-dexes if missing and
fall back to files/secondary-dexes when it is unavailable/unwritable
(RuntimeHelper). Defensively create the parent directory in
ProxyGenerator.saveProxy before createNewFile to avoid ENOENT crashes on newer
Android versions.

Verified: app + generator Java compile exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…968)

Record c9d41e6 + fce8e29 as deferred — reflection into hidden BaseDexClassLoader
internals, API-level-branched, with a release-only crash the second commit fixes.
Must be ported as the combined end-state and validated on real devices across
Android versions + a release build, which isn't possible here.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… inspector, timers, URLSearchParams spec)

Complete the 2bab8f5..HEAD triage: defer the ESM-dependent module-path fixes
(92c2654/45ed1f6), the workers->C++ refactor (a84d3c7), the two inspector
features (55da2da/4b5ab0a), the timers rewrite (bfd7650), and the URLSearchParams
spec overhaul (89893ae), each with rationale. Add a status summary to the ledger.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tration

Port of upstream nativescript/android-runtime #1921 + #1942 (085bc4f + 3c956cf)
as their combined end-state.

Hot native calls (generateNewObjectId, getCurrentRuntimeId, getPointerSize as
@CriticalNative; notifyGc, SetManualInstrumentationMode as @fastNative) use
Android's optimized JNI calling conventions. Because dynamic JNI lookup of these
annotated methods is unimplemented on Android 8-10 and buggy on 11, JNI_OnLoad
binds the annotated variants via RegisterNatives, and the Java side dispatches
to auto-bound *Legacy variants when SDK_INT < 26.

generateNewObjectId becomes static and is called with (nullptr, nullptr) since
its impl ignores env/obj; getCurrentRuntimeId uses Runtime::Current() so it needs
no JNIEnv. notifyGc keeps this fork's (int, int[]) signature -> "(I[I)Z".

Verified: native + Java compile across ABIs exit 0. Calling-convention
correctness must be validated on-device (Android 8-11, 12+, and a release build).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings July 10, 2026 04:16

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings July 10, 2026 13:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings July 11, 2026 03:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings July 14, 2026 04:47
Comment on lines +48 to +111
name: hermes (${{ matrix.host }})
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- { host: linux-x64, runner: ubuntu-24.04 }
- { host: linux-arm64, runner: ubuntu-24.04-arm }
- { host: darwin-x64, runner: macos-13 }
- { host: darwin-arm64, runner: macos-14 }
- { host: win32-x64, runner: windows-2022 }
- { host: win32-arm64, runner: windows-11-arm }
steps:
- name: Install toolchain (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y cmake ninja-build build-essential python3
- name: Install toolchain (macOS)
if: runner.os == 'macOS'
run: brew install cmake ninja
- name: Install toolchain (Windows)
if: runner.os == 'Windows'
run: choco install ninja -y

- name: Clone Hermes
shell: bash
run: git clone --depth 1 --branch "${{ github.event.inputs.hermes_ref || 'master' }}" "$HERMES_REPO" hermes

- name: Build hermesc (Unix)
if: runner.os != 'Windows'
shell: bash
run: |
set -euxo pipefail
cmake -S hermes -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DHERMES_BUILD_APPLE_FRAMEWORK=OFF
cmake --build build --target hermesc

- name: Build hermesc (Windows)
if: runner.os == 'Windows'
shell: bash
run: |
set -euxo pipefail
# Use the default (Visual Studio) generator; Ninja+MSVC also works if the
# VS dev environment is on PATH.
cmake -S hermes -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --target hermesc --config Release

- name: Stage binary
shell: bash
run: |
set -euxo pipefail
mkdir -p "out/hermes/${{ matrix.host }}"
bin="$(find build -type f \( -name hermesc -o -name hermesc.exe \) | head -n1)"
test -n "$bin"
cp "$bin" "out/hermes/${{ matrix.host }}/"

- uses: actions/upload-artifact@v4
with:
name: bytecode-compiler-hermes-${{ matrix.host }}
path: out/hermes/${{ matrix.host }}
if-no-files-found: error

# ---------------------------------------------------------------------------
# QuickJS (bellard) — build the engine lib, then our blob-emitting shim.
# ---------------------------------------------------------------------------
quickjs:
Comment on lines +112 to +163
name: quickjs (${{ matrix.host }})
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- { host: linux-x64, runner: ubuntu-24.04 }
- { host: linux-arm64, runner: ubuntu-24.04-arm }
- { host: darwin-x64, runner: macos-13 }
- { host: darwin-arm64, runner: macos-14 }
- { host: win32-x64, runner: windows-2022 }
- { host: win32-arm64, runner: windows-11-arm }
steps:
- uses: actions/checkout@v4
- name: Install toolchain (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y build-essential
- name: Install toolchain (Windows)
if: runner.os == 'Windows'
run: choco install llvm -y

- name: Clone QuickJS
shell: bash
run: git clone --depth 1 --branch "${{ github.event.inputs.quickjs_ref || 'master' }}" "$QUICKJS_REPO" quickjs

- name: Build shim
shell: bash
env:
SHIM: ${{ github.workspace }}/tools/bytecode-compiler/native/qjs-compile.c
run: |
set -euxo pipefail
cd quickjs
CC="cc"; [ "${{ runner.os }}" = "Windows" ] && CC="clang"
# Compile the lib sources directly (avoids qjs/qjsc main() collisions).
# If bellard changes the source set, adjust this list.
libsrc="quickjs.c cutils.c libregexp.c libunicode.c"
[ -f dtoa.c ] && libsrc="$libsrc dtoa.c"
out="../out/quickjs/${{ matrix.host }}"; mkdir -p "$out"
bin="$out/nsbc-quickjs"; [ "${{ runner.os }}" = "Windows" ] && bin="$bin.exe"
$CC -O2 -DNSBC_MAGIC='"NSBCQJS"' -I. -o "$bin" "$SHIM" $libsrc -lm
"$bin" || true # usage line (exit 2) proves it links & runs

- uses: actions/upload-artifact@v4
with:
name: bytecode-compiler-quickjs-${{ matrix.host }}
path: out/quickjs/${{ matrix.host }}
if-no-files-found: error

# ---------------------------------------------------------------------------
# QuickJS-NG — CMake build of libqjs, then our shim (same JS_* API).
# ---------------------------------------------------------------------------
quickjs-ng:
Comment on lines +164 to +221
name: quickjs-ng (${{ matrix.host }})
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- { host: linux-x64, runner: ubuntu-24.04 }
- { host: linux-arm64, runner: ubuntu-24.04-arm }
- { host: darwin-x64, runner: macos-13 }
- { host: darwin-arm64, runner: macos-14 }
- { host: win32-x64, runner: windows-2022 }
- { host: win32-arm64, runner: windows-11-arm }
steps:
- uses: actions/checkout@v4
- name: Install toolchain (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y cmake ninja-build build-essential
- name: Install toolchain (macOS)
if: runner.os == 'macOS'
run: brew install cmake ninja
- name: Install toolchain (Windows)
if: runner.os == 'Windows'
run: choco install ninja llvm -y

- name: Clone QuickJS-NG
shell: bash
run: git clone --depth 1 --branch "${{ github.event.inputs.quickjs_ng_ref || 'master' }}" "$QUICKJS_NG_REPO" quickjs-ng

- name: Build lib + shim
shell: bash
env:
SHIM: ${{ github.workspace }}/tools/bytecode-compiler/native/qjs-compile.c
run: |
set -euxo pipefail
cmake -S quickjs-ng -B quickjs-ng/build -DCMAKE_BUILD_TYPE=Release -DBUILD_QJS_LIBC=OFF
cmake --build quickjs-ng/build --config Release
lib="$(find quickjs-ng/build -type f \( -name 'libqjs.a' -o -name 'qjs.lib' \) | head -n1)"
test -n "$lib"
CC="cc"; [ "${{ runner.os }}" = "Windows" ] && CC="clang"
out="out/quickjs-ng/${{ matrix.host }}"; mkdir -p "$out"
bin="$out/nsbc-quickjs-ng"; [ "${{ runner.os }}" = "Windows" ] && bin="$bin.exe"
$CC -O2 -DNSBC_MAGIC='"NSBCNGS"' -I quickjs-ng -o "$bin" "$SHIM" "$lib" -lm
"$bin" || true

- uses: actions/upload-artifact@v4
with:
name: bytecode-compiler-quickjs-ng-${{ matrix.host }}
path: out/quickjs-ng/${{ matrix.host }}
if-no-files-found: error

# ---------------------------------------------------------------------------
# PrimJS — build the engine, then our LEPUS_* shim.
# NOTE: PrimJS's build system is nonstandard; the steps below are best-effort
# and will very likely need adjustment against lynx-family/primjs@develop
# (its actual CMake targets / include + lib paths). Treat the first CI run as
# the source of truth and pin once green.
# ---------------------------------------------------------------------------
primjs:
Comment on lines +222 to +277
name: primjs (${{ matrix.host }})
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- { host: linux-x64, runner: ubuntu-24.04 }
- { host: linux-arm64, runner: ubuntu-24.04-arm }
- { host: darwin-x64, runner: macos-13 }
- { host: darwin-arm64, runner: macos-14 }
- { host: win32-x64, runner: windows-2022 }
- { host: win32-arm64, runner: windows-11-arm }
steps:
- uses: actions/checkout@v4
- name: Install toolchain (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y cmake ninja-build build-essential python3
- name: Install toolchain (macOS)
if: runner.os == 'macOS'
run: brew install cmake ninja
- name: Install toolchain (Windows)
if: runner.os == 'Windows'
run: choco install ninja llvm -y

- name: Clone PrimJS
shell: bash
run: |
git clone --depth 1 --branch "${{ github.event.inputs.primjs_ref || 'develop' }}" "$PRIMJS_REPO" primjs
# PrimJS vendors deps via a script in some layouts; run it if present.
if [ -f primjs/tools/hooks/generate_gni.py ]; then python3 primjs/tools/hooks/generate_gni.py || true; fi

- name: Build engine + shim
shell: bash
env:
SHIM: ${{ github.workspace }}/tools/bytecode-compiler/native/primjs-compile.c
run: |
set -euxo pipefail
# Best-effort CMake build of the PrimJS/quickjs static lib. Adjust the
# target and include/lib paths to match the repo once observed in CI.
cmake -S primjs -B primjs/build -DCMAKE_BUILD_TYPE=Release || {
echo "::warning::PrimJS cmake configure needs adjustment for this repo layout"; exit 1; }
cmake --build primjs/build --config Release
lib="$(find primjs/build -type f \( -name 'libquick*.a' -o -name 'libprimjs*.a' -o -name '*.lib' \) | head -n1)"
inc="$(dirname "$(find primjs -name quickjs.h | head -n1)")"
test -n "$lib" && test -n "$inc"
CC="cc"; [ "${{ runner.os }}" = "Windows" ] && CC="clang"
out="out/primjs/${{ matrix.host }}"; mkdir -p "$out"
bin="$out/nsbc-primjs"; [ "${{ runner.os }}" = "Windows" ] && bin="$bin.exe"
$CC -O2 -I"$inc" -o "$bin" "$SHIM" "$lib" -lm
"$bin" || true

- uses: actions/upload-artifact@v4
with:
name: bytecode-compiler-primjs-${{ matrix.host }}
path: out/primjs/${{ matrix.host }}
if-no-files-found: error

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings July 14, 2026 05:00

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants