Skip to content

Commit 30203a4

Browse files
committed
chore: misc updates to runtime
1 parent 2f7790e commit 30203a4

13 files changed

Lines changed: 99 additions & 57 deletions

File tree

scripts/build.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const path = require('path');
88
const readline = require('readline');
99

1010
const VALID_ENGINES = ['V8-10',"V8-11","V8-13", 'QUICKJS', "QUICKJS_NG", 'HERMES', 'JSC', 'PRIMJS'];
11-
const HOST_OBJECTS_SUPPORTED = new Set(['V8-10','V8-11',"V8-13", 'QUICKJS',"QUICKJS_NG", 'PRIMJS']);
11+
const HOST_OBJECTS_SUPPORTED = new Set(['V8-10','V8-11',"V8-13", 'QUICKJS',"QUICKJS_NG",'HERMES', 'PRIMJS', "JSC"]);
1212

1313
// Host objects are enabled by default whenever the selected engine supports
1414
// them. They can be force-disabled with --disable-host-objects (or by

test-app/runtime/CMakeLists.txt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,8 @@ endif ()
145145
if (PRIMJS)
146146
set(SOURCES ${SOURCES}
147147
src/main/cpp/napi/primjs/jsr.cpp
148-
src/main/cpp/napi/primjs/code_cache.cc
149-
src/main/cpp/napi/primjs/primjs-api.cc
150-
src/main/cpp/napi/primjs/napi_env.cc
148+
src/main/cpp/napi/primjs/js_native_api_adapter.cc
149+
src/main/cpp/napi/primjs/js_native_api_extensions.cc
151150
)
152151
include_directories(
153152
src/main/cpp/napi/primjs
@@ -314,7 +313,7 @@ if (HERMES)
314313
endif ()
315314

316315
if (JSC)
317-
target_link_libraries(NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/jsc/${ANDROID_ABI}/libjsc.so)
316+
target_link_libraries(NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/jsc/${ANDROID_ABI}/libJavaScriptCore.so)
318317
add_compile_definitions(NativeScript, PRIVATE __JSC__)
319318
endif ()
320319

@@ -338,8 +337,12 @@ if (V8_13)
338337
endif ()
339338

340339
if (PRIMJS)
341-
# target_link_libraries(NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/primjs/${ANDROID_ABI}/libnapi.so)
340+
# libnapi.so provides the napi host/setup entry points (napi_new_env,
341+
# napi_attach_quickjs, napi_setup_loader, the quickjs<->napi bridges, ...)
342+
# and installs the value-op vtable consumed by js_native_api_adapter.cc.
343+
# It depends on libquick.so (the quickjs engine); link both.
342344
target_link_libraries(NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/primjs/${ANDROID_ABI}/libquick.so)
345+
target_link_libraries(NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/primjs/${ANDROID_ABI}/libnapi.so)
343346
add_compile_definitions(NativeScript, PRIVATE __PRIMJS__)
344347
endif ()
345348

test-app/runtime/build.gradle

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
22

33
// can be: "V8-11", "V8-10","V8-13", "JSC", "HERMES", "QUICKJS", "QUICKJS_NG", "PRIMJS"
44

5-
def jsEngine = "HERMES"
5+
def jsEngine = "V8-13"
66

77
def hasEngine = project.hasProperty("engine")
88
if (hasEngine) {
@@ -136,7 +136,7 @@ android {
136136

137137
if (jsEngine == "QUICKJS" || jsEngine == "QUICKJS_NG") {
138138
arguments.add("-DQUICKJS=1")
139-
// arguments.add("-DUSE_MIMALLOC=1")
139+
arguments.add("-DUSE_MIMALLOC=1")
140140
if (jsEngine == "QUICKJS_NG") {
141141
arguments.add("-DQUICKJS_NG=1")
142142
}
@@ -177,7 +177,13 @@ android {
177177
ndk {
178178
minSdkVersion NS_DEFAULT_MIN_SDK_VERSION as int
179179
if (onlyX86) {
180-
abiFilters 'x86'
180+
// The updated JSC only ships 64-bit libraries, so fall back to
181+
// x86_64 when a single-ABI (emulator) build is requested.
182+
abiFilters jsEngine == "JSC" ? 'x86_64' : 'x86'
183+
} else if (jsEngine == "JSC") {
184+
// The newer JSC engine only provides arm64-v8a and x86_64
185+
// prebuilts, so restrict the runtime to those two ABIs.
186+
abiFilters 'x86_64', 'arm64-v8a'
181187
} else {
182188
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
183189
}

test-app/runtime/src/main/cpp/napi/common/js_native_api.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,12 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_reject_deferred(napi_env env,
451451
NAPI_EXTERN napi_status NAPI_CDECL napi_is_promise(napi_env env,
452452
napi_value value,
453453
bool *is_promise);
454-
454+
#ifdef __PRIMJS__
455+
// Running a script
456+
NAPI_EXTERN napi_status NAPI_CDECL napi_run_script(napi_env env, const char* script,
457+
size_t length, const char* filename,
458+
napi_value* result);
459+
#else
455460
// Running a script
456461
NAPI_EXTERN napi_status NAPI_CDECL napi_run_script(napi_env env,
457462
napi_value script,
@@ -461,6 +466,8 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_run_script_source(napi_env env,
461466
napi_value script,
462467
const char* source_url,
463468
napi_value* result);
469+
#endif
470+
464471

465472
// Memory management
466473
NAPI_EXTERN napi_status NAPI_CDECL napi_adjust_external_memory(

test-app/runtime/src/main/cpp/napi/common/jsr_common.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77

88
#include "js_native_api.h"
99

10-
typedef struct napi_runtime__ *napi_runtime;
10+
typedef struct jsr_ns_runtime__ *jsr_ns_runtime;
1111

12-
napi_status js_create_runtime(napi_runtime* runtime);
13-
napi_status js_create_napi_env(napi_env* env, napi_runtime runtime);
12+
napi_status js_create_runtime(jsr_ns_runtime* runtime);
13+
napi_status js_create_napi_env(napi_env* env, jsr_ns_runtime runtime);
1414
napi_status js_set_runtime_flags(const char* flags);
1515
napi_status js_lock_env(napi_env env);
1616
napi_status js_unlock_env(napi_env env);
1717
napi_status js_free_napi_env(napi_env env);
18-
napi_status js_free_runtime(napi_runtime runtime);
18+
napi_status js_free_runtime(jsr_ns_runtime runtime);
1919
napi_status js_execute_script(napi_env env,
2020
napi_value script,
2121
const char *file,

test-app/runtime/src/main/cpp/napi/hermes/jsr.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
std::unordered_map<napi_env, JSR *> JSR::env_to_jsr_cache;
55

6-
typedef struct napi_runtime__ {
6+
typedef struct jsr_ns_runtime__ {
77
JSR *hermes;
8-
} napi_runtime__;
8+
} jsr_ns_runtime__;
99

1010
JSR::JSR() {
1111
hermes::vm::RuntimeConfig config =
@@ -19,9 +19,9 @@ JSR::JSR() {
1919
rt = (facebook::hermes::HermesRuntime *) &threadSafeRuntime->getUnsafeRuntime();
2020
}
2121

22-
napi_status js_create_runtime(napi_runtime *runtime) {
22+
napi_status js_create_runtime(jsr_ns_runtime *runtime) {
2323
if (runtime == nullptr) return napi_invalid_arg;
24-
*runtime = new napi_runtime__();
24+
*runtime = new jsr_ns_runtime__();
2525
(*runtime)->hermes = new JSR();
2626

2727
return napi_ok;
@@ -47,7 +47,7 @@ napi_status js_unlock_env(napi_env env) {
4747
return napi_ok;
4848
}
4949

50-
napi_status js_create_napi_env(napi_env *env, napi_runtime runtime) {
50+
napi_status js_create_napi_env(napi_env *env, jsr_ns_runtime runtime) {
5151
if (env == nullptr) return napi_invalid_arg;
5252

5353
// Extract the underlying hermes::vm::Runtime from the JSI HermesRuntime via
@@ -74,7 +74,7 @@ napi_status js_free_napi_env(napi_env env) {
7474
return napi_ok;
7575
}
7676

77-
napi_status js_free_runtime(napi_runtime runtime) {
77+
napi_status js_free_runtime(jsr_ns_runtime runtime) {
7878
if (runtime == nullptr) return napi_invalid_arg;
7979
runtime->hermes->threadSafeRuntime.reset();
8080
runtime->hermes->rt = nullptr;

test-app/runtime/src/main/cpp/napi/quickjs/jsr.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,27 @@
44
JSR::JSR() = default;
55
tns::SimpleMap<napi_env, JSR *> JSR::env_to_jsr_cache;
66

7-
napi_status js_create_runtime(napi_runtime *runtime) {
8-
return qjs_create_runtime(runtime);
7+
// Engine-agnostic runtime handle for the jsr layer. QuickJS keeps its own
8+
// napi_runtime (the real engine runtime defined in quickjs-api.c); this wrapper
9+
// just points at it so the jsr API can speak jsr_ns_runtime while
10+
// quickjs-api.c / quicks-runtime.h stay unchanged.
11+
struct jsr_ns_runtime__ {
12+
napi_runtime rt;
13+
};
14+
15+
napi_status js_create_runtime(jsr_ns_runtime *runtime) {
16+
if (!runtime) return napi_invalid_arg;
17+
auto *wrapper = new jsr_ns_runtime__();
18+
napi_status status = qjs_create_runtime(&wrapper->rt);
19+
if (status != napi_ok) {
20+
delete wrapper;
21+
return status;
22+
}
23+
*runtime = wrapper;
24+
return napi_ok;
925
}
10-
napi_status js_create_napi_env(napi_env *env, napi_runtime runtime) {
11-
napi_status status = qjs_create_napi_env(env, runtime);
26+
napi_status js_create_napi_env(napi_env *env, jsr_ns_runtime runtime) {
27+
napi_status status = qjs_create_napi_env(env, runtime->rt);
1228
JSR::env_to_jsr_cache.Insert((*env), new JSR());
1329
return status;
1430
}
@@ -37,8 +53,10 @@ napi_status js_free_napi_env(napi_env env) {
3753
return qjs_free_napi_env(env);
3854
}
3955

40-
napi_status js_free_runtime(napi_runtime runtime) {
41-
return qjs_free_runtime(runtime);
56+
napi_status js_free_runtime(jsr_ns_runtime runtime) {
57+
napi_status status = qjs_free_runtime(runtime->rt);
58+
delete runtime;
59+
return status;
4260
}
4361

4462
napi_status js_execute_script(napi_env env,

test-app/runtime/src/main/cpp/napi/quickjs/quickjs-api.c

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ static inline napi_status CreateJSValueHandle(napi_env env, JSValue value, struc
427427
CHECK_ARG(env)
428428
CHECK_ARG(result)
429429

430-
RETURN_STATUS_IF_FALSE(!LIST_EMPTY(&env->handleScopeList), napi_handle_scope_empty)
430+
RETURN_STATUS_IF_FALSE(!LIST_EMPTY(&env->handleScopeList), napi_handle_scope_mismatch)
431431

432432
napi_handle_scope handleScope = LIST_FIRST(&env->handleScopeList);
433433

@@ -483,7 +483,7 @@ napi_status napi_open_handle_scope(napi_env env, napi_handle_scope *result) {
483483
napi_handle_scope__ *handleScope = (napi_handle_scope__ *) mi_malloc(
484484
sizeof(napi_handle_scope__));
485485

486-
RETURN_STATUS_IF_FALSE(handleScope, napi_memory_error)
486+
RETURN_STATUS_IF_FALSE(handleScope, napi_handle_scope_mismatch)
487487
handleScope->type = HANDLE_HEAP_ALLOCATED;
488488
handleScope->handleCount = 0;
489489
handleScope->escapeCalled = false;
@@ -529,12 +529,12 @@ napi_status napi_open_escapable_handle_scope(napi_env env, napi_escapable_handle
529529
sizeof(napi_handle_scope__));
530530
handleScope->type = HANDLE_HEAP_ALLOCATED;
531531
handleScope->handleCount = 0;
532-
RETURN_STATUS_IF_FALSE(handleScope, napi_memory_error)
532+
RETURN_STATUS_IF_FALSE(handleScope, napi_handle_scope_mismatch)
533533
SLIST_INIT(&handleScope->handleList);
534534
handleScope->escapeCalled = false;
535535
LIST_INSERT_HEAD(&env->handleScopeList, handleScope, node);
536536

537-
*result = handleScope;
537+
*result = (napi_escapable_handle_scope) handleScope;
538538

539539
return napi_clear_last_error(env);
540540
}
@@ -544,23 +544,27 @@ napi_close_escapable_handle_scope(napi_env env, napi_escapable_handle_scope esca
544544
CHECK_ARG(env)
545545
CHECK_ARG(escapableScope)
546546

547-
assert(LIST_FIRST(&env->handleScopeList) == escapableScope &&
547+
// Escapable scopes share the napi_handle_scope__ representation; the public
548+
// type is opaque and distinct, so cast to operate on the members.
549+
napi_handle_scope__ *scope = (napi_handle_scope__ *) escapableScope;
550+
551+
assert(LIST_FIRST(&env->handleScopeList) == scope &&
548552
"napi_close_handle_scope() or napi_close_escapable_handle_scope() should follow FILO rule.");
549553

550554
Handle *handle, *tempHandle;
551-
SLIST_FOREACH_SAFE(handle, &escapableScope->handleList, node, tempHandle) {
555+
SLIST_FOREACH_SAFE(handle, &scope->handleList, node, tempHandle) {
552556
JS_FreeValue(env->context, handle->value);
553557
handle->value = JSUndefined;
554558

555559
// Instead of freeing, return the handle to the pool for reuse
556-
SLIST_REMOVE(&escapableScope->handleList, handle, Handle, node);
560+
SLIST_REMOVE(&scope->handleList, handle, Handle, node);
557561
if (handle->type == HANDLE_HEAP_ALLOCATED) {
558562
mi_free(handle);
559563
}
560564
}
561565

562-
LIST_REMOVE(escapableScope, node);
563-
mi_free(escapableScope);
566+
LIST_REMOVE(scope, node);
567+
mi_free(scope);
564568

565569
return napi_clear_last_error(env);
566570
}
@@ -573,16 +577,20 @@ napi_status napi_escape_handle(napi_env env, napi_escapable_handle_scope scope,
573577
CHECK_ARG(scope)
574578
CHECK_ARG(escapee)
575579

576-
RETURN_STATUS_IF_FALSE(!scope->escapeCalled, napi_escape_called_twice)
580+
// Escapable scopes share the napi_handle_scope__ representation; the public
581+
// type is opaque and distinct, so cast to operate on the members.
582+
napi_handle_scope__ *hs = (napi_handle_scope__ *) scope;
583+
584+
RETURN_STATUS_IF_FALSE(!hs->escapeCalled, napi_escape_called_twice)
577585
// Get the outer handle scope
578-
napi_handle_scope handleScope = LIST_NEXT(scope, node);
579-
RETURN_STATUS_IF_FALSE(handleScope, napi_handle_scope_empty)
586+
napi_handle_scope handleScope = LIST_NEXT(hs, node);
587+
RETURN_STATUS_IF_FALSE(handleScope, napi_handle_scope_mismatch)
580588

581589
Handle *handle = (Handle *) mi_malloc(sizeof(Handle));
582590

583-
RETURN_STATUS_IF_FALSE(handle, napi_memory_error)
591+
RETURN_STATUS_IF_FALSE(handle, napi_handle_scope_mismatch)
584592

585-
scope->escapeCalled = true;
593+
hs->escapeCalled = true;
586594
handle->value = JS_DupValue(env->context, *((JSValue *) escapee));
587595
SLIST_INSERT_HEAD(&handleScope->handleList, handle, node);
588596

@@ -795,7 +803,7 @@ napi_create_reference(napi_env env, napi_value value, uint32_t initialRefCount,
795803
CHECK_ARG(result)
796804

797805
*result = (napi_ref__ *) mi_malloc(sizeof(napi_ref__));
798-
RETURN_STATUS_IF_FALSE(*result, napi_memory_error)
806+
RETURN_STATUS_IF_FALSE(*result, napi_generic_failure)
799807

800808
JSValue jsValue = *((JSValue *) value);
801809

@@ -3223,7 +3231,7 @@ napi_create_function(napi_env env, const char *utf8name, size_t length, napi_cal
32233231
CHECK_ARG(result)
32243232

32253233
FunctionInfo *functionInfo = (FunctionInfo *) mi_malloc(sizeof(FunctionInfo));
3226-
RETURN_STATUS_IF_FALSE(functionInfo, napi_memory_error)
3234+
RETURN_STATUS_IF_FALSE(functionInfo, napi_generic_failure)
32273235
functionInfo->data = data;
32283236
functionInfo->callback = cb;
32293237

test-app/runtime/src/main/cpp/napi/quickjs/quicks-runtime.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88

99
EXTERN_C_START
1010

11+
// QuickJS' own runtime handle. This is the engine-internal runtime (defined in
12+
// quickjs-api.c as napi_runtime__ holding the JSRuntime and class IDs) and is
13+
// distinct from the engine-agnostic jsr_ns_runtime used by the jsr layer. The
14+
// jsr adapter (jsr.cpp) wraps this in a jsr_ns_runtime__.
15+
typedef struct napi_runtime__ *napi_runtime;
16+
1117
NAPI_EXTERN napi_status NAPI_CDECL qjs_create_runtime(napi_runtime *runtime);
1218

1319
NAPI_EXTERN napi_status NAPI_CDECL qjs_create_napi_env(napi_env *env, napi_runtime runtime);

test-app/runtime/src/main/cpp/napi/v8/jsr.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ std::unique_ptr<v8::Platform> JSR::platform = nullptr;
3131
bool JSR::s_mainThreadInitialized = false;
3232
std::unordered_map<napi_env, JSR *> JSR::env_to_jsr_cache;
3333

34-
napi_status js_create_runtime(napi_runtime *runtime) {
34+
napi_status js_create_runtime(jsr_ns_runtime *runtime) {
3535
if (!runtime) return napi_invalid_arg;
36-
*runtime = (napi_runtime) new JSR();
36+
*runtime = (jsr_ns_runtime) new JSR();
3737

3838
return napi_ok;
3939
}
@@ -65,7 +65,7 @@ napi_status js_unlock_env(napi_env env) {
6565
return napi_ok;
6666
}
6767

68-
napi_status js_create_napi_env(napi_env *env, napi_runtime runtime) {
68+
napi_status js_create_napi_env(napi_env *env, jsr_ns_runtime runtime) {
6969
if (env == nullptr) return napi_invalid_arg;
7070
JSR *jsr = (JSR *) runtime;
7171
// Must enter explictly
@@ -122,7 +122,7 @@ napi_status js_free_napi_env(napi_env env) {
122122
return napi_ok;
123123
}
124124

125-
napi_status js_free_runtime(napi_runtime runtime) {
125+
napi_status js_free_runtime(jsr_ns_runtime runtime) {
126126
JSR *jsr = (JSR *) runtime;
127127
jsr->isolate->Dispose();
128128
delete jsr;

0 commit comments

Comments
 (0)