@react-native-quickjs/quickjs 1.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/LICENSE +21 -0
- package/NOTICE +31 -0
- package/README.md +217 -0
- package/ReactNativeQuickJS.podspec +197 -0
- package/android/CMakeLists.txt +134 -0
- package/android/build.gradle +214 -0
- package/android/quickjs.gradle +39 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/reactnativequickjs/quickjs/QuickJSInstance.kt +39 -0
- package/android/src/main/java/com/reactnativequickjs/quickjs/QuickJSPackage.kt +32 -0
- package/android/src/main/jni/JJSRuntimeFactory.h +37 -0
- package/android/src/main/jni/JQuickJSInstance.cpp +27 -0
- package/android/src/main/jni/JQuickJSInstance.h +46 -0
- package/android/src/main/jni/OnLoad.cpp +15 -0
- package/app.plugin.js +11 -0
- package/apple/RCTQuickJSInstanceFactory.h +32 -0
- package/apple/RCTQuickJSInstanceFactory.mm +16 -0
- package/bin/qjsc/darwin-arm64/qjsc +0 -0
- package/bin/qjsc/darwin-x64/qjsc +0 -0
- package/bin/qjsc/linux-arm64/qjsc +0 -0
- package/bin/qjsc/linux-x64/qjsc +0 -0
- package/bin/qjsc/manifest.json +11 -0
- package/bin/qjsc/win32-x64/qjsc.exe +0 -0
- package/bin/react-native-quickjs.js +28 -0
- package/cmake/jsi.cmake +24 -0
- package/cmake/quickjs.cmake +125 -0
- package/engine/quickjs-rel/LICENSE +24 -0
- package/engine/quickjs-rel/MANIFEST.json +55 -0
- package/engine/quickjs-rel/builtin-array-fromasync.h +120 -0
- package/engine/quickjs-rel/builtin-iterator-zip-keyed.h +332 -0
- package/engine/quickjs-rel/builtin-iterator-zip.h +337 -0
- package/engine/quickjs-rel/cutils.h +1998 -0
- package/engine/quickjs-rel/dtoa.c +1619 -0
- package/engine/quickjs-rel/dtoa.h +87 -0
- package/engine/quickjs-rel/libregexp-opcode.h +73 -0
- package/engine/quickjs-rel/libregexp.c +3478 -0
- package/engine/quickjs-rel/libregexp.h +101 -0
- package/engine/quickjs-rel/libunicode-table.h +5173 -0
- package/engine/quickjs-rel/libunicode.c +2069 -0
- package/engine/quickjs-rel/libunicode.h +172 -0
- package/engine/quickjs-rel/list.h +107 -0
- package/engine/quickjs-rel/quickjs-atom.h +280 -0
- package/engine/quickjs-rel/quickjs-c-atomics.h +54 -0
- package/engine/quickjs-rel/quickjs-opcode.h +385 -0
- package/engine/quickjs-rel/quickjs.c +64854 -0
- package/engine/quickjs-rel/quickjs.h +1577 -0
- package/modules/cdp/quickjs-cdp.c +1386 -0
- package/modules/cdp/quickjs-cdp.h +122 -0
- package/modules/cdp/react/QuickJSInspector.cpp +322 -0
- package/modules/cdp/react/QuickJSInspector.h +114 -0
- package/modules/hermes-compat/include/hermes/DebuggerAPI.h +20 -0
- package/modules/hermes-compat/include/hermes/Public/CrashManager.h +47 -0
- package/modules/hermes-compat/include/hermes/Public/CtorConfig.h +88 -0
- package/modules/hermes-compat/include/hermes/Public/GCConfig.h +83 -0
- package/modules/hermes-compat/include/hermes/Public/HermesExport.h +17 -0
- package/modules/hermes-compat/include/hermes/Public/RuntimeConfig.h +66 -0
- package/modules/hermes-compat/include/hermes/Public/SamplingProfiler.h +22 -0
- package/modules/hermes-compat/include/hermes/hermes.h +195 -0
- package/modules/hermes-compat/include/hermes/inspector/RuntimeAdapter.h +43 -0
- package/modules/hermes-compat/include/hermes/inspector-modern/chrome/Registration.h +31 -0
- package/modules/hermes-compat/include/hermes-compat/Diagnostics.h +35 -0
- package/modules/hermes-compat/src/HermesCompat.cpp +557 -0
- package/package.json +104 -0
- package/scripts/bytecode/compile.js +99 -0
- package/scripts/expo/plugin.js +231 -0
- package/scripts/postinstall.js +74 -0
- package/scripts/react_native_quickjs_pods.rb +237 -0
- package/scripts/setup/edits.js +311 -0
- package/scripts/setup/run.js +121 -0
- package/src/bytecode/QuickJSBytecode.cpp +50 -0
- package/src/bytecode/QuickJSBytecode.h +50 -0
- package/src/module/QuickJSCompat.cpp +92 -0
- package/src/module/QuickJSCompat.h +19 -0
- package/src/module/QuickJSModule.cpp +70 -0
- package/src/module/QuickJSModule.h +108 -0
- package/src/module/QuickJSModuleNative.h +93 -0
- package/src/runtime/QuickJSInstance.cpp +37 -0
- package/src/runtime/QuickJSInstance.h +74 -0
- package/src/runtime/QuickJSRuntime.cpp +1864 -0
- package/src/runtime/QuickJSRuntime.h +529 -0
- package/src/runtime/QuickJSRuntimeConfig.h +103 -0
- package/src/runtime/QuickJSRuntimeFactory.cpp +34 -0
- package/src/runtime/QuickJSRuntimeFactory.h +24 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Ammar Ahmed.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include "QuickJSModule.h"
|
|
9
|
+
|
|
10
|
+
#include <algorithm>
|
|
11
|
+
#include <cstring>
|
|
12
|
+
|
|
13
|
+
#include "QuickJSRuntime.h"
|
|
14
|
+
|
|
15
|
+
namespace qjs {
|
|
16
|
+
|
|
17
|
+
namespace {
|
|
18
|
+
|
|
19
|
+
// Function-local rather than namespace-scope, so registration from another
|
|
20
|
+
// translation unit's static initializer cannot run before the vector is
|
|
21
|
+
// constructed. QJS_REGISTER_MODULE exists to be used from other translation
|
|
22
|
+
// units, and initialization order across them is unspecified.
|
|
23
|
+
std::vector<ModuleRegistration> ®istry() {
|
|
24
|
+
static std::vector<ModuleRegistration> modules;
|
|
25
|
+
return modules;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
} // namespace
|
|
29
|
+
|
|
30
|
+
void registerModule(const ModuleRegistration &module) {
|
|
31
|
+
if (module.install == nullptr || module.name == nullptr) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
auto &modules = registry();
|
|
36
|
+
for (const auto &existing : modules) {
|
|
37
|
+
if (std::strcmp(existing.name, module.name) == 0) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
modules.push_back(module);
|
|
42
|
+
|
|
43
|
+
// stable_sort so equal priorities keep registration order, which is what a
|
|
44
|
+
// module author leaving priority at its default would expect.
|
|
45
|
+
std::stable_sort(
|
|
46
|
+
modules.begin(), modules.end(),
|
|
47
|
+
[](const ModuleRegistration &a, const ModuleRegistration &b) {
|
|
48
|
+
return a.priority < b.priority;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const std::vector<ModuleRegistration> ®isteredModules() {
|
|
53
|
+
return registry();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void installModules(jsi::Runtime &runtime) {
|
|
57
|
+
for (const auto &module : registry()) {
|
|
58
|
+
module.install(runtime);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
JSContext *contextFromRuntime(jsi::Runtime &runtime) noexcept {
|
|
63
|
+
// dynamic_cast rather than a type tag: the reference may be any
|
|
64
|
+
// implementation, including a decorator around ours, and guessing wrong
|
|
65
|
+
// would corrupt memory rather than fail cleanly.
|
|
66
|
+
auto *quickjs = dynamic_cast<QuickJSRuntime *>(&runtime);
|
|
67
|
+
return quickjs != nullptr ? quickjs->context() : nullptr;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
} // namespace qjs
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Ammar Ahmed.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <jsi/jsi.h>
|
|
11
|
+
|
|
12
|
+
#include <vector>
|
|
13
|
+
|
|
14
|
+
struct JSContext;
|
|
15
|
+
|
|
16
|
+
namespace qjs {
|
|
17
|
+
|
|
18
|
+
namespace jsi = facebook::jsi;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The QuickJS module ABI.
|
|
22
|
+
*
|
|
23
|
+
* A module is a standalone npm package containing C or C++ that installs
|
|
24
|
+
* globals into the runtime -- a native implementation of an API React Native
|
|
25
|
+
* would otherwise ship as a JavaScript shim. `TextEncoder` is the archetype:
|
|
26
|
+
* the shim walks a string one code unit at a time building an array, where the
|
|
27
|
+
* native version is a bounds-checked loop into a pre-sized buffer.
|
|
28
|
+
*
|
|
29
|
+
* Modules are ordinary consumers of JSI, so they stay portable and testable on
|
|
30
|
+
* the host -- until they need not to be, at which point see
|
|
31
|
+
* `contextFromRuntime()`.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/// Installs a module's globals. Called once per runtime, before any
|
|
35
|
+
/// application JavaScript runs.
|
|
36
|
+
using ModuleInstaller = void (*)(jsi::Runtime &);
|
|
37
|
+
|
|
38
|
+
struct ModuleRegistration {
|
|
39
|
+
/// Conventionally the npm package name. Used in diagnostics and to make
|
|
40
|
+
/// double registration detectable.
|
|
41
|
+
const char *name;
|
|
42
|
+
|
|
43
|
+
ModuleInstaller install;
|
|
44
|
+
|
|
45
|
+
/// Ascending install order, so a module depending on another's globals can
|
|
46
|
+
/// order itself after it. Ties keep registration order.
|
|
47
|
+
int priority;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Registers a module to be installed into every runtime created afterwards.
|
|
52
|
+
* Safe to call before any runtime exists.
|
|
53
|
+
*
|
|
54
|
+
* A duplicate name is ignored rather than fatal: static libraries get linked
|
|
55
|
+
* twice more often than anyone expects, and crashing an app over it would be a
|
|
56
|
+
* poor trade.
|
|
57
|
+
*/
|
|
58
|
+
void registerModule(const ModuleRegistration &module);
|
|
59
|
+
|
|
60
|
+
inline void registerModule(
|
|
61
|
+
const char *name, ModuleInstaller install, int priority = 0) {
|
|
62
|
+
registerModule(ModuleRegistration{name, install, priority});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/// `makeQuickJSRuntime()` calls this. Call it yourself only for a runtime you
|
|
66
|
+
/// built by other means.
|
|
67
|
+
void installModules(jsi::Runtime &runtime);
|
|
68
|
+
|
|
69
|
+
const std::vector<ModuleRegistration> ®isteredModules();
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The `JSContext *` behind `runtime`, or nullptr if it is not one of ours.
|
|
73
|
+
*
|
|
74
|
+
* Use it where JSI cannot express something efficiently. The cost is
|
|
75
|
+
* portability, so check the return value rather than assuming it, and keep a
|
|
76
|
+
* plain-JSI path behind it. `QuickJSModuleNative.h` has the companion helpers;
|
|
77
|
+
* it is a separate header because it pulls in `quickjs.h`, which a portable
|
|
78
|
+
* module has no reason to see.
|
|
79
|
+
*/
|
|
80
|
+
JSContext *contextFromRuntime(jsi::Runtime &runtime) noexcept;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Registers a module at static-initialization time.
|
|
84
|
+
*
|
|
85
|
+
* Convenient, but a static initializer in a static library is dropped by the
|
|
86
|
+
* linker unless something in its translation unit is referenced. The primary
|
|
87
|
+
* mechanism for a shipped module is therefore generated registration code,
|
|
88
|
+
* which cannot be stripped. Use this for shared libraries and tests.
|
|
89
|
+
*/
|
|
90
|
+
/* The indirection is so INSTALL_FN may be a qualified name such as
|
|
91
|
+
ns::install -- pasting that into an identifier would not compile. */
|
|
92
|
+
#define QJS_REGISTER_MODULE_IMPL2(NAME, INSTALL_FN, UNIQUE) \
|
|
93
|
+
namespace { \
|
|
94
|
+
struct QjsModuleAutoRegister_##UNIQUE { \
|
|
95
|
+
QjsModuleAutoRegister_##UNIQUE() { \
|
|
96
|
+
::qjs::registerModule(NAME, INSTALL_FN); \
|
|
97
|
+
} \
|
|
98
|
+
}; \
|
|
99
|
+
static QjsModuleAutoRegister_##UNIQUE qjs_module_auto_register_##UNIQUE; \
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
#define QJS_REGISTER_MODULE_IMPL(NAME, INSTALL_FN, UNIQUE) \
|
|
103
|
+
QJS_REGISTER_MODULE_IMPL2(NAME, INSTALL_FN, UNIQUE)
|
|
104
|
+
|
|
105
|
+
#define QJS_REGISTER_MODULE(NAME, INSTALL_FN) \
|
|
106
|
+
QJS_REGISTER_MODULE_IMPL(NAME, INSTALL_FN, __LINE__)
|
|
107
|
+
|
|
108
|
+
} // namespace qjs
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Ammar Ahmed.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <jsi/jsi.h>
|
|
11
|
+
#include <quickjs.h>
|
|
12
|
+
|
|
13
|
+
#include "QuickJSModule.h"
|
|
14
|
+
#include "QuickJSRuntime.h"
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The engine escape hatch for QuickJS modules.
|
|
18
|
+
*
|
|
19
|
+
* Include this to work directly against the engine, which is the recommended
|
|
20
|
+
* way to write a module here. A module written against `QuickJSModule.h` alone
|
|
21
|
+
* is portable JSI and runs on any jsi::Runtime; that is the right choice only
|
|
22
|
+
* when the module must also run on Hermes.
|
|
23
|
+
*
|
|
24
|
+
* The decisive reason is constructors. A jsi::Function from
|
|
25
|
+
* createFromHostFunction is not a constructor, and `new` against it does not
|
|
26
|
+
* fail loudly: `thisVal` is the constructor function itself, so writes to
|
|
27
|
+
* `this` mutate the constructor, `instanceof` is false, and
|
|
28
|
+
* `class S extends Thing {}` gives undefined from `new S()`. JSI's
|
|
29
|
+
* HostFunctionType has no new.target and no way to build `this` from
|
|
30
|
+
* `.prototype`, so it cannot be fixed from above. `JS_NewCFunction2` with
|
|
31
|
+
* `JS_CFUNC_constructor` gives a real constructor.
|
|
32
|
+
*
|
|
33
|
+
* The rest is cost. Creating a Uint8Array in plain JSI means fetching the
|
|
34
|
+
* global constructor and calling it, per call, against one `JS_NewUint8Array`;
|
|
35
|
+
* `JS_NewStringLen` takes UTF-8 bytes directly; `JS_GetUint8Array` reads a
|
|
36
|
+
* typed array without copying. Atoms, classes and opaque pointers have no JSI
|
|
37
|
+
* spelling at all.
|
|
38
|
+
*
|
|
39
|
+
* A module that needs both writes the fast path behind a check:
|
|
40
|
+
*
|
|
41
|
+
* JSContext *ctx = qjs::contextFromRuntime(rt);
|
|
42
|
+
* if (ctx) { ... } else { ... }
|
|
43
|
+
*
|
|
44
|
+
* Ownership follows the rest of the runtime. `adopt*` takes the reference you
|
|
45
|
+
* pass; `borrow*` returns one you must not free, valid only as long as the
|
|
46
|
+
* original. A `JS_*` function returning a JSValue gives you a reference you
|
|
47
|
+
* own.
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
namespace qjs {
|
|
51
|
+
|
|
52
|
+
/// The concrete runtime, or nullptr if `runtime` is not ours.
|
|
53
|
+
inline QuickJSRuntime *quickJSRuntime(jsi::Runtime &runtime) noexcept {
|
|
54
|
+
return dynamic_cast<QuickJSRuntime *>(&runtime);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/// Wraps a JSValue you own as a jsi::Value, transferring ownership. The usual
|
|
58
|
+
/// return path for a host function that used the engine directly.
|
|
59
|
+
inline jsi::Value adoptJSValue(jsi::Runtime &runtime, JSValue value) {
|
|
60
|
+
auto *rt = quickJSRuntime(runtime);
|
|
61
|
+
if (rt == nullptr) {
|
|
62
|
+
// Nothing owns this value now and it cannot be freed without a context, so
|
|
63
|
+
// this is a programming error rather than a runtime condition.
|
|
64
|
+
throw jsi::JSINativeException(
|
|
65
|
+
"adoptJSValue called on a runtime that is not QuickJS-backed");
|
|
66
|
+
}
|
|
67
|
+
return rt->createValue(value);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/// Borrows the JSValue behind a jsi::Value. Owned by `value`, valid only while
|
|
71
|
+
/// it is, and must not be freed.
|
|
72
|
+
inline JSValue borrowJSValue(jsi::Runtime &runtime, const jsi::Value &value) {
|
|
73
|
+
auto *rt = quickJSRuntime(runtime);
|
|
74
|
+
if (rt == nullptr) {
|
|
75
|
+
throw jsi::JSINativeException(
|
|
76
|
+
"borrowJSValue called on a runtime that is not QuickJS-backed");
|
|
77
|
+
}
|
|
78
|
+
return rt->toJSValue(value);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/// Converts a pending quickjs exception into a thrown jsi::JSError. Call it
|
|
82
|
+
/// whenever an engine API returns the exception sentinel: a pending exception
|
|
83
|
+
/// left alive past the host function's return corrupts the engine's error
|
|
84
|
+
/// state and fails far from its cause.
|
|
85
|
+
[[noreturn]] inline void throwPendingQuickJSError(jsi::Runtime &runtime) {
|
|
86
|
+
auto *rt = quickJSRuntime(runtime);
|
|
87
|
+
if (rt == nullptr) {
|
|
88
|
+
throw jsi::JSINativeException("QuickJS error on a non-QuickJS runtime");
|
|
89
|
+
}
|
|
90
|
+
rt->throwPendingError();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
} // namespace qjs
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Ammar Ahmed.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include "QuickJSInstance.h"
|
|
9
|
+
|
|
10
|
+
#include "QuickJSRuntimeFactory.h"
|
|
11
|
+
|
|
12
|
+
#if defined(RNQJS_ENABLE_CDP) && RNQJS_ENABLE_CDP
|
|
13
|
+
#include "QuickJSInspector.h"
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
namespace facebook::react {
|
|
17
|
+
|
|
18
|
+
std::unique_ptr<JSRuntime> QuickJSInstance::createJSRuntime(
|
|
19
|
+
std::shared_ptr<MessageQueueThread> /*msgQueueThread*/) noexcept {
|
|
20
|
+
// The message queue thread is unused: the debugger work that has to happen on
|
|
21
|
+
// the JS thread is routed through React Native's RuntimeExecutor instead.
|
|
22
|
+
auto runtime = qjs::makeQuickJSRuntime(config_);
|
|
23
|
+
|
|
24
|
+
#if defined(RNQJS_ENABLE_CDP) && RNQJS_ENABLE_CDP
|
|
25
|
+
if (config_.enableDebugger) {
|
|
26
|
+
return std::make_unique<qjs::QuickJSInspectorRuntime>(std::move(runtime));
|
|
27
|
+
}
|
|
28
|
+
#endif
|
|
29
|
+
|
|
30
|
+
// JSIRuntimeHolder's base class vends a FallbackRuntimeTargetDelegate, which
|
|
31
|
+
// is the honest answer for a runtime that was never instrumented: DevTools
|
|
32
|
+
// still gets the Runtime domain through generic JSI, and the Debugger domain
|
|
33
|
+
// reports that it cannot bind breakpoints.
|
|
34
|
+
return std::make_unique<JSIRuntimeHolder>(std::move(runtime));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Ammar Ahmed.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <react/runtime/JSRuntimeFactory.h>
|
|
11
|
+
|
|
12
|
+
#include <memory>
|
|
13
|
+
#include <utility>
|
|
14
|
+
|
|
15
|
+
#include "QuickJSRuntimeConfig.h"
|
|
16
|
+
|
|
17
|
+
namespace facebook::react {
|
|
18
|
+
|
|
19
|
+
class MessageQueueThread;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The React Native engine entry point: hands a QuickJS-backed jsi::Runtime to
|
|
23
|
+
* ReactInstance. Shared by the Android and Apple layers, which do nothing but
|
|
24
|
+
* construct this and pass it through.
|
|
25
|
+
*/
|
|
26
|
+
class QuickJSInstance : public JSRuntimeFactory {
|
|
27
|
+
public:
|
|
28
|
+
/**
|
|
29
|
+
* Default construction turns the debugger on in debug builds.
|
|
30
|
+
*
|
|
31
|
+
* Decided here rather than in the two platform layers, which would otherwise
|
|
32
|
+
* each need the same decision and fail silently on getting it wrong: the app
|
|
33
|
+
* runs, DevTools attaches, and no breakpoint ever binds -- on that platform
|
|
34
|
+
* only.
|
|
35
|
+
*
|
|
36
|
+
* It cannot be deferred until a frontend connects. Statement traps are
|
|
37
|
+
* emitted at parse time, so a runtime that was not instrumented before the
|
|
38
|
+
* bundle ran cannot be made debuggable afterwards. "Is this app debuggable?"
|
|
39
|
+
* is therefore a build-time question, and the honest default is yes in debug
|
|
40
|
+
* and no in release -- matching where React Native enables its own inspector.
|
|
41
|
+
*/
|
|
42
|
+
QuickJSInstance() {
|
|
43
|
+
config_.enableDebugger = debuggerEnabledByDefault();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
explicit QuickJSInstance(qjs::QuickJSRuntimeConfig config)
|
|
47
|
+
: config_(std::move(config)) {}
|
|
48
|
+
|
|
49
|
+
~QuickJSInstance() override = default;
|
|
50
|
+
|
|
51
|
+
/// Exposed so an embedder building a config by hand can ask for the same
|
|
52
|
+
/// answer rather than re-deriving it. DEBUG is what CocoaPods defines for
|
|
53
|
+
/// Debug configurations and NDEBUG what CMake defines for Release; neither
|
|
54
|
+
/// platform sets the other's macro, so both are checked.
|
|
55
|
+
static constexpr bool debuggerEnabledByDefault() {
|
|
56
|
+
#if !defined(RNQJS_ENABLE_CDP) || !RNQJS_ENABLE_CDP
|
|
57
|
+
// No debugger compiled into this binary, so setting the flag would only buy
|
|
58
|
+
// parse-time instrumentation nothing can use.
|
|
59
|
+
return false;
|
|
60
|
+
#elif (defined(DEBUG) && DEBUG) || !defined(NDEBUG)
|
|
61
|
+
return true;
|
|
62
|
+
#else
|
|
63
|
+
return false;
|
|
64
|
+
#endif
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
std::unique_ptr<JSRuntime> createJSRuntime(
|
|
68
|
+
std::shared_ptr<MessageQueueThread> msgQueueThread) noexcept override;
|
|
69
|
+
|
|
70
|
+
private:
|
|
71
|
+
qjs::QuickJSRuntimeConfig config_;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
} // namespace facebook::react
|