@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,88 @@
|
|
|
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
|
+
/*
|
|
9
|
+
* Generates a config class and its Builder from a field list, the way Hermes
|
|
10
|
+
* does. Same shape as upstream -- getX, getDefaultX, rebuild, Builder::withX,
|
|
11
|
+
* hasX, update, build -- so code written against Hermes compiles unchanged.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
#pragma once
|
|
15
|
+
|
|
16
|
+
#include <utility>
|
|
17
|
+
|
|
18
|
+
#define _HERMES_CTORCONFIG_FIELD(CX, TYPE, NAME, ...) TYPE NAME##_{__VA_ARGS__};
|
|
19
|
+
#define _HERMES_CTORCONFIG_EXPLICIT(CX, TYPE, NAME, ...) \
|
|
20
|
+
bool NAME##Explicit_{false};
|
|
21
|
+
|
|
22
|
+
#define _HERMES_CTORCONFIG_GETTER(CX, TYPE, NAME, ...) \
|
|
23
|
+
inline TYPE get##NAME() const { \
|
|
24
|
+
return NAME##_; \
|
|
25
|
+
} \
|
|
26
|
+
static CX TYPE getDefault##NAME() { \
|
|
27
|
+
using TypeAsSingleToken = TYPE; \
|
|
28
|
+
return TypeAsSingleToken{__VA_ARGS__}; \
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
#define _HERMES_CTORCONFIG_SETTER(CX, TYPE, NAME, ...) \
|
|
32
|
+
inline auto with##NAME(TYPE NAME)->decltype(*this) { \
|
|
33
|
+
config_.NAME##_ = std::move(NAME); \
|
|
34
|
+
NAME##Explicit_ = true; \
|
|
35
|
+
return *this; \
|
|
36
|
+
} \
|
|
37
|
+
bool has##NAME() const { \
|
|
38
|
+
return NAME##Explicit_; \
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#define _HERMES_CTORCONFIG_UPDATE(CX, TYPE, NAME, ...) \
|
|
42
|
+
if (newConfig.has##NAME()) with##NAME(newConfig.config_.get##NAME());
|
|
43
|
+
|
|
44
|
+
#define _HERMES_CTORCONFIG_STRUCT(NAME, FIELDS, BUILD_BODY) \
|
|
45
|
+
class NAME { \
|
|
46
|
+
FIELDS(_HERMES_CTORCONFIG_FIELD) \
|
|
47
|
+
\
|
|
48
|
+
public: \
|
|
49
|
+
class Builder; \
|
|
50
|
+
friend Builder; \
|
|
51
|
+
FIELDS(_HERMES_CTORCONFIG_GETTER) \
|
|
52
|
+
inline Builder rebuild() const; \
|
|
53
|
+
\
|
|
54
|
+
private: \
|
|
55
|
+
inline void doBuild(const Builder &builder); \
|
|
56
|
+
}; \
|
|
57
|
+
\
|
|
58
|
+
class NAME::Builder { \
|
|
59
|
+
NAME config_; \
|
|
60
|
+
FIELDS(_HERMES_CTORCONFIG_EXPLICIT) \
|
|
61
|
+
\
|
|
62
|
+
public: \
|
|
63
|
+
Builder() = default; \
|
|
64
|
+
explicit Builder(const NAME &config) : config_(config) {} \
|
|
65
|
+
inline const NAME build() { \
|
|
66
|
+
config_.doBuild(*this); \
|
|
67
|
+
return config_; \
|
|
68
|
+
} \
|
|
69
|
+
inline Builder update(const NAME::Builder &newConfig); \
|
|
70
|
+
FIELDS(_HERMES_CTORCONFIG_SETTER) \
|
|
71
|
+
}; \
|
|
72
|
+
\
|
|
73
|
+
inline NAME::Builder NAME::rebuild() const { \
|
|
74
|
+
return Builder(*this); \
|
|
75
|
+
} \
|
|
76
|
+
\
|
|
77
|
+
inline NAME::Builder NAME::Builder::update(const NAME::Builder &newConfig) { \
|
|
78
|
+
FIELDS(_HERMES_CTORCONFIG_UPDATE) \
|
|
79
|
+
return *this; \
|
|
80
|
+
} \
|
|
81
|
+
\
|
|
82
|
+
inline void NAME::doBuild(const NAME::Builder &builder) { \
|
|
83
|
+
(void)builder; \
|
|
84
|
+
BUILD_BODY \
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/// Marks a field whose default is not constexpr, as upstream does.
|
|
88
|
+
#define HERMES_NON_CONSTEXPR
|
|
@@ -0,0 +1,83 @@
|
|
|
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 <hermes/Public/CtorConfig.h>
|
|
11
|
+
|
|
12
|
+
#include <chrono>
|
|
13
|
+
#include <cstdint>
|
|
14
|
+
#include <functional>
|
|
15
|
+
#include <limits>
|
|
16
|
+
#include <string>
|
|
17
|
+
|
|
18
|
+
namespace hermes::vm {
|
|
19
|
+
|
|
20
|
+
using gcheapsize_t = uint32_t;
|
|
21
|
+
|
|
22
|
+
enum ReleaseUnused {
|
|
23
|
+
kReleaseUnusedNone = 0,
|
|
24
|
+
kReleaseUnusedOld,
|
|
25
|
+
kReleaseUnusedYoungOnFull,
|
|
26
|
+
kReleaseUnusedYoungAlways
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
enum class GCEventKind {
|
|
30
|
+
CollectionStart,
|
|
31
|
+
CollectionEnd,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/// Hermes fills this in for its analytics callback. QuickJS never emits one,
|
|
35
|
+
/// so the fields exist to be named, not to be populated.
|
|
36
|
+
struct GCAnalyticsEvent {
|
|
37
|
+
std::string runtimeDescription;
|
|
38
|
+
std::string gcKind;
|
|
39
|
+
std::string collectionType;
|
|
40
|
+
std::string cause;
|
|
41
|
+
std::chrono::milliseconds duration{0};
|
|
42
|
+
std::chrono::milliseconds cpuDuration{0};
|
|
43
|
+
uint64_t allocated{0};
|
|
44
|
+
uint64_t size{0};
|
|
45
|
+
uint64_t external{0};
|
|
46
|
+
uint64_t survivalRatio{0};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
#define GC_TRIPWIRE_FIELDS(F) \
|
|
50
|
+
F(constexpr, gcheapsize_t, Limit, std::numeric_limits<gcheapsize_t>::max())
|
|
51
|
+
|
|
52
|
+
_HERMES_CTORCONFIG_STRUCT(GCTripwireConfig, GC_TRIPWIRE_FIELDS, {});
|
|
53
|
+
|
|
54
|
+
#define GC_HANDLESAN_FIELDS(F) \
|
|
55
|
+
F(constexpr, double, SanitizeRate, 0.0) \
|
|
56
|
+
F(constexpr, int64_t, RandomSeed, -1)
|
|
57
|
+
|
|
58
|
+
_HERMES_CTORCONFIG_STRUCT(GCSanitizeConfig, GC_HANDLESAN_FIELDS, {});
|
|
59
|
+
|
|
60
|
+
#define GC_FIELDS(F) \
|
|
61
|
+
F(constexpr, gcheapsize_t, MinHeapSize, 0) \
|
|
62
|
+
F(constexpr, gcheapsize_t, InitHeapSize, 32 << 20) \
|
|
63
|
+
F(constexpr, gcheapsize_t, MaxHeapSize, 3u << 30) \
|
|
64
|
+
F(constexpr, double, OccupancyTarget, 0.5) \
|
|
65
|
+
F(constexpr, unsigned, EffectiveOOMThreshold, \
|
|
66
|
+
std::numeric_limits<unsigned>::max()) \
|
|
67
|
+
F(constexpr, GCSanitizeConfig, SanitizeConfig) \
|
|
68
|
+
F(constexpr, bool, ShouldRandomizeAllocSpace, false) \
|
|
69
|
+
F(constexpr, bool, ShouldRecordStats, false) \
|
|
70
|
+
F(constexpr, ReleaseUnused, ShouldReleaseUnused, kReleaseUnusedOld) \
|
|
71
|
+
F(HERMES_NON_CONSTEXPR, std::string, Name, "") \
|
|
72
|
+
F(HERMES_NON_CONSTEXPR, GCTripwireConfig, TripwireConfig) \
|
|
73
|
+
F(constexpr, bool, AllocInYoung, true) \
|
|
74
|
+
F(constexpr, bool, RevertToYGAtTTI, false) \
|
|
75
|
+
F(constexpr, bool, ProtectMetadata, false) \
|
|
76
|
+
F(HERMES_NON_CONSTEXPR, std::function<void(const GCAnalyticsEvent &)>, \
|
|
77
|
+
AnalyticsCallback, nullptr) \
|
|
78
|
+
F(HERMES_NON_CONSTEXPR, std::function<void(GCEventKind, const char *)>, \
|
|
79
|
+
Callback, nullptr)
|
|
80
|
+
|
|
81
|
+
_HERMES_CTORCONFIG_STRUCT(GCConfig, GC_FIELDS, {});
|
|
82
|
+
|
|
83
|
+
} // namespace hermes::vm
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
// The shim is always compiled into the app, so there is no import case.
|
|
11
|
+
#ifndef HERMES_EXPORT
|
|
12
|
+
#if defined(_MSC_VER)
|
|
13
|
+
#define HERMES_EXPORT
|
|
14
|
+
#else
|
|
15
|
+
#define HERMES_EXPORT __attribute__((visibility("default")))
|
|
16
|
+
#endif
|
|
17
|
+
#endif
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
+
/*
|
|
9
|
+
* The full field set, with Hermes's own defaults, so that code configuring the
|
|
10
|
+
* VM compiles unchanged.
|
|
11
|
+
*
|
|
12
|
+
* Almost none of it has a QuickJS equivalent. Rather than drop settings
|
|
13
|
+
* silently, makeHermesRuntime() compares the config it is handed against these
|
|
14
|
+
* defaults and reports every field it cannot honour -- loudly for the ones
|
|
15
|
+
* that change what JavaScript is allowed to do, such as EnableEval, and once
|
|
16
|
+
* for tuning fields nothing observable depends on.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
#pragma once
|
|
20
|
+
|
|
21
|
+
#include <hermes/Public/CrashManager.h>
|
|
22
|
+
#include <hermes/Public/CtorConfig.h>
|
|
23
|
+
#include <hermes/Public/GCConfig.h>
|
|
24
|
+
|
|
25
|
+
#include <cstdint>
|
|
26
|
+
#include <string>
|
|
27
|
+
|
|
28
|
+
namespace hermes::vm {
|
|
29
|
+
|
|
30
|
+
enum CompilationMode {
|
|
31
|
+
SmartCompilation,
|
|
32
|
+
ForceEagerCompilation,
|
|
33
|
+
ForceLazyCompilation
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
class PinnedHermesValue;
|
|
37
|
+
|
|
38
|
+
#define RUNTIME_FIELDS(F) \
|
|
39
|
+
F(HERMES_NON_CONSTEXPR, vm::GCConfig, GCConfig) \
|
|
40
|
+
F(constexpr, PinnedHermesValue *, RegisterStack, nullptr) \
|
|
41
|
+
F(constexpr, unsigned, MaxNumRegisters, 1024 * 1024) \
|
|
42
|
+
F(constexpr, bool, EnableJIT, false) \
|
|
43
|
+
F(constexpr, bool, EnableEval, true) \
|
|
44
|
+
F(constexpr, bool, VerifyEvalIR, false) \
|
|
45
|
+
F(constexpr, bool, OptimizedEval, false) \
|
|
46
|
+
F(constexpr, bool, AsyncBreakCheckInEval, false) \
|
|
47
|
+
F(constexpr, bool, ES6Promise, true) \
|
|
48
|
+
F(constexpr, bool, ES6Proxy, true) \
|
|
49
|
+
F(constexpr, bool, Intl, true) \
|
|
50
|
+
F(constexpr, bool, TraceEnabled, false) \
|
|
51
|
+
F(HERMES_NON_CONSTEXPR, std::string, TraceScratchPath, "") \
|
|
52
|
+
F(HERMES_NON_CONSTEXPR, std::string, TraceResultPath, "") \
|
|
53
|
+
F(constexpr, bool, EnableSampledStats, false) \
|
|
54
|
+
F(constexpr, bool, EnableSampleProfiling, true) \
|
|
55
|
+
F(constexpr, bool, RandomizeMemoryLayout, false) \
|
|
56
|
+
F(constexpr, unsigned, BytecodeWarmupPercent, 0) \
|
|
57
|
+
F(constexpr, bool, TrackIO, false) \
|
|
58
|
+
F(constexpr, bool, EnableHermesInternal, true) \
|
|
59
|
+
F(constexpr, bool, EnableHermesInternalTestMethods, false) \
|
|
60
|
+
F(constexpr, bool, EnableGenerator, true) \
|
|
61
|
+
F(constexpr, bool, MicrotaskQueue, false) \
|
|
62
|
+
F(constexpr, uint32_t, VMExperimentFlags, 0)
|
|
63
|
+
|
|
64
|
+
_HERMES_CTORCONFIG_STRUCT(RuntimeConfig, RUNTIME_FIELDS, {});
|
|
65
|
+
|
|
66
|
+
} // namespace hermes::vm
|
|
@@ -0,0 +1,22 @@
|
|
|
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 <hermes/Public/HermesExport.h>
|
|
11
|
+
|
|
12
|
+
namespace facebook::hermes::sampling_profiler {
|
|
13
|
+
|
|
14
|
+
// Named so that IHermes::dumpSampledTraceToProfile has a complete return type.
|
|
15
|
+
// QuickJS has no sampling profiler, so a caller that reads a Profile does not
|
|
16
|
+
// compile -- which is the right answer, and happens at build time.
|
|
17
|
+
class HERMES_EXPORT Profile {
|
|
18
|
+
public:
|
|
19
|
+
Profile() = default;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
} // namespace facebook::hermes::sampling_profiler
|
|
@@ -0,0 +1,195 @@
|
|
|
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
|
+
/*
|
|
9
|
+
* A source-compatible <hermes/hermes.h> whose makeHermesRuntime() returns a
|
|
10
|
+
* QuickJS-backed runtime, so libraries that create their own Hermes runtime --
|
|
11
|
+
* react-native-worklets, and so react-native-reanimated -- build and run
|
|
12
|
+
* unmodified. Those libraries select an engine with __has_include(<hermes/
|
|
13
|
+
* hermes.h>) and have no third-engine branch, so without this they cannot be
|
|
14
|
+
* used at all.
|
|
15
|
+
*
|
|
16
|
+
* This is source compatibility, never ABI compatibility. These headers must
|
|
17
|
+
* not be on the include path while a real libhermes is on the link line.
|
|
18
|
+
*
|
|
19
|
+
* Rule when editing: no member declaration below may be conditional on a
|
|
20
|
+
* preprocessor macro. Free functions may be; virtual functions and data
|
|
21
|
+
* members may not. A conditional virtual shifts every vtable slot after it,
|
|
22
|
+
* and consumers are compiled separately from this shim with flags it does not
|
|
23
|
+
* control -- the failure is a silent call to the wrong function.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
#pragma once
|
|
27
|
+
|
|
28
|
+
#include <hermes/DebuggerAPI.h>
|
|
29
|
+
#include <hermes/Public/HermesExport.h>
|
|
30
|
+
#include <hermes/Public/RuntimeConfig.h>
|
|
31
|
+
#include <hermes/Public/SamplingProfiler.h>
|
|
32
|
+
#include <jsi/jsi.h>
|
|
33
|
+
|
|
34
|
+
#include <memory>
|
|
35
|
+
#include <ostream>
|
|
36
|
+
#include <string>
|
|
37
|
+
#include <unordered_map>
|
|
38
|
+
#include <utility>
|
|
39
|
+
#include <vector>
|
|
40
|
+
|
|
41
|
+
struct SHUnit;
|
|
42
|
+
struct SHRuntime;
|
|
43
|
+
|
|
44
|
+
namespace hermes::vm {
|
|
45
|
+
class GCExecTrace {
|
|
46
|
+
public:
|
|
47
|
+
GCExecTrace() = default;
|
|
48
|
+
};
|
|
49
|
+
class Runtime;
|
|
50
|
+
} // namespace hermes::vm
|
|
51
|
+
|
|
52
|
+
namespace facebook {
|
|
53
|
+
namespace jsi {
|
|
54
|
+
class ThreadSafeRuntime;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
namespace hermes {
|
|
58
|
+
|
|
59
|
+
class HermesRuntime;
|
|
60
|
+
|
|
61
|
+
/// Engine-global operations that need no runtime instance. The UUIDs match
|
|
62
|
+
/// real Hermes so that castInterface in unmodified third-party code succeeds.
|
|
63
|
+
class HERMES_EXPORT IHermesRootAPI : public jsi::ICast {
|
|
64
|
+
public:
|
|
65
|
+
static constexpr jsi::UUID uuid{
|
|
66
|
+
0xb654d898, 0xdfad, 0x11ef, 0x859a, 0x325096b39f47};
|
|
67
|
+
|
|
68
|
+
virtual std::unique_ptr<HermesRuntime> makeHermesRuntime(
|
|
69
|
+
const ::hermes::vm::RuntimeConfig &runtimeConfig) = 0;
|
|
70
|
+
|
|
71
|
+
/// Always false: nothing here produces Hermes bytecode. A caller handed a
|
|
72
|
+
/// real .hbc bundle takes its "this is source" path and fails in the parser,
|
|
73
|
+
/// so the shim sniffs the HBC magic and reports, naming the real cause.
|
|
74
|
+
virtual bool isHermesBytecode(const uint8_t *data, size_t len) = 0;
|
|
75
|
+
virtual uint32_t getBytecodeVersion() = 0;
|
|
76
|
+
virtual void prefetchHermesBytecode(const uint8_t *data, size_t len) = 0;
|
|
77
|
+
virtual bool hermesBytecodeSanityCheck(
|
|
78
|
+
const uint8_t *data, size_t len, std::string *errorMessage) = 0;
|
|
79
|
+
virtual void setFatalHandler(void (*handler)(const std::string &)) = 0;
|
|
80
|
+
virtual std::pair<const uint8_t *, size_t> getBytecodeEpilogue(
|
|
81
|
+
const uint8_t *data, size_t len) = 0;
|
|
82
|
+
virtual void enableSamplingProfiler(double meanHzFreq) = 0;
|
|
83
|
+
virtual void disableSamplingProfiler() = 0;
|
|
84
|
+
virtual void dumpSampledTraceToFile(const std::string &fileName) = 0;
|
|
85
|
+
virtual void dumpSampledTraceToStream(std::ostream &stream) = 0;
|
|
86
|
+
virtual std::unordered_map<std::string, std::vector<std::string>>
|
|
87
|
+
getExecutedFunctions() = 0;
|
|
88
|
+
virtual bool isCodeCoverageProfilerEnabled() = 0;
|
|
89
|
+
virtual void enableCodeCoverageProfiler() = 0;
|
|
90
|
+
virtual void disableCodeCoverageProfiler() = 0;
|
|
91
|
+
|
|
92
|
+
protected:
|
|
93
|
+
~IHermesRootAPI() {}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
class HERMES_EXPORT ISetFatalHandler : public jsi::ICast {
|
|
97
|
+
public:
|
|
98
|
+
static constexpr jsi::UUID uuid{
|
|
99
|
+
0xda98a610, 0x09cb, 0x11f0, 0x87bf, 0x325096b39f47};
|
|
100
|
+
virtual void setFatalHandler(void (*handler)(const std::string &)) = 0;
|
|
101
|
+
|
|
102
|
+
protected:
|
|
103
|
+
~ISetFatalHandler() = default;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/// Hermes-specific per-runtime methods.
|
|
107
|
+
class HERMES_EXPORT IHermes : public jsi::ICast {
|
|
108
|
+
public:
|
|
109
|
+
static constexpr jsi::UUID uuid{
|
|
110
|
+
0xe85cfa22, 0xdfae, 0x11ef, 0xa6f7, 0x325096b39f47};
|
|
111
|
+
|
|
112
|
+
virtual ICast *getHermesRootAPI() = 0;
|
|
113
|
+
virtual void sampledTraceToStreamInDevToolsFormat(std::ostream &stream) = 0;
|
|
114
|
+
virtual sampling_profiler::Profile dumpSampledTraceToProfile() = 0;
|
|
115
|
+
virtual void resetTimezoneCache() = 0;
|
|
116
|
+
virtual void loadSegment(
|
|
117
|
+
std::unique_ptr<const jsi::Buffer> buffer, const jsi::Value &context) = 0;
|
|
118
|
+
|
|
119
|
+
/// QuickJS heap objects do not move, so an object's address is a stable id
|
|
120
|
+
/// for its lifetime -- the contract Hermes documents, including that an id
|
|
121
|
+
/// may be reused after the object is collected.
|
|
122
|
+
virtual uint64_t getUniqueID(const jsi::Object &o) const = 0;
|
|
123
|
+
virtual uint64_t getUniqueID(const jsi::BigInt &s) const = 0;
|
|
124
|
+
virtual uint64_t getUniqueID(const jsi::String &s) const = 0;
|
|
125
|
+
virtual uint64_t getUniqueID(const jsi::PropNameID &pni) const = 0;
|
|
126
|
+
virtual uint64_t getUniqueID(const jsi::Symbol &sym) const = 0;
|
|
127
|
+
virtual uint64_t getUniqueID(const jsi::Value &val) const = 0;
|
|
128
|
+
virtual jsi::Value getObjectForID(uint64_t id) = 0;
|
|
129
|
+
|
|
130
|
+
virtual const ::hermes::vm::GCExecTrace &getGCExecTrace() const = 0;
|
|
131
|
+
virtual std::string getIOTrackingInfoJSON() = 0;
|
|
132
|
+
virtual debugger::Debugger &getDebugger() = 0;
|
|
133
|
+
|
|
134
|
+
struct DebugFlags {};
|
|
135
|
+
|
|
136
|
+
virtual void debugJavaScript(
|
|
137
|
+
const std::string &src, const std::string &sourceURL,
|
|
138
|
+
const DebugFlags &debugFlags) = 0;
|
|
139
|
+
virtual void registerForProfiling() = 0;
|
|
140
|
+
virtual void unregisterForProfiling() = 0;
|
|
141
|
+
|
|
142
|
+
/// Backed by the engine's interrupt handler, which the interpreter polls.
|
|
143
|
+
virtual void asyncTriggerTimeout() = 0;
|
|
144
|
+
virtual void watchTimeLimit(uint32_t timeoutInMs) = 0;
|
|
145
|
+
virtual void unwatchTimeLimit() = 0;
|
|
146
|
+
|
|
147
|
+
virtual jsi::Value evaluateJavaScriptWithSourceMap(
|
|
148
|
+
const std::shared_ptr<const jsi::Buffer> &buffer,
|
|
149
|
+
const std::shared_ptr<const jsi::Buffer> &sourceMapBuf,
|
|
150
|
+
const std::string &sourceURL) = 0;
|
|
151
|
+
virtual jsi::Value evaluateSHUnit(SHUnit *(*shUnitCreator)()) = 0;
|
|
152
|
+
virtual SHRuntime *getSHRuntime() noexcept = 0;
|
|
153
|
+
|
|
154
|
+
/// Returns nullptr. Handing back the JSContext* would let a caller
|
|
155
|
+
/// reinterpret_cast it to hermes::vm::Runtime* and corrupt memory.
|
|
156
|
+
virtual void *getVMRuntimeUnsafe() const = 0;
|
|
157
|
+
|
|
158
|
+
protected:
|
|
159
|
+
~IHermes() = default;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
class HERMES_EXPORT IHermesTestHelpers : public jsi::ICast {
|
|
163
|
+
public:
|
|
164
|
+
static constexpr jsi::UUID uuid{
|
|
165
|
+
0x664e489a, 0xf941, 0x11ef, 0xa44c, 0x325096b39f47};
|
|
166
|
+
virtual size_t rootsListLengthForTests() const = 0;
|
|
167
|
+
|
|
168
|
+
protected:
|
|
169
|
+
~IHermesTestHelpers() = default;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
class HermesRuntime : public jsi::Runtime, public IHermes {
|
|
173
|
+
public:
|
|
174
|
+
~HermesRuntime() override = default;
|
|
175
|
+
|
|
176
|
+
using jsi::Runtime::castInterface;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
HERMES_EXPORT jsi::ICast *makeHermesRootAPI();
|
|
180
|
+
|
|
181
|
+
HERMES_EXPORT ::hermes::vm::RuntimeConfig hardenedHermesRuntimeConfig();
|
|
182
|
+
|
|
183
|
+
HERMES_EXPORT std::unique_ptr<HermesRuntime> makeHermesRuntime(
|
|
184
|
+
const ::hermes::vm::RuntimeConfig &runtimeConfig =
|
|
185
|
+
::hermes::vm::RuntimeConfig());
|
|
186
|
+
|
|
187
|
+
/// Returns nullptr rather than an unlocked runtime: a caller expecting
|
|
188
|
+
/// Hermes's ThreadSafeRuntime semantics should not silently get less.
|
|
189
|
+
HERMES_EXPORT std::unique_ptr<jsi::ThreadSafeRuntime>
|
|
190
|
+
makeThreadSafeHermesRuntime(
|
|
191
|
+
const ::hermes::vm::RuntimeConfig &runtimeConfig =
|
|
192
|
+
::hermes::vm::RuntimeConfig());
|
|
193
|
+
|
|
194
|
+
} // namespace hermes
|
|
195
|
+
} // namespace facebook
|
|
@@ -0,0 +1,43 @@
|
|
|
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 <hermes/hermes.h>
|
|
11
|
+
|
|
12
|
+
#include <memory>
|
|
13
|
+
|
|
14
|
+
#ifndef INSPECTOR_EXPORT
|
|
15
|
+
#if defined(_MSC_VER)
|
|
16
|
+
#define INSPECTOR_EXPORT
|
|
17
|
+
#else
|
|
18
|
+
#define INSPECTOR_EXPORT __attribute__((visibility("default")))
|
|
19
|
+
#endif
|
|
20
|
+
#endif
|
|
21
|
+
|
|
22
|
+
namespace facebook::hermes::inspector_modern {
|
|
23
|
+
|
|
24
|
+
/// Owns a runtime for the debugger to attach to. Kept because worklets names
|
|
25
|
+
/// the type; see Registration.h for what attaching actually does here.
|
|
26
|
+
class INSPECTOR_EXPORT RuntimeAdapter {
|
|
27
|
+
public:
|
|
28
|
+
virtual ~RuntimeAdapter() = 0;
|
|
29
|
+
virtual HermesRuntime &getRuntime() = 0;
|
|
30
|
+
virtual void tickleJs();
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
class INSPECTOR_EXPORT SharedRuntimeAdapter : public RuntimeAdapter {
|
|
34
|
+
public:
|
|
35
|
+
explicit SharedRuntimeAdapter(std::shared_ptr<HermesRuntime> runtime);
|
|
36
|
+
~SharedRuntimeAdapter() override;
|
|
37
|
+
HermesRuntime &getRuntime() override;
|
|
38
|
+
|
|
39
|
+
private:
|
|
40
|
+
std::shared_ptr<HermesRuntime> runtime_;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
} // namespace facebook::hermes::inspector_modern
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
#ifdef HERMES_ENABLE_DEBUGGER
|
|
11
|
+
|
|
12
|
+
#include <hermes/hermes.h>
|
|
13
|
+
#include <hermes/inspector/RuntimeAdapter.h>
|
|
14
|
+
|
|
15
|
+
#include <memory>
|
|
16
|
+
#include <string>
|
|
17
|
+
|
|
18
|
+
namespace facebook::hermes::inspector_modern::chrome {
|
|
19
|
+
|
|
20
|
+
using DebugSessionToken = int;
|
|
21
|
+
|
|
22
|
+
/// Defined so debug builds of worklets link. It does not register a target:
|
|
23
|
+
/// the app's main runtime is debuggable through jsinspector-modern and
|
|
24
|
+
/// modules/cdp, a runtime created through this shim is not.
|
|
25
|
+
extern DebugSessionToken enableDebugging(
|
|
26
|
+
std::unique_ptr<RuntimeAdapter> adapter, const std::string &title);
|
|
27
|
+
extern void disableDebugging(DebugSessionToken session);
|
|
28
|
+
|
|
29
|
+
} // namespace facebook::hermes::inspector_modern::chrome
|
|
30
|
+
|
|
31
|
+
#endif // HERMES_ENABLE_DEBUGGER
|
|
@@ -0,0 +1,35 @@
|
|
|
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 <cstdint>
|
|
11
|
+
#include <functional>
|
|
12
|
+
|
|
13
|
+
namespace qjs::hermescompat {
|
|
14
|
+
|
|
15
|
+
enum class Severity : uint8_t {
|
|
16
|
+
Degraded, ///< Ran, but not the way Hermes would have.
|
|
17
|
+
Ignored, ///< Did nothing, and nothing observable depended on it.
|
|
18
|
+
Unsupported, ///< Could not be honoured; the result is a safe stand-in.
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
using Handler =
|
|
22
|
+
std::function<void(Severity, const char *api, const char *detail)>;
|
|
23
|
+
|
|
24
|
+
/// Replaces the default handler, which writes to stderr, or to logcat on
|
|
25
|
+
/// Android. Nothing aborts: how strict to be is the embedder's call.
|
|
26
|
+
void setHandler(Handler handler);
|
|
27
|
+
|
|
28
|
+
/// Reports the first time each `api` is seen, so a call in a loop says it
|
|
29
|
+
/// once. Called by the shim; `api` is always a literal.
|
|
30
|
+
void report(Severity severity, const char *api, const char *detail);
|
|
31
|
+
|
|
32
|
+
/// Forgets which APIs have reported, so the next call to each reports again.
|
|
33
|
+
void resetForTesting();
|
|
34
|
+
|
|
35
|
+
} // namespace qjs::hermescompat
|