Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
ba33209
JavaScriptCore wrapper previously passed nullptr to JSObjectCallAsFun…
matthargett Oct 12, 2025
e1fce6b
Add the node-lite test suite Vlad added into hermes-windows. The JSC …
matthargett Oct 12, 2025
e9aa436
Android tests now pass. StdoutLogger was holding on to destroyed mute…
matthargett Oct 12, 2025
9ebd4ce
Run the macOS NodeApiTests under sanitizers, which found another bug …
matthargett Oct 13, 2025
eb2eae4
Fix build errors. This deduplicates struct definitions that were inli…
matthargett Oct 15, 2025
a18d1cc
always build the napi tests
matthargett Oct 16, 2025
2eabe90
try and get address sanitizer and thread sanitizer to run on Android,…
matthargett Oct 16, 2025
8362442
Add N-API version/conformance roadmap (folds in engine-compat baseline)
matthargett Jun 4, 2026
1180892
Restore NodeApi tests build on current macOS toolchain
matthargett Jun 4, 2026
900b8eb
Restore Android NodeApi test build (compiles/links/installs/runs on e…
matthargett Jun 4, 2026
7714d9f
Fix Android NodeApi harness JNI crash; wire up SetNodeApiTestEnvironment
matthargett Jun 4, 2026
1cedda1
Android: make the NodeApi conformance tests actually execute on-device
matthargett Jun 4, 2026
33412f5
Android: enter the V8 context in jsr_open_napi_env_scope (fix napi_cr…
matthargett Jun 4, 2026
b15d528
Android/in-process node_lite: let ExitOnException propagate the fatal…
matthargett Jun 4, 2026
b35d519
Android/in-process: make node_lite teardown destructors exception-safe
matthargett Jun 4, 2026
f4e170b
Android/in-process: guard the fatal handler against throwing while un…
matthargett Jun 4, 2026
38864e4
Android/in-process: drop noexcept from throwing error-exit functions …
matthargett Jun 4, 2026
39a87ea
Android: skip in-process js-native-api addon tests pending shared-lib…
matthargett Jun 4, 2026
b559f69
docs(roadmap): document Android in-process addon-load constraint + sh…
matthargett Jun 4, 2026
f32130e
Android: statically link conformance addons into the test binary (run…
matthargett Jun 5, 2026
f0d1c2e
Android tests: pump native stdout/stderr to logcat
matthargett Jun 5, 2026
1938ff0
docs(roadmap): Android v5 js-native-api now green via static linking …
matthargett Jun 5, 2026
d4231ee
Android: drop the now-dead dynamic-.node build machinery (superseded …
matthargett Jun 5, 2026
04e3158
Android: remove vestigial V8Platform scaffolding from the env holder
matthargett Jun 5, 2026
b51d1a7
docs(roadmap): record node-api-cts FetchContent evaluation (task 6) —…
matthargett Jun 5, 2026
58223c0
Android: dlopen conformance addons as dynamic .node backed by a share…
matthargett Jun 5, 2026
538fe04
docs(roadmap): Android uses dynamic .node + shared libnapi.so (aligns…
matthargett Jun 5, 2026
44d903e
Android tests: use AndroidExtensions StdoutLogger for stdout->logcat
matthargett Jun 5, 2026
d225e74
docs(roadmap): stdout->logcat is via AndroidExtensions StdoutLogger, …
matthargett Jun 5, 2026
e94c72e
Sync napi shared-lib change with PR #183 (gate behind JSR_NAPI_SHARED…
matthargett Jun 5, 2026
17316b7
Tests: enable the v5-clean reference double-free conformance test
matthargett Jun 5, 2026
ed74d61
docs(roadmap): reference-test staging + GC-safety review (re hermes-w…
matthargett Jun 5, 2026
3f63934
Node-API: address #116 review (JSC call dispatch, status type, Window…
matthargett Jun 5, 2026
9ba6ece
Refresh Node-API conformance against current upstream
matthargett Jul 22, 2026
4ebbecb
Fix CTS transformed asset staging
matthargett Jul 22, 2026
049054b
Update Node-API CTS coverage and JSC lifetime handling
matthargett Jul 26, 2026
f5a2d0d
Fix cross-platform Node-API CTS runners
matthargett Jul 26, 2026
06a195a
Fix QuickJS Node-API throw status semantics
matthargett Jul 26, 2026
0140011
Skip C Node-API throw test on JSI
matthargett Jul 26, 2026
c33f9eb
Restack N-API v7 after CTS staging fix
matthargett Jul 26, 2026
cba438c
Restack Worker after CTS staging fix
matthargett Jul 26, 2026
b4bea62
Support visualization worker startup
matthargett Jul 26, 2026
3ff0e11
Trace Worker WPT lifecycle progress
matthargett Jul 26, 2026
e35e1d7
Fix JSC global event handler accessors
matthargett Jul 26, 2026
f36bb79
Improve Worker bootstrap diagnostics
matthargett Jul 26, 2026
b7190c7
Support visualization Worker cache hydration
matthargett Jul 26, 2026
2162628
Mirror visualization cache batch hydration
matthargett Jul 26, 2026
42bf1fa
Preserve primitive abort reasons safely
matthargett Jul 26, 2026
a23342f
Honor Node-API function name lengths
matthargett Jul 26, 2026
fb3f768
Use QuickJS for Worker thread sanitizer coverage
matthargett Jul 26, 2026
a89a469
Add optional WHATWG Streams polyfill
matthargett Jul 26, 2026
125583f
Add browser-compatible compression streams
matthargett Jul 26, 2026
46652cc
Complete Blob streaming and slicing support
matthargett Jul 26, 2026
112e7db
Add browser-compatible Headers and Response
matthargett Jul 26, 2026
70cef01
Handle empty Response byte bodies
matthargett Jul 26, 2026
2fbad6b
Support data URLs in the fetch polyfill
matthargett Jul 26, 2026
d4c67e8
Avoid intermediate data URL decode buffers
matthargett Jul 26, 2026
ad09b33
Keep Streams implementations internally consistent
matthargett Jul 26, 2026
145e471
Write Blob BYOB reads into caller buffers
matthargett Jul 26, 2026
28c198f
Track Response body disturbance through stream operations
matthargett Jul 26, 2026
7edcac7
Preserve Streams bundle bytes across source splits
matthargett Jul 26, 2026
db88700
Add an in-memory IndexedDB polyfill
matthargett Jul 26, 2026
0520bf6
Compose Worker with standalone browser polyfills
matthargett Jul 26, 2026
a7e6ea3
Fix IndexedDB bundle portability
matthargett Jul 26, 2026
68706ee
Support IndexedDB on older ChakraCore
matthargett Jul 26, 2026
18b0b60
Avoid per-stream Blob callback wrappers
matthargett Jul 26, 2026
4781dba
Use JSC-compatible Blob stream state key
matthargett Jul 26, 2026
ebbf1ee
Make JSC explicit GC finalizers deterministic
matthargett Jul 26, 2026
231fa40
Restack N-API v7 after CTS staging fix
matthargett Jul 26, 2026
78fde64
Merge refreshed napi-v7 CTS runtime fixes
matthargett Jul 26, 2026
ca6a518
Share Blob stream source callbacks
matthargett Jul 26, 2026
4373b23
Refresh ArrayBuffer metadata after detach
matthargett Jul 27, 2026
3253f45
Replace vendored WPT with focused Worker regressions
matthargett Jul 27, 2026
020c822
Normalize detached JSC ArrayBuffer metadata
matthargett Jul 27, 2026
7081e93
Detect detached buffers on transitional JSC
matthargett Jul 27, 2026
14b72a1
Detect transitional JSC detachment via slice
matthargett Jul 27, 2026
cc04b8e
Verify JavaScriptCore detach postcondition
matthargett Jul 27, 2026
1dbd388
Gate detach regression off Chakra
matthargett Jul 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
18 changes: 14 additions & 4 deletions .github/workflows/build-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,24 @@ jobs:

- name: Run Tests
working-directory: Build/ubuntu/Tests/UnitTests
run: ./UnitTests
env:
TSAN_OPTIONS: ${{ inputs.enable-thread-sanitizer && format('suppressions={0}/.github/tsan_suppressions.txt', github.workspace) || '' }}
run: |
# JSC's concurrent GC on Linux uses SIGUSR1 + sem_wait to suspend mutator
# threads at safepoints. TSan's signal interception delays SIGUSR1 delivery
# indefinitely, deadlocking the Collector Thread's sem_wait. Disabling the
# concurrent collector removes the dedicated Collector Thread, so GC runs
# on the mutator without cross-thread signals. macOS JSC uses Mach
# thread_suspend() and is unaffected.
JSC_useConcurrentGC: ${{ inputs.enable-thread-sanitizer && '0' || '' }}
if [[ "${{ inputs.enable-thread-sanitizer }}" == "true" ]]; then
export TSAN_OPTIONS="suppressions=${{ github.workspace }}/.github/tsan_suppressions.txt"
export JSC_useConcurrentGC=0
fi
./UnitTests

- name: Run Node-API v7 conformance
working-directory: Build/ubuntu/Tests/NodeApi
run: |
if [[ "${{ inputs.enable-thread-sanitizer }}" == "true" ]]; then
export TSAN_OPTIONS="suppressions=${{ github.workspace }}/.github/tsan_suppressions.txt"
export JSC_useConcurrentGC=0
fi
./NodeApiTests
7 changes: 6 additions & 1 deletion .github/workflows/build-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,16 @@ jobs:
-D ENABLE_THREAD_SANITIZER=${{ inputs.enable-thread-sanitizer && 'ON' || 'OFF' }}

- name: Build
run: cmake --build Build/macOS --target UnitTests --config RelWithDebInfo
run: cmake --build Build/macOS --target UnitTests NodeApiTests --config RelWithDebInfo

- name: Run Tests
working-directory: Build/macOS/Tests/UnitTests/RelWithDebInfo
run: ./UnitTests
env:
TSAN_OPTIONS: ${{ inputs.enable-thread-sanitizer && format('suppressions={0}/.github/tsan_suppressions.txt', github.workspace) || '' }}

- name: Run Node-API v7 conformance
working-directory: Build/macOS/Tests/NodeApi/RelWithDebInfo
run: ./NodeApiTests
env:
TSAN_OPTIONS: ${{ inputs.enable-thread-sanitizer && format('suppressions={0}/.github/tsan_suppressions.txt', github.workspace) || '' }}
29 changes: 29 additions & 0 deletions .github/workflows/worker-wpt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Worker WPT

on:
pull_request:
branches: [napi-v7]

jobs:
Ubuntu_JSC:
uses: ./.github/workflows/build-linux.yml

Ubuntu_JSC_Sanitizers:
uses: ./.github/workflows/build-linux.yml
with:
cc: clang
cxx: clang++
enable-sanitizers: true

Ubuntu_QuickJS_ThreadSanitizer:
uses: ./.github/workflows/build-linux.yml
with:
cc: clang
cxx: clang++
# Linux JSC suspends mutator threads with SIGUSR1. TSan intercepts the
# signal and deadlocks inside the uninstrumented system library, even
# with concurrent GC disabled. QuickJS still exercises the instrumented
# Worker ownership, message queues, and teardown paths without hiding
# host races behind an incompatible third-party runtime.
js-engine: QuickJS
enable-thread-sanitizer: true
28 changes: 27 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,14 @@ FetchContent_Declare(UrlLib
GIT_REPOSITORY https://github.com/BabylonJS/UrlLib.git
GIT_TAG e86ffb34e77092266145497681efc74e0a920ffe
EXCLUDE_FROM_ALL)
FetchContent_Declare(zlib
URL "https://github.com/madler/zlib/archive/refs/tags/v1.3.1.tar.gz"
EXCLUDE_FROM_ALL)
FetchContent_Declare(quickjs-ng
GIT_REPOSITORY https://github.com/quickjs-ng/quickjs.git
GIT_TAG 93d3f7df465027f487ed37e175a0bc3012fee79e
EXCLUDE_FROM_ALL)

# --------------------------------------------------

FetchContent_MakeAvailable(CMakeExtensions)
Expand All @@ -75,6 +78,14 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# A newer MSVC (windows-latest) emits C4875 ("a non-string literal argument to [[gsl::suppress]] is
# deprecated") from the vendored GSL headers, which several targets compile with warnings-as-error.
# Suppress this dependency-side deprecation so the Windows build isn't broken by toolchain drift. Must
# be set before arcana.cpp / Core / Polyfills are added below so they inherit it.
if(MSVC)
add_compile_options(/wd4875)
endif()

# --------------------------------------------------
# Options
# --------------------------------------------------
Expand Down Expand Up @@ -102,6 +113,10 @@ option(JSRUNTIMEHOST_POLYFILL_FILE "Include JsRuntimeHost Polyfill File and File
option(JSRUNTIMEHOST_POLYFILL_PERFORMANCE "Include JsRuntimeHost Polyfill Performance." ON)
option(JSRUNTIMEHOST_POLYFILL_TEXTDECODER "Include JsRuntimeHost Polyfill TextDecoder." ON)
option(JSRUNTIMEHOST_POLYFILL_TEXTENCODER "Include JsRuntimeHost Polyfill TextEncoder." ON)
option(JSRUNTIMEHOST_POLYFILL_WORKER "Include JsRuntimeHost Polyfill Worker." ON)
option(JSRUNTIMEHOST_POLYFILL_STREAMS "Include JsRuntimeHost Polyfill Web Streams." ON)
option(JSRUNTIMEHOST_POLYFILL_COMPRESSION "Include JsRuntimeHost Polyfills CompressionStream and DecompressionStream." ON)
option(JSRUNTIMEHOST_POLYFILL_INDEXEDDB "Include JsRuntimeHost Polyfill IndexedDB." ON)

# Sanitizers
option(ENABLE_SANITIZERS "Enable AddressSanitizer and UBSan" OFF)
Expand Down Expand Up @@ -154,6 +169,17 @@ endif()
FetchContent_MakeAvailable_With_Message(arcana.cpp)
set_property(TARGET arcana PROPERTY FOLDER Dependencies)

if(ANDROID)
FetchContent_GetProperties(AndroidExtensions)
if(NOT AndroidExtensions_POPULATED)
FetchContent_Populate(AndroidExtensions)
FetchContent_GetProperties(AndroidExtensions)
add_subdirectory(${androidextensions_SOURCE_DIR} ${androidextensions_BINARY_DIR})
else()
add_subdirectory(${androidextensions_SOURCE_DIR} ${androidextensions_BINARY_DIR})
endif()
endif()

if(JSRUNTIMEHOST_POLYFILL_XMLHTTPREQUEST OR JSRUNTIMEHOST_POLYFILL_FETCH)
FetchContent_MakeAvailable_With_Message(UrlLib)
set_property(TARGET UrlLib PROPERTY FOLDER Dependencies)
Expand Down
2 changes: 2 additions & 0 deletions Core/AppRuntime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ if(NAPI_JAVASCRIPT_ENGINE STREQUAL "V8" AND JSRUNTIMEHOST_CORE_APPRUNTIME_V8_INS
set_property(TARGET v8inspector PROPERTY FOLDER Dependencies)
elseif(NAPI_JAVASCRIPT_ENGINE STREQUAL "QuickJS")
target_link_libraries(AppRuntime PRIVATE qjs)
elseif(NAPI_JAVASCRIPT_ENGINE STREQUAL "JavaScriptCore" AND UNIX AND NOT APPLE)
target_link_libraries(AppRuntime PRIVATE ${CMAKE_DL_LIBS})
endif()

set_property(TARGET AppRuntime PROPERTY FOLDER Core)
Expand Down
24 changes: 24 additions & 0 deletions Core/AppRuntime/Include/Babylon/AppRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ namespace Babylon
// Optional handler for unhandled exceptions.
std::function<void(const Napi::Error&)> UnhandledExceptionHandler{DefaultUnhandledExceptionHandler};

// Optional final runtime-thread notification after engine and
// environment teardown. The callback is the thread's last action
// and must not access that runtime's Napi objects.
std::function<void()> ThreadExitHandler{};

// Defines whether to enable the debugger. Only implemented for V8 and Chakra.
bool EnableDebugger{false};

Expand All @@ -43,6 +48,17 @@ namespace Babylon
void Suspend();
void Resume();

// Permanently stop accepting work and exit after the currently
// executing dispatch returns. Unlike Terminate(), this does not
// interrupt JavaScript in the middle of its current task.
void Close();

// Permanently stop accepting work and request interruption of any
// JavaScript currently executing. The interruption is immediate on
// engines with an interrupt hook (including system JavaScriptCore) and
// cooperative between dispatches on the remaining engines.
void Terminate();

void Dispatch(Dispatchable<void(Napi::Env)> callback);

// Default unhandled exception handler that outputs the error message to the program output.
Expand Down Expand Up @@ -76,6 +92,14 @@ namespace Babylon
// queue explicitly (Napi::DrainJobs / JS_ExecutePendingJob).
void DrainMicrotasks(Napi::Env env);

// Engine tiers may query the shared termination flag without exposing
// engine types in the public API.
bool IsTerminationRequested() const noexcept;

// Execution watchdogs use a separate flag so Close() can finish the
// current task while Terminate() can still interrupt a tight loop.
bool IsExecutionTerminationRequested() const noexcept;

Options m_options;

class Impl;
Expand Down
59 changes: 47 additions & 12 deletions Core/AppRuntime/Source/AppRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <arcana/threading/dispatcher.h>

#include <cassert>
#include <atomic>
#include <optional>
#include <mutex>
#include <thread>
Expand Down Expand Up @@ -36,6 +37,8 @@ namespace Babylon
arcana::cancellation_source m_cancelSource{};
arcana::manual_dispatcher<128> m_dispatcher{};
std::thread m_thread;
std::atomic_bool m_terminationRequested{false};
std::atomic_bool m_executionTerminationRequested{false};
};

AppRuntime::AppRuntime() :
Expand All @@ -47,7 +50,13 @@ namespace Babylon
: m_options{std::move(options)}
, m_impl{std::make_unique<Impl>()}
{
m_impl->m_thread = std::thread{[this] { RunPlatformTier(); }};
m_impl->m_thread = std::thread{[this] {
RunPlatformTier();
if (m_options.ThreadExitHandler)
{
m_options.ThreadExitHandler();
}
}};

Dispatch([this](Napi::Env env) {
JsRuntime::CreateForJavaScript(env, [this](auto func) { Dispatch(std::move(func)); });
Expand All @@ -61,17 +70,7 @@ namespace Babylon
m_impl->m_suspensionLock.reset();
}

// Cancel immediately so pending work is dropped promptly, then append
// a no-op work item to wake the worker thread from blocking_tick. The
// no-op goes through push() which acquires the queue mutex, avoiding
// the race where a bare notify_all() can be missed by wait().
//
// NOTE: This preserves the existing shutdown behavior where pending
// callbacks are dropped on cancellation. A more complete solution
// would add cooperative shutdown (e.g. NotifyDisposing/Rundown) so
// consumers can finish cleanup work before the runtime is destroyed.
m_impl->m_cancelSource.cancel();
m_impl->Append([](Napi::Env) {});
Terminate();

m_impl->m_thread.join();
}
Expand Down Expand Up @@ -105,8 +104,44 @@ namespace Babylon
m_impl->m_suspensionLock.reset();
}

void AppRuntime::Terminate()
{
m_impl->m_executionTerminationRequested.store(true);
Close();
}

void AppRuntime::Close()
{
if (m_impl->m_terminationRequested.exchange(true))
{
return;
}

m_impl->m_cancelSource.cancel();

// Queueing under the dispatcher's mutex makes the wake-up immune to
// the missed-notification race covered by DestroyDoesNotDeadlock.
// The cancelled run loop drops this no-op rather than executing it.
m_impl->m_dispatcher.queue([]() {});
}

bool AppRuntime::IsTerminationRequested() const noexcept
{
return m_impl->m_terminationRequested.load();
}

bool AppRuntime::IsExecutionTerminationRequested() const noexcept
{
return m_impl->m_executionTerminationRequested.load();
}

void AppRuntime::Dispatch(Dispatchable<void(Napi::Env)> func)
{
if (IsTerminationRequested())
{
return;
}

m_impl->Append([this, func{std::move(func)}](Napi::Env env) mutable {
Execute([this, env, func{std::move(func)}]() mutable {
// Some engines (notably Hermes) require an open NAPI handle
Expand Down
59 changes: 59 additions & 0 deletions Core/AppRuntime/Source/AppRuntime_JavaScriptCore.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,62 @@
#include "AppRuntime.h"
#include <napi/env.h>

#if __has_include(<JavaScriptCore/JSContextRefPrivate.h>)
#include <JavaScriptCore/JSContextRefPrivate.h>
#define JSRUNTIMEHOST_HAS_JSC_EXECUTION_TIME_LIMIT 1
#elif defined(__unix__)
#include <dlfcn.h>
#define JSRUNTIMEHOST_LOOKUP_JSC_EXECUTION_TIME_LIMIT 1
#endif

namespace
{
#if defined(JSRUNTIMEHOST_LOOKUP_JSC_EXECUTION_TIME_LIMIT)
using SetExecutionTimeLimit = void (*)(JSContextGroupRef, double, bool (*)(JSContextRef, void*), void*);
using ClearExecutionTimeLimit = void (*)(JSContextGroupRef);
#endif
}

namespace Babylon
{
void AppRuntime::RunEnvironmentTier(const char*)
{
auto globalContext = JSGlobalContextCreateInGroup(nullptr, nullptr);

#if defined(JSRUNTIMEHOST_HAS_JSC_EXECUTION_TIME_LIMIT) || \
defined(JSRUNTIMEHOST_LOOKUP_JSC_EXECUTION_TIME_LIMIT)
auto contextGroup = JSContextGetGroup(globalContext);
const auto shouldTerminateJSC = [](JSContextRef, void* context) {
return static_cast<AppRuntime*>(context)->IsExecutionTerminationRequested();
};
#endif

#if defined(JSRUNTIMEHOST_HAS_JSC_EXECUTION_TIME_LIMIT)
// Poll at a modest interval while JS is running. Returning true from
// this callback raises a catchable termination exception and lets the
// AppRuntime thread unwind, so Worker::terminate() also stops a tight
// loop that never reaches the dispatch queue.
JSContextGroupSetExecutionTimeLimit(
contextGroup,
0.05,
shouldTerminateJSC,
this);
#elif defined(JSRUNTIMEHOST_LOOKUP_JSC_EXECUTION_TIME_LIMIT)
// WebKitGTK deliberately omits JSContextRefPrivate.h from its dev
// package, but current system builds export the same C ABI. Resolve it
// dynamically so JsRuntimeHost stays buildable against the public
// package and gracefully falls back to between-dispatch termination on
// older builds that do not export the watchdog.
auto setExecutionTimeLimit = reinterpret_cast<SetExecutionTimeLimit>(
dlsym(RTLD_DEFAULT, "JSContextGroupSetExecutionTimeLimit"));
auto clearExecutionTimeLimit = reinterpret_cast<ClearExecutionTimeLimit>(
dlsym(RTLD_DEFAULT, "JSContextGroupClearExecutionTimeLimit"));
if (setExecutionTimeLimit != nullptr && clearExecutionTimeLimit != nullptr)
{
setExecutionTimeLimit(contextGroup, 0.05, shouldTerminateJSC, this);
}
#endif

#if __APPLE__
if (__builtin_available(iOS 16.4, macOS 13.3, *))
{
Expand All @@ -18,6 +68,15 @@ namespace Babylon

Run(env);

#if defined(JSRUNTIMEHOST_HAS_JSC_EXECUTION_TIME_LIMIT)
JSContextGroupClearExecutionTimeLimit(contextGroup);
#elif defined(JSRUNTIMEHOST_LOOKUP_JSC_EXECUTION_TIME_LIMIT)
if (setExecutionTimeLimit != nullptr && clearExecutionTimeLimit != nullptr)
{
clearExecutionTimeLimit(contextGroup);
}
#endif

JSGlobalContextRelease(globalContext);

// Detach must come after JSGlobalContextRelease since it triggers finalizers which require env.
Expand Down
7 changes: 6 additions & 1 deletion Core/Node-API-JSI/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ if(NOT TARGET jsi)
endif()

target_include_directories(napi
PUBLIC "include")
PUBLIC "include"
# napi.h pulls in the shared <napi/js_native_api_types.h>, which lives in
# Core/Node-API/Include/Shared. That sibling isn't built when the engine is JSI
# (Core/CMakeLists.txt selects Node-API-JSI instead of Node-API), so reference the shared
# headers directly here -- otherwise the JSI napi fails to compile with C1083.
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../Node-API/Include/Shared")

target_link_libraries(napi
PUBLIC jsi)
Expand Down
Loading