react-native-windows 0.78.5 → 0.78.7
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/Directory.Build.props +6 -4
- package/Folly/Folly.vcxproj +46 -6
- package/Folly/Folly.vcxproj.filters +16 -4
- package/Folly/TEMP_UntilFollyUpdate/ConstexprMath.h +26 -18
- package/Folly/TEMP_UntilFollyUpdate/Conv.cpp +1205 -0
- package/Folly/TEMP_UntilFollyUpdate/chrono/Hardware.h +155 -0
- package/Folly/TEMP_UntilFollyUpdate/concurrency/CacheLocality.cpp +633 -0
- package/Folly/TEMP_UntilFollyUpdate/{dynamic-inl.h → json/dynamic-inl.h} +3 -4
- package/Folly/TEMP_UntilFollyUpdate/{json.cpp → json/json.cpp} +14 -10
- package/Folly/TEMP_UntilFollyUpdate/lang/SafeAssert.h +7 -14
- package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h +6 -6
- package/Folly/ThreadNameStub.cpp +10 -0
- package/Folly/cgmanifest.json +11 -1
- package/Libraries/Components/View/View.windows.js +107 -56
- package/Libraries/Components/View/ViewAccessibility.d.ts +60 -1
- package/Libraries/Image/Image.windows.js +42 -21
- package/Libraries/Modal/Modal.d.ts +7 -0
- package/Libraries/Modal/Modal.windows.js +7 -1
- package/Libraries/NativeComponent/BaseViewConfig.windows.js +3 -0
- package/Libraries/Text/Text.d.ts +18 -0
- package/Microsoft.ReactNative/AsynchronousEventBeat.cpp +4 -25
- package/Microsoft.ReactNative/AsynchronousEventBeat.h +0 -3
- package/Microsoft.ReactNative/Base/FollyIncludes.h +1 -0
- package/Microsoft.ReactNative/CallInvoker.cpp +42 -0
- package/Microsoft.ReactNative/CallInvoker.h +34 -0
- package/Microsoft.ReactNative/{JSDispatcherWriter.cpp → CallInvokerWriter.cpp} +35 -47
- package/Microsoft.ReactNative/CallInvokerWriter.h +74 -0
- package/Microsoft.ReactNative/CompositionComponentView.idl +0 -5
- package/Microsoft.ReactNative/CompositionSwitcher.idl +7 -0
- package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +8 -10
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.cpp +12 -2
- package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.cpp +100 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.h +31 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +77 -11
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +43 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +7 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +86 -56
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +5 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +0 -4
- package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService.cpp +0 -2
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +118 -63
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +133 -8
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +16 -2
- package/Microsoft.ReactNative/Fabric/Composition/FocusManager.cpp +4 -2
- package/Microsoft.ReactNative/Fabric/Composition/FocusManager.h +9 -1
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +34 -11
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +3 -0
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +133 -135
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +9 -6
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +46 -49
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +6 -1
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +13 -8
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +5 -2
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +146 -25
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +14 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +160 -12
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +6 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputEventEmitter.cpp +47 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputEventEmitter.h +15 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.cpp +6 -2
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.h +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp +7 -9
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.h +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +5 -0
- package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +40 -36
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +68 -0
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +11 -0
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +70 -13
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +10 -2
- package/Microsoft.ReactNative/Fabric/ImageManager.cpp +5 -5
- package/Microsoft.ReactNative/Fabric/ImageRequestParams.cpp +26 -0
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +47 -8
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.h +10 -1
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/CompositionAccessibilityProps.h +67 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewEventEmitter.cpp +22 -4
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewEventEmitter.h +15 -2
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.cpp +20 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.h +5 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/MouseEvent.h +20 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/HostPlatformColor.h +5 -8
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/PlatformColorParser.h +1 -2
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +247 -45
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.h +15 -0
- package/Microsoft.ReactNative/Fabric/platform/react/threading/MessageQueueThreadImpl.cpp +39 -0
- package/Microsoft.ReactNative/Fabric/platform/react/threading/MessageQueueThreadImpl.h +54 -0
- package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.cpp +126 -0
- package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.h +73 -0
- package/Microsoft.ReactNative/IReactContext.cpp +17 -0
- package/Microsoft.ReactNative/IReactContext.h +1 -0
- package/Microsoft.ReactNative/IReactContext.idl +18 -1
- package/Microsoft.ReactNative/IReactDispatcher.idl +1 -0
- package/Microsoft.ReactNative/IReactModuleBuilder.cpp +12 -0
- package/Microsoft.ReactNative/IReactModuleBuilder.h +2 -0
- package/Microsoft.ReactNative/IReactModuleBuilder.idl +8 -0
- package/Microsoft.ReactNative/JsiApi.cpp +10 -2
- package/Microsoft.ReactNative/JsiApi.h +1 -0
- package/Microsoft.ReactNative/JsiApi.idl +1 -0
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +0 -3
- package/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +2 -3
- package/Microsoft.ReactNative/Modules/AlertModule.cpp +7 -12
- package/Microsoft.ReactNative/Modules/Animated/AnimationDriver.cpp +2 -1
- package/Microsoft.ReactNative/Modules/Animated/NativeAnimatedModule.cpp +4 -8
- package/Microsoft.ReactNative/Modules/AppStateModule.cpp +2 -2
- package/Microsoft.ReactNative/Modules/ClipboardModule.cpp +6 -8
- package/Microsoft.ReactNative/Modules/ClipboardModule.h +1 -1
- package/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp +6 -15
- package/Microsoft.ReactNative/Modules/NativeUIManager.cpp +13 -24
- package/Microsoft.ReactNative/QuirkSettings.cpp +0 -16
- package/Microsoft.ReactNative/QuirkSettings.h +0 -3
- package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +11 -1
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +78 -68
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -2
- package/Microsoft.ReactNative/ReactInstanceSettings.cpp +12 -0
- package/Microsoft.ReactNative/ReactInstanceSettings.h +2 -0
- package/Microsoft.ReactNative/ReactInstanceSettings.idl +6 -0
- package/Microsoft.ReactNative/ReactNativeIsland.idl +3 -0
- package/Microsoft.ReactNative/ReactSupport.cpp +44 -11
- package/Microsoft.ReactNative/RedBox.cpp +30 -1
- package/Microsoft.ReactNative/SchedulerSettings.cpp +4 -4
- package/Microsoft.ReactNative/SchedulerSettings.h +1 -1
- package/Microsoft.ReactNative/TurboModulesProvider.cpp +30 -12
- package/Microsoft.ReactNative/Utils/ImageUtils.h +1 -0
- package/Microsoft.ReactNative/Utils/LocalBundleReader.cpp +37 -31
- package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.cpp +1 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.inc +2 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_posix.cpp +1 -1
- package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +94 -27
- package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +27 -6
- package/Microsoft.ReactNative.Cxx/JSI/JsiApiContext.cpp +45 -11
- package/Microsoft.ReactNative.Cxx/JSI/JsiApiContext.h +6 -0
- package/Microsoft.ReactNative.Cxx/JSI/decorator.h +220 -0
- package/Microsoft.ReactNative.Cxx/JSI/instrumentation.h +28 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi-inl.h +6 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi.cpp +241 -4
- package/Microsoft.ReactNative.Cxx/JSI/jsi.h +207 -19
- package/Microsoft.ReactNative.Cxx/JSValue.cpp +19 -3
- package/Microsoft.ReactNative.Cxx/JSValue.h +15 -7
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +2 -2
- package/Microsoft.ReactNative.Cxx/NativeModules.h +60 -2
- package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.cpp +1267 -614
- package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.h +4 -2
- package/Microsoft.ReactNative.Cxx/ReactContext.h +7 -0
- package/Microsoft.ReactNative.Cxx/TurboModuleProvider.cpp +11 -13
- package/Microsoft.ReactNative.Cxx/TurboModuleProvider.h +2 -3
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api.h +81 -20
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api_types.h +47 -2
- package/Microsoft.ReactNative.Cxx/node-api/js_runtime_api.h +13 -0
- package/Microsoft.ReactNative.Cxx/stubs/glog/logging.h +1 -1
- package/Microsoft.ReactNative.Managed/ReactContext.cs +3 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +1 -1
- package/PropertySheets/React.Cpp.props +2 -1
- package/PropertySheets/WebView2.props +1 -1
- package/PropertySheets/WinUI.props +2 -2
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jserrorhandler/JsErrorHandler.cpp +429 -0
- package/ReactCommon/cgmanifest.json +1 -1
- package/Shared/HermesRuntimeHolder.cpp +6 -0
- package/Shared/JSI/ChakraRuntime.cpp +4 -0
- package/Shared/JSI/ChakraRuntime.h +2 -0
- package/Shared/Modules/BlobModule.cpp +14 -16
- package/Shared/Modules/BlobModule.h +3 -1
- package/Shared/Shared.vcxitems +11 -7
- package/Shared/Shared.vcxitems.filters +6 -1
- package/Shared/TurboModuleManager.cpp +0 -15
- package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidSwitch.g.h +6 -6
- package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +6 -6
- package/codegen/react/components/rnwcore/InputAccessory.g.h +6 -6
- package/codegen/react/components/rnwcore/ModalHostView.g.h +11 -7
- package/codegen/react/components/rnwcore/Props.cpp +2 -1
- package/codegen/react/components/rnwcore/Props.h +1 -0
- package/codegen/react/components/rnwcore/PullToRefreshView.g.h +6 -6
- package/codegen/react/components/rnwcore/SafeAreaView.g.h +6 -6
- package/codegen/react/components/rnwcore/Switch.g.h +6 -6
- package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +6 -6
- package/index.windows.js +4 -2
- package/package.json +3 -4
- package/src/private/specs/components/RCTModalHostViewNativeComponent.js +8 -0
- package/stubs/glog/logging.h +1 -1
- package/Microsoft.ReactNative/JSDispatcherWriter.h +0 -47
- package/Microsoft.ReactNative/SynchronousEventBeat.cpp +0 -51
- package/Microsoft.ReactNative/SynchronousEventBeat.h +0 -31
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
#include <algorithm>
|
|
9
9
|
#include <array>
|
|
10
|
+
#include <mutex>
|
|
10
11
|
#include <optional>
|
|
11
12
|
#include <sstream>
|
|
12
13
|
#include <string_view>
|
|
@@ -60,7 +61,7 @@ using namespace std::string_view_literals;
|
|
|
60
61
|
} \
|
|
61
62
|
} while (false)
|
|
62
63
|
|
|
63
|
-
// Check
|
|
64
|
+
// Check Node-API result and and throw JS exception if it is not napi_ok.
|
|
64
65
|
#define CHECK_NAPI(...) \
|
|
65
66
|
do { \
|
|
66
67
|
napi_status temp_error_code_ = (__VA_ARGS__); \
|
|
@@ -69,7 +70,7 @@ using namespace std::string_view_literals;
|
|
|
69
70
|
} \
|
|
70
71
|
} while (false)
|
|
71
72
|
|
|
72
|
-
// Check
|
|
73
|
+
// Check Node-API result and and crash if it is not napi_ok.
|
|
73
74
|
#define CHECK_NAPI_ELSE_CRASH(expression) \
|
|
74
75
|
do { \
|
|
75
76
|
napi_status temp_error_code_ = (expression); \
|
|
@@ -78,7 +79,7 @@ using namespace std::string_view_literals;
|
|
|
78
79
|
} \
|
|
79
80
|
} while (false)
|
|
80
81
|
|
|
81
|
-
// Check
|
|
82
|
+
// Check Node-API result and return it when it is an error.
|
|
82
83
|
#define NAPI_CALL(expression) \
|
|
83
84
|
do { \
|
|
84
85
|
napi_status temp_error_code_ = (expression); \
|
|
@@ -176,18 +177,29 @@ class StringKey {
|
|
|
176
177
|
size_t hash_;
|
|
177
178
|
};
|
|
178
179
|
|
|
180
|
+
struct NodeApiAttachTag {
|
|
181
|
+
} attachTag;
|
|
182
|
+
|
|
179
183
|
// Implementation of N-API JSI Runtime
|
|
180
184
|
class NodeApiJsiRuntime : public jsi::Runtime {
|
|
181
185
|
public:
|
|
182
|
-
NodeApiJsiRuntime(
|
|
186
|
+
NodeApiJsiRuntime(
|
|
187
|
+
napi_env env,
|
|
188
|
+
JSRuntimeApi *jsrApi,
|
|
189
|
+
std::function<void()> onDelete) noexcept;
|
|
183
190
|
~NodeApiJsiRuntime() override;
|
|
184
191
|
|
|
185
|
-
jsi::Value evaluateJavaScript(
|
|
186
|
-
|
|
192
|
+
jsi::Value evaluateJavaScript(
|
|
193
|
+
const std::shared_ptr<const jsi::Buffer> &buffer,
|
|
194
|
+
const std::string &sourceURL) override;
|
|
187
195
|
std::shared_ptr<const jsi::PreparedJavaScript> prepareJavaScript(
|
|
188
196
|
const std::shared_ptr<const jsi::Buffer> &buffer,
|
|
189
197
|
std::string sourceURL) override;
|
|
190
|
-
jsi::Value evaluatePreparedJavaScript(
|
|
198
|
+
jsi::Value evaluatePreparedJavaScript(
|
|
199
|
+
const std::shared_ptr<const jsi::PreparedJavaScript> &js) override;
|
|
200
|
+
#if JSI_VERSION >= 12
|
|
201
|
+
void queueMicrotask(const jsi::Function &callback) override;
|
|
202
|
+
#endif
|
|
191
203
|
#if JSI_VERSION >= 4
|
|
192
204
|
bool drainMicrotasks(int maxMicrotasksHint = -1) override;
|
|
193
205
|
#endif
|
|
@@ -204,8 +216,10 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
204
216
|
PointerValue *cloneObject(const PointerValue *pointerValue) override;
|
|
205
217
|
PointerValue *clonePropNameID(const PointerValue *pointerValue) override;
|
|
206
218
|
|
|
207
|
-
jsi::PropNameID createPropNameIDFromAscii(const char *str, size_t length)
|
|
208
|
-
|
|
219
|
+
jsi::PropNameID createPropNameIDFromAscii(const char *str, size_t length)
|
|
220
|
+
override;
|
|
221
|
+
jsi::PropNameID createPropNameIDFromUtf8(const uint8_t *utf8, size_t length)
|
|
222
|
+
override;
|
|
209
223
|
jsi::PropNameID createPropNameIDFromString(const jsi::String &str) override;
|
|
210
224
|
#if JSI_VERSION >= 5
|
|
211
225
|
jsi::PropNameID createPropNameIDFromSymbol(const jsi::Symbol &sym) override;
|
|
@@ -235,16 +249,28 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
235
249
|
|
|
236
250
|
#if JSI_VERSION >= 7
|
|
237
251
|
bool hasNativeState(const jsi::Object &value) override;
|
|
238
|
-
std::shared_ptr<jsi::NativeState> getNativeState(
|
|
239
|
-
|
|
252
|
+
std::shared_ptr<jsi::NativeState> getNativeState(
|
|
253
|
+
const jsi::Object &value) override;
|
|
254
|
+
void setNativeState(
|
|
255
|
+
const jsi::Object &value,
|
|
256
|
+
std::shared_ptr<jsi::NativeState> state) override;
|
|
240
257
|
#endif
|
|
241
258
|
|
|
242
|
-
jsi::Value getProperty(const jsi::Object &obj, const jsi::PropNameID &name)
|
|
243
|
-
|
|
244
|
-
|
|
259
|
+
jsi::Value getProperty(const jsi::Object &obj, const jsi::PropNameID &name)
|
|
260
|
+
override;
|
|
261
|
+
jsi::Value getProperty(const jsi::Object &obj, const jsi::String &name)
|
|
262
|
+
override;
|
|
263
|
+
bool hasProperty(const jsi::Object &obj, const jsi::PropNameID &name)
|
|
264
|
+
override;
|
|
245
265
|
bool hasProperty(const jsi::Object &obj, const jsi::String &name) override;
|
|
246
|
-
void setPropertyValue(
|
|
247
|
-
|
|
266
|
+
void setPropertyValue(
|
|
267
|
+
JSI_CONST_10 jsi::Object &obj,
|
|
268
|
+
const jsi::PropNameID &name,
|
|
269
|
+
const jsi::Value &value) override;
|
|
270
|
+
void setPropertyValue(
|
|
271
|
+
JSI_CONST_10 jsi::Object &obj,
|
|
272
|
+
const jsi::String &name,
|
|
273
|
+
const jsi::Value &value) override;
|
|
248
274
|
|
|
249
275
|
bool isArray(const jsi::Object &obj) const override;
|
|
250
276
|
bool isArrayBuffer(const jsi::Object &obj) const override;
|
|
@@ -254,24 +280,36 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
254
280
|
jsi::Array getPropertyNames(const jsi::Object &obj) override;
|
|
255
281
|
|
|
256
282
|
jsi::WeakObject createWeakObject(const jsi::Object &obj) override;
|
|
257
|
-
jsi::Value lockWeakObject(
|
|
283
|
+
jsi::Value lockWeakObject(
|
|
284
|
+
JSI_NO_CONST_3 JSI_CONST_10 jsi::WeakObject &weakObj) override;
|
|
258
285
|
|
|
259
286
|
jsi::Array createArray(size_t length) override;
|
|
260
287
|
#if JSI_VERSION >= 9
|
|
261
|
-
jsi::ArrayBuffer createArrayBuffer(
|
|
288
|
+
jsi::ArrayBuffer createArrayBuffer(
|
|
289
|
+
std::shared_ptr<jsi::MutableBuffer> buffer);
|
|
262
290
|
#endif
|
|
263
291
|
size_t size(const jsi::Array &arr) override;
|
|
264
292
|
size_t size(const jsi::ArrayBuffer &arrBuf) override;
|
|
265
293
|
uint8_t *data(const jsi::ArrayBuffer &arrBuff) override;
|
|
266
294
|
jsi::Value getValueAtIndex(const jsi::Array &arr, size_t index) override;
|
|
267
|
-
void setValueAtIndexImpl(
|
|
295
|
+
void setValueAtIndexImpl(
|
|
296
|
+
JSI_CONST_10 jsi::Array &arr,
|
|
297
|
+
size_t index,
|
|
298
|
+
const jsi::Value &value) override;
|
|
268
299
|
|
|
269
300
|
jsi::Function createFunctionFromHostFunction(
|
|
270
301
|
const jsi::PropNameID &name,
|
|
271
302
|
unsigned int paramCount,
|
|
272
303
|
jsi::HostFunctionType func) override;
|
|
273
|
-
jsi::Value call(
|
|
274
|
-
|
|
304
|
+
jsi::Value call(
|
|
305
|
+
const jsi::Function &func,
|
|
306
|
+
const jsi::Value &jsThis,
|
|
307
|
+
const jsi::Value *args,
|
|
308
|
+
size_t count) override;
|
|
309
|
+
jsi::Value callAsConstructor(
|
|
310
|
+
const jsi::Function &func,
|
|
311
|
+
const jsi::Value *args,
|
|
312
|
+
size_t count) override;
|
|
275
313
|
|
|
276
314
|
ScopeState *pushScope() override;
|
|
277
315
|
void popScope(ScopeState *) override;
|
|
@@ -286,7 +324,8 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
286
324
|
bool instanceOf(const jsi::Object &obj, const jsi::Function &func) override;
|
|
287
325
|
|
|
288
326
|
#if JSI_VERSION >= 11
|
|
289
|
-
void setExternalMemoryPressure(const jsi::Object &obj, size_t amount)
|
|
327
|
+
void setExternalMemoryPressure(const jsi::Object &obj, size_t amount)
|
|
328
|
+
override;
|
|
290
329
|
#endif
|
|
291
330
|
|
|
292
331
|
private:
|
|
@@ -313,13 +352,15 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
313
352
|
~NodeApiPointerValueScope() noexcept;
|
|
314
353
|
|
|
315
354
|
NodeApiPointerValueScope(const NodeApiPointerValueScope &) = delete;
|
|
316
|
-
NodeApiPointerValueScope &operator=(const NodeApiPointerValueScope &) =
|
|
355
|
+
NodeApiPointerValueScope &operator=(const NodeApiPointerValueScope &) =
|
|
356
|
+
delete;
|
|
317
357
|
|
|
318
358
|
private:
|
|
319
359
|
NodeApiJsiRuntime &runtime_;
|
|
320
360
|
};
|
|
321
361
|
|
|
322
|
-
// Sets the variable in the constructor and then restores its value in the
|
|
362
|
+
// Sets the variable in the constructor and then restores its value in the
|
|
363
|
+
// destructor.
|
|
323
364
|
template <typename T>
|
|
324
365
|
class AutoRestore {
|
|
325
366
|
public:
|
|
@@ -334,7 +375,7 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
334
375
|
T oldValue_;
|
|
335
376
|
};
|
|
336
377
|
|
|
337
|
-
enum class NodeApiPointerValueKind {
|
|
378
|
+
enum class NodeApiPointerValueKind : uint8_t {
|
|
338
379
|
Object,
|
|
339
380
|
WeakObject,
|
|
340
381
|
String,
|
|
@@ -345,173 +386,335 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
345
386
|
|
|
346
387
|
class NodeApiRefCountedPointerValue;
|
|
347
388
|
|
|
389
|
+
class NodeApiRefCount {
|
|
390
|
+
public:
|
|
391
|
+
static void incRefCount(std::atomic<int32_t> &value) noexcept {
|
|
392
|
+
int refCount = value.fetch_add(1, std::memory_order_relaxed) + 1;
|
|
393
|
+
CHECK_ELSE_CRASH(refCount > 1, "The ref count cannot bounce from zero.");
|
|
394
|
+
CHECK_ELSE_CRASH(
|
|
395
|
+
refCount < std::numeric_limits<int32_t>::max(),
|
|
396
|
+
"The ref count is too big.");
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
static bool decRefCount(std::atomic<int32_t> &value) noexcept {
|
|
400
|
+
int refCount = value.fetch_sub(1, std::memory_order_release) - 1;
|
|
401
|
+
CHECK_ELSE_CRASH(refCount >= 0, "The ref count must not be negative.");
|
|
402
|
+
if (refCount == 0) {
|
|
403
|
+
std::atomic_thread_fence(std::memory_order_acquire);
|
|
404
|
+
return true;
|
|
405
|
+
}
|
|
406
|
+
return false;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
static bool isZero(std::atomic<int32_t> &value) noexcept {
|
|
410
|
+
return value.load(std::memory_order_relaxed) == 0;
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
// A smart pointer for types that implement intrusive ref count using
|
|
415
|
+
// methods incRefCount and decRefCount.
|
|
416
|
+
template <typename T>
|
|
417
|
+
class NodeApiRefCountedPtr final {
|
|
418
|
+
public:
|
|
419
|
+
NodeApiRefCountedPtr() noexcept = default;
|
|
420
|
+
|
|
421
|
+
explicit NodeApiRefCountedPtr(T *ptr, NodeApiAttachTag) noexcept
|
|
422
|
+
: ptr_(ptr) {}
|
|
423
|
+
|
|
424
|
+
NodeApiRefCountedPtr(const NodeApiRefCountedPtr &other) noexcept
|
|
425
|
+
: ptr_(other.ptr_) {
|
|
426
|
+
if (ptr_ != nullptr) {
|
|
427
|
+
ptr_->incRefCount();
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
NodeApiRefCountedPtr(NodeApiRefCountedPtr &&other)
|
|
432
|
+
: ptr_(std::exchange(other.ptr_, nullptr)) {}
|
|
433
|
+
|
|
434
|
+
~NodeApiRefCountedPtr() noexcept {
|
|
435
|
+
if (ptr_ != nullptr) {
|
|
436
|
+
ptr_->decRefCount();
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
NodeApiRefCountedPtr &operator=(std::nullptr_t) noexcept {
|
|
441
|
+
if (ptr_ != nullptr) {
|
|
442
|
+
ptr_->decRefCount();
|
|
443
|
+
}
|
|
444
|
+
ptr_ = nullptr;
|
|
445
|
+
return *this;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
NodeApiRefCountedPtr &operator=(
|
|
449
|
+
const NodeApiRefCountedPtr &other) noexcept {
|
|
450
|
+
if (this != &other) {
|
|
451
|
+
NodeApiRefCountedPtr temp(std::move(*this));
|
|
452
|
+
ptr_ = other.ptr_;
|
|
453
|
+
if (ptr_ != nullptr) {
|
|
454
|
+
ptr_->incRefCount();
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return *this;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
NodeApiRefCountedPtr &operator=(NodeApiRefCountedPtr &&other) noexcept {
|
|
461
|
+
if (this != &other) {
|
|
462
|
+
NodeApiRefCountedPtr temp(std::move(*this));
|
|
463
|
+
ptr_ = std::exchange(other.ptr_, nullptr);
|
|
464
|
+
}
|
|
465
|
+
return *this;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
T *operator->() const noexcept {
|
|
469
|
+
return ptr_;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
T *get() const noexcept {
|
|
473
|
+
return ptr_;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
explicit operator bool() const noexcept {
|
|
477
|
+
return ptr_ != nullptr;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
T *release() noexcept {
|
|
481
|
+
return std::exchange(ptr_, nullptr);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
private:
|
|
485
|
+
T *ptr_{};
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
// Removes the `napi_value value_` field.
|
|
489
|
+
class NodeApiStackValueDeleter {
|
|
490
|
+
public:
|
|
491
|
+
void operator()(NodeApiRefCountedPointerValue *ptr) const noexcept;
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
// Removes the NodeApiRefCountedPointerValue instance and ignores the
|
|
495
|
+
// `napi_ref ref_` field.
|
|
496
|
+
class NodeApiRefDeleter {
|
|
497
|
+
public:
|
|
498
|
+
void operator()(NodeApiRefCountedPointerValue *ptr) const noexcept;
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
using NodeApiRefHolder = NodeApiRefCountedPtr<NodeApiRefCountedPointerValue>;
|
|
502
|
+
using NodeApiStackValuePtr =
|
|
503
|
+
std::unique_ptr<NodeApiRefCountedPointerValue, NodeApiStackValueDeleter>;
|
|
504
|
+
using NodeApiRefPtr =
|
|
505
|
+
std::unique_ptr<NodeApiRefCountedPointerValue, NodeApiRefDeleter>;
|
|
506
|
+
|
|
507
|
+
// NodeApiPendingDeletions helps to delete PointerValues in a thread safe way
|
|
508
|
+
// from the JS thread. According to JSI spec the PointerValue's release method
|
|
509
|
+
// can be called from any thread, while Node-API can only manage objects in
|
|
510
|
+
// the JS thread. So, when a PointerValue's ref count goes to zero after
|
|
511
|
+
// calling the release method, the PointerValue is added into the
|
|
512
|
+
// pointerValuesToDelete_ vector, and then NodeApiJsiRuntime deletes them
|
|
513
|
+
// later from the JS thread. Note that the napi_delete_reference can only be
|
|
514
|
+
// called before the napi_env is destroyed. Thus, we remove the pointer to
|
|
515
|
+
// napi_env as soon as NodeApiJsiRuntime destructor starts.
|
|
516
|
+
class NodeApiPendingDeletions {
|
|
517
|
+
public:
|
|
518
|
+
// Create new instance of NodeApiPendingDeletions.
|
|
519
|
+
static NodeApiRefCountedPtr<NodeApiPendingDeletions> create() noexcept {
|
|
520
|
+
return NodeApiRefCountedPtr<NodeApiPendingDeletions>(
|
|
521
|
+
new NodeApiPendingDeletions(), attachTag);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// Add PointerValues to delete from JS thread. The method can be called from
|
|
525
|
+
// any thread.
|
|
526
|
+
void addPointerValueToDelete(NodeApiRefPtr pointerValueToDelete) noexcept {
|
|
527
|
+
std::scoped_lock lock{mutex_};
|
|
528
|
+
pointerValuesToDeletePool_[poolSelector_].push_back(
|
|
529
|
+
std::move(pointerValueToDelete));
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Delete all PointerValues scheduled for deletion along with their napi_ref
|
|
533
|
+
// instances. It must be called from a JS thread.
|
|
534
|
+
void deletePointerValues(NodeApiJsiRuntime &runtime) noexcept {
|
|
535
|
+
{
|
|
536
|
+
// TODO: Does it affect the performance to take the lock every time?
|
|
537
|
+
// Should we use an atomic variable?
|
|
538
|
+
std::scoped_lock lock{mutex_};
|
|
539
|
+
if (pointerValuesToDeletePool_[poolSelector_].empty()) {
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// Switch the pool entries.
|
|
544
|
+
poolSelector_ = poolSelector_ ^ 1;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
std::vector<NodeApiRefPtr> &deleteInJSThread =
|
|
548
|
+
pointerValuesToDeletePool_[poolSelector_ ^ 1];
|
|
549
|
+
for (auto &pointerValue : deleteInJSThread) {
|
|
550
|
+
pointerValue.release()->deleteNodeApiRef(runtime);
|
|
551
|
+
}
|
|
552
|
+
deleteInJSThread.resize(0);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
private:
|
|
556
|
+
friend class NodeApiRefCountedPtr<NodeApiPendingDeletions>;
|
|
557
|
+
|
|
558
|
+
NodeApiPendingDeletions() noexcept = default;
|
|
559
|
+
|
|
560
|
+
void incRefCount() noexcept {
|
|
561
|
+
NodeApiRefCount::incRefCount(refCount_);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
void decRefCount() noexcept {
|
|
565
|
+
if (NodeApiRefCount::decRefCount(refCount_)) {
|
|
566
|
+
delete this;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
private:
|
|
571
|
+
mutable std::atomic<int32_t> refCount_{1};
|
|
572
|
+
std::recursive_mutex mutex_;
|
|
573
|
+
// One of the vectors is used from different threads under the mutex_ lock
|
|
574
|
+
// to add items, while another is from JS thread to remove items. Since we
|
|
575
|
+
// never change the capacity of the vectors, it should help avoiding memory
|
|
576
|
+
// allocations at some point.
|
|
577
|
+
std::vector<NodeApiRefPtr> pointerValuesToDeletePool_[2]{
|
|
578
|
+
std::vector<NodeApiRefPtr>(),
|
|
579
|
+
std::vector<NodeApiRefPtr>()};
|
|
580
|
+
// Index of the pool to access under mutex.
|
|
581
|
+
int32_t poolSelector_{0};
|
|
582
|
+
};
|
|
583
|
+
|
|
348
584
|
// NodeApiPointerValue is used by jsi::Pointer derived classes.
|
|
349
585
|
struct NodeApiPointerValue : PointerValue {
|
|
350
|
-
virtual NodeApiRefCountedPointerValue *clone(
|
|
586
|
+
virtual NodeApiRefCountedPointerValue *clone(
|
|
587
|
+
NodeApiJsiRuntime &runtime) const noexcept = 0;
|
|
351
588
|
virtual napi_value getValue(NodeApiJsiRuntime &runtime) noexcept = 0;
|
|
352
589
|
virtual NodeApiPointerValueKind getKind() const noexcept = 0;
|
|
353
590
|
};
|
|
354
591
|
|
|
355
|
-
// NodeApiStackOnlyPointerValue helps to avoid memory allocation in some
|
|
356
|
-
// It is used by the JsiValueView, JsiValueViewArgs, and
|
|
357
|
-
// to keep temporary PointerValues on the call stack
|
|
592
|
+
// NodeApiStackOnlyPointerValue helps to avoid memory allocation in some
|
|
593
|
+
// scenarios. It is used by the JsiValueView, JsiValueViewArgs, and
|
|
594
|
+
// PropNameIDView classes to keep temporary PointerValues on the call stack
|
|
595
|
+
// when we call functions. Note that the clone() method return a new instance
|
|
596
|
+
// of the NodeApiRefCountedPointerValue.
|
|
358
597
|
class NodeApiStackOnlyPointerValue final : public NodeApiPointerValue {
|
|
359
598
|
public:
|
|
360
|
-
NodeApiStackOnlyPointerValue(
|
|
599
|
+
NodeApiStackOnlyPointerValue(
|
|
600
|
+
napi_value value,
|
|
601
|
+
NodeApiPointerValueKind pointerKind) noexcept;
|
|
361
602
|
|
|
362
603
|
void invalidate() noexcept override;
|
|
363
|
-
NodeApiRefCountedPointerValue *clone(
|
|
604
|
+
NodeApiRefCountedPointerValue *clone(
|
|
605
|
+
NodeApiJsiRuntime &runtime) const noexcept override;
|
|
364
606
|
napi_value getValue(NodeApiJsiRuntime &runtime) noexcept override;
|
|
365
607
|
NodeApiPointerValueKind getKind() const noexcept override;
|
|
366
608
|
|
|
367
609
|
NodeApiStackOnlyPointerValue(const NodeApiStackOnlyPointerValue &) = delete;
|
|
368
|
-
NodeApiStackOnlyPointerValue &operator=(
|
|
610
|
+
NodeApiStackOnlyPointerValue &operator=(
|
|
611
|
+
const NodeApiStackOnlyPointerValue &) = delete;
|
|
369
612
|
|
|
370
613
|
private:
|
|
371
614
|
napi_value value_{};
|
|
372
615
|
NodeApiPointerValueKind pointerKind_{NodeApiPointerValueKind::Object};
|
|
373
616
|
};
|
|
374
617
|
|
|
375
|
-
//
|
|
376
|
-
|
|
377
|
-
//
|
|
378
|
-
//
|
|
379
|
-
//
|
|
380
|
-
//
|
|
618
|
+
// TODO: Use arena allocator for NodeApiRefCountedPointerValue.
|
|
619
|
+
|
|
620
|
+
// NodeApiRefCountedPointerValue is a ref counted implementation of
|
|
621
|
+
// PointerValue that is allocated in the heap.
|
|
622
|
+
//
|
|
623
|
+
// Its lifetime is controlled by the atomic `refCount_` field. Since the
|
|
624
|
+
// `refCount_` can be changed from any thread, we do not remove the instance
|
|
625
|
+
// immediately when the `refCount_` becomes zero. Instead, we add it to the
|
|
626
|
+
// `NodeApiJsiRuntime::pendingDeletions_` list and delete it later from the JS
|
|
627
|
+
// thread. If `node_value value_` field is not null, then the
|
|
628
|
+
// `NodeApiRefCountedPointerValue` instance is also referenced from the
|
|
629
|
+
// `NodeApiJsiRuntime::stackValues_` list.
|
|
381
630
|
//
|
|
382
|
-
//
|
|
383
|
-
//
|
|
384
|
-
//
|
|
385
|
-
//
|
|
631
|
+
// The `NodeApiJsiRuntime::pendingDeletions_` is responsible for deleting
|
|
632
|
+
// `napi_ref ref_` and it deletes `NodeApiRefCountedPointerValue` instance if
|
|
633
|
+
// the `node_value value_` field is null. While
|
|
634
|
+
// `NodeApiJsiRuntime::stackValues_` is responsible for deleting
|
|
635
|
+
// `NodeApiRefCountedPointerValue` instance if `node_value value_` field is
|
|
636
|
+
// not null and `napi_ref ref_` is null. In case if
|
|
637
|
+
// `NodeApiJsiRuntime::pendingDeletions_` or `NodeApiJsiRuntime::stackValues_`
|
|
638
|
+
// cannot delete the instance, they set their "owned" `value_` or `ref_`
|
|
639
|
+
// fields to null.
|
|
386
640
|
//
|
|
387
|
-
// Some NodeApiRefCountedPointerValue are created with napi_value and may
|
|
388
|
-
// When stack scope is closed we
|
|
389
|
-
// we ensure that it has an associated napi_ref or we
|
|
641
|
+
// Some NodeApiRefCountedPointerValue are created with napi_value and may
|
|
642
|
+
// never get napi_ref. When stack scope is closed we check the `refCount_`. If
|
|
643
|
+
// it is not zero, then we ensure that it has an associated `napi_ref` or we
|
|
644
|
+
// create one.
|
|
390
645
|
//
|
|
391
|
-
//
|
|
392
|
-
//
|
|
393
|
-
// - When we grow the NodeApiJsiRuntime::stackValues_ vector and we reached current capacity.
|
|
394
|
-
// - When we grow the NodeApiJsiRuntime::refs_ vector and we reached current capacity.
|
|
646
|
+
// All methods except for invalidate() and decRefCount() must be called from
|
|
647
|
+
// the JS thread.
|
|
395
648
|
class NodeApiRefCountedPointerValue final : public NodeApiPointerValue {
|
|
649
|
+
friend class NodeApiStackValueDeleter;
|
|
650
|
+
friend class NodeApiRefDeleter;
|
|
651
|
+
friend class NodeApiRefCountedPtr<NodeApiRefCountedPointerValue>;
|
|
652
|
+
|
|
396
653
|
public:
|
|
397
|
-
// Creates new NodeApiRefCountedPointerValue and adds it to the
|
|
398
|
-
//
|
|
399
|
-
|
|
400
|
-
static NodeApiRefCountedPointerValue *make(
|
|
654
|
+
// Creates new NodeApiRefCountedPointerValue and adds it to the
|
|
655
|
+
// NodeApiJsiRuntime::stackValues_.
|
|
656
|
+
static NodeApiRefHolder make(
|
|
401
657
|
NodeApiJsiRuntime &runtime,
|
|
402
658
|
napi_value value,
|
|
403
659
|
NodeApiPointerValueKind pointerKind,
|
|
404
|
-
int32_t initialRefCount =
|
|
660
|
+
int32_t initialRefCount = 1);
|
|
405
661
|
|
|
406
|
-
//
|
|
407
|
-
|
|
408
|
-
// for the targeting NodeApiRefHolder.
|
|
409
|
-
static NodeApiRefCountedPointerValue *makeNodeApiRef(
|
|
662
|
+
// Calls `make` method and forces creation of `napi_ref`.
|
|
663
|
+
static NodeApiRefHolder makeNodeApiRef(
|
|
410
664
|
NodeApiJsiRuntime &runtime,
|
|
411
665
|
napi_value value,
|
|
412
666
|
NodeApiPointerValueKind pointerKind,
|
|
413
|
-
int32_t initialRefCount =
|
|
667
|
+
int32_t initialRefCount = 1);
|
|
414
668
|
|
|
415
669
|
void invalidate() noexcept override;
|
|
416
|
-
NodeApiRefCountedPointerValue *clone(
|
|
670
|
+
NodeApiRefCountedPointerValue *clone(
|
|
671
|
+
NodeApiJsiRuntime &runtime) const noexcept override;
|
|
417
672
|
napi_value getValue(NodeApiJsiRuntime &runtime) noexcept override;
|
|
418
673
|
NodeApiPointerValueKind getKind() const noexcept override;
|
|
419
674
|
|
|
420
|
-
// Returns true if the
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
// Remove napi_value field.
|
|
424
|
-
static void deleteStackValue(NodeApiRefCountedPointerValue *ptr) noexcept;
|
|
675
|
+
// Returns true if the refCount_ is not zero.
|
|
676
|
+
bool usedByJsiPointer() const noexcept;
|
|
425
677
|
|
|
426
|
-
// Removes napi_value
|
|
427
|
-
//
|
|
428
|
-
//
|
|
429
|
-
void
|
|
678
|
+
// Removes `napi_value value_` field.
|
|
679
|
+
// In case if `refCount_` is not null, it ensures existence of the `napi_ref
|
|
680
|
+
// ref_` field.
|
|
681
|
+
void deleteStackValue(NodeApiJsiRuntime &runtime) noexcept;
|
|
430
682
|
|
|
431
|
-
// Removes napi_ref
|
|
432
|
-
//
|
|
433
|
-
|
|
683
|
+
// Removes napi_ref and deletes `NodeApiRefCountedPointerValue` if `value_`
|
|
684
|
+
// is null.
|
|
685
|
+
void deleteNodeApiRef(NodeApiJsiRuntime &runtime) noexcept;
|
|
434
686
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
NodeApiRefCountedPointerValue(const NodeApiRefCountedPointerValue &) = delete;
|
|
440
|
-
NodeApiRefCountedPointerValue &operator=(const NodeApiRefCountedPointerValue &) = delete;
|
|
687
|
+
NodeApiRefCountedPointerValue(const NodeApiRefCountedPointerValue &) =
|
|
688
|
+
delete;
|
|
689
|
+
NodeApiRefCountedPointerValue &operator=(
|
|
690
|
+
const NodeApiRefCountedPointerValue &) = delete;
|
|
441
691
|
|
|
442
692
|
private:
|
|
443
693
|
NodeApiRefCountedPointerValue(
|
|
694
|
+
NodeApiJsiRuntime &runtime,
|
|
444
695
|
napi_value value,
|
|
445
696
|
NodeApiPointerValueKind pointerKind,
|
|
446
697
|
int32_t initialRefCount) noexcept;
|
|
447
698
|
|
|
448
699
|
void incRefCount() const noexcept;
|
|
449
|
-
|
|
450
|
-
// Decrements ref count. Delete this instance if ref count is zero.
|
|
451
700
|
void decRefCount() const noexcept;
|
|
452
701
|
|
|
702
|
+
// Creates `napi_ref ref_` field for the `napi_value value_` field.
|
|
453
703
|
NodeApiRefCountedPointerValue *createNodeApiRef(NodeApiJsiRuntime &runtime);
|
|
454
704
|
|
|
455
705
|
private:
|
|
706
|
+
NodeApiRefCountedPtr<NodeApiPendingDeletions> pendingDeletions_;
|
|
456
707
|
napi_value value_{};
|
|
457
708
|
napi_ref ref_{};
|
|
458
|
-
mutable std::atomic<int32_t> refCount_{};
|
|
709
|
+
mutable std::atomic<int32_t> refCount_{1};
|
|
459
710
|
const NodeApiPointerValueKind pointerKind_{NodeApiPointerValueKind::Object};
|
|
711
|
+
bool canBeDeletedFromStack_{false};
|
|
460
712
|
|
|
461
713
|
static constexpr char kPrimitivePropertyName[] = "X";
|
|
462
714
|
};
|
|
463
715
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
template <NodeApiPointerValueDeleter *deleter>
|
|
467
|
-
class NodeApiPointerValueHolder {
|
|
468
|
-
public:
|
|
469
|
-
NodeApiPointerValueHolder() = default;
|
|
470
|
-
explicit NodeApiPointerValueHolder(NodeApiRefCountedPointerValue *ptr) : ptr_(ptr) {}
|
|
471
|
-
|
|
472
|
-
NodeApiPointerValueHolder(NodeApiPointerValueHolder &&other) : ptr_(std::exchange(other.ptr_, nullptr)) {}
|
|
473
|
-
|
|
474
|
-
NodeApiPointerValueHolder &operator=(NodeApiPointerValueHolder &&other) {
|
|
475
|
-
if (this != &other) {
|
|
476
|
-
NodeApiPointerValueHolder temp(std::move(*this));
|
|
477
|
-
ptr_ = std::exchange(other.ptr_, nullptr);
|
|
478
|
-
}
|
|
479
|
-
return *this;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
~NodeApiPointerValueHolder() {
|
|
483
|
-
if (NodeApiRefCountedPointerValue *ptr = std::exchange(ptr_, nullptr)) {
|
|
484
|
-
deleter(ptr);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
NodeApiRefCountedPointerValue *operator->() const {
|
|
489
|
-
return ptr_;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
NodeApiRefCountedPointerValue *get() const {
|
|
493
|
-
return ptr_;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
NodeApiRefCountedPointerValue *release() {
|
|
497
|
-
return std::exchange(ptr_, nullptr);
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
explicit operator bool() const {
|
|
501
|
-
return ptr_ != nullptr;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
NodeApiPointerValueHolder(NodeApiPointerValueHolder const &) = delete;
|
|
505
|
-
NodeApiPointerValueHolder &operator=(NodeApiPointerValueHolder const &) = delete;
|
|
506
|
-
|
|
507
|
-
private:
|
|
508
|
-
NodeApiRefCountedPointerValue *ptr_{};
|
|
509
|
-
};
|
|
510
|
-
|
|
511
|
-
using NodeApiStackValueHolder = NodeApiPointerValueHolder<&NodeApiRefCountedPointerValue::deleteStackValue>;
|
|
512
|
-
using NodeApiRefHolder = NodeApiPointerValueHolder<&NodeApiRefCountedPointerValue::deleteNodeApiRef>;
|
|
513
|
-
|
|
514
|
-
// SmallBuffer keeps InplaceSize elements in place in the class, and uses heap memory for more elements.
|
|
716
|
+
// SmallBuffer keeps InplaceSize elements in place in the class, and uses heap
|
|
717
|
+
// memory for more elements.
|
|
515
718
|
template <typename T, size_t InplaceSize>
|
|
516
719
|
class SmallBuffer {
|
|
517
720
|
public:
|
|
@@ -529,12 +732,13 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
529
732
|
std::unique_ptr<T[]> heapData_{};
|
|
530
733
|
};
|
|
531
734
|
|
|
532
|
-
// The number of arguments that we keep on stack. We use heap if we have more
|
|
735
|
+
// The number of arguments that we keep on stack. We use heap if we have more
|
|
736
|
+
// arguments.
|
|
533
737
|
constexpr static size_t MaxStackArgCount = 8;
|
|
534
738
|
|
|
535
|
-
// NodeApiValueArgs helps optimize passing arguments to
|
|
536
|
-
// If number of arguments is below or equal to MaxStackArgCount, they are kept
|
|
537
|
-
// otherwise arguments are allocated on the heap.
|
|
739
|
+
// NodeApiValueArgs helps optimize passing arguments to Node-API functions.
|
|
740
|
+
// If number of arguments is below or equal to MaxStackArgCount, they are kept
|
|
741
|
+
// on the call stack, otherwise arguments are allocated on the heap.
|
|
538
742
|
class NodeApiValueArgs {
|
|
539
743
|
public:
|
|
540
744
|
NodeApiValueArgs(NodeApiJsiRuntime &runtime, span<const jsi::Value> args);
|
|
@@ -547,8 +751,9 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
547
751
|
SmallBuffer<napi_value, MaxStackArgCount> args_;
|
|
548
752
|
};
|
|
549
753
|
|
|
550
|
-
// Helps to use the stack storage for a temporary conversion from napi_value
|
|
551
|
-
// It also helps to avoid a conversion to a relatively
|
|
754
|
+
// Helps to use the stack storage for a temporary conversion from napi_value
|
|
755
|
+
// to jsi::Value. It also helps to avoid a conversion to a relatively
|
|
756
|
+
// expensive napi_ref.
|
|
552
757
|
class JsiValueView {
|
|
553
758
|
public:
|
|
554
759
|
union StoreType {
|
|
@@ -562,7 +767,8 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
562
767
|
JsiValueView(NodeApiJsiRuntime *runtime, napi_value jsValue);
|
|
563
768
|
operator const jsi::Value &() const noexcept;
|
|
564
769
|
|
|
565
|
-
static jsi::Value
|
|
770
|
+
static jsi::Value
|
|
771
|
+
initValue(NodeApiJsiRuntime *runtime, napi_value jsValue, StoreType *store);
|
|
566
772
|
|
|
567
773
|
JsiValueView(const JsiValueView &) = delete;
|
|
568
774
|
JsiValueView &operator=(const JsiValueView &) = delete;
|
|
@@ -572,12 +778,14 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
572
778
|
jsi::Value value_{};
|
|
573
779
|
};
|
|
574
780
|
|
|
575
|
-
// Helps to use stack storage for passing arguments that must be temporarily
|
|
576
|
-
// from napi_value to jsi::Value.
|
|
577
|
-
//
|
|
781
|
+
// Helps to use stack storage for passing arguments that must be temporarily
|
|
782
|
+
// converted from napi_value to jsi::Value. It helps to avoid conversion to a
|
|
783
|
+
// relatively expensive napi_ref.
|
|
578
784
|
class JsiValueViewArgs {
|
|
579
785
|
public:
|
|
580
|
-
JsiValueViewArgs(
|
|
786
|
+
JsiValueViewArgs(
|
|
787
|
+
NodeApiJsiRuntime *runtime,
|
|
788
|
+
span<napi_value> args) noexcept;
|
|
581
789
|
const jsi::Value *data() noexcept;
|
|
582
790
|
size_t size() const noexcept;
|
|
583
791
|
|
|
@@ -590,8 +798,9 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
590
798
|
SmallBuffer<jsi::Value, MaxStackArgCount> args_{0};
|
|
591
799
|
};
|
|
592
800
|
|
|
593
|
-
// Helps to use stack storage for a temporary conversion from napi_value to
|
|
594
|
-
// It helps to avoid conversions to a relatively expensive
|
|
801
|
+
// Helps to use stack storage for a temporary conversion from napi_value to
|
|
802
|
+
// jsi::PropNameID. It helps to avoid conversions to a relatively expensive
|
|
803
|
+
// napi_ref.
|
|
595
804
|
class PropNameIDView {
|
|
596
805
|
public:
|
|
597
806
|
PropNameIDView(NodeApiJsiRuntime *runtime, napi_value propertyId) noexcept;
|
|
@@ -609,7 +818,9 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
609
818
|
// Wraps up the jsi::HostFunctionType along with the NodeApiJsiRuntime.
|
|
610
819
|
class HostFunctionWrapper {
|
|
611
820
|
public:
|
|
612
|
-
HostFunctionWrapper(
|
|
821
|
+
HostFunctionWrapper(
|
|
822
|
+
jsi::HostFunctionType &&hostFunction,
|
|
823
|
+
NodeApiJsiRuntime &runtime);
|
|
613
824
|
|
|
614
825
|
jsi::HostFunctionType &hostFunction() noexcept;
|
|
615
826
|
NodeApiJsiRuntime &runtime() noexcept;
|
|
@@ -625,7 +836,10 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
625
836
|
// Wraps up the jsr_prepared_script.
|
|
626
837
|
class NodeApiPreparedJavaScript final : public jsi::PreparedJavaScript {
|
|
627
838
|
public:
|
|
628
|
-
NodeApiPreparedJavaScript(
|
|
839
|
+
NodeApiPreparedJavaScript(
|
|
840
|
+
napi_env env,
|
|
841
|
+
jsr_prepared_script script,
|
|
842
|
+
std::string sourceURL)
|
|
629
843
|
: env_(env), script_(script), sourceURL_(std::move(sourceURL)) {}
|
|
630
844
|
|
|
631
845
|
~NodeApiPreparedJavaScript() override {
|
|
@@ -641,7 +855,8 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
641
855
|
}
|
|
642
856
|
|
|
643
857
|
NodeApiPreparedJavaScript(const NodeApiPreparedJavaScript &) = delete;
|
|
644
|
-
NodeApiPreparedJavaScript &operator=(const NodeApiPreparedJavaScript &) =
|
|
858
|
+
NodeApiPreparedJavaScript &operator=(const NodeApiPreparedJavaScript &) =
|
|
859
|
+
delete;
|
|
645
860
|
|
|
646
861
|
private:
|
|
647
862
|
napi_env env_;
|
|
@@ -662,7 +877,7 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
662
877
|
bool setException(napi_value error) const noexcept;
|
|
663
878
|
bool setException(std::string_view message) const noexcept;
|
|
664
879
|
|
|
665
|
-
private: // Shared
|
|
880
|
+
private: // Shared Node-API call helpers
|
|
666
881
|
napi_valuetype typeOf(napi_value value) const;
|
|
667
882
|
bool strictEquals(napi_value left, napi_value right) const;
|
|
668
883
|
napi_value getUndefined() const;
|
|
@@ -685,28 +900,47 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
685
900
|
std::string propertyIdToStdString(napi_value propertyId);
|
|
686
901
|
napi_value createSymbol(std::string_view symbolDescription) const;
|
|
687
902
|
std::string symbolToStdString(napi_value symbolValue);
|
|
688
|
-
napi_value callFunction(
|
|
689
|
-
|
|
903
|
+
napi_value callFunction(
|
|
904
|
+
napi_value thisArg,
|
|
905
|
+
napi_value function,
|
|
906
|
+
span<napi_value> args = {}) const;
|
|
907
|
+
napi_value constructObject(napi_value constructor, span<napi_value> args = {})
|
|
908
|
+
const;
|
|
690
909
|
bool instanceOf(napi_value object, napi_value constructor) const;
|
|
691
910
|
napi_value createNodeApiObject() const;
|
|
692
911
|
bool hasProperty(napi_value object, napi_value propertyId) const;
|
|
693
912
|
napi_value getProperty(napi_value object, napi_value propertyId) const;
|
|
694
|
-
void setProperty(napi_value object, napi_value propertyId, napi_value value)
|
|
695
|
-
|
|
913
|
+
void setProperty(napi_value object, napi_value propertyId, napi_value value)
|
|
914
|
+
const;
|
|
915
|
+
void setProperty(
|
|
916
|
+
napi_value object,
|
|
917
|
+
napi_value propertyId,
|
|
918
|
+
napi_value value,
|
|
919
|
+
napi_property_attributes attrs) const;
|
|
696
920
|
napi_value createNodeApiArray(size_t length) const;
|
|
697
921
|
bool isArray(napi_value value) const;
|
|
698
922
|
size_t getArrayLength(napi_value value) const;
|
|
699
923
|
napi_value getElement(napi_value arr, size_t index) const;
|
|
700
924
|
void setElement(napi_value array, uint32_t index, napi_value value) const;
|
|
701
|
-
static napi_value __cdecl jsiHostFunctionCallback(
|
|
702
|
-
|
|
703
|
-
|
|
925
|
+
static napi_value __cdecl jsiHostFunctionCallback(
|
|
926
|
+
napi_env env,
|
|
927
|
+
napi_callback_info info) noexcept;
|
|
928
|
+
napi_value createExternalFunction(
|
|
929
|
+
napi_value name,
|
|
930
|
+
int32_t paramCount,
|
|
931
|
+
napi_callback callback,
|
|
932
|
+
void *callbackData);
|
|
933
|
+
napi_value createExternalObject(
|
|
934
|
+
void *data,
|
|
935
|
+
node_api_nogc_finalize finalizeCallback) const;
|
|
704
936
|
template <typename T>
|
|
705
937
|
napi_value createExternalObject(std::unique_ptr<T> &&data) const;
|
|
706
938
|
void *getExternalData(napi_value object) const;
|
|
707
939
|
const std::shared_ptr<jsi::HostObject> &getJsiHostObject(napi_value obj);
|
|
708
940
|
napi_value getHostObjectProxyHandler();
|
|
709
|
-
template <
|
|
941
|
+
template <
|
|
942
|
+
napi_value (NodeApiJsiRuntime::*trapMethod)(span<napi_value>),
|
|
943
|
+
size_t argCount>
|
|
710
944
|
void setProxyTrap(napi_value handler, napi_value propertyName);
|
|
711
945
|
napi_value hostObjectHasTrap(span<napi_value> args);
|
|
712
946
|
napi_value hostObjectGetTrap(span<napi_value> args);
|
|
@@ -720,17 +954,28 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
720
954
|
napi_value getNodeApiValue(const jsi::Value &value) const;
|
|
721
955
|
napi_value getNodeApiValue(const jsi::Pointer &ptr) const;
|
|
722
956
|
napi_value getNodeApiValue(const NodeApiRefHolder &ref) const;
|
|
723
|
-
NodeApiRefCountedPointerValue *cloneNodeApiPointerValue(
|
|
724
|
-
|
|
957
|
+
NodeApiRefCountedPointerValue *cloneNodeApiPointerValue(
|
|
958
|
+
const PointerValue *pointerValue);
|
|
959
|
+
std::optional<uint32_t> toArrayIndex(
|
|
960
|
+
std::string::const_iterator first,
|
|
961
|
+
std::string::const_iterator last);
|
|
725
962
|
|
|
726
|
-
template <
|
|
963
|
+
template <
|
|
964
|
+
typename T,
|
|
965
|
+
std::enable_if_t<std::is_same_v<jsi::Object, T>, int> = 0>
|
|
727
966
|
T makeJsiPointer(napi_value value) const;
|
|
728
|
-
template <
|
|
967
|
+
template <
|
|
968
|
+
typename T,
|
|
969
|
+
std::enable_if_t<std::is_same_v<jsi::String, T>, int> = 0>
|
|
729
970
|
T makeJsiPointer(napi_value value) const;
|
|
730
|
-
template <
|
|
971
|
+
template <
|
|
972
|
+
typename T,
|
|
973
|
+
std::enable_if_t<std::is_same_v<jsi::Symbol, T>, int> = 0>
|
|
731
974
|
T makeJsiPointer(napi_value value) const;
|
|
732
975
|
#if JSI_VERSION >= 6
|
|
733
|
-
template <
|
|
976
|
+
template <
|
|
977
|
+
typename T,
|
|
978
|
+
std::enable_if_t<std::is_same_v<jsi::BigInt, T>, int> = 0>
|
|
734
979
|
T makeJsiPointer(napi_value value) const;
|
|
735
980
|
#endif
|
|
736
981
|
template <
|
|
@@ -739,14 +984,14 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
739
984
|
std::enable_if_t<std::is_base_of_v<jsi::Pointer, TTo>, int> = 0,
|
|
740
985
|
std::enable_if_t<std::is_base_of_v<jsi::Pointer, TFrom>, int> = 0>
|
|
741
986
|
TTo cloneAs(const TFrom &pointer) const;
|
|
742
|
-
NodeApiRefHolder makeNodeApiRef(
|
|
987
|
+
NodeApiRefHolder makeNodeApiRef(
|
|
988
|
+
napi_value value,
|
|
989
|
+
NodeApiPointerValueKind pointerKind,
|
|
990
|
+
int32_t initialRefCount = 1);
|
|
743
991
|
|
|
744
|
-
void addStackValue(
|
|
745
|
-
void addRef(NodeApiRefHolder &&refHolder);
|
|
992
|
+
void addStackValue(NodeApiStackValuePtr stackPointer);
|
|
746
993
|
void pushPointerValueScope() noexcept;
|
|
747
994
|
void popPointerValueScope() noexcept;
|
|
748
|
-
void collectUnusedStackValues();
|
|
749
|
-
void collectUnusedRefs() noexcept;
|
|
750
995
|
|
|
751
996
|
napi_env getEnv() const noexcept {
|
|
752
997
|
return env_;
|
|
@@ -796,13 +1041,19 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
796
1041
|
bool hasPendingJSError_{false};
|
|
797
1042
|
|
|
798
1043
|
std::vector<size_t> stackScopes_;
|
|
799
|
-
std::vector<
|
|
800
|
-
std::vector<NodeApiRefHolder> refs_;
|
|
1044
|
+
std::vector<NodeApiStackValuePtr> stackValues_;
|
|
801
1045
|
|
|
802
1046
|
// TODO: implement GC for propNameIDs_
|
|
803
|
-
std::unordered_map<
|
|
1047
|
+
std::unordered_map<
|
|
1048
|
+
StringKey,
|
|
1049
|
+
NodeApiRefHolder,
|
|
1050
|
+
StringKey::Hash,
|
|
1051
|
+
StringKey::EqualTo>
|
|
1052
|
+
propNameIDs_;
|
|
804
1053
|
|
|
805
1054
|
NodeApiJsiRuntime &runtime{*this};
|
|
1055
|
+
NodeApiRefCountedPtr<NodeApiPendingDeletions> pendingDeletions_{
|
|
1056
|
+
NodeApiPendingDeletions::create()};
|
|
806
1057
|
};
|
|
807
1058
|
|
|
808
1059
|
//=====================================================================================================================
|
|
@@ -810,19 +1061,27 @@ class NodeApiJsiRuntime : public jsi::Runtime {
|
|
|
810
1061
|
//=====================================================================================================================
|
|
811
1062
|
|
|
812
1063
|
StringKey::StringKey(std::string &&string) noexcept
|
|
813
|
-
: string_(std::move(string)),
|
|
1064
|
+
: string_(std::move(string)),
|
|
1065
|
+
type_(Type::String),
|
|
1066
|
+
hash_(std::hash<std::string_view>{}(string_)) {}
|
|
814
1067
|
|
|
815
1068
|
StringKey::StringKey(std::string_view view) noexcept
|
|
816
|
-
: view_(view),
|
|
1069
|
+
: view_(view),
|
|
1070
|
+
type_(Type::View),
|
|
1071
|
+
hash_(std::hash<std::string_view>{}(view_)) {}
|
|
817
1072
|
|
|
818
1073
|
StringKey::StringKey(const char *data, size_t length) noexcept
|
|
819
|
-
: view_(data, length),
|
|
1074
|
+
: view_(data, length),
|
|
1075
|
+
type_(Type::View),
|
|
1076
|
+
hash_(std::hash<std::string_view>{}(view_)) {}
|
|
820
1077
|
|
|
821
|
-
StringKey::StringKey(StringKey &&other) noexcept
|
|
1078
|
+
StringKey::StringKey(StringKey &&other) noexcept
|
|
1079
|
+
: type_(other.type_), hash_(std::exchange(other.hash_, 0)) {
|
|
822
1080
|
if (type_ == Type::String) {
|
|
823
1081
|
::new (std::addressof(string_)) std::string(std::move(other.string_));
|
|
824
1082
|
} else {
|
|
825
|
-
::new (std::addressof(view_))
|
|
1083
|
+
::new (std::addressof(view_))
|
|
1084
|
+
std::string_view(std::exchange(other.view_, std::string_view()));
|
|
826
1085
|
}
|
|
827
1086
|
}
|
|
828
1087
|
|
|
@@ -858,7 +1117,9 @@ size_t StringKey::Hash::operator()(const StringKey &key) const {
|
|
|
858
1117
|
return key.hash();
|
|
859
1118
|
}
|
|
860
1119
|
|
|
861
|
-
bool StringKey::EqualTo::operator()(
|
|
1120
|
+
bool StringKey::EqualTo::operator()(
|
|
1121
|
+
const StringKey &left,
|
|
1122
|
+
const StringKey &right) const {
|
|
862
1123
|
return left.equalTo(right);
|
|
863
1124
|
}
|
|
864
1125
|
|
|
@@ -866,37 +1127,65 @@ bool StringKey::EqualTo::operator()(const StringKey &left, const StringKey &righ
|
|
|
866
1127
|
// NodeApiJsiRuntime implementation
|
|
867
1128
|
//=====================================================================================================================
|
|
868
1129
|
|
|
869
|
-
NodeApiJsiRuntime::NodeApiJsiRuntime(
|
|
1130
|
+
NodeApiJsiRuntime::NodeApiJsiRuntime(
|
|
1131
|
+
napi_env env,
|
|
1132
|
+
JSRuntimeApi *jsrApi,
|
|
1133
|
+
std::function<void()> onDelete) noexcept
|
|
870
1134
|
: env_(env), jsrApi_(jsrApi), onDelete_(std::move(onDelete)) {
|
|
871
1135
|
NodeApiScope scope{*this};
|
|
872
|
-
propertyId_.Error = makeNodeApiRef(
|
|
873
|
-
|
|
874
|
-
propertyId_.
|
|
875
|
-
|
|
876
|
-
propertyId_.
|
|
877
|
-
|
|
878
|
-
propertyId_.
|
|
879
|
-
|
|
880
|
-
propertyId_.
|
|
881
|
-
|
|
882
|
-
propertyId_.
|
|
883
|
-
|
|
884
|
-
propertyId_.
|
|
885
|
-
|
|
886
|
-
propertyId_.
|
|
887
|
-
|
|
888
|
-
propertyId_.
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
propertyId_.
|
|
892
|
-
|
|
893
|
-
propertyId_.
|
|
894
|
-
|
|
895
|
-
propertyId_.
|
|
896
|
-
|
|
897
|
-
|
|
1136
|
+
propertyId_.Error = makeNodeApiRef(
|
|
1137
|
+
getPropertyIdFromName("Error"), NodeApiPointerValueKind::String);
|
|
1138
|
+
propertyId_.Object = makeNodeApiRef(
|
|
1139
|
+
getPropertyIdFromName("Object"), NodeApiPointerValueKind::String);
|
|
1140
|
+
propertyId_.Proxy = makeNodeApiRef(
|
|
1141
|
+
getPropertyIdFromName("Proxy"), NodeApiPointerValueKind::String);
|
|
1142
|
+
propertyId_.Symbol = makeNodeApiRef(
|
|
1143
|
+
getPropertyIdFromName("Symbol"), NodeApiPointerValueKind::String);
|
|
1144
|
+
propertyId_.byteLength = makeNodeApiRef(
|
|
1145
|
+
getPropertyIdFromName("byteLength"), NodeApiPointerValueKind::String);
|
|
1146
|
+
propertyId_.configurable = makeNodeApiRef(
|
|
1147
|
+
getPropertyIdFromName("configurable"), NodeApiPointerValueKind::String);
|
|
1148
|
+
propertyId_.enumerable = makeNodeApiRef(
|
|
1149
|
+
getPropertyIdFromName("enumerable"), NodeApiPointerValueKind::String);
|
|
1150
|
+
propertyId_.get = makeNodeApiRef(
|
|
1151
|
+
getPropertyIdFromName("get"), NodeApiPointerValueKind::String);
|
|
1152
|
+
propertyId_.getOwnPropertyDescriptor = makeNodeApiRef(
|
|
1153
|
+
getPropertyIdFromName("getOwnPropertyDescriptor"),
|
|
1154
|
+
NodeApiPointerValueKind::String);
|
|
1155
|
+
propertyId_.has = makeNodeApiRef(
|
|
1156
|
+
getPropertyIdFromName("has"), NodeApiPointerValueKind::String);
|
|
1157
|
+
propertyId_.hostFunctionSymbol = makeNodeApiRef(
|
|
1158
|
+
createSymbol("hostFunctionSymbol"), NodeApiPointerValueKind::Symbol);
|
|
1159
|
+
propertyId_.hostObjectSymbol = makeNodeApiRef(
|
|
1160
|
+
createSymbol("hostObjectSymbol"), NodeApiPointerValueKind::Symbol);
|
|
1161
|
+
propertyId_.length = makeNodeApiRef(
|
|
1162
|
+
getPropertyIdFromName("length"), NodeApiPointerValueKind::String);
|
|
1163
|
+
propertyId_.message = makeNodeApiRef(
|
|
1164
|
+
getPropertyIdFromName("message"), NodeApiPointerValueKind::String);
|
|
1165
|
+
propertyId_.ownKeys = makeNodeApiRef(
|
|
1166
|
+
getPropertyIdFromName("ownKeys"), NodeApiPointerValueKind::String);
|
|
1167
|
+
propertyId_.propertyIsEnumerable = makeNodeApiRef(
|
|
1168
|
+
getPropertyIdFromName("propertyIsEnumerable"),
|
|
1169
|
+
NodeApiPointerValueKind::String);
|
|
1170
|
+
propertyId_.prototype = makeNodeApiRef(
|
|
1171
|
+
getPropertyIdFromName("prototype"), NodeApiPointerValueKind::String);
|
|
1172
|
+
propertyId_.set = makeNodeApiRef(
|
|
1173
|
+
getPropertyIdFromName("set"), NodeApiPointerValueKind::String);
|
|
1174
|
+
propertyId_.stack = makeNodeApiRef(
|
|
1175
|
+
getPropertyIdFromName("stack"), NodeApiPointerValueKind::String);
|
|
1176
|
+
propertyId_.toString = makeNodeApiRef(
|
|
1177
|
+
getPropertyIdFromName("toString"), NodeApiPointerValueKind::String);
|
|
1178
|
+
propertyId_.value = makeNodeApiRef(
|
|
1179
|
+
getPropertyIdFromName("value"), NodeApiPointerValueKind::String);
|
|
1180
|
+
propertyId_.writable = makeNodeApiRef(
|
|
1181
|
+
getPropertyIdFromName("writable"), NodeApiPointerValueKind::String);
|
|
1182
|
+
|
|
1183
|
+
cachedValue_.Global =
|
|
1184
|
+
makeNodeApiRef(getGlobal(), NodeApiPointerValueKind::Object);
|
|
898
1185
|
cachedValue_.Error = makeNodeApiRef(
|
|
899
|
-
getProperty(
|
|
1186
|
+
getProperty(
|
|
1187
|
+
getNodeApiValue(cachedValue_.Global),
|
|
1188
|
+
getNodeApiValue(propertyId_.Error)),
|
|
900
1189
|
NodeApiPointerValueKind::Object);
|
|
901
1190
|
}
|
|
902
1191
|
|
|
@@ -912,7 +1201,8 @@ jsi::Value NodeApiJsiRuntime::evaluateJavaScript(
|
|
|
912
1201
|
return evaluatePreparedJavaScript(prepareJavaScript(buffer, sourceURL));
|
|
913
1202
|
}
|
|
914
1203
|
|
|
915
|
-
std::shared_ptr<const jsi::PreparedJavaScript>
|
|
1204
|
+
std::shared_ptr<const jsi::PreparedJavaScript>
|
|
1205
|
+
NodeApiJsiRuntime::prepareJavaScript(
|
|
916
1206
|
const std::shared_ptr<const jsi::Buffer> &sourceBuffer,
|
|
917
1207
|
std::string sourceURL) {
|
|
918
1208
|
NodeApiScope scope{*this};
|
|
@@ -922,24 +1212,38 @@ std::shared_ptr<const jsi::PreparedJavaScript> NodeApiJsiRuntime::prepareJavaScr
|
|
|
922
1212
|
sourceBuffer->data(),
|
|
923
1213
|
sourceBuffer->size(),
|
|
924
1214
|
[](void * /*data*/, void *deleterData) {
|
|
925
|
-
delete reinterpret_cast<std::shared_ptr<const jsi::Buffer> *>(
|
|
1215
|
+
delete reinterpret_cast<std::shared_ptr<const jsi::Buffer> *>(
|
|
1216
|
+
deleterData);
|
|
926
1217
|
},
|
|
927
1218
|
new std::shared_ptr<const jsi::Buffer>(sourceBuffer),
|
|
928
1219
|
sourceURL.c_str(),
|
|
929
1220
|
&script);
|
|
930
1221
|
CHECK_NAPI(status); // Not for the call to keep better automated formatting.
|
|
931
|
-
return std::make_shared<NodeApiPreparedJavaScript>(
|
|
1222
|
+
return std::make_shared<NodeApiPreparedJavaScript>(
|
|
1223
|
+
env_, script, std::move(sourceURL));
|
|
932
1224
|
}
|
|
933
1225
|
|
|
934
|
-
jsi::Value NodeApiJsiRuntime::evaluatePreparedJavaScript(
|
|
1226
|
+
jsi::Value NodeApiJsiRuntime::evaluatePreparedJavaScript(
|
|
1227
|
+
const std::shared_ptr<const jsi::PreparedJavaScript> &js) {
|
|
935
1228
|
NodeApiScope scope{*this};
|
|
936
|
-
auto preparedScript =
|
|
937
|
-
|
|
1229
|
+
auto preparedScript =
|
|
1230
|
+
static_cast<const NodeApiPreparedJavaScript *>(js.get());
|
|
1231
|
+
AutoRestore<std::string> sourceURLScope{
|
|
1232
|
+
sourceURL_, preparedScript->sourceURL()};
|
|
938
1233
|
napi_value result{};
|
|
939
|
-
CHECK_NAPI(jsrApi_->jsr_prepared_script_run(
|
|
1234
|
+
CHECK_NAPI(jsrApi_->jsr_prepared_script_run(
|
|
1235
|
+
env_, preparedScript->getScript(), &result));
|
|
940
1236
|
return toJsiValue(result);
|
|
941
1237
|
}
|
|
942
1238
|
|
|
1239
|
+
#if JSI_VERSION >= 12
|
|
1240
|
+
void NodeApiJsiRuntime::queueMicrotask(const jsi::Function &callback) {
|
|
1241
|
+
NodeApiScope scope{*this};
|
|
1242
|
+
napi_value callbackValue = getNodeApiValue(callback);
|
|
1243
|
+
CHECK_NAPI(jsrApi_->jsr_queue_microtask(env_, callbackValue));
|
|
1244
|
+
}
|
|
1245
|
+
#endif
|
|
1246
|
+
|
|
943
1247
|
#if JSI_VERSION >= 4
|
|
944
1248
|
bool NodeApiJsiRuntime::drainMicrotasks(int maxMicrotasksHint) {
|
|
945
1249
|
bool result{};
|
|
@@ -964,29 +1268,36 @@ bool NodeApiJsiRuntime::isInspectable() {
|
|
|
964
1268
|
return result;
|
|
965
1269
|
}
|
|
966
1270
|
|
|
967
|
-
jsi::Runtime::PointerValue *NodeApiJsiRuntime::cloneSymbol(
|
|
1271
|
+
jsi::Runtime::PointerValue *NodeApiJsiRuntime::cloneSymbol(
|
|
1272
|
+
const jsi::Runtime::PointerValue *pointerValue) {
|
|
968
1273
|
return cloneNodeApiPointerValue(pointerValue);
|
|
969
1274
|
}
|
|
970
1275
|
|
|
971
1276
|
#if JSI_VERSION >= 6
|
|
972
|
-
jsi::Runtime::PointerValue *NodeApiJsiRuntime::cloneBigInt(
|
|
1277
|
+
jsi::Runtime::PointerValue *NodeApiJsiRuntime::cloneBigInt(
|
|
1278
|
+
const jsi::Runtime::PointerValue *pointerValue) {
|
|
973
1279
|
return cloneNodeApiPointerValue(pointerValue);
|
|
974
1280
|
}
|
|
975
1281
|
#endif
|
|
976
1282
|
|
|
977
|
-
jsi::Runtime::PointerValue *NodeApiJsiRuntime::cloneString(
|
|
1283
|
+
jsi::Runtime::PointerValue *NodeApiJsiRuntime::cloneString(
|
|
1284
|
+
const jsi::Runtime::PointerValue *pointerValue) {
|
|
978
1285
|
return cloneNodeApiPointerValue(pointerValue);
|
|
979
1286
|
}
|
|
980
1287
|
|
|
981
|
-
jsi::Runtime::PointerValue *NodeApiJsiRuntime::cloneObject(
|
|
1288
|
+
jsi::Runtime::PointerValue *NodeApiJsiRuntime::cloneObject(
|
|
1289
|
+
const jsi::Runtime::PointerValue *pointerValue) {
|
|
982
1290
|
return cloneNodeApiPointerValue(pointerValue);
|
|
983
1291
|
}
|
|
984
1292
|
|
|
985
|
-
jsi::Runtime::PointerValue *NodeApiJsiRuntime::clonePropNameID(
|
|
1293
|
+
jsi::Runtime::PointerValue *NodeApiJsiRuntime::clonePropNameID(
|
|
1294
|
+
const jsi::Runtime::PointerValue *pointerValue) {
|
|
986
1295
|
return cloneNodeApiPointerValue(pointerValue);
|
|
987
1296
|
}
|
|
988
1297
|
|
|
989
|
-
jsi::PropNameID NodeApiJsiRuntime::createPropNameIDFromAscii(
|
|
1298
|
+
jsi::PropNameID NodeApiJsiRuntime::createPropNameIDFromAscii(
|
|
1299
|
+
const char *str,
|
|
1300
|
+
size_t length) {
|
|
990
1301
|
NodeApiScope scope{*this};
|
|
991
1302
|
StringKey keyName{str, length};
|
|
992
1303
|
auto it = propNameIDs_.find(keyName);
|
|
@@ -1000,15 +1311,24 @@ jsi::PropNameID NodeApiJsiRuntime::createPropNameIDFromAscii(const char *str, si
|
|
|
1000
1311
|
CHECK_NAPI(jsrApi_->napi_set_property(env_, obj, propName, getUndefined()));
|
|
1001
1312
|
napi_value props{};
|
|
1002
1313
|
CHECK_NAPI(jsrApi_->napi_get_all_property_names(
|
|
1003
|
-
env_,
|
|
1314
|
+
env_,
|
|
1315
|
+
obj,
|
|
1316
|
+
napi_key_own_only,
|
|
1317
|
+
napi_key_skip_symbols,
|
|
1318
|
+
napi_key_numbers_to_strings,
|
|
1319
|
+
&props));
|
|
1004
1320
|
napi_value propNameId = getElement(props, 0);
|
|
1005
|
-
NodeApiRefHolder propNameRef =
|
|
1321
|
+
NodeApiRefHolder propNameRef =
|
|
1322
|
+
makeNodeApiRef(propNameId, NodeApiPointerValueKind::StringPropNameID, 2);
|
|
1006
1323
|
jsi::PropNameID result = make<jsi::PropNameID>(propNameRef.get());
|
|
1007
|
-
propNameIDs_.try_emplace(
|
|
1324
|
+
propNameIDs_.try_emplace(
|
|
1325
|
+
StringKey(std::string(keyName.getStringView())), std::move(propNameRef));
|
|
1008
1326
|
return result;
|
|
1009
1327
|
}
|
|
1010
1328
|
|
|
1011
|
-
jsi::PropNameID NodeApiJsiRuntime::createPropNameIDFromUtf8(
|
|
1329
|
+
jsi::PropNameID NodeApiJsiRuntime::createPropNameIDFromUtf8(
|
|
1330
|
+
const uint8_t *utf8,
|
|
1331
|
+
size_t length) {
|
|
1012
1332
|
NodeApiScope scope{*this};
|
|
1013
1333
|
StringKey keyName{reinterpret_cast<const char *>(utf8), length};
|
|
1014
1334
|
auto it = propNameIDs_.find(keyName);
|
|
@@ -1018,21 +1338,31 @@ jsi::PropNameID NodeApiJsiRuntime::createPropNameIDFromUtf8(const uint8_t *utf8,
|
|
|
1018
1338
|
|
|
1019
1339
|
napi_value obj = createNodeApiObject();
|
|
1020
1340
|
napi_value propName{};
|
|
1021
|
-
CHECK_NAPI(jsrApi_->napi_create_string_utf8(
|
|
1341
|
+
CHECK_NAPI(jsrApi_->napi_create_string_utf8(
|
|
1342
|
+
env_, reinterpret_cast<const char *>(utf8), length, &propName));
|
|
1022
1343
|
CHECK_NAPI(jsrApi_->napi_set_property(env_, obj, propName, getUndefined()));
|
|
1023
1344
|
napi_value props{};
|
|
1024
1345
|
CHECK_NAPI(jsrApi_->napi_get_all_property_names(
|
|
1025
|
-
env_,
|
|
1346
|
+
env_,
|
|
1347
|
+
obj,
|
|
1348
|
+
napi_key_own_only,
|
|
1349
|
+
napi_key_skip_symbols,
|
|
1350
|
+
napi_key_numbers_to_strings,
|
|
1351
|
+
&props));
|
|
1026
1352
|
napi_value propNameId = getElement(props, 0);
|
|
1027
|
-
NodeApiRefHolder propNameRef =
|
|
1353
|
+
NodeApiRefHolder propNameRef =
|
|
1354
|
+
makeNodeApiRef(propNameId, NodeApiPointerValueKind::StringPropNameID, 2);
|
|
1028
1355
|
jsi::PropNameID result = make<jsi::PropNameID>(propNameRef.get());
|
|
1029
|
-
propNameIDs_.try_emplace(
|
|
1356
|
+
propNameIDs_.try_emplace(
|
|
1357
|
+
StringKey(std::string(keyName.getStringView())), std::move(propNameRef));
|
|
1030
1358
|
return result;
|
|
1031
1359
|
}
|
|
1032
1360
|
|
|
1033
|
-
jsi::PropNameID NodeApiJsiRuntime::createPropNameIDFromString(
|
|
1361
|
+
jsi::PropNameID NodeApiJsiRuntime::createPropNameIDFromString(
|
|
1362
|
+
const jsi::String &str) {
|
|
1034
1363
|
NodeApiScope scope{*this};
|
|
1035
|
-
const NodeApiPointerValue *pv =
|
|
1364
|
+
const NodeApiPointerValue *pv =
|
|
1365
|
+
static_cast<const NodeApiPointerValue *>(getPointerValue(str));
|
|
1036
1366
|
if (pv->getKind() == NodeApiPointerValueKind::StringPropNameID) {
|
|
1037
1367
|
return make<jsi::PropNameID>(pv->clone(*this));
|
|
1038
1368
|
}
|
|
@@ -1049,16 +1379,24 @@ jsi::PropNameID NodeApiJsiRuntime::createPropNameIDFromString(const jsi::String
|
|
|
1049
1379
|
setProperty(obj, napiStr, getUndefined());
|
|
1050
1380
|
napi_value props{};
|
|
1051
1381
|
CHECK_NAPI(jsrApi_->napi_get_all_property_names(
|
|
1052
|
-
env_,
|
|
1382
|
+
env_,
|
|
1383
|
+
obj,
|
|
1384
|
+
napi_key_own_only,
|
|
1385
|
+
napi_key_skip_symbols,
|
|
1386
|
+
napi_key_numbers_to_strings,
|
|
1387
|
+
&props));
|
|
1053
1388
|
napi_value propNameId = getElement(props, 0);
|
|
1054
|
-
NodeApiRefHolder propNameRef =
|
|
1389
|
+
NodeApiRefHolder propNameRef =
|
|
1390
|
+
makeNodeApiRef(propNameId, NodeApiPointerValueKind::StringPropNameID, 2);
|
|
1055
1391
|
jsi::PropNameID result = make<jsi::PropNameID>(propNameRef.get());
|
|
1056
|
-
propNameIDs_.try_emplace(
|
|
1392
|
+
propNameIDs_.try_emplace(
|
|
1393
|
+
StringKey(std::string(keyName.getStringView())), std::move(propNameRef));
|
|
1057
1394
|
return result;
|
|
1058
1395
|
}
|
|
1059
1396
|
|
|
1060
1397
|
#if JSI_VERSION >= 5
|
|
1061
|
-
jsi::PropNameID NodeApiJsiRuntime::createPropNameIDFromSymbol(
|
|
1398
|
+
jsi::PropNameID NodeApiJsiRuntime::createPropNameIDFromSymbol(
|
|
1399
|
+
const jsi::Symbol &sym) {
|
|
1062
1400
|
// TODO: Should we ensure uniqueness of symbols?
|
|
1063
1401
|
return cloneAs<jsi::PropNameID>(sym);
|
|
1064
1402
|
}
|
|
@@ -1069,9 +1407,12 @@ std::string NodeApiJsiRuntime::utf8(const jsi::PropNameID &id) {
|
|
|
1069
1407
|
return propertyIdToStdString(getNodeApiValue(id));
|
|
1070
1408
|
}
|
|
1071
1409
|
|
|
1072
|
-
bool NodeApiJsiRuntime::compare(
|
|
1410
|
+
bool NodeApiJsiRuntime::compare(
|
|
1411
|
+
const jsi::PropNameID &lhs,
|
|
1412
|
+
const jsi::PropNameID &rhs) {
|
|
1073
1413
|
NodeApiScope scope{*this};
|
|
1074
|
-
return getPointerValue(lhs) == getPointerValue(rhs) ||
|
|
1414
|
+
return getPointerValue(lhs) == getPointerValue(rhs) ||
|
|
1415
|
+
strictEquals(getNodeApiValue(lhs), getNodeApiValue(rhs));
|
|
1075
1416
|
}
|
|
1076
1417
|
|
|
1077
1418
|
std::string NodeApiJsiRuntime::symbolToString(const jsi::Symbol &sym) {
|
|
@@ -1099,7 +1440,8 @@ bool NodeApiJsiRuntime::bigintIsInt64(const jsi::BigInt &bigint) {
|
|
|
1099
1440
|
napi_value value = getNodeApiValue(bigint);
|
|
1100
1441
|
bool lossless{false};
|
|
1101
1442
|
int64_t result{};
|
|
1102
|
-
CHECK_NAPI(
|
|
1443
|
+
CHECK_NAPI(
|
|
1444
|
+
jsrApi_->napi_get_value_bigint_int64(env_, value, &result, &lossless));
|
|
1103
1445
|
return lossless;
|
|
1104
1446
|
}
|
|
1105
1447
|
|
|
@@ -1108,7 +1450,8 @@ bool NodeApiJsiRuntime::bigintIsUint64(const jsi::BigInt &bigint) {
|
|
|
1108
1450
|
napi_value value = getNodeApiValue(bigint);
|
|
1109
1451
|
bool lossless{false};
|
|
1110
1452
|
uint64_t result{};
|
|
1111
|
-
CHECK_NAPI(
|
|
1453
|
+
CHECK_NAPI(
|
|
1454
|
+
jsrApi_->napi_get_value_bigint_uint64(env_, value, &result, &lossless));
|
|
1112
1455
|
return lossless;
|
|
1113
1456
|
}
|
|
1114
1457
|
|
|
@@ -1117,7 +1460,8 @@ uint64_t NodeApiJsiRuntime::truncate(const jsi::BigInt &bigint) {
|
|
|
1117
1460
|
napi_value value = getNodeApiValue(bigint);
|
|
1118
1461
|
bool lossless{false};
|
|
1119
1462
|
uint64_t result{};
|
|
1120
|
-
CHECK_NAPI(
|
|
1463
|
+
CHECK_NAPI(
|
|
1464
|
+
jsrApi_->napi_get_value_bigint_uint64(env_, value, &result, &lossless));
|
|
1121
1465
|
return result;
|
|
1122
1466
|
}
|
|
1123
1467
|
|
|
@@ -1126,12 +1470,17 @@ inline uint32_t constexpr maxCharsPerDigitInRadix(int32_t radix) {
|
|
|
1126
1470
|
// char. For power of 2 radixes, it is known (exactly) that each character
|
|
1127
1471
|
// covers log2(radix) bits. For non-power of 2 radixes, a lower bound is
|
|
1128
1472
|
// log2(greatest power of 2 that is less than radix).
|
|
1129
|
-
uint32_t minNumBitsPerChar = radix < 4 ? 1
|
|
1473
|
+
uint32_t minNumBitsPerChar = radix < 4 ? 1
|
|
1474
|
+
: radix < 8 ? 2
|
|
1475
|
+
: radix < 16 ? 3
|
|
1476
|
+
: radix < 32 ? 4
|
|
1477
|
+
: 5;
|
|
1130
1478
|
|
|
1131
1479
|
// With minNumBitsPerChar being the lower bound estimate of how many bits each
|
|
1132
1480
|
// char can represent, the upper bound of how many chars "fit" in a bigint
|
|
1133
1481
|
// digit is ceil(sizeofInBits(bigint digit) / minNumBitsPerChar).
|
|
1134
|
-
uint32_t numCharsPerDigits =
|
|
1482
|
+
uint32_t numCharsPerDigits =
|
|
1483
|
+
static_cast<uint32_t>(sizeof(uint64_t)) / (1 << minNumBitsPerChar);
|
|
1135
1484
|
|
|
1136
1485
|
return numCharsPerDigits;
|
|
1137
1486
|
}
|
|
@@ -1151,7 +1500,9 @@ constexpr inline uint64_t Make_64(uint32_t High, uint32_t Low) {
|
|
|
1151
1500
|
return ((uint64_t)High << 32) | (uint64_t)Low;
|
|
1152
1501
|
}
|
|
1153
1502
|
|
|
1154
|
-
jsi::String NodeApiJsiRuntime::bigintToString(
|
|
1503
|
+
jsi::String NodeApiJsiRuntime::bigintToString(
|
|
1504
|
+
const jsi::BigInt &bigint,
|
|
1505
|
+
int32_t radix) {
|
|
1155
1506
|
NodeApiScope scope{*this};
|
|
1156
1507
|
if (radix < 2 || radix > 36) {
|
|
1157
1508
|
throw makeJSError("Invalid radix ", radix, " to BigInt.toString");
|
|
@@ -1159,7 +1510,8 @@ jsi::String NodeApiJsiRuntime::bigintToString(const jsi::BigInt &bigint, int32_t
|
|
|
1159
1510
|
|
|
1160
1511
|
napi_value value = getNodeApiValue(bigint);
|
|
1161
1512
|
size_t wordCount{};
|
|
1162
|
-
CHECK_NAPI(jsrApi_->napi_get_value_bigint_words(
|
|
1513
|
+
CHECK_NAPI(jsrApi_->napi_get_value_bigint_words(
|
|
1514
|
+
env_, value, nullptr, &wordCount, nullptr));
|
|
1163
1515
|
uint64_t stackWords[8]{};
|
|
1164
1516
|
std::unique_ptr<uint64_t[]> heapWords;
|
|
1165
1517
|
uint64_t *words = stackWords;
|
|
@@ -1168,7 +1520,8 @@ jsi::String NodeApiJsiRuntime::bigintToString(const jsi::BigInt &bigint, int32_t
|
|
|
1168
1520
|
words = heapWords.get();
|
|
1169
1521
|
}
|
|
1170
1522
|
int32_t signBit{};
|
|
1171
|
-
CHECK_NAPI(jsrApi_->napi_get_value_bigint_words(
|
|
1523
|
+
CHECK_NAPI(jsrApi_->napi_get_value_bigint_words(
|
|
1524
|
+
env_, value, &signBit, &wordCount, words));
|
|
1172
1525
|
|
|
1173
1526
|
if (wordCount == 0) {
|
|
1174
1527
|
return createStringFromAscii("0", 1);
|
|
@@ -1243,12 +1596,16 @@ jsi::String NodeApiJsiRuntime::bigintToString(const jsi::BigInt &bigint, int32_t
|
|
|
1243
1596
|
}
|
|
1244
1597
|
#endif
|
|
1245
1598
|
|
|
1246
|
-
jsi::String NodeApiJsiRuntime::createStringFromAscii(
|
|
1599
|
+
jsi::String NodeApiJsiRuntime::createStringFromAscii(
|
|
1600
|
+
const char *str,
|
|
1601
|
+
size_t length) {
|
|
1247
1602
|
NodeApiScope scope{*this};
|
|
1248
1603
|
return makeJsiPointer<jsi::String>(createStringLatin1({str, length}));
|
|
1249
1604
|
}
|
|
1250
1605
|
|
|
1251
|
-
jsi::String NodeApiJsiRuntime::createStringFromUtf8(
|
|
1606
|
+
jsi::String NodeApiJsiRuntime::createStringFromUtf8(
|
|
1607
|
+
const uint8_t *str,
|
|
1608
|
+
size_t length) {
|
|
1252
1609
|
NodeApiScope scope{*this};
|
|
1253
1610
|
return makeJsiPointer<jsi::String>(createStringUtf8(str, length));
|
|
1254
1611
|
}
|
|
@@ -1263,38 +1620,51 @@ jsi::Object NodeApiJsiRuntime::createObject() {
|
|
|
1263
1620
|
return makeJsiPointer<jsi::Object>(createNodeApiObject());
|
|
1264
1621
|
}
|
|
1265
1622
|
|
|
1266
|
-
jsi::Object NodeApiJsiRuntime::createObject(
|
|
1623
|
+
jsi::Object NodeApiJsiRuntime::createObject(
|
|
1624
|
+
std::shared_ptr<jsi::HostObject> hostObject) {
|
|
1267
1625
|
NodeApiScope scope{*this};
|
|
1268
1626
|
// The hostObjectHolder keeps the hostObject as external data.
|
|
1269
|
-
// Then, the hostObjectHolder is wrapped up by a Proxy object to provide
|
|
1270
|
-
// to the hostObject's get, set, and getPropertyNames methods.
|
|
1271
|
-
//
|
|
1627
|
+
// Then, the hostObjectHolder is wrapped up by a Proxy object to provide
|
|
1628
|
+
// access to the hostObject's get, set, and getPropertyNames methods. There is
|
|
1629
|
+
// a special symbol property ID, 'hostObjectSymbol', used to access the
|
|
1630
|
+
// hostObjectWrapper from the Proxy.
|
|
1272
1631
|
napi_value hostObjectHolder =
|
|
1273
|
-
createExternalObject(std::make_unique<std::shared_ptr<jsi::HostObject>>(
|
|
1632
|
+
createExternalObject(std::make_unique<std::shared_ptr<jsi::HostObject>>(
|
|
1633
|
+
std::move(hostObject)));
|
|
1274
1634
|
napi_value obj = createNodeApiObject();
|
|
1275
|
-
setProperty(
|
|
1635
|
+
setProperty(
|
|
1636
|
+
obj, getNodeApiValue(propertyId_.hostObjectSymbol), hostObjectHolder);
|
|
1276
1637
|
if (!cachedValue_.ProxyConstructor) {
|
|
1277
1638
|
cachedValue_.ProxyConstructor = makeNodeApiRef(
|
|
1278
|
-
getProperty(
|
|
1639
|
+
getProperty(
|
|
1640
|
+
getNodeApiValue(cachedValue_.Global),
|
|
1641
|
+
getNodeApiValue(propertyId_.Proxy)),
|
|
1279
1642
|
NodeApiPointerValueKind::Object);
|
|
1280
1643
|
}
|
|
1281
1644
|
napi_value args[] = {obj, getHostObjectProxyHandler()};
|
|
1282
|
-
napi_value proxy =
|
|
1645
|
+
napi_value proxy =
|
|
1646
|
+
constructObject(getNodeApiValue(cachedValue_.ProxyConstructor), args);
|
|
1283
1647
|
return makeJsiPointer<jsi::Object>(proxy);
|
|
1284
1648
|
}
|
|
1285
1649
|
|
|
1286
|
-
std::shared_ptr<jsi::HostObject> NodeApiJsiRuntime::getHostObject(
|
|
1650
|
+
std::shared_ptr<jsi::HostObject> NodeApiJsiRuntime::getHostObject(
|
|
1651
|
+
const jsi::Object &obj) {
|
|
1287
1652
|
NodeApiScope scope{*this};
|
|
1288
1653
|
return getJsiHostObject(getNodeApiValue(obj));
|
|
1289
1654
|
}
|
|
1290
1655
|
|
|
1291
|
-
jsi::HostFunctionType &NodeApiJsiRuntime::getHostFunction(
|
|
1656
|
+
jsi::HostFunctionType &NodeApiJsiRuntime::getHostFunction(
|
|
1657
|
+
const jsi::Function &func) {
|
|
1292
1658
|
NodeApiScope scope{*this};
|
|
1293
|
-
napi_value hostFunctionHolder = getProperty(
|
|
1659
|
+
napi_value hostFunctionHolder = getProperty(
|
|
1660
|
+
getNodeApiValue(func), getNodeApiValue((propertyId_.hostFunctionSymbol)));
|
|
1294
1661
|
if (typeOf(hostFunctionHolder) == napi_valuetype::napi_external) {
|
|
1295
|
-
return static_cast<HostFunctionWrapper *>(
|
|
1662
|
+
return static_cast<HostFunctionWrapper *>(
|
|
1663
|
+
getExternalData(hostFunctionHolder))
|
|
1664
|
+
->hostFunction();
|
|
1296
1665
|
} else {
|
|
1297
|
-
throw jsi::JSINativeException(
|
|
1666
|
+
throw jsi::JSINativeException(
|
|
1667
|
+
"getHostFunction() can only be called with HostFunction.");
|
|
1298
1668
|
}
|
|
1299
1669
|
}
|
|
1300
1670
|
|
|
@@ -1302,11 +1672,13 @@ jsi::HostFunctionType &NodeApiJsiRuntime::getHostFunction(const jsi::Function &f
|
|
|
1302
1672
|
bool NodeApiJsiRuntime::hasNativeState(const jsi::Object &obj) {
|
|
1303
1673
|
NodeApiScope scope{*this};
|
|
1304
1674
|
void *nativeState{};
|
|
1305
|
-
napi_status status =
|
|
1675
|
+
napi_status status =
|
|
1676
|
+
jsrApi_->napi_unwrap(env_, getNodeApiValue(obj), &nativeState);
|
|
1306
1677
|
return status == napi_ok && nativeState != nullptr;
|
|
1307
1678
|
}
|
|
1308
1679
|
|
|
1309
|
-
std::shared_ptr<jsi::NativeState> NodeApiJsiRuntime::getNativeState(
|
|
1680
|
+
std::shared_ptr<jsi::NativeState> NodeApiJsiRuntime::getNativeState(
|
|
1681
|
+
const jsi::Object &obj) {
|
|
1310
1682
|
NodeApiScope scope{*this};
|
|
1311
1683
|
void *nativeState{};
|
|
1312
1684
|
CHECK_NAPI(jsrApi_->napi_unwrap(env_, getNodeApiValue(obj), &nativeState));
|
|
@@ -1317,14 +1689,17 @@ std::shared_ptr<jsi::NativeState> NodeApiJsiRuntime::getNativeState(const jsi::O
|
|
|
1317
1689
|
}
|
|
1318
1690
|
}
|
|
1319
1691
|
|
|
1320
|
-
void NodeApiJsiRuntime::setNativeState(
|
|
1692
|
+
void NodeApiJsiRuntime::setNativeState(
|
|
1693
|
+
const jsi::Object &obj,
|
|
1694
|
+
std::shared_ptr<jsi::NativeState> state) {
|
|
1321
1695
|
NodeApiScope scope{*this};
|
|
1322
1696
|
if (hasNativeState(obj)) {
|
|
1323
1697
|
void *nativeState{};
|
|
1324
|
-
CHECK_NAPI(
|
|
1698
|
+
CHECK_NAPI(
|
|
1699
|
+
jsrApi_->napi_remove_wrap(env_, getNodeApiValue(obj), &nativeState));
|
|
1325
1700
|
if (nativeState != nullptr) {
|
|
1326
|
-
std::shared_ptr<jsi::NativeState> oldState{
|
|
1327
|
-
|
|
1701
|
+
std::shared_ptr<jsi::NativeState> oldState{std::move(
|
|
1702
|
+
*reinterpret_cast<std::shared_ptr<jsi::NativeState> *>(nativeState))};
|
|
1328
1703
|
}
|
|
1329
1704
|
}
|
|
1330
1705
|
|
|
@@ -1333,9 +1708,9 @@ void NodeApiJsiRuntime::setNativeState(const jsi::Object &obj, std::shared_ptr<j
|
|
|
1333
1708
|
env_,
|
|
1334
1709
|
getNodeApiValue(obj),
|
|
1335
1710
|
new std::shared_ptr<jsi::NativeState>(std::move(state)),
|
|
1336
|
-
[](
|
|
1337
|
-
std::shared_ptr<jsi::NativeState> oldState{
|
|
1338
|
-
|
|
1711
|
+
[](node_api_nogc_env /*env*/, void *data, void * /*finalize_hint*/) {
|
|
1712
|
+
std::shared_ptr<jsi::NativeState> oldState{std::move(
|
|
1713
|
+
*reinterpret_cast<std::shared_ptr<jsi::NativeState> *>(data))};
|
|
1339
1714
|
},
|
|
1340
1715
|
nullptr,
|
|
1341
1716
|
nullptr));
|
|
@@ -1343,22 +1718,30 @@ void NodeApiJsiRuntime::setNativeState(const jsi::Object &obj, std::shared_ptr<j
|
|
|
1343
1718
|
}
|
|
1344
1719
|
#endif
|
|
1345
1720
|
|
|
1346
|
-
jsi::Value NodeApiJsiRuntime::getProperty(
|
|
1721
|
+
jsi::Value NodeApiJsiRuntime::getProperty(
|
|
1722
|
+
const jsi::Object &obj,
|
|
1723
|
+
const jsi::PropNameID &name) {
|
|
1347
1724
|
NodeApiScope scope{*this};
|
|
1348
1725
|
return toJsiValue(getProperty(getNodeApiValue(obj), getNodeApiValue(name)));
|
|
1349
1726
|
}
|
|
1350
1727
|
|
|
1351
|
-
jsi::Value NodeApiJsiRuntime::getProperty(
|
|
1728
|
+
jsi::Value NodeApiJsiRuntime::getProperty(
|
|
1729
|
+
const jsi::Object &obj,
|
|
1730
|
+
const jsi::String &name) {
|
|
1352
1731
|
NodeApiScope scope{*this};
|
|
1353
1732
|
return toJsiValue(getProperty(getNodeApiValue(obj), getNodeApiValue(name)));
|
|
1354
1733
|
}
|
|
1355
1734
|
|
|
1356
|
-
bool NodeApiJsiRuntime::hasProperty(
|
|
1735
|
+
bool NodeApiJsiRuntime::hasProperty(
|
|
1736
|
+
const jsi::Object &obj,
|
|
1737
|
+
const jsi::PropNameID &name) {
|
|
1357
1738
|
NodeApiScope scope{*this};
|
|
1358
1739
|
return hasProperty(getNodeApiValue(obj), getNodeApiValue(name));
|
|
1359
1740
|
}
|
|
1360
1741
|
|
|
1361
|
-
bool NodeApiJsiRuntime::hasProperty(
|
|
1742
|
+
bool NodeApiJsiRuntime::hasProperty(
|
|
1743
|
+
const jsi::Object &obj,
|
|
1744
|
+
const jsi::String &name) {
|
|
1362
1745
|
NodeApiScope scope{*this};
|
|
1363
1746
|
return hasProperty(getNodeApiValue(obj), getNodeApiValue(name));
|
|
1364
1747
|
}
|
|
@@ -1368,7 +1751,8 @@ void NodeApiJsiRuntime::setPropertyValue(
|
|
|
1368
1751
|
const jsi::PropNameID &name,
|
|
1369
1752
|
const jsi::Value &value) {
|
|
1370
1753
|
NodeApiScope scope{*this};
|
|
1371
|
-
setProperty(
|
|
1754
|
+
setProperty(
|
|
1755
|
+
getNodeApiValue(obj), getNodeApiValue(name), getNodeApiValue(value));
|
|
1372
1756
|
}
|
|
1373
1757
|
|
|
1374
1758
|
void NodeApiJsiRuntime::setPropertyValue(
|
|
@@ -1376,7 +1760,8 @@ void NodeApiJsiRuntime::setPropertyValue(
|
|
|
1376
1760
|
const jsi::String &name,
|
|
1377
1761
|
const jsi::Value &value) {
|
|
1378
1762
|
NodeApiScope scope{*this};
|
|
1379
|
-
setProperty(
|
|
1763
|
+
setProperty(
|
|
1764
|
+
getNodeApiValue(obj), getNodeApiValue(name), getNodeApiValue(value));
|
|
1380
1765
|
}
|
|
1381
1766
|
|
|
1382
1767
|
bool NodeApiJsiRuntime::isArray(const jsi::Object &obj) const {
|
|
@@ -1398,7 +1783,8 @@ bool NodeApiJsiRuntime::isFunction(const jsi::Object &obj) const {
|
|
|
1398
1783
|
|
|
1399
1784
|
bool NodeApiJsiRuntime::isHostObject(const jsi::Object &obj) const {
|
|
1400
1785
|
NodeApiScope scope{*this};
|
|
1401
|
-
napi_value hostObjectHolder = getProperty(
|
|
1786
|
+
napi_value hostObjectHolder = getProperty(
|
|
1787
|
+
getNodeApiValue(obj), getNodeApiValue(propertyId_.hostObjectSymbol));
|
|
1402
1788
|
if (typeOf(hostObjectHolder) == napi_valuetype::napi_external) {
|
|
1403
1789
|
return getExternalData(hostObjectHolder) != nullptr;
|
|
1404
1790
|
} else {
|
|
@@ -1408,7 +1794,8 @@ bool NodeApiJsiRuntime::isHostObject(const jsi::Object &obj) const {
|
|
|
1408
1794
|
|
|
1409
1795
|
bool NodeApiJsiRuntime::isHostFunction(const jsi::Function &func) const {
|
|
1410
1796
|
NodeApiScope scope{*this};
|
|
1411
|
-
napi_value hostFunctionHolder = getProperty(
|
|
1797
|
+
napi_value hostFunctionHolder = getProperty(
|
|
1798
|
+
getNodeApiValue(func), getNodeApiValue(propertyId_.hostFunctionSymbol));
|
|
1412
1799
|
if (typeOf(hostFunctionHolder) == napi_valuetype::napi_external) {
|
|
1413
1800
|
return getExternalData(hostFunctionHolder) != nullptr;
|
|
1414
1801
|
} else {
|
|
@@ -1432,10 +1819,14 @@ jsi::Array NodeApiJsiRuntime::getPropertyNames(const jsi::Object &obj) {
|
|
|
1432
1819
|
jsi::WeakObject NodeApiJsiRuntime::createWeakObject(const jsi::Object &obj) {
|
|
1433
1820
|
NodeApiScope scope{*this};
|
|
1434
1821
|
return make<jsi::WeakObject>(NodeApiRefCountedPointerValue::make(
|
|
1435
|
-
|
|
1822
|
+
*const_cast<NodeApiJsiRuntime *>(this),
|
|
1823
|
+
getNodeApiValue(obj),
|
|
1824
|
+
NodeApiPointerValueKind::WeakObject)
|
|
1825
|
+
.release());
|
|
1436
1826
|
}
|
|
1437
1827
|
|
|
1438
|
-
jsi::Value NodeApiJsiRuntime::lockWeakObject(
|
|
1828
|
+
jsi::Value NodeApiJsiRuntime::lockWeakObject(
|
|
1829
|
+
JSI_NO_CONST_3 JSI_CONST_10 jsi::WeakObject &weakObject) {
|
|
1439
1830
|
NodeApiScope scope{*this};
|
|
1440
1831
|
napi_value value = getNodeApiValue(weakObject);
|
|
1441
1832
|
if (value) {
|
|
@@ -1451,7 +1842,8 @@ jsi::Array NodeApiJsiRuntime::createArray(size_t length) {
|
|
|
1451
1842
|
}
|
|
1452
1843
|
|
|
1453
1844
|
#if JSI_VERSION >= 9
|
|
1454
|
-
jsi::ArrayBuffer NodeApiJsiRuntime::createArrayBuffer(
|
|
1845
|
+
jsi::ArrayBuffer NodeApiJsiRuntime::createArrayBuffer(
|
|
1846
|
+
std::shared_ptr<jsi::MutableBuffer> buffer) {
|
|
1455
1847
|
NodeApiScope scope{*this};
|
|
1456
1848
|
napi_value result{};
|
|
1457
1849
|
void *data = buffer->data();
|
|
@@ -1460,9 +1852,10 @@ jsi::ArrayBuffer NodeApiJsiRuntime::createArrayBuffer(std::shared_ptr<jsi::Mutab
|
|
|
1460
1852
|
env_,
|
|
1461
1853
|
data,
|
|
1462
1854
|
size,
|
|
1463
|
-
[](
|
|
1855
|
+
[](node_api_nogc_env /*env*/, void * /*data*/, void *finalizeHint) {
|
|
1464
1856
|
std::shared_ptr<jsi::MutableBuffer> buffer{
|
|
1465
|
-
std::move(*reinterpret_cast<std::shared_ptr<jsi::MutableBuffer> *>(
|
|
1857
|
+
std::move(*reinterpret_cast<std::shared_ptr<jsi::MutableBuffer> *>(
|
|
1858
|
+
finalizeHint))};
|
|
1466
1859
|
},
|
|
1467
1860
|
new std::shared_ptr<jsi::MutableBuffer>{std::move(buffer)},
|
|
1468
1861
|
&result));
|
|
@@ -1478,26 +1871,38 @@ size_t NodeApiJsiRuntime::size(const jsi::Array &arr) {
|
|
|
1478
1871
|
size_t NodeApiJsiRuntime::size(const jsi::ArrayBuffer &arrBuf) {
|
|
1479
1872
|
NodeApiScope scope{*this};
|
|
1480
1873
|
size_t result{};
|
|
1481
|
-
CHECK_NAPI(jsrApi_->napi_get_arraybuffer_info(
|
|
1874
|
+
CHECK_NAPI(jsrApi_->napi_get_arraybuffer_info(
|
|
1875
|
+
env_, getNodeApiValue(arrBuf), nullptr, &result));
|
|
1482
1876
|
return result;
|
|
1483
1877
|
}
|
|
1484
1878
|
|
|
1485
1879
|
uint8_t *NodeApiJsiRuntime::data(const jsi::ArrayBuffer &arrBuf) {
|
|
1486
1880
|
NodeApiScope scope{*this};
|
|
1487
1881
|
uint8_t *result{};
|
|
1488
|
-
CHECK_NAPI(
|
|
1489
|
-
|
|
1882
|
+
CHECK_NAPI(jsrApi_->napi_get_arraybuffer_info(
|
|
1883
|
+
env_,
|
|
1884
|
+
getNodeApiValue(arrBuf),
|
|
1885
|
+
reinterpret_cast<void **>(&result),
|
|
1886
|
+
nullptr));
|
|
1490
1887
|
return result;
|
|
1491
1888
|
}
|
|
1492
1889
|
|
|
1493
|
-
jsi::Value NodeApiJsiRuntime::getValueAtIndex(
|
|
1890
|
+
jsi::Value NodeApiJsiRuntime::getValueAtIndex(
|
|
1891
|
+
const jsi::Array &arr,
|
|
1892
|
+
size_t index) {
|
|
1494
1893
|
NodeApiScope scope{*this};
|
|
1495
1894
|
return toJsiValue(getElement(getNodeApiValue(arr), index));
|
|
1496
1895
|
}
|
|
1497
1896
|
|
|
1498
|
-
void NodeApiJsiRuntime::setValueAtIndexImpl(
|
|
1897
|
+
void NodeApiJsiRuntime::setValueAtIndexImpl(
|
|
1898
|
+
JSI_CONST_10 jsi::Array &arr,
|
|
1899
|
+
size_t index,
|
|
1900
|
+
const jsi::Value &value) {
|
|
1499
1901
|
NodeApiScope scope{*this};
|
|
1500
|
-
setElement(
|
|
1902
|
+
setElement(
|
|
1903
|
+
getNodeApiValue(arr),
|
|
1904
|
+
static_cast<uint32_t>(index),
|
|
1905
|
+
getNodeApiValue(value));
|
|
1501
1906
|
}
|
|
1502
1907
|
|
|
1503
1908
|
jsi::Function NodeApiJsiRuntime::createFunctionFromHostFunction(
|
|
@@ -1505,11 +1910,16 @@ jsi::Function NodeApiJsiRuntime::createFunctionFromHostFunction(
|
|
|
1505
1910
|
unsigned int paramCount,
|
|
1506
1911
|
jsi::HostFunctionType func) {
|
|
1507
1912
|
NodeApiScope scope{*this};
|
|
1508
|
-
auto hostFunctionWrapper =
|
|
1913
|
+
auto hostFunctionWrapper =
|
|
1914
|
+
std::make_unique<HostFunctionWrapper>(std::move(func), *this);
|
|
1509
1915
|
napi_value function = createExternalFunction(
|
|
1510
|
-
getNodeApiValue(name),
|
|
1916
|
+
getNodeApiValue(name),
|
|
1917
|
+
static_cast<int32_t>(paramCount),
|
|
1918
|
+
jsiHostFunctionCallback,
|
|
1919
|
+
hostFunctionWrapper.get());
|
|
1511
1920
|
|
|
1512
|
-
const napi_value hostFunctionHolder =
|
|
1921
|
+
const napi_value hostFunctionHolder =
|
|
1922
|
+
createExternalObject(std::move(hostFunctionWrapper));
|
|
1513
1923
|
setProperty(
|
|
1514
1924
|
function,
|
|
1515
1925
|
getNodeApiValue(propertyId_.hostFunctionSymbol),
|
|
@@ -1518,21 +1928,29 @@ jsi::Function NodeApiJsiRuntime::createFunctionFromHostFunction(
|
|
|
1518
1928
|
return makeJsiPointer<jsi::Object>(function).getFunction(*this);
|
|
1519
1929
|
}
|
|
1520
1930
|
|
|
1521
|
-
jsi::Value
|
|
1522
|
-
|
|
1931
|
+
jsi::Value NodeApiJsiRuntime::call(
|
|
1932
|
+
const jsi::Function &func,
|
|
1933
|
+
const jsi::Value &jsThis,
|
|
1934
|
+
const jsi::Value *args,
|
|
1935
|
+
size_t count) {
|
|
1523
1936
|
NodeApiScope scope{*this};
|
|
1524
1937
|
return toJsiValue(callFunction(
|
|
1525
|
-
getNodeApiValue(jsThis),
|
|
1938
|
+
getNodeApiValue(jsThis),
|
|
1939
|
+
getNodeApiValue(func),
|
|
1940
|
+
NodeApiValueArgs(*this, span<const jsi::Value>(args, count))));
|
|
1526
1941
|
}
|
|
1527
1942
|
|
|
1528
|
-
jsi::Value NodeApiJsiRuntime::callAsConstructor(
|
|
1943
|
+
jsi::Value NodeApiJsiRuntime::callAsConstructor(
|
|
1944
|
+
const jsi::Function &func,
|
|
1945
|
+
const jsi::Value *args,
|
|
1946
|
+
size_t count) {
|
|
1529
1947
|
NodeApiScope scope{*this};
|
|
1530
|
-
return toJsiValue(
|
|
1531
|
-
|
|
1948
|
+
return toJsiValue(constructObject(
|
|
1949
|
+
getNodeApiValue(func),
|
|
1950
|
+
NodeApiValueArgs(*this, span<jsi::Value const>(args, count))));
|
|
1532
1951
|
}
|
|
1533
1952
|
|
|
1534
1953
|
jsi::Runtime::ScopeState *NodeApiJsiRuntime::pushScope() {
|
|
1535
|
-
NodeApiEnvScope scope{getEnv()};
|
|
1536
1954
|
napi_handle_scope result{};
|
|
1537
1955
|
CHECK_NAPI(jsrApi_->napi_open_handle_scope(env_, &result));
|
|
1538
1956
|
pushPointerValueScope();
|
|
@@ -1540,40 +1958,48 @@ jsi::Runtime::ScopeState *NodeApiJsiRuntime::pushScope() {
|
|
|
1540
1958
|
}
|
|
1541
1959
|
|
|
1542
1960
|
void NodeApiJsiRuntime::popScope(jsi::Runtime::ScopeState *state) {
|
|
1543
|
-
NodeApiEnvScope scope{getEnv()};
|
|
1544
1961
|
popPointerValueScope();
|
|
1545
|
-
CHECK_NAPI(jsrApi_->napi_close_handle_scope(
|
|
1962
|
+
CHECK_NAPI(jsrApi_->napi_close_handle_scope(
|
|
1963
|
+
env_, reinterpret_cast<napi_handle_scope>(state)));
|
|
1546
1964
|
}
|
|
1547
1965
|
|
|
1548
|
-
bool NodeApiJsiRuntime::strictEquals(const jsi::Symbol &a, const jsi::Symbol &b)
|
|
1966
|
+
bool NodeApiJsiRuntime::strictEquals(const jsi::Symbol &a, const jsi::Symbol &b)
|
|
1967
|
+
const {
|
|
1549
1968
|
NodeApiScope scope{*this};
|
|
1550
1969
|
return strictEquals(getNodeApiValue(a), getNodeApiValue(b));
|
|
1551
1970
|
}
|
|
1552
1971
|
|
|
1553
1972
|
#if JSI_VERSION >= 6
|
|
1554
|
-
bool NodeApiJsiRuntime::strictEquals(const jsi::BigInt &a, const jsi::BigInt &b)
|
|
1973
|
+
bool NodeApiJsiRuntime::strictEquals(const jsi::BigInt &a, const jsi::BigInt &b)
|
|
1974
|
+
const {
|
|
1555
1975
|
NodeApiScope scope{*this};
|
|
1556
1976
|
return strictEquals(getNodeApiValue(a), getNodeApiValue(b));
|
|
1557
1977
|
}
|
|
1558
1978
|
#endif
|
|
1559
1979
|
|
|
1560
|
-
bool NodeApiJsiRuntime::strictEquals(const jsi::String &a, const jsi::String &b)
|
|
1980
|
+
bool NodeApiJsiRuntime::strictEquals(const jsi::String &a, const jsi::String &b)
|
|
1981
|
+
const {
|
|
1561
1982
|
NodeApiScope scope{*this};
|
|
1562
1983
|
return strictEquals(getNodeApiValue(a), getNodeApiValue(b));
|
|
1563
1984
|
}
|
|
1564
1985
|
|
|
1565
|
-
bool NodeApiJsiRuntime::strictEquals(const jsi::Object &a, const jsi::Object &b)
|
|
1986
|
+
bool NodeApiJsiRuntime::strictEquals(const jsi::Object &a, const jsi::Object &b)
|
|
1987
|
+
const {
|
|
1566
1988
|
NodeApiScope scope{*this};
|
|
1567
1989
|
return strictEquals(getNodeApiValue(a), getNodeApiValue(b));
|
|
1568
1990
|
}
|
|
1569
1991
|
|
|
1570
|
-
bool NodeApiJsiRuntime::instanceOf(
|
|
1992
|
+
bool NodeApiJsiRuntime::instanceOf(
|
|
1993
|
+
const jsi::Object &obj,
|
|
1994
|
+
const jsi::Function &func) {
|
|
1571
1995
|
NodeApiScope scope{*this};
|
|
1572
1996
|
return instanceOf(getNodeApiValue(obj), getNodeApiValue(func));
|
|
1573
1997
|
}
|
|
1574
1998
|
|
|
1575
1999
|
#if JSI_VERSION >= 11
|
|
1576
|
-
void NodeApiJsiRuntime::setExternalMemoryPressure(
|
|
2000
|
+
void NodeApiJsiRuntime::setExternalMemoryPressure(
|
|
2001
|
+
const jsi::Object & /*obj*/,
|
|
2002
|
+
size_t /*amount*/) {
|
|
1577
2003
|
// TODO: implement
|
|
1578
2004
|
}
|
|
1579
2005
|
#endif
|
|
@@ -1582,13 +2008,20 @@ void NodeApiJsiRuntime::setExternalMemoryPressure(const jsi::Object &/*obj*/, si
|
|
|
1582
2008
|
// NodeApiJsiRuntime::NodeApiScope implementation
|
|
1583
2009
|
//=====================================================================================================================
|
|
1584
2010
|
|
|
1585
|
-
NodeApiJsiRuntime::NodeApiScope::NodeApiScope(
|
|
2011
|
+
NodeApiJsiRuntime::NodeApiScope::NodeApiScope(
|
|
2012
|
+
const NodeApiJsiRuntime &runtime) noexcept
|
|
1586
2013
|
: NodeApiScope(const_cast<NodeApiJsiRuntime &>(runtime)) {}
|
|
1587
2014
|
|
|
1588
|
-
NodeApiJsiRuntime::NodeApiScope::NodeApiScope(
|
|
1589
|
-
|
|
2015
|
+
NodeApiJsiRuntime::NodeApiScope::NodeApiScope(
|
|
2016
|
+
NodeApiJsiRuntime &runtime) noexcept
|
|
2017
|
+
: runtime_(runtime),
|
|
2018
|
+
envScope_(runtime_.getEnv()),
|
|
2019
|
+
scopeState_(runtime_.pushScope()) {
|
|
2020
|
+
runtime_.pushPointerValueScope();
|
|
2021
|
+
}
|
|
1590
2022
|
|
|
1591
2023
|
NodeApiJsiRuntime::NodeApiScope::~NodeApiScope() noexcept {
|
|
2024
|
+
runtime_.popPointerValueScope();
|
|
1592
2025
|
runtime_.popScope(scopeState_);
|
|
1593
2026
|
}
|
|
1594
2027
|
|
|
@@ -1596,12 +2029,14 @@ NodeApiJsiRuntime::NodeApiScope::~NodeApiScope() noexcept {
|
|
|
1596
2029
|
// NodeApiJsiRuntime::NodeApiPointerValueScope implementation
|
|
1597
2030
|
//=====================================================================================================================
|
|
1598
2031
|
|
|
1599
|
-
NodeApiJsiRuntime::NodeApiPointerValueScope::NodeApiPointerValueScope(
|
|
2032
|
+
NodeApiJsiRuntime::NodeApiPointerValueScope::NodeApiPointerValueScope(
|
|
2033
|
+
NodeApiJsiRuntime &runtime) noexcept
|
|
1600
2034
|
: runtime_(runtime) {
|
|
1601
2035
|
runtime_.pushPointerValueScope();
|
|
1602
2036
|
}
|
|
1603
2037
|
|
|
1604
|
-
NodeApiJsiRuntime::NodeApiPointerValueScope
|
|
2038
|
+
NodeApiJsiRuntime::NodeApiPointerValueScope::
|
|
2039
|
+
~NodeApiPointerValueScope() noexcept {
|
|
1605
2040
|
runtime_.popPointerValueScope();
|
|
1606
2041
|
}
|
|
1607
2042
|
|
|
@@ -1627,19 +2062,23 @@ NodeApiJsiRuntime::NodeApiStackOnlyPointerValue::NodeApiStackOnlyPointerValue(
|
|
|
1627
2062
|
NodeApiPointerValueKind pointerKind) noexcept
|
|
1628
2063
|
: value_(value), pointerKind_(pointerKind) {}
|
|
1629
2064
|
|
|
1630
|
-
// Intentionally do nothing.
|
|
2065
|
+
// Intentionally do nothing since the value is allocated on the stack.
|
|
1631
2066
|
void NodeApiJsiRuntime::NodeApiStackOnlyPointerValue::invalidate() noexcept {}
|
|
1632
2067
|
|
|
1633
|
-
NodeApiJsiRuntime::NodeApiRefCountedPointerValue *
|
|
1634
|
-
|
|
1635
|
-
|
|
2068
|
+
NodeApiJsiRuntime::NodeApiRefCountedPointerValue *
|
|
2069
|
+
NodeApiJsiRuntime::NodeApiStackOnlyPointerValue::clone(
|
|
2070
|
+
NodeApiJsiRuntime &runtime) const noexcept {
|
|
2071
|
+
return NodeApiRefCountedPointerValue::make(runtime, value_, pointerKind_)
|
|
2072
|
+
.release();
|
|
1636
2073
|
}
|
|
1637
2074
|
|
|
1638
|
-
napi_value NodeApiJsiRuntime::NodeApiStackOnlyPointerValue::getValue(
|
|
2075
|
+
napi_value NodeApiJsiRuntime::NodeApiStackOnlyPointerValue::getValue(
|
|
2076
|
+
NodeApiJsiRuntime & /*runtime*/) noexcept {
|
|
1639
2077
|
return value_;
|
|
1640
2078
|
}
|
|
1641
2079
|
|
|
1642
|
-
NodeApiJsiRuntime::NodeApiPointerValueKind
|
|
2080
|
+
NodeApiJsiRuntime::NodeApiPointerValueKind
|
|
2081
|
+
NodeApiJsiRuntime::NodeApiStackOnlyPointerValue::getKind() const noexcept {
|
|
1643
2082
|
return pointerKind_;
|
|
1644
2083
|
}
|
|
1645
2084
|
|
|
@@ -1648,41 +2087,53 @@ NodeApiJsiRuntime::NodeApiPointerValueKind NodeApiJsiRuntime::NodeApiStackOnlyPo
|
|
|
1648
2087
|
//=====================================================================================================================
|
|
1649
2088
|
|
|
1650
2089
|
NodeApiJsiRuntime::NodeApiRefCountedPointerValue::NodeApiRefCountedPointerValue(
|
|
2090
|
+
NodeApiJsiRuntime &runtime,
|
|
1651
2091
|
napi_value value,
|
|
1652
2092
|
NodeApiJsiRuntime::NodeApiPointerValueKind pointerKind,
|
|
1653
2093
|
int32_t initialRefCount) noexcept
|
|
1654
|
-
:
|
|
2094
|
+
: pendingDeletions_(runtime.pendingDeletions_),
|
|
2095
|
+
value_(value),
|
|
2096
|
+
refCount_(initialRefCount),
|
|
2097
|
+
pointerKind_(pointerKind) {}
|
|
1655
2098
|
|
|
1656
|
-
/*static*/ NodeApiJsiRuntime::
|
|
2099
|
+
/*static*/ NodeApiJsiRuntime::NodeApiRefHolder
|
|
2100
|
+
NodeApiJsiRuntime::NodeApiRefCountedPointerValue::make(
|
|
1657
2101
|
NodeApiJsiRuntime &runtime,
|
|
1658
2102
|
napi_value value,
|
|
1659
2103
|
NodeApiJsiRuntime::NodeApiPointerValueKind pointerKind,
|
|
1660
2104
|
int32_t initialRefCount) {
|
|
1661
|
-
|
|
1662
|
-
|
|
2105
|
+
NodeApiRefHolder result{
|
|
2106
|
+
new NodeApiRefCountedPointerValue(
|
|
2107
|
+
runtime, value, pointerKind, initialRefCount),
|
|
2108
|
+
attachTag};
|
|
2109
|
+
runtime.addStackValue(NodeApiStackValuePtr{result.get()});
|
|
1663
2110
|
return result;
|
|
1664
2111
|
}
|
|
1665
2112
|
|
|
1666
|
-
/*static*/ NodeApiJsiRuntime::
|
|
2113
|
+
/*static*/ NodeApiJsiRuntime::NodeApiRefHolder
|
|
1667
2114
|
NodeApiJsiRuntime::NodeApiRefCountedPointerValue::makeNodeApiRef(
|
|
1668
2115
|
NodeApiJsiRuntime &runtime,
|
|
1669
2116
|
napi_value value,
|
|
1670
2117
|
NodeApiPointerValueKind pointerKind,
|
|
1671
2118
|
int32_t initialRefCount) {
|
|
1672
|
-
|
|
2119
|
+
NodeApiRefHolder result{make(runtime, value, pointerKind, initialRefCount)};
|
|
2120
|
+
result->createNodeApiRef(runtime);
|
|
2121
|
+
return result;
|
|
1673
2122
|
}
|
|
1674
2123
|
|
|
1675
2124
|
void NodeApiJsiRuntime::NodeApiRefCountedPointerValue::invalidate() noexcept {
|
|
1676
2125
|
decRefCount();
|
|
1677
2126
|
}
|
|
1678
2127
|
|
|
1679
|
-
NodeApiJsiRuntime::NodeApiRefCountedPointerValue *
|
|
1680
|
-
|
|
2128
|
+
NodeApiJsiRuntime::NodeApiRefCountedPointerValue *
|
|
2129
|
+
NodeApiJsiRuntime::NodeApiRefCountedPointerValue::clone(
|
|
2130
|
+
NodeApiJsiRuntime & /*runtime*/) const noexcept {
|
|
1681
2131
|
incRefCount();
|
|
1682
2132
|
return const_cast<NodeApiRefCountedPointerValue *>(this);
|
|
1683
2133
|
}
|
|
1684
2134
|
|
|
1685
|
-
napi_value NodeApiJsiRuntime::NodeApiRefCountedPointerValue::getValue(
|
|
2135
|
+
napi_value NodeApiJsiRuntime::NodeApiRefCountedPointerValue::getValue(
|
|
2136
|
+
NodeApiJsiRuntime &runtime) noexcept {
|
|
1686
2137
|
if (value_ != nullptr) {
|
|
1687
2138
|
return value_;
|
|
1688
2139
|
}
|
|
@@ -1692,104 +2143,123 @@ napi_value NodeApiJsiRuntime::NodeApiRefCountedPointerValue::getValue(NodeApiJsi
|
|
|
1692
2143
|
}
|
|
1693
2144
|
|
|
1694
2145
|
JSRuntimeApi *jsrApi = JSRuntimeApi::current();
|
|
1695
|
-
if (pointerKind_ == NodeApiPointerValueKind::Object ||
|
|
1696
|
-
|
|
2146
|
+
if (pointerKind_ == NodeApiPointerValueKind::Object ||
|
|
2147
|
+
pointerKind_ == NodeApiPointerValueKind::WeakObject) {
|
|
2148
|
+
CHECK_NAPI_ELSE_CRASH(
|
|
2149
|
+
jsrApi->napi_get_reference_value(runtime.getEnv(), ref_, &value_));
|
|
1697
2150
|
} else {
|
|
1698
2151
|
napi_value obj{};
|
|
1699
|
-
CHECK_NAPI_ELSE_CRASH(
|
|
1700
|
-
|
|
2152
|
+
CHECK_NAPI_ELSE_CRASH(
|
|
2153
|
+
jsrApi->napi_get_reference_value(runtime.getEnv(), ref_, &obj));
|
|
2154
|
+
// TODO: Should we use an interned property key?
|
|
2155
|
+
CHECK_NAPI_ELSE_CRASH(jsrApi->napi_get_named_property(
|
|
2156
|
+
runtime.getEnv(), obj, kPrimitivePropertyName, &value_));
|
|
1701
2157
|
}
|
|
1702
2158
|
|
|
1703
2159
|
if (value_ != nullptr) {
|
|
1704
|
-
runtime.addStackValue(
|
|
1705
|
-
incRefCount();
|
|
2160
|
+
runtime.addStackValue(NodeApiStackValuePtr(this));
|
|
1706
2161
|
}
|
|
1707
2162
|
|
|
1708
2163
|
return value_;
|
|
1709
2164
|
}
|
|
1710
2165
|
|
|
1711
|
-
NodeApiJsiRuntime::NodeApiPointerValueKind
|
|
2166
|
+
NodeApiJsiRuntime::NodeApiPointerValueKind
|
|
2167
|
+
NodeApiJsiRuntime::NodeApiRefCountedPointerValue::getKind() const noexcept {
|
|
1712
2168
|
return pointerKind_;
|
|
1713
2169
|
}
|
|
1714
2170
|
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
return false;
|
|
1719
|
-
const int32_t internalRefCount = (ptr->value_ != nullptr ? 1 : 0) + (ptr->ref_ != nullptr ? 1 : 0);
|
|
1720
|
-
const int32_t refCount = ptr->refCount_.load(std::memory_order_acquire);
|
|
1721
|
-
return refCount > internalRefCount;
|
|
1722
|
-
}
|
|
1723
|
-
|
|
1724
|
-
/*static*/ void NodeApiJsiRuntime::NodeApiRefCountedPointerValue::deleteStackValue(
|
|
1725
|
-
NodeApiRefCountedPointerValue *ptr) noexcept {
|
|
1726
|
-
if (ptr != nullptr && ptr->value_ != nullptr) {
|
|
1727
|
-
ptr->value_ = nullptr;
|
|
1728
|
-
ptr->decRefCount();
|
|
1729
|
-
}
|
|
2171
|
+
bool NodeApiJsiRuntime::NodeApiRefCountedPointerValue::usedByJsiPointer()
|
|
2172
|
+
const noexcept {
|
|
2173
|
+
return !NodeApiRefCount::isZero(refCount_);
|
|
1730
2174
|
}
|
|
1731
2175
|
|
|
1732
|
-
void NodeApiJsiRuntime::NodeApiRefCountedPointerValue::
|
|
1733
|
-
|
|
2176
|
+
void NodeApiJsiRuntime::NodeApiRefCountedPointerValue::deleteStackValue(
|
|
2177
|
+
NodeApiJsiRuntime &runtime) noexcept {
|
|
2178
|
+
CHECK_ELSE_CRASH(value_, "value_ must not be null");
|
|
2179
|
+
if (canBeDeletedFromStack_) {
|
|
2180
|
+
delete this;
|
|
1734
2181
|
return;
|
|
1735
2182
|
}
|
|
1736
2183
|
|
|
1737
|
-
if (ref_ == nullptr
|
|
2184
|
+
if (usedByJsiPointer() && ref_ == nullptr) {
|
|
1738
2185
|
createNodeApiRef(runtime);
|
|
1739
|
-
runtime.addRef(NodeApiRefHolder(this));
|
|
1740
|
-
value_ = nullptr;
|
|
1741
|
-
return;
|
|
1742
2186
|
}
|
|
1743
2187
|
|
|
1744
2188
|
value_ = nullptr;
|
|
1745
|
-
decRefCount();
|
|
1746
|
-
return;
|
|
1747
2189
|
}
|
|
1748
2190
|
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
if (
|
|
1752
|
-
|
|
1753
|
-
|
|
2191
|
+
void NodeApiJsiRuntime::NodeApiRefCountedPointerValue::deleteNodeApiRef(
|
|
2192
|
+
NodeApiJsiRuntime &runtime) noexcept {
|
|
2193
|
+
if (ref_ != nullptr) {
|
|
2194
|
+
CHECK_NAPI_ELSE_CRASH(
|
|
2195
|
+
JSRuntimeApi::current()->napi_delete_reference(runtime.getEnv(), ref_));
|
|
2196
|
+
ref_ = nullptr;
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2199
|
+
if (value_ != nullptr) {
|
|
2200
|
+
canBeDeletedFromStack_ = true;
|
|
2201
|
+
} else {
|
|
2202
|
+
delete this;
|
|
1754
2203
|
}
|
|
1755
2204
|
}
|
|
1756
2205
|
|
|
1757
|
-
|
|
1758
|
-
NodeApiRefCountedPointerValue *ptr
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
2206
|
+
void NodeApiJsiRuntime::NodeApiStackValueDeleter::operator()(
|
|
2207
|
+
NodeApiRefCountedPointerValue *ptr) const noexcept {
|
|
2208
|
+
if (ptr == nullptr) {
|
|
2209
|
+
return;
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
ptr->value_ = nullptr;
|
|
2213
|
+
if (ptr->canBeDeletedFromStack_) {
|
|
2214
|
+
delete ptr;
|
|
1764
2215
|
}
|
|
1765
2216
|
}
|
|
1766
2217
|
|
|
1767
|
-
void NodeApiJsiRuntime::
|
|
1768
|
-
|
|
2218
|
+
void NodeApiJsiRuntime::NodeApiRefDeleter::operator()(
|
|
2219
|
+
NodeApiRefCountedPointerValue *ptr) const noexcept {
|
|
2220
|
+
if (ptr == nullptr) {
|
|
2221
|
+
return;
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
if (ptr->value_ != nullptr) {
|
|
2225
|
+
ptr->canBeDeletedFromStack_ = true;
|
|
2226
|
+
} else {
|
|
2227
|
+
delete ptr;
|
|
2228
|
+
}
|
|
1769
2229
|
}
|
|
1770
2230
|
|
|
1771
|
-
void NodeApiJsiRuntime::NodeApiRefCountedPointerValue::
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
2231
|
+
void NodeApiJsiRuntime::NodeApiRefCountedPointerValue::incRefCount()
|
|
2232
|
+
const noexcept {
|
|
2233
|
+
NodeApiRefCount::incRefCount(refCount_);
|
|
2234
|
+
}
|
|
2235
|
+
|
|
2236
|
+
void NodeApiJsiRuntime::NodeApiRefCountedPointerValue::decRefCount()
|
|
2237
|
+
const noexcept {
|
|
2238
|
+
if (NodeApiRefCount::decRefCount(refCount_)) {
|
|
2239
|
+
pendingDeletions_->addPointerValueToDelete(
|
|
2240
|
+
NodeApiRefPtr(const_cast<NodeApiRefCountedPointerValue *>(this)));
|
|
1776
2241
|
}
|
|
1777
2242
|
}
|
|
1778
2243
|
|
|
1779
|
-
NodeApiJsiRuntime::NodeApiRefCountedPointerValue *
|
|
2244
|
+
NodeApiJsiRuntime::NodeApiRefCountedPointerValue *
|
|
2245
|
+
NodeApiJsiRuntime::NodeApiRefCountedPointerValue::createNodeApiRef(
|
|
1780
2246
|
NodeApiJsiRuntime &runtime) {
|
|
1781
2247
|
JSRuntimeApi *jsrApi = JSRuntimeApi::current();
|
|
1782
2248
|
CHECK_ELSE_CRASH(value_ != nullptr, "value_ must not be null");
|
|
1783
2249
|
CHECK_ELSE_CRASH(ref_ == nullptr, "ref_ must be null");
|
|
1784
2250
|
if (pointerKind_ == NodeApiPointerValueKind::Object) {
|
|
1785
|
-
CHECK_NAPI_ELSE_CRASH(
|
|
2251
|
+
CHECK_NAPI_ELSE_CRASH(
|
|
2252
|
+
jsrApi->napi_create_reference(runtime.getEnv(), value_, 1, &ref_));
|
|
1786
2253
|
} else if (pointerKind_ != NodeApiPointerValueKind::WeakObject) {
|
|
1787
2254
|
napi_value obj{};
|
|
1788
2255
|
CHECK_NAPI_ELSE_CRASH(jsrApi->napi_create_object(runtime.getEnv(), &obj));
|
|
1789
|
-
CHECK_NAPI_ELSE_CRASH(jsrApi->napi_set_named_property(
|
|
1790
|
-
|
|
2256
|
+
CHECK_NAPI_ELSE_CRASH(jsrApi->napi_set_named_property(
|
|
2257
|
+
runtime.getEnv(), obj, kPrimitivePropertyName, value_));
|
|
2258
|
+
CHECK_NAPI_ELSE_CRASH(
|
|
2259
|
+
jsrApi->napi_create_reference(runtime.getEnv(), obj, 1, &ref_));
|
|
1791
2260
|
} else {
|
|
1792
|
-
CHECK_NAPI_ELSE_CRASH(
|
|
2261
|
+
CHECK_NAPI_ELSE_CRASH(
|
|
2262
|
+
jsrApi->napi_create_reference(runtime.getEnv(), value_, 0, &ref_));
|
|
1793
2263
|
}
|
|
1794
2264
|
return this;
|
|
1795
2265
|
}
|
|
@@ -1799,8 +2269,10 @@ NodeApiJsiRuntime::NodeApiRefCountedPointerValue *NodeApiJsiRuntime::NodeApiRefC
|
|
|
1799
2269
|
//=====================================================================================================================
|
|
1800
2270
|
|
|
1801
2271
|
template <typename T, size_t InplaceSize>
|
|
1802
|
-
NodeApiJsiRuntime::SmallBuffer<T, InplaceSize>::SmallBuffer(
|
|
1803
|
-
|
|
2272
|
+
NodeApiJsiRuntime::SmallBuffer<T, InplaceSize>::SmallBuffer(
|
|
2273
|
+
size_t size) noexcept
|
|
2274
|
+
: size_{size},
|
|
2275
|
+
heapData_{size_ > InplaceSize ? std::make_unique<T[]>(size_) : nullptr} {}
|
|
1804
2276
|
|
|
1805
2277
|
template <typename T, size_t InplaceSize>
|
|
1806
2278
|
T *NodeApiJsiRuntime::SmallBuffer<T, InplaceSize>::data() noexcept {
|
|
@@ -1816,7 +2288,9 @@ size_t NodeApiJsiRuntime::SmallBuffer<T, InplaceSize>::size() const noexcept {
|
|
|
1816
2288
|
// NodeApiJsiRuntime::NodeApiValueArgs implementation
|
|
1817
2289
|
//=====================================================================================================================
|
|
1818
2290
|
|
|
1819
|
-
NodeApiJsiRuntime::NodeApiValueArgs::NodeApiValueArgs(
|
|
2291
|
+
NodeApiJsiRuntime::NodeApiValueArgs::NodeApiValueArgs(
|
|
2292
|
+
NodeApiJsiRuntime &runtime,
|
|
2293
|
+
span<const jsi::Value> args)
|
|
1820
2294
|
: args_{args.size()} {
|
|
1821
2295
|
napi_value *jsArgs = args_.data();
|
|
1822
2296
|
for (size_t i = 0; i < args.size(); ++i) {
|
|
@@ -1832,15 +2306,19 @@ NodeApiJsiRuntime::NodeApiValueArgs::operator span<napi_value>() {
|
|
|
1832
2306
|
// NodeApiJsiRuntime::JsiValueView implementation
|
|
1833
2307
|
//=====================================================================================================================
|
|
1834
2308
|
|
|
1835
|
-
NodeApiJsiRuntime::JsiValueView::JsiValueView(
|
|
2309
|
+
NodeApiJsiRuntime::JsiValueView::JsiValueView(
|
|
2310
|
+
NodeApiJsiRuntime *runtime,
|
|
2311
|
+
napi_value jsValue)
|
|
1836
2312
|
: value_{initValue(runtime, jsValue, std::addressof(pointerStore_))} {}
|
|
1837
2313
|
|
|
1838
2314
|
NodeApiJsiRuntime::JsiValueView::operator const jsi::Value &() const noexcept {
|
|
1839
2315
|
return value_;
|
|
1840
2316
|
}
|
|
1841
2317
|
|
|
1842
|
-
/*static*/ jsi::Value
|
|
1843
|
-
NodeApiJsiRuntime
|
|
2318
|
+
/*static*/ jsi::Value NodeApiJsiRuntime::JsiValueView::initValue(
|
|
2319
|
+
NodeApiJsiRuntime *runtime,
|
|
2320
|
+
napi_value value,
|
|
2321
|
+
StoreType *store) {
|
|
1844
2322
|
switch (runtime->typeOf(value)) {
|
|
1845
2323
|
case napi_valuetype::napi_undefined:
|
|
1846
2324
|
return jsi::Value::undefined();
|
|
@@ -1851,16 +2329,20 @@ NodeApiJsiRuntime::JsiValueView::initValue(NodeApiJsiRuntime *runtime, napi_valu
|
|
|
1851
2329
|
case napi_valuetype::napi_number:
|
|
1852
2330
|
return jsi::Value{runtime->getValueDouble(value)};
|
|
1853
2331
|
case napi_valuetype::napi_string:
|
|
1854
|
-
return make<jsi::String>(new (store) NodeApiStackOnlyPointerValue(
|
|
2332
|
+
return make<jsi::String>(new (store) NodeApiStackOnlyPointerValue(
|
|
2333
|
+
value, NodeApiPointerValueKind::String));
|
|
1855
2334
|
case napi_valuetype::napi_symbol:
|
|
1856
|
-
return make<jsi::Symbol>(new (store) NodeApiStackOnlyPointerValue(
|
|
2335
|
+
return make<jsi::Symbol>(new (store) NodeApiStackOnlyPointerValue(
|
|
2336
|
+
value, NodeApiPointerValueKind::Symbol));
|
|
1857
2337
|
case napi_valuetype::napi_object:
|
|
1858
2338
|
case napi_valuetype::napi_function:
|
|
1859
2339
|
case napi_valuetype::napi_external:
|
|
1860
|
-
return make<jsi::Object>(new (store) NodeApiStackOnlyPointerValue(
|
|
2340
|
+
return make<jsi::Object>(new (store) NodeApiStackOnlyPointerValue(
|
|
2341
|
+
value, NodeApiPointerValueKind::Object));
|
|
1861
2342
|
#if JSI_VERSION >= 8
|
|
1862
2343
|
case napi_valuetype::napi_bigint:
|
|
1863
|
-
return make<jsi::BigInt>(new (store) NodeApiStackOnlyPointerValue(
|
|
2344
|
+
return make<jsi::BigInt>(new (store) NodeApiStackOnlyPointerValue(
|
|
2345
|
+
value, NodeApiPointerValueKind::BigInt));
|
|
1864
2346
|
#endif
|
|
1865
2347
|
default:
|
|
1866
2348
|
throw jsi::JSINativeException("Unexpected value type");
|
|
@@ -1871,12 +2353,15 @@ NodeApiJsiRuntime::JsiValueView::initValue(NodeApiJsiRuntime *runtime, napi_valu
|
|
|
1871
2353
|
// NodeApiJsiRuntime::JsiValueViewArgs implementation
|
|
1872
2354
|
//=====================================================================================================================
|
|
1873
2355
|
|
|
1874
|
-
NodeApiJsiRuntime::JsiValueViewArgs::JsiValueViewArgs(
|
|
2356
|
+
NodeApiJsiRuntime::JsiValueViewArgs::JsiValueViewArgs(
|
|
2357
|
+
NodeApiJsiRuntime *runtime,
|
|
2358
|
+
span<napi_value> args) noexcept
|
|
1875
2359
|
: pointerStore_{args.size()}, args_{args.size()} {
|
|
1876
2360
|
JsiValueView::StoreType *pointerStore = pointerStore_.data();
|
|
1877
2361
|
jsi::Value *jsiArgs = args_.data();
|
|
1878
2362
|
for (size_t i = 0; i < args_.size(); ++i) {
|
|
1879
|
-
jsiArgs[i] = JsiValueView::initValue(
|
|
2363
|
+
jsiArgs[i] = JsiValueView::initValue(
|
|
2364
|
+
runtime, args[i], std::addressof(pointerStore[i]));
|
|
1880
2365
|
}
|
|
1881
2366
|
}
|
|
1882
2367
|
|
|
@@ -1893,11 +2378,16 @@ size_t NodeApiJsiRuntime::JsiValueViewArgs::size() const noexcept {
|
|
|
1893
2378
|
//=====================================================================================================================
|
|
1894
2379
|
|
|
1895
2380
|
// TODO: account for symbol
|
|
1896
|
-
NodeApiJsiRuntime::PropNameIDView::PropNameIDView(
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
2381
|
+
NodeApiJsiRuntime::PropNameIDView::PropNameIDView(
|
|
2382
|
+
NodeApiJsiRuntime * /*runtime*/,
|
|
2383
|
+
napi_value propertyId) noexcept
|
|
2384
|
+
: propertyId_{make<jsi::PropNameID>(
|
|
2385
|
+
new(std::addressof(pointerStore_)) NodeApiStackOnlyPointerValue(
|
|
2386
|
+
propertyId,
|
|
2387
|
+
NodeApiPointerValueKind::StringPropNameID))} {}
|
|
2388
|
+
|
|
2389
|
+
NodeApiJsiRuntime::PropNameIDView::operator jsi::PropNameID const &()
|
|
2390
|
+
const noexcept {
|
|
1901
2391
|
return propertyId_;
|
|
1902
2392
|
}
|
|
1903
2393
|
|
|
@@ -1905,10 +2395,13 @@ NodeApiJsiRuntime::PropNameIDView::operator jsi::PropNameID const &() const noex
|
|
|
1905
2395
|
// NodeApiJsiRuntime::HostFunctionWrapper implementation
|
|
1906
2396
|
//=====================================================================================================================
|
|
1907
2397
|
|
|
1908
|
-
NodeApiJsiRuntime::HostFunctionWrapper::HostFunctionWrapper(
|
|
2398
|
+
NodeApiJsiRuntime::HostFunctionWrapper::HostFunctionWrapper(
|
|
2399
|
+
jsi::HostFunctionType &&type,
|
|
2400
|
+
NodeApiJsiRuntime &runtime)
|
|
1909
2401
|
: hostFunction_{std::move(type)}, runtime_{runtime} {}
|
|
1910
2402
|
|
|
1911
|
-
jsi::HostFunctionType &
|
|
2403
|
+
jsi::HostFunctionType &
|
|
2404
|
+
NodeApiJsiRuntime::HostFunctionWrapper::hostFunction() noexcept {
|
|
1912
2405
|
return hostFunction_;
|
|
1913
2406
|
}
|
|
1914
2407
|
|
|
@@ -1928,24 +2421,35 @@ jsi::JSError NodeApiJsiRuntime::makeJSError(Args &&...args) {
|
|
|
1928
2421
|
}
|
|
1929
2422
|
|
|
1930
2423
|
// Throws jsi::JSError or jsi::JSINativeException from Node-API error.
|
|
1931
|
-
[[noreturn]] void NodeApiJsiRuntime::throwJSException(
|
|
2424
|
+
[[noreturn]] void NodeApiJsiRuntime::throwJSException(
|
|
2425
|
+
napi_status status) const {
|
|
1932
2426
|
napi_value jsError{};
|
|
1933
|
-
CHECK_NAPI_ELSE_CRASH(
|
|
2427
|
+
CHECK_NAPI_ELSE_CRASH(
|
|
2428
|
+
jsrApi_->napi_get_and_clear_last_exception(env_, &jsError));
|
|
2429
|
+
napi_valuetype jsErrorType;
|
|
2430
|
+
CHECK_NAPI_ELSE_CRASH(jsrApi_->napi_typeof(env_, jsError, &jsErrorType));
|
|
1934
2431
|
|
|
1935
2432
|
if (!hasPendingJSError_ &&
|
|
1936
|
-
(status == napi_pending_exception ||
|
|
1937
|
-
AutoRestore<bool> setValue(
|
|
1938
|
-
|
|
1939
|
-
|
|
2433
|
+
(status == napi_pending_exception || jsErrorType != napi_undefined)) {
|
|
2434
|
+
AutoRestore<bool> setValue(
|
|
2435
|
+
const_cast<NodeApiJsiRuntime *>(this)->hasPendingJSError_, true);
|
|
2436
|
+
if (jsErrorType == napi_object &&
|
|
2437
|
+
instanceOf(jsError, getNodeApiValue(cachedValue_.Error))) {
|
|
2438
|
+
rewriteErrorMessage(jsError);
|
|
2439
|
+
}
|
|
2440
|
+
throw jsi::JSError(
|
|
2441
|
+
*const_cast<NodeApiJsiRuntime *>(this), toJsiValue(jsError));
|
|
1940
2442
|
} else {
|
|
1941
2443
|
std::ostringstream errorStream;
|
|
1942
|
-
errorStream << "A call to Node-API returned error code 0x" << std::hex
|
|
2444
|
+
errorStream << "A call to Node-API returned error code 0x" << std::hex
|
|
2445
|
+
<< status << '.';
|
|
1943
2446
|
throw jsi::JSINativeException(errorStream.str().c_str());
|
|
1944
2447
|
}
|
|
1945
2448
|
}
|
|
1946
2449
|
|
|
1947
2450
|
// Throws jsi::JSINativeException with a message.
|
|
1948
|
-
[[noreturn]] void NodeApiJsiRuntime::throwNativeException(
|
|
2451
|
+
[[noreturn]] void NodeApiJsiRuntime::throwNativeException(
|
|
2452
|
+
char const *errorMessage) const {
|
|
1949
2453
|
throw jsi::JSINativeException(errorMessage);
|
|
1950
2454
|
}
|
|
1951
2455
|
|
|
@@ -1954,9 +2458,11 @@ void NodeApiJsiRuntime::rewriteErrorMessage(napi_value jsError) const {
|
|
|
1954
2458
|
// The code below must work correctly even if the 'message' getter throws.
|
|
1955
2459
|
// In case when it throws, we ignore that exception.
|
|
1956
2460
|
napi_value message{};
|
|
1957
|
-
napi_status status = jsrApi_->napi_get_property(
|
|
2461
|
+
napi_status status = jsrApi_->napi_get_property(
|
|
2462
|
+
env_, jsError, getNodeApiValue(propertyId_.message), &message);
|
|
1958
2463
|
if (status != napi_ok) {
|
|
1959
|
-
// If the 'message' property getter throws, then we clear the exception and
|
|
2464
|
+
// If the 'message' property getter throws, then we clear the exception and
|
|
2465
|
+
// ignore it.
|
|
1960
2466
|
napi_value ignoreJSError{};
|
|
1961
2467
|
jsrApi_->napi_get_and_clear_last_exception(env_, &ignoreJSError);
|
|
1962
2468
|
} else if (typeOf(message) == napi_string) {
|
|
@@ -1972,9 +2478,11 @@ void NodeApiJsiRuntime::rewriteErrorMessage(napi_value jsError) const {
|
|
|
1972
2478
|
// Make sure that the call stack has the current URL
|
|
1973
2479
|
if (!sourceURL_.empty()) {
|
|
1974
2480
|
napi_value stack{};
|
|
1975
|
-
status = jsrApi_->napi_get_property(
|
|
2481
|
+
status = jsrApi_->napi_get_property(
|
|
2482
|
+
env_, jsError, getNodeApiValue(propertyId_.stack), &stack);
|
|
1976
2483
|
if (status != napi_ok) {
|
|
1977
|
-
// If the 'stack' property getter throws, then we clear the exception and
|
|
2484
|
+
// If the 'stack' property getter throws, then we clear the exception and
|
|
2485
|
+
// ignore it.
|
|
1978
2486
|
napi_value ignoreJSError{};
|
|
1979
2487
|
jsrApi_->napi_get_and_clear_last_exception(env_, &ignoreJSError);
|
|
1980
2488
|
} else if (typeOf(message) == napi_string) {
|
|
@@ -1982,7 +2490,10 @@ void NodeApiJsiRuntime::rewriteErrorMessage(napi_value jsError) const {
|
|
|
1982
2490
|
std::string stackStr = stringToStdString(stack);
|
|
1983
2491
|
if (stackStr.find(sourceURL_) == std::string::npos) {
|
|
1984
2492
|
stackStr += sourceURL_ + '\n' + stackStr;
|
|
1985
|
-
setProperty(
|
|
2493
|
+
setProperty(
|
|
2494
|
+
jsError,
|
|
2495
|
+
getNodeApiValue(propertyId_.stack),
|
|
2496
|
+
createStringUtf8(stackStr.c_str()));
|
|
1986
2497
|
}
|
|
1987
2498
|
}
|
|
1988
2499
|
}
|
|
@@ -1990,21 +2501,26 @@ void NodeApiJsiRuntime::rewriteErrorMessage(napi_value jsError) const {
|
|
|
1990
2501
|
|
|
1991
2502
|
// Evaluates lambda and augments exception messages with the method's name.
|
|
1992
2503
|
template <typename TLambda>
|
|
1993
|
-
auto NodeApiJsiRuntime::runInMethodContext(
|
|
2504
|
+
auto NodeApiJsiRuntime::runInMethodContext(
|
|
2505
|
+
char const *methodName,
|
|
2506
|
+
TLambda lambda) {
|
|
1994
2507
|
try {
|
|
1995
2508
|
return lambda();
|
|
1996
2509
|
} catch (jsi::JSError const &) {
|
|
1997
2510
|
throw; // do not augment the JSError exceptions.
|
|
1998
2511
|
} catch (std::exception const &ex) {
|
|
1999
|
-
throwNativeException(
|
|
2512
|
+
throwNativeException(
|
|
2513
|
+
(std::string{"Exception in "} + methodName + ": " + ex.what()).c_str());
|
|
2000
2514
|
} catch (...) {
|
|
2001
|
-
throwNativeException(
|
|
2515
|
+
throwNativeException(
|
|
2516
|
+
(std::string{"Exception in "} + methodName + ": <unknown>").c_str());
|
|
2002
2517
|
}
|
|
2003
2518
|
}
|
|
2004
2519
|
|
|
2005
|
-
// Evaluates lambda and converts all exceptions to
|
|
2520
|
+
// Evaluates lambda and converts all exceptions to Node-API errors.
|
|
2006
2521
|
template <typename TLambda>
|
|
2007
|
-
napi_value NodeApiJsiRuntime::handleCallbackExceptions(
|
|
2522
|
+
napi_value NodeApiJsiRuntime::handleCallbackExceptions(
|
|
2523
|
+
TLambda lambda) const noexcept {
|
|
2008
2524
|
try {
|
|
2009
2525
|
try {
|
|
2010
2526
|
return lambda();
|
|
@@ -2021,16 +2537,17 @@ napi_value NodeApiJsiRuntime::handleCallbackExceptions(TLambda lambda) const noe
|
|
|
2021
2537
|
return getUndefined();
|
|
2022
2538
|
}
|
|
2023
2539
|
|
|
2024
|
-
// Throws JavaScript exception using
|
|
2540
|
+
// Throws JavaScript exception using Node-API.
|
|
2025
2541
|
bool NodeApiJsiRuntime::setException(napi_value error) const noexcept {
|
|
2026
2542
|
// This method must not throw. We return false in case of error.
|
|
2027
2543
|
return jsrApi_->napi_throw(env_, error) == napi_status::napi_ok;
|
|
2028
2544
|
}
|
|
2029
2545
|
|
|
2030
|
-
// Throws JavaScript error exception with the provided message using
|
|
2546
|
+
// Throws JavaScript error exception with the provided message using Node-API.
|
|
2031
2547
|
bool NodeApiJsiRuntime::setException(std::string_view message) const noexcept {
|
|
2032
2548
|
// This method must not throw. We return false in case of error.
|
|
2033
|
-
return jsrApi_->napi_throw_error(env_, "Unknown", message.data()) ==
|
|
2549
|
+
return jsrApi_->napi_throw_error(env_, "Unknown", message.data()) ==
|
|
2550
|
+
napi_status::napi_ok;
|
|
2034
2551
|
}
|
|
2035
2552
|
|
|
2036
2553
|
// Gets type of the napi_value.
|
|
@@ -2110,12 +2627,13 @@ double NodeApiJsiRuntime::getValueDouble(napi_value value) const {
|
|
|
2110
2627
|
return result;
|
|
2111
2628
|
}
|
|
2112
2629
|
|
|
2113
|
-
// Creates a napi_value string from the extended ASCII symbols that correspond
|
|
2114
|
-
// Each character is a byte-sized value from 0 to 255.
|
|
2630
|
+
// Creates a napi_value string from the extended ASCII symbols that correspond
|
|
2631
|
+
// to the Latin1 encoding. Each character is a byte-sized value from 0 to 255.
|
|
2115
2632
|
napi_value NodeApiJsiRuntime::createStringLatin1(std::string_view value) const {
|
|
2116
2633
|
CHECK_ELSE_THROW(value.data(), "Cannot convert a nullptr to a JS string.");
|
|
2117
2634
|
napi_value result{};
|
|
2118
|
-
CHECK_NAPI(jsrApi_->napi_create_string_latin1(
|
|
2635
|
+
CHECK_NAPI(jsrApi_->napi_create_string_latin1(
|
|
2636
|
+
env_, value.data(), value.size(), &result));
|
|
2119
2637
|
return result;
|
|
2120
2638
|
}
|
|
2121
2639
|
|
|
@@ -2123,12 +2641,16 @@ napi_value NodeApiJsiRuntime::createStringLatin1(std::string_view value) const {
|
|
|
2123
2641
|
napi_value NodeApiJsiRuntime::createStringUtf8(std::string_view value) const {
|
|
2124
2642
|
CHECK_ELSE_THROW(value.data(), "Cannot convert a nullptr to a JS string.");
|
|
2125
2643
|
napi_value result{};
|
|
2126
|
-
CHECK_NAPI(jsrApi_->napi_create_string_utf8(
|
|
2644
|
+
CHECK_NAPI(jsrApi_->napi_create_string_utf8(
|
|
2645
|
+
env_, value.data(), value.size(), &result));
|
|
2127
2646
|
return result;
|
|
2128
2647
|
}
|
|
2129
2648
|
|
|
2130
|
-
// Creates a napi_value string from a UTF-8 string. Use data and length instead
|
|
2131
|
-
|
|
2649
|
+
// Creates a napi_value string from a UTF-8 string. Use data and length instead
|
|
2650
|
+
// of string_view.
|
|
2651
|
+
napi_value NodeApiJsiRuntime::createStringUtf8(
|
|
2652
|
+
const uint8_t *data,
|
|
2653
|
+
size_t length) const {
|
|
2132
2654
|
return createStringUtf8({reinterpret_cast<const char *>(data), length});
|
|
2133
2655
|
}
|
|
2134
2656
|
|
|
@@ -2139,23 +2661,29 @@ std::string NodeApiJsiRuntime::stringToStdString(napi_value stringValue) const {
|
|
|
2139
2661
|
typeOf(stringValue) == napi_valuetype::napi_string,
|
|
2140
2662
|
"Cannot convert a non JS string Node-API Value to a std::string.");
|
|
2141
2663
|
size_t strLength{};
|
|
2142
|
-
CHECK_NAPI(jsrApi_->napi_get_value_string_utf8(
|
|
2664
|
+
CHECK_NAPI(jsrApi_->napi_get_value_string_utf8(
|
|
2665
|
+
env_, stringValue, nullptr, 0, &strLength));
|
|
2143
2666
|
result.assign(strLength, '\0');
|
|
2144
2667
|
size_t copiedLength{};
|
|
2145
|
-
CHECK_NAPI(jsrApi_->napi_get_value_string_utf8(
|
|
2668
|
+
CHECK_NAPI(jsrApi_->napi_get_value_string_utf8(
|
|
2669
|
+
env_, stringValue, &result[0], result.length() + 1, &copiedLength));
|
|
2146
2670
|
CHECK_ELSE_THROW(result.length() == copiedLength, "Unexpected string length");
|
|
2147
2671
|
return result;
|
|
2148
2672
|
}
|
|
2149
2673
|
|
|
2150
2674
|
// Gets or creates a unique string value from an UTF-8 string_view.
|
|
2151
|
-
napi_value NodeApiJsiRuntime::getPropertyIdFromName(
|
|
2675
|
+
napi_value NodeApiJsiRuntime::getPropertyIdFromName(
|
|
2676
|
+
std::string_view value) const {
|
|
2152
2677
|
napi_value result{};
|
|
2153
|
-
CHECK_NAPI(jsrApi_->napi_create_string_utf8(
|
|
2678
|
+
CHECK_NAPI(jsrApi_->napi_create_string_utf8(
|
|
2679
|
+
env_, value.data(), value.size(), &result));
|
|
2154
2680
|
return result;
|
|
2155
2681
|
}
|
|
2156
2682
|
|
|
2157
2683
|
// Gets or creates a unique string value from an UTF-8 data/length range.
|
|
2158
|
-
napi_value NodeApiJsiRuntime::getPropertyIdFromName(
|
|
2684
|
+
napi_value NodeApiJsiRuntime::getPropertyIdFromName(
|
|
2685
|
+
const uint8_t *data,
|
|
2686
|
+
size_t length) const {
|
|
2159
2687
|
return getPropertyIdFromName({reinterpret_cast<const char *>(data), length});
|
|
2160
2688
|
}
|
|
2161
2689
|
|
|
@@ -2179,7 +2707,8 @@ std::string NodeApiJsiRuntime::propertyIdToStdString(napi_value propertyId) {
|
|
|
2179
2707
|
}
|
|
2180
2708
|
|
|
2181
2709
|
// Creates a JavaScript symbol napi_value.
|
|
2182
|
-
napi_value NodeApiJsiRuntime::createSymbol(
|
|
2710
|
+
napi_value NodeApiJsiRuntime::createSymbol(
|
|
2711
|
+
std::string_view symbolDescription) const {
|
|
2183
2712
|
napi_value result{};
|
|
2184
2713
|
napi_value description = createStringUtf8(symbolDescription);
|
|
2185
2714
|
CHECK_NAPI(jsrApi_->napi_create_symbol(env_, description, &result));
|
|
@@ -2189,31 +2718,44 @@ napi_value NodeApiJsiRuntime::createSymbol(std::string_view symbolDescription) c
|
|
|
2189
2718
|
// Calls Symbol.toString() and returns it as std::string.
|
|
2190
2719
|
std::string NodeApiJsiRuntime::symbolToStdString(napi_value symbolValue) {
|
|
2191
2720
|
if (!cachedValue_.SymbolToString) {
|
|
2192
|
-
napi_value symbolCtor = getProperty(
|
|
2193
|
-
|
|
2721
|
+
napi_value symbolCtor = getProperty(
|
|
2722
|
+
getNodeApiValue(cachedValue_.Global),
|
|
2723
|
+
getNodeApiValue(propertyId_.Symbol));
|
|
2724
|
+
napi_value symbolPrototype =
|
|
2725
|
+
getProperty(symbolCtor, getNodeApiValue(propertyId_.prototype));
|
|
2194
2726
|
cachedValue_.SymbolToString = makeNodeApiRef(
|
|
2195
|
-
getProperty(symbolPrototype, getNodeApiValue(propertyId_.toString)),
|
|
2727
|
+
getProperty(symbolPrototype, getNodeApiValue(propertyId_.toString)),
|
|
2728
|
+
NodeApiPointerValueKind::Object);
|
|
2196
2729
|
}
|
|
2197
|
-
napi_value jsString = callFunction(
|
|
2730
|
+
napi_value jsString = callFunction(
|
|
2731
|
+
symbolValue, getNodeApiValue(cachedValue_.SymbolToString), {});
|
|
2198
2732
|
return stringToStdString(jsString);
|
|
2199
2733
|
}
|
|
2200
2734
|
|
|
2201
2735
|
// Calls a JavaScript function.
|
|
2202
|
-
napi_value NodeApiJsiRuntime::callFunction(
|
|
2736
|
+
napi_value NodeApiJsiRuntime::callFunction(
|
|
2737
|
+
napi_value thisArg,
|
|
2738
|
+
napi_value function,
|
|
2739
|
+
span<napi_value> args) const {
|
|
2203
2740
|
napi_value result{};
|
|
2204
|
-
CHECK_NAPI(jsrApi_->napi_call_function(
|
|
2741
|
+
CHECK_NAPI(jsrApi_->napi_call_function(
|
|
2742
|
+
env_, thisArg, function, args.size(), args.data(), &result));
|
|
2205
2743
|
return result;
|
|
2206
2744
|
}
|
|
2207
2745
|
|
|
2208
2746
|
// Constructs a new JavaScript Object using a constructor function.
|
|
2209
|
-
napi_value NodeApiJsiRuntime::constructObject(
|
|
2747
|
+
napi_value NodeApiJsiRuntime::constructObject(
|
|
2748
|
+
napi_value constructor,
|
|
2749
|
+
span<napi_value> args) const {
|
|
2210
2750
|
napi_value result{};
|
|
2211
|
-
CHECK_NAPI(jsrApi_->napi_new_instance(
|
|
2751
|
+
CHECK_NAPI(jsrApi_->napi_new_instance(
|
|
2752
|
+
env_, constructor, args.size(), args.data(), &result));
|
|
2212
2753
|
return result;
|
|
2213
2754
|
}
|
|
2214
2755
|
|
|
2215
2756
|
// Returns true if object was constructed using the provided constructor.
|
|
2216
|
-
bool NodeApiJsiRuntime::instanceOf(napi_value object, napi_value constructor)
|
|
2757
|
+
bool NodeApiJsiRuntime::instanceOf(napi_value object, napi_value constructor)
|
|
2758
|
+
const {
|
|
2217
2759
|
bool result{false};
|
|
2218
2760
|
CHECK_NAPI(jsrApi_->napi_instanceof(env_, object, constructor, &result));
|
|
2219
2761
|
return result;
|
|
@@ -2227,25 +2769,32 @@ napi_value NodeApiJsiRuntime::createNodeApiObject() const {
|
|
|
2227
2769
|
}
|
|
2228
2770
|
|
|
2229
2771
|
// Returns true if the object has a property with the provided property ID.
|
|
2230
|
-
bool NodeApiJsiRuntime::hasProperty(napi_value object, napi_value propertyId)
|
|
2772
|
+
bool NodeApiJsiRuntime::hasProperty(napi_value object, napi_value propertyId)
|
|
2773
|
+
const {
|
|
2231
2774
|
bool result{};
|
|
2232
2775
|
CHECK_NAPI(jsrApi_->napi_has_property(env_, object, propertyId, &result));
|
|
2233
2776
|
return result;
|
|
2234
2777
|
}
|
|
2235
2778
|
|
|
2236
2779
|
// Gets object property value.
|
|
2237
|
-
napi_value NodeApiJsiRuntime::getProperty(
|
|
2780
|
+
napi_value NodeApiJsiRuntime::getProperty(
|
|
2781
|
+
napi_value object,
|
|
2782
|
+
napi_value propertyId) const {
|
|
2238
2783
|
napi_value result{};
|
|
2239
2784
|
CHECK_NAPI(jsrApi_->napi_get_property(env_, object, propertyId, &result));
|
|
2240
2785
|
return result;
|
|
2241
2786
|
}
|
|
2242
2787
|
|
|
2243
2788
|
// Sets object property value.
|
|
2244
|
-
void NodeApiJsiRuntime::setProperty(
|
|
2789
|
+
void NodeApiJsiRuntime::setProperty(
|
|
2790
|
+
napi_value object,
|
|
2791
|
+
napi_value propertyId,
|
|
2792
|
+
napi_value value) const {
|
|
2245
2793
|
CHECK_NAPI(jsrApi_->napi_set_property(env_, object, propertyId, value));
|
|
2246
2794
|
}
|
|
2247
2795
|
|
|
2248
|
-
// Sets object property value with the provided property accessibility
|
|
2796
|
+
// Sets object property value with the provided property accessibility
|
|
2797
|
+
// attributes.
|
|
2249
2798
|
void NodeApiJsiRuntime::setProperty(
|
|
2250
2799
|
napi_value object,
|
|
2251
2800
|
napi_value propertyId,
|
|
@@ -2279,41 +2828,55 @@ size_t NodeApiJsiRuntime::getArrayLength(napi_value value) const {
|
|
|
2279
2828
|
|
|
2280
2829
|
napi_value NodeApiJsiRuntime::getElement(napi_value arr, size_t index) const {
|
|
2281
2830
|
napi_value result{};
|
|
2282
|
-
CHECK_NAPI(jsrApi_->napi_get_element(
|
|
2831
|
+
CHECK_NAPI(jsrApi_->napi_get_element(
|
|
2832
|
+
env_, arr, static_cast<int32_t>(index), &result));
|
|
2283
2833
|
return result;
|
|
2284
2834
|
}
|
|
2285
2835
|
|
|
2286
2836
|
// Sets array element.
|
|
2287
|
-
void NodeApiJsiRuntime::setElement(
|
|
2837
|
+
void NodeApiJsiRuntime::setElement(
|
|
2838
|
+
napi_value array,
|
|
2839
|
+
uint32_t index,
|
|
2840
|
+
napi_value value) const {
|
|
2288
2841
|
CHECK_NAPI(jsrApi_->napi_set_element(env_, array, index, value));
|
|
2289
2842
|
}
|
|
2290
2843
|
|
|
2291
|
-
// The
|
|
2844
|
+
// The Node-API external function callback used for the JSI host function
|
|
2845
|
+
// implementation.
|
|
2292
2846
|
/*static*/ napi_value __cdecl NodeApiJsiRuntime::jsiHostFunctionCallback(
|
|
2293
2847
|
napi_env env,
|
|
2294
2848
|
napi_callback_info info) noexcept {
|
|
2295
2849
|
HostFunctionWrapper *hostFuncWrapper{};
|
|
2296
2850
|
size_t argc{};
|
|
2297
2851
|
CHECK_NAPI_ELSE_CRASH(JSRuntimeApi::current()->napi_get_cb_info(
|
|
2298
|
-
env,
|
|
2852
|
+
env,
|
|
2853
|
+
info,
|
|
2854
|
+
&argc,
|
|
2855
|
+
nullptr,
|
|
2856
|
+
nullptr,
|
|
2857
|
+
reinterpret_cast<void **>(&hostFuncWrapper)));
|
|
2299
2858
|
CHECK_ELSE_CRASH(hostFuncWrapper, "Cannot find the host function");
|
|
2300
2859
|
NodeApiJsiRuntime &runtime = hostFuncWrapper->runtime();
|
|
2301
2860
|
NodeApiPointerValueScope scope{runtime};
|
|
2302
2861
|
|
|
2303
|
-
return runtime.handleCallbackExceptions(
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
JSRuntimeApi::current()->napi_get_cb_info(
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2862
|
+
return runtime.handleCallbackExceptions(
|
|
2863
|
+
[&env, &info, &argc, &runtime, &hostFuncWrapper]() {
|
|
2864
|
+
SmallBuffer<napi_value, MaxStackArgCount> napiArgs(argc);
|
|
2865
|
+
napi_value thisArg{};
|
|
2866
|
+
CHECK_NAPI_ELSE_CRASH(JSRuntimeApi::current()->napi_get_cb_info(
|
|
2867
|
+
env, info, &argc, napiArgs.data(), &thisArg, nullptr));
|
|
2868
|
+
CHECK_ELSE_CRASH(napiArgs.size() == argc, "Wrong argument count");
|
|
2869
|
+
const JsiValueView jsiThisArg{&runtime, thisArg};
|
|
2870
|
+
JsiValueViewArgs jsiArgs(
|
|
2871
|
+
&runtime, span<napi_value>(napiArgs.data(), napiArgs.size()));
|
|
2872
|
+
|
|
2873
|
+
const jsi::HostFunctionType &hostFunc = hostFuncWrapper->hostFunction();
|
|
2874
|
+
return runtime.runInMethodContext(
|
|
2875
|
+
"HostFunction", [&hostFunc, &runtime, &jsiThisArg, &jsiArgs]() {
|
|
2876
|
+
return runtime.getNodeApiValue(hostFunc(
|
|
2877
|
+
runtime, jsiThisArg, jsiArgs.data(), jsiArgs.size()));
|
|
2878
|
+
});
|
|
2879
|
+
});
|
|
2317
2880
|
}
|
|
2318
2881
|
|
|
2319
2882
|
// Creates an external function.
|
|
@@ -2324,25 +2887,39 @@ napi_value NodeApiJsiRuntime::createExternalFunction(
|
|
|
2324
2887
|
void *callbackData) {
|
|
2325
2888
|
std::string funcName = stringToStdString(name);
|
|
2326
2889
|
napi_value function{};
|
|
2327
|
-
CHECK_NAPI(
|
|
2328
|
-
|
|
2890
|
+
CHECK_NAPI(jsrApi_->napi_create_function(
|
|
2891
|
+
env_,
|
|
2892
|
+
funcName.data(),
|
|
2893
|
+
funcName.length(),
|
|
2894
|
+
callback,
|
|
2895
|
+
callbackData,
|
|
2896
|
+
&function));
|
|
2329
2897
|
setProperty(
|
|
2330
|
-
function,
|
|
2898
|
+
function,
|
|
2899
|
+
getNodeApiValue(propertyId_.length),
|
|
2900
|
+
createInt32(paramCount),
|
|
2901
|
+
napi_property_attributes::napi_default);
|
|
2331
2902
|
|
|
2332
2903
|
return function;
|
|
2333
2904
|
}
|
|
2334
2905
|
|
|
2335
2906
|
// Creates an object that wraps up external data.
|
|
2336
|
-
napi_value NodeApiJsiRuntime::createExternalObject(
|
|
2907
|
+
napi_value NodeApiJsiRuntime::createExternalObject(
|
|
2908
|
+
void *data,
|
|
2909
|
+
node_api_nogc_finalize finalizeCallback) const {
|
|
2337
2910
|
napi_value result{};
|
|
2338
|
-
CHECK_NAPI(jsrApi_->napi_create_external(
|
|
2911
|
+
CHECK_NAPI(jsrApi_->napi_create_external(
|
|
2912
|
+
env_, data, finalizeCallback, nullptr, &result));
|
|
2339
2913
|
return result;
|
|
2340
2914
|
}
|
|
2341
2915
|
|
|
2342
2916
|
// Wraps up std::unique_ptr as an external object.
|
|
2343
2917
|
template <typename T>
|
|
2344
|
-
napi_value NodeApiJsiRuntime::createExternalObject(
|
|
2345
|
-
|
|
2918
|
+
napi_value NodeApiJsiRuntime::createExternalObject(
|
|
2919
|
+
std::unique_ptr<T> &&data) const {
|
|
2920
|
+
node_api_nogc_finalize finalize = [](node_api_nogc_env /*env*/,
|
|
2921
|
+
void *dataToDestroy,
|
|
2922
|
+
void * /*finalizerHint*/) {
|
|
2346
2923
|
// We wrap dataToDestroy in a unique_ptr to avoid calling delete explicitly.
|
|
2347
2924
|
std::unique_ptr<T> dataDeleter{static_cast<T *>(dataToDestroy)};
|
|
2348
2925
|
};
|
|
@@ -2363,8 +2940,10 @@ void *NodeApiJsiRuntime::getExternalData(napi_value object) const {
|
|
|
2363
2940
|
}
|
|
2364
2941
|
|
|
2365
2942
|
// Gets JSI host object wrapped into a napi_value object.
|
|
2366
|
-
const std::shared_ptr<jsi::HostObject> &NodeApiJsiRuntime::getJsiHostObject(
|
|
2367
|
-
|
|
2943
|
+
const std::shared_ptr<jsi::HostObject> &NodeApiJsiRuntime::getJsiHostObject(
|
|
2944
|
+
napi_value obj) {
|
|
2945
|
+
const napi_value hostObjectHolder =
|
|
2946
|
+
getProperty(obj, getNodeApiValue(propertyId_.hostObjectSymbol));
|
|
2368
2947
|
|
|
2369
2948
|
if (typeOf(hostObjectHolder) == napi_valuetype::napi_external) {
|
|
2370
2949
|
if (void *data = getExternalData(hostObjectHolder)) {
|
|
@@ -2379,34 +2958,53 @@ const std::shared_ptr<jsi::HostObject> &NodeApiJsiRuntime::getJsiHostObject(napi
|
|
|
2379
2958
|
napi_value NodeApiJsiRuntime::getHostObjectProxyHandler() {
|
|
2380
2959
|
if (!cachedValue_.HostObjectProxyHandler) {
|
|
2381
2960
|
const napi_value handler = createNodeApiObject();
|
|
2382
|
-
setProxyTrap<&NodeApiJsiRuntime::hostObjectHasTrap, 2>(
|
|
2383
|
-
|
|
2384
|
-
setProxyTrap<&NodeApiJsiRuntime::
|
|
2385
|
-
|
|
2961
|
+
setProxyTrap<&NodeApiJsiRuntime::hostObjectHasTrap, 2>(
|
|
2962
|
+
handler, getNodeApiValue(propertyId_.has));
|
|
2963
|
+
setProxyTrap<&NodeApiJsiRuntime::hostObjectGetTrap, 3>(
|
|
2964
|
+
handler, getNodeApiValue(propertyId_.get));
|
|
2965
|
+
setProxyTrap<&NodeApiJsiRuntime::hostObjectSetTrap, 4>(
|
|
2966
|
+
handler, getNodeApiValue(propertyId_.set));
|
|
2967
|
+
setProxyTrap<&NodeApiJsiRuntime::hostObjectOwnKeysTrap, 1>(
|
|
2968
|
+
handler, getNodeApiValue(propertyId_.ownKeys));
|
|
2386
2969
|
setProxyTrap<&NodeApiJsiRuntime::hostObjectGetOwnPropertyDescriptorTrap, 2>(
|
|
2387
2970
|
handler, getNodeApiValue(propertyId_.getOwnPropertyDescriptor));
|
|
2388
|
-
cachedValue_.HostObjectProxyHandler =
|
|
2971
|
+
cachedValue_.HostObjectProxyHandler =
|
|
2972
|
+
makeNodeApiRef(handler, NodeApiPointerValueKind::Object);
|
|
2389
2973
|
}
|
|
2390
2974
|
|
|
2391
2975
|
return getNodeApiValue(cachedValue_.HostObjectProxyHandler);
|
|
2392
2976
|
}
|
|
2393
2977
|
|
|
2394
2978
|
// Sets Proxy trap method as a pointer to NodeApiJsiRuntime instance method.
|
|
2395
|
-
template <
|
|
2396
|
-
|
|
2979
|
+
template <
|
|
2980
|
+
napi_value (NodeApiJsiRuntime::*trapMethod)(span<napi_value>),
|
|
2981
|
+
size_t argCount>
|
|
2982
|
+
void NodeApiJsiRuntime::setProxyTrap(
|
|
2983
|
+
napi_value handler,
|
|
2984
|
+
napi_value propertyName) {
|
|
2397
2985
|
napi_callback proxyTrap = [](napi_env env, napi_callback_info info) noexcept {
|
|
2398
2986
|
NodeApiJsiRuntime *runtime{};
|
|
2399
2987
|
napi_value args[argCount]{};
|
|
2400
2988
|
size_t actualArgCount{argCount};
|
|
2401
2989
|
CHECK_NAPI_ELSE_CRASH(JSRuntimeApi::current()->napi_get_cb_info(
|
|
2402
|
-
env,
|
|
2403
|
-
|
|
2990
|
+
env,
|
|
2991
|
+
info,
|
|
2992
|
+
&actualArgCount,
|
|
2993
|
+
args,
|
|
2994
|
+
nullptr,
|
|
2995
|
+
reinterpret_cast<void **>(&runtime)));
|
|
2996
|
+
CHECK_ELSE_CRASH(
|
|
2997
|
+
actualArgCount == argCount, "proxy trap requires argCount arguments.");
|
|
2404
2998
|
NodeApiPointerValueScope scope{*runtime};
|
|
2405
|
-
return runtime->handleCallbackExceptions(
|
|
2406
|
-
|
|
2999
|
+
return runtime->handleCallbackExceptions([&runtime, &args]() {
|
|
3000
|
+
return (runtime->*trapMethod)(span<napi_value>(args, argCount));
|
|
3001
|
+
});
|
|
2407
3002
|
};
|
|
2408
3003
|
|
|
2409
|
-
setProperty(
|
|
3004
|
+
setProperty(
|
|
3005
|
+
handler,
|
|
3006
|
+
propertyName,
|
|
3007
|
+
createExternalFunction(propertyName, argCount, proxyTrap, this));
|
|
2410
3008
|
}
|
|
2411
3009
|
|
|
2412
3010
|
// The host object Proxy 'has' trap implementation.
|
|
@@ -2415,15 +3013,17 @@ napi_value NodeApiJsiRuntime::hostObjectHasTrap(span<napi_value> args) {
|
|
|
2415
3013
|
// args[1] - the name of the property to check.
|
|
2416
3014
|
napi_value propertyName = args[1];
|
|
2417
3015
|
const auto &hostObject = getJsiHostObject(args[0]);
|
|
2418
|
-
return runInMethodContext(
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
3016
|
+
return runInMethodContext(
|
|
3017
|
+
"HostObject::has", [&hostObject, &propertyName, this]() {
|
|
3018
|
+
// std::vector<jsi::PropNameID> ownKeys =
|
|
3019
|
+
// hostObject->getPropertyNames(*this); for (jsi::PropNameID &ownKey :
|
|
3020
|
+
// ownKeys) {
|
|
3021
|
+
// if (strictEquals(propertyName, getNodeApiValue(ownKey))) {
|
|
3022
|
+
return getBoolean(true);
|
|
3023
|
+
// }
|
|
3024
|
+
// }
|
|
3025
|
+
// return getBoolean(false);
|
|
3026
|
+
});
|
|
2427
3027
|
}
|
|
2428
3028
|
|
|
2429
3029
|
// The host object Proxy 'get' trap implementation.
|
|
@@ -2434,15 +3034,17 @@ napi_value NodeApiJsiRuntime::hostObjectGetTrap(span<napi_value> args) {
|
|
|
2434
3034
|
napi_value target = args[0];
|
|
2435
3035
|
napi_value propertyName = args[1];
|
|
2436
3036
|
bool isTargetOwnProp{};
|
|
2437
|
-
CHECK_NAPI(jsrApi_->napi_has_own_property(
|
|
3037
|
+
CHECK_NAPI(jsrApi_->napi_has_own_property(
|
|
3038
|
+
env_, target, propertyName, &isTargetOwnProp));
|
|
2438
3039
|
if (isTargetOwnProp) {
|
|
2439
3040
|
return getProperty(target, propertyName);
|
|
2440
3041
|
}
|
|
2441
3042
|
const auto &hostObject = getJsiHostObject(args[0]);
|
|
2442
3043
|
PropNameIDView propertyId{this, propertyName};
|
|
2443
|
-
return runInMethodContext(
|
|
2444
|
-
|
|
2445
|
-
|
|
3044
|
+
return runInMethodContext(
|
|
3045
|
+
"HostObject::get", [&hostObject, &propertyId, this]() {
|
|
3046
|
+
return getNodeApiValue(hostObject->get(*this, propertyId));
|
|
3047
|
+
});
|
|
2446
3048
|
}
|
|
2447
3049
|
|
|
2448
3050
|
// The host object Proxy 'set' trap implementation.
|
|
@@ -2455,7 +3057,9 @@ napi_value NodeApiJsiRuntime::hostObjectSetTrap(span<napi_value> args) {
|
|
|
2455
3057
|
PropNameIDView propertyId{this, args[1]};
|
|
2456
3058
|
JsiValueView value{this, args[2]};
|
|
2457
3059
|
runInMethodContext(
|
|
2458
|
-
"HostObject::set", [&hostObject, &propertyId, &value, this]() {
|
|
3060
|
+
"HostObject::set", [&hostObject, &propertyId, &value, this]() {
|
|
3061
|
+
hostObject->set(*this, propertyId, value);
|
|
3062
|
+
});
|
|
2459
3063
|
return getUndefined();
|
|
2460
3064
|
}
|
|
2461
3065
|
|
|
@@ -2466,13 +3070,19 @@ napi_value NodeApiJsiRuntime::hostObjectOwnKeysTrap(span<napi_value> args) {
|
|
|
2466
3070
|
|
|
2467
3071
|
napi_value targetOwnKeys{};
|
|
2468
3072
|
CHECK_NAPI(jsrApi_->napi_get_all_property_names(
|
|
2469
|
-
env_,
|
|
3073
|
+
env_,
|
|
3074
|
+
target,
|
|
3075
|
+
napi_key_own_only,
|
|
3076
|
+
napi_key_all_properties,
|
|
3077
|
+
napi_key_numbers_to_strings,
|
|
3078
|
+
&targetOwnKeys));
|
|
2470
3079
|
CHECK_ELSE_THROW(isArray(targetOwnKeys), "Expected an array");
|
|
2471
3080
|
size_t targetOwnKeysLength = getArrayLength(targetOwnKeys);
|
|
2472
3081
|
|
|
2473
3082
|
const auto &hostObject = getJsiHostObject(target);
|
|
2474
3083
|
std::vector<jsi::PropNameID> hostOwnKeys = runInMethodContext(
|
|
2475
|
-
"HostObject::getPropertyNames",
|
|
3084
|
+
"HostObject::getPropertyNames",
|
|
3085
|
+
[&hostObject, this]() { return hostObject->getPropertyNames(*this); });
|
|
2476
3086
|
|
|
2477
3087
|
std::vector<jsi::PropNameID> ownKeys;
|
|
2478
3088
|
std::unordered_set<const PointerValue *> uniqueOwnKeys;
|
|
@@ -2482,23 +3092,26 @@ napi_value NodeApiJsiRuntime::hostObjectOwnKeysTrap(span<napi_value> args) {
|
|
|
2482
3092
|
|
|
2483
3093
|
// Read all target own keys.
|
|
2484
3094
|
if (targetOwnKeysLength > 1) {
|
|
2485
|
-
auto addPropNameId =
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
3095
|
+
auto addPropNameId =
|
|
3096
|
+
[this, &uniqueOwnKeys, &ownKeys](jsi::PropNameID &&propNameId) {
|
|
3097
|
+
const PointerValue *pv = getPointerValue(propNameId);
|
|
3098
|
+
auto inserted = uniqueOwnKeys.insert(pv);
|
|
3099
|
+
CHECK_ELSE_THROW(inserted.second, "Target has non-unique keys");
|
|
3100
|
+
ownKeys.push_back(std::move(propNameId));
|
|
3101
|
+
};
|
|
2491
3102
|
for (size_t i = 0; i < targetOwnKeysLength; ++i) {
|
|
2492
3103
|
napi_value key = getElement(targetOwnKeys, i);
|
|
2493
3104
|
napi_valuetype keyType = typeOf(key);
|
|
2494
3105
|
if (keyType == napi_string) {
|
|
2495
|
-
addPropNameId(
|
|
3106
|
+
addPropNameId(
|
|
3107
|
+
createPropNameIDFromString(makeJsiPointer<jsi::String>(key)));
|
|
2496
3108
|
#if JSI_VERSION >= 8
|
|
2497
3109
|
} else if (keyType == napi_symbol) {
|
|
2498
3110
|
if (strictEquals(key, getNodeApiValue(propertyId_.hostObjectSymbol))) {
|
|
2499
3111
|
continue;
|
|
2500
3112
|
}
|
|
2501
|
-
addPropNameId(
|
|
3113
|
+
addPropNameId(
|
|
3114
|
+
createPropNameIDFromSymbol(makeJsiPointer<jsi::Symbol>(key)));
|
|
2502
3115
|
#endif
|
|
2503
3116
|
} else {
|
|
2504
3117
|
throwNativeException("Unexpected key type");
|
|
@@ -2528,7 +3141,8 @@ napi_value NodeApiJsiRuntime::hostObjectOwnKeysTrap(span<napi_value> args) {
|
|
|
2528
3141
|
napi_valuetype valueType = typeOf(napiKey);
|
|
2529
3142
|
if (valueType == napi_string) {
|
|
2530
3143
|
std::string keyStr = stringToStdString(napiKey);
|
|
2531
|
-
std::optional<uint32_t> indexKey =
|
|
3144
|
+
std::optional<uint32_t> indexKey =
|
|
3145
|
+
toArrayIndex(keyStr.begin(), keyStr.end());
|
|
2532
3146
|
if (indexKey.has_value()) {
|
|
2533
3147
|
indexKeys.push_back(Index{indexKey.value(), napiKey});
|
|
2534
3148
|
continue;
|
|
@@ -2537,9 +3151,12 @@ napi_value NodeApiJsiRuntime::hostObjectOwnKeysTrap(span<napi_value> args) {
|
|
|
2537
3151
|
nonIndexKeys.push_back(napiKey);
|
|
2538
3152
|
}
|
|
2539
3153
|
|
|
2540
|
-
std::sort(
|
|
2541
|
-
|
|
2542
|
-
|
|
3154
|
+
std::sort(
|
|
3155
|
+
indexKeys.begin(),
|
|
3156
|
+
indexKeys.end(),
|
|
3157
|
+
[](const Index &left, const Index &right) {
|
|
3158
|
+
return left.index < right.index;
|
|
3159
|
+
});
|
|
2543
3160
|
|
|
2544
3161
|
napi_value ownKeyArray = createNodeApiArray(0);
|
|
2545
3162
|
uint32_t index = 0;
|
|
@@ -2554,27 +3171,42 @@ napi_value NodeApiJsiRuntime::hostObjectOwnKeysTrap(span<napi_value> args) {
|
|
|
2554
3171
|
}
|
|
2555
3172
|
|
|
2556
3173
|
// The host object Proxy 'getOwnPropertyDescriptor' trap implementation.
|
|
2557
|
-
napi_value NodeApiJsiRuntime::hostObjectGetOwnPropertyDescriptorTrap(
|
|
3174
|
+
napi_value NodeApiJsiRuntime::hostObjectGetOwnPropertyDescriptorTrap(
|
|
3175
|
+
span<napi_value> args) {
|
|
2558
3176
|
// args[0] - the Proxy target object.
|
|
2559
3177
|
// args[1] - the property
|
|
2560
3178
|
const auto &hostObject = getJsiHostObject(args[0]);
|
|
2561
3179
|
PropNameIDView propertyId{this, args[1]};
|
|
2562
3180
|
|
|
2563
|
-
return runInMethodContext(
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
3181
|
+
return runInMethodContext(
|
|
3182
|
+
"HostObject::getOwnPropertyDescriptor",
|
|
3183
|
+
[&hostObject, &propertyId, this]() {
|
|
3184
|
+
auto getPropDescriptor = [](napi_value name, napi_value value) {
|
|
3185
|
+
return napi_property_descriptor{
|
|
3186
|
+
nullptr,
|
|
3187
|
+
name,
|
|
3188
|
+
nullptr,
|
|
3189
|
+
nullptr,
|
|
3190
|
+
nullptr,
|
|
3191
|
+
value,
|
|
3192
|
+
napi_default_jsproperty,
|
|
3193
|
+
nullptr};
|
|
3194
|
+
};
|
|
3195
|
+
napi_value trueValue = getBoolean(true);
|
|
3196
|
+
napi_property_descriptor properties[]{
|
|
3197
|
+
getPropDescriptor(
|
|
3198
|
+
getNodeApiValue(propertyId_.value),
|
|
3199
|
+
getNodeApiValue(hostObject->get(*this, propertyId))),
|
|
3200
|
+
getPropDescriptor(getNodeApiValue(propertyId_.writable), trueValue),
|
|
3201
|
+
getPropDescriptor(
|
|
3202
|
+
getNodeApiValue(propertyId_.enumerable), trueValue),
|
|
3203
|
+
getPropDescriptor(
|
|
3204
|
+
getNodeApiValue(propertyId_.configurable), trueValue)};
|
|
3205
|
+
napi_value descriptor = createNodeApiObject();
|
|
3206
|
+
CHECK_NAPI(jsrApi_->napi_define_properties(
|
|
3207
|
+
env_, descriptor, std::size(properties), properties));
|
|
3208
|
+
return descriptor;
|
|
3209
|
+
});
|
|
2578
3210
|
}
|
|
2579
3211
|
|
|
2580
3212
|
// Converts jsi::Bufer to span.
|
|
@@ -2620,14 +3252,18 @@ napi_value NodeApiJsiRuntime::getNodeApiValue(const jsi::Value &value) const {
|
|
|
2620
3252
|
} else if (value.isNumber()) {
|
|
2621
3253
|
return createDouble(value.getNumber());
|
|
2622
3254
|
} else if (value.isSymbol()) {
|
|
2623
|
-
return getNodeApiValue(
|
|
3255
|
+
return getNodeApiValue(
|
|
3256
|
+
value.getSymbol(*const_cast<NodeApiJsiRuntime *>(this)));
|
|
2624
3257
|
} else if (value.isString()) {
|
|
2625
|
-
return getNodeApiValue(
|
|
3258
|
+
return getNodeApiValue(
|
|
3259
|
+
value.getString(*const_cast<NodeApiJsiRuntime *>(this)));
|
|
2626
3260
|
} else if (value.isObject()) {
|
|
2627
|
-
return getNodeApiValue(
|
|
3261
|
+
return getNodeApiValue(
|
|
3262
|
+
value.getObject(*const_cast<NodeApiJsiRuntime *>(this)));
|
|
2628
3263
|
#if JSI_VERSION >= 8
|
|
2629
3264
|
} else if (value.isBigInt()) {
|
|
2630
|
-
return getNodeApiValue(
|
|
3265
|
+
return getNodeApiValue(
|
|
3266
|
+
value.getBigInt(*const_cast<NodeApiJsiRuntime *>(this)));
|
|
2631
3267
|
#endif
|
|
2632
3268
|
} else {
|
|
2633
3269
|
throw jsi::JSINativeException("Unexpected jsi::Value type");
|
|
@@ -2635,16 +3271,18 @@ napi_value NodeApiJsiRuntime::getNodeApiValue(const jsi::Value &value) const {
|
|
|
2635
3271
|
}
|
|
2636
3272
|
|
|
2637
3273
|
napi_value NodeApiJsiRuntime::getNodeApiValue(const jsi::Pointer &ptr) const {
|
|
2638
|
-
return const_cast<NodeApiPointerValue *>(
|
|
3274
|
+
return const_cast<NodeApiPointerValue *>(
|
|
3275
|
+
static_cast<const NodeApiPointerValue *>(getPointerValue(ptr)))
|
|
2639
3276
|
->getValue(*const_cast<NodeApiJsiRuntime *>(this));
|
|
2640
3277
|
}
|
|
2641
3278
|
|
|
2642
|
-
napi_value NodeApiJsiRuntime::getNodeApiValue(
|
|
3279
|
+
napi_value NodeApiJsiRuntime::getNodeApiValue(
|
|
3280
|
+
const NodeApiRefHolder &ref) const {
|
|
2643
3281
|
return ref->getValue(*const_cast<NodeApiJsiRuntime *>(this));
|
|
2644
3282
|
}
|
|
2645
3283
|
|
|
2646
|
-
NodeApiJsiRuntime::NodeApiRefCountedPointerValue *
|
|
2647
|
-
|
|
3284
|
+
NodeApiJsiRuntime::NodeApiRefCountedPointerValue *
|
|
3285
|
+
NodeApiJsiRuntime::cloneNodeApiPointerValue(const PointerValue *pointerValue) {
|
|
2648
3286
|
return static_cast<const NodeApiPointerValue *>(pointerValue)->clone(*this);
|
|
2649
3287
|
}
|
|
2650
3288
|
|
|
@@ -2688,26 +3326,38 @@ std::optional<uint32_t> NodeApiJsiRuntime::toArrayIndex(
|
|
|
2688
3326
|
template <typename T, std::enable_if_t<std::is_same_v<jsi::Object, T>, int>>
|
|
2689
3327
|
T NodeApiJsiRuntime::makeJsiPointer(napi_value value) const {
|
|
2690
3328
|
return make<T>(NodeApiRefCountedPointerValue::make(
|
|
2691
|
-
|
|
3329
|
+
*const_cast<NodeApiJsiRuntime *>(this),
|
|
3330
|
+
value,
|
|
3331
|
+
NodeApiPointerValueKind::Object)
|
|
3332
|
+
.release());
|
|
2692
3333
|
}
|
|
2693
3334
|
|
|
2694
3335
|
template <typename T, std::enable_if_t<std::is_same_v<jsi::String, T>, int>>
|
|
2695
3336
|
T NodeApiJsiRuntime::makeJsiPointer(napi_value value) const {
|
|
2696
3337
|
return make<T>(NodeApiRefCountedPointerValue::make(
|
|
2697
|
-
|
|
3338
|
+
*const_cast<NodeApiJsiRuntime *>(this),
|
|
3339
|
+
value,
|
|
3340
|
+
NodeApiPointerValueKind::String)
|
|
3341
|
+
.release());
|
|
2698
3342
|
}
|
|
2699
3343
|
|
|
2700
3344
|
template <typename T, std::enable_if_t<std::is_same_v<jsi::Symbol, T>, int>>
|
|
2701
3345
|
T NodeApiJsiRuntime::makeJsiPointer(napi_value value) const {
|
|
2702
3346
|
return make<T>(NodeApiRefCountedPointerValue::make(
|
|
2703
|
-
|
|
3347
|
+
*const_cast<NodeApiJsiRuntime *>(this),
|
|
3348
|
+
value,
|
|
3349
|
+
NodeApiPointerValueKind::Symbol)
|
|
3350
|
+
.release());
|
|
2704
3351
|
}
|
|
2705
3352
|
|
|
2706
3353
|
#if JSI_VERSION >= 6
|
|
2707
3354
|
template <typename T, std::enable_if_t<std::is_same_v<jsi::BigInt, T>, int>>
|
|
2708
3355
|
T NodeApiJsiRuntime::makeJsiPointer(napi_value value) const {
|
|
2709
3356
|
return make<T>(NodeApiRefCountedPointerValue::make(
|
|
2710
|
-
|
|
3357
|
+
*const_cast<NodeApiJsiRuntime *>(this),
|
|
3358
|
+
value,
|
|
3359
|
+
NodeApiPointerValueKind::BigInt)
|
|
3360
|
+
.release());
|
|
2711
3361
|
}
|
|
2712
3362
|
#endif
|
|
2713
3363
|
|
|
@@ -2717,29 +3367,21 @@ template <
|
|
|
2717
3367
|
std::enable_if_t<std::is_base_of_v<jsi::Pointer, TTo>, int>,
|
|
2718
3368
|
std::enable_if_t<std::is_base_of_v<jsi::Pointer, TFrom>, int>>
|
|
2719
3369
|
TTo NodeApiJsiRuntime::cloneAs(const TFrom &pointer) const {
|
|
2720
|
-
return make<TTo>(static_cast<const NodeApiRefCountedPointerValue *>(
|
|
3370
|
+
return make<TTo>(static_cast<const NodeApiRefCountedPointerValue *>(
|
|
3371
|
+
getPointerValue(pointer))
|
|
2721
3372
|
->clone(*const_cast<NodeApiJsiRuntime *>(this)));
|
|
2722
3373
|
}
|
|
2723
3374
|
|
|
2724
3375
|
NodeApiJsiRuntime::NodeApiRefHolder NodeApiJsiRuntime::makeNodeApiRef(
|
|
2725
3376
|
napi_value value,
|
|
2726
|
-
|
|
3377
|
+
NodeApiPointerValueKind pointerKind,
|
|
2727
3378
|
int32_t initialRefCount) {
|
|
2728
|
-
return
|
|
3379
|
+
return NodeApiRefCountedPointerValue::make(
|
|
3380
|
+
*this, value, pointerKind, initialRefCount);
|
|
2729
3381
|
}
|
|
2730
3382
|
|
|
2731
|
-
void NodeApiJsiRuntime::addStackValue(
|
|
2732
|
-
|
|
2733
|
-
collectUnusedStackValues();
|
|
2734
|
-
}
|
|
2735
|
-
stackValues_.push_back(std::move(pointerHolder));
|
|
2736
|
-
}
|
|
2737
|
-
|
|
2738
|
-
void NodeApiJsiRuntime::addRef(NodeApiRefHolder &&refHolder) {
|
|
2739
|
-
if (refs_.size() == refs_.capacity()) {
|
|
2740
|
-
collectUnusedRefs();
|
|
2741
|
-
}
|
|
2742
|
-
refs_.push_back(std::move(refHolder));
|
|
3383
|
+
void NodeApiJsiRuntime::addStackValue(NodeApiStackValuePtr stackPointer) {
|
|
3384
|
+
stackValues_.push_back(std::move(stackPointer));
|
|
2743
3385
|
}
|
|
2744
3386
|
|
|
2745
3387
|
void NodeApiJsiRuntime::pushPointerValueScope() noexcept {
|
|
@@ -2748,45 +3390,24 @@ void NodeApiJsiRuntime::pushPointerValueScope() noexcept {
|
|
|
2748
3390
|
|
|
2749
3391
|
void NodeApiJsiRuntime::popPointerValueScope() noexcept {
|
|
2750
3392
|
CHECK_ELSE_CRASH(!stackScopes_.empty(), "There are no scopes to pop");
|
|
2751
|
-
|
|
2752
3393
|
size_t newStackSize = stackScopes_.back();
|
|
2753
3394
|
auto beginIterator = stackValues_.begin() + newStackSize;
|
|
2754
3395
|
stackScopes_.pop_back();
|
|
2755
|
-
std::for_each(
|
|
2756
|
-
|
|
2757
|
-
|
|
3396
|
+
std::for_each(
|
|
3397
|
+
beginIterator, stackValues_.end(), [this](NodeApiStackValuePtr &ptr) {
|
|
3398
|
+
ptr.release()->deleteStackValue(*this);
|
|
3399
|
+
});
|
|
2758
3400
|
stackValues_.resize(newStackSize);
|
|
2759
|
-
}
|
|
2760
3401
|
|
|
2761
|
-
|
|
2762
|
-
auto usedByJsiPointer = [](NodeApiStackValueHolder &holder) {
|
|
2763
|
-
return NodeApiRefCountedPointerValue::usedByJsiPointer(holder.get());
|
|
2764
|
-
};
|
|
2765
|
-
auto beginIterator = stackValues_.begin();
|
|
2766
|
-
for (size_t &scope : stackScopes_) {
|
|
2767
|
-
auto endIterator = stackValues_.begin() + scope;
|
|
2768
|
-
beginIterator = std::partition(beginIterator, endIterator, usedByJsiPointer);
|
|
2769
|
-
scope -= endIterator - beginIterator;
|
|
2770
|
-
}
|
|
2771
|
-
beginIterator = std::partition(beginIterator, stackValues_.end(), usedByJsiPointer);
|
|
2772
|
-
stackValues_.resize(beginIterator - stackValues_.begin());
|
|
2773
|
-
}
|
|
2774
|
-
|
|
2775
|
-
void NodeApiJsiRuntime::collectUnusedRefs() noexcept {
|
|
2776
|
-
auto usedByJsiPointer = [](NodeApiRefHolder &holder) {
|
|
2777
|
-
return NodeApiRefCountedPointerValue::usedByJsiPointer(holder.get());
|
|
2778
|
-
};
|
|
2779
|
-
auto beginIterator = std::partition(refs_.begin(), refs_.end(), usedByJsiPointer);
|
|
2780
|
-
std::for_each(beginIterator, refs_.end(), [this](NodeApiRefHolder &holder) {
|
|
2781
|
-
NodeApiRefCountedPointerValue::deleteNodeApiRef(holder.release(), *this);
|
|
2782
|
-
});
|
|
2783
|
-
refs_.resize(beginIterator - refs_.begin());
|
|
3402
|
+
pendingDeletions_->deletePointerValues(*this);
|
|
2784
3403
|
}
|
|
2785
3404
|
|
|
2786
3405
|
} // namespace
|
|
2787
3406
|
|
|
2788
|
-
std::unique_ptr<jsi::Runtime>
|
|
2789
|
-
|
|
3407
|
+
std::unique_ptr<jsi::Runtime> makeNodeApiJsiRuntime(
|
|
3408
|
+
napi_env env,
|
|
3409
|
+
JSRuntimeApi *jsrApi,
|
|
3410
|
+
std::function<void()> onDelete) noexcept {
|
|
2790
3411
|
return std::make_unique<NodeApiJsiRuntime>(env, jsrApi, std::move(onDelete));
|
|
2791
3412
|
}
|
|
2792
3413
|
|
|
@@ -2794,47 +3415,67 @@ makeNodeApiJsiRuntime(napi_env env, JSRuntimeApi *jsrApi, std::function<void()>
|
|
|
2794
3415
|
|
|
2795
3416
|
EXTERN_C_START
|
|
2796
3417
|
|
|
2797
|
-
// Default implementation of jsr_get_description if it is not provided by JS
|
|
2798
|
-
// It returns "NodeApiJsiRuntime" string.
|
|
2799
|
-
napi_status NAPI_CDECL
|
|
3418
|
+
// Default implementation of jsr_get_description if it is not provided by JS
|
|
3419
|
+
// engine. It returns "NodeApiJsiRuntime" string.
|
|
3420
|
+
napi_status NAPI_CDECL
|
|
3421
|
+
default_jsr_get_description(napi_env /*env*/, const char **result) {
|
|
2800
3422
|
if (result != nullptr) {
|
|
2801
3423
|
*result = "NodeApiJsiRuntime";
|
|
2802
3424
|
}
|
|
2803
3425
|
return napi_ok;
|
|
2804
3426
|
}
|
|
2805
3427
|
|
|
2806
|
-
// Default implementation of
|
|
2807
|
-
// It does nothing
|
|
2808
|
-
napi_status NAPI_CDECL
|
|
3428
|
+
// Default implementation of jsr_queue_microtask if it is not provided by JS
|
|
3429
|
+
// engine. It does nothing.
|
|
3430
|
+
napi_status NAPI_CDECL
|
|
3431
|
+
default_jsr_queue_microtask(napi_env /*env*/, napi_value /*callback*/) {
|
|
3432
|
+
return napi_generic_failure;
|
|
3433
|
+
}
|
|
3434
|
+
|
|
3435
|
+
// Default implementation of jsr_drain_microtasks if it is not provided by JS
|
|
3436
|
+
// engine. It does nothing.
|
|
3437
|
+
napi_status NAPI_CDECL default_jsr_drain_microtasks(
|
|
3438
|
+
napi_env /*env*/,
|
|
3439
|
+
int32_t /*max_count_hint*/,
|
|
3440
|
+
bool *result) {
|
|
2809
3441
|
if (result != nullptr) {
|
|
2810
3442
|
*result = true; // All tasks are drained
|
|
2811
3443
|
}
|
|
2812
3444
|
return napi_ok;
|
|
2813
3445
|
}
|
|
2814
3446
|
|
|
2815
|
-
// Default implementation of jsr_is_inspectable if it is not provided by JS
|
|
2816
|
-
// It always returns false.
|
|
2817
|
-
napi_status NAPI_CDECL
|
|
3447
|
+
// Default implementation of jsr_is_inspectable if it is not provided by JS
|
|
3448
|
+
// engine. It always returns false.
|
|
3449
|
+
napi_status NAPI_CDECL
|
|
3450
|
+
default_jsr_is_inspectable(napi_env /*env*/, bool *result) {
|
|
2818
3451
|
if (result != nullptr) {
|
|
2819
3452
|
*result = false;
|
|
2820
3453
|
}
|
|
2821
3454
|
return napi_ok;
|
|
2822
3455
|
}
|
|
2823
3456
|
|
|
2824
|
-
// Default implementation of jsr_open_napi_env_scope if it is not provided by JS
|
|
2825
|
-
|
|
3457
|
+
// Default implementation of jsr_open_napi_env_scope if it is not provided by JS
|
|
3458
|
+
// engine.
|
|
3459
|
+
napi_status NAPI_CDECL default_jsr_open_napi_env_scope(
|
|
3460
|
+
napi_env /*env*/,
|
|
3461
|
+
jsr_napi_env_scope * /*scope*/) {
|
|
2826
3462
|
return napi_ok;
|
|
2827
3463
|
}
|
|
2828
3464
|
|
|
2829
|
-
// Default implementation of jsr_close_napi_env_scope if it is not provided by
|
|
2830
|
-
|
|
3465
|
+
// Default implementation of jsr_close_napi_env_scope if it is not provided by
|
|
3466
|
+
// JS engine.
|
|
3467
|
+
napi_status NAPI_CDECL default_jsr_close_napi_env_scope(
|
|
3468
|
+
napi_env /*env*/,
|
|
3469
|
+
jsr_napi_env_scope /*scope*/) {
|
|
2831
3470
|
return napi_ok;
|
|
2832
3471
|
}
|
|
2833
3472
|
|
|
2834
|
-
// TODO: Ensure that we either load all three functions or use their default
|
|
3473
|
+
// TODO: Ensure that we either load all three functions or use their default
|
|
3474
|
+
// versions and never mix and match.
|
|
2835
3475
|
|
|
2836
|
-
// Default implementation of jsr_create_prepared_script if it is not provided by
|
|
2837
|
-
// It return napi_ref as a jsr_prepared_script that wraps up an
|
|
3476
|
+
// Default implementation of jsr_create_prepared_script if it is not provided by
|
|
3477
|
+
// JS engine. It return napi_ref as a jsr_prepared_script that wraps up an
|
|
3478
|
+
// object with a "script" property string.
|
|
2838
3479
|
napi_status NAPI_CDECL default_jsr_create_prepared_script(
|
|
2839
3480
|
napi_env env,
|
|
2840
3481
|
const uint8_t *script_data,
|
|
@@ -2843,34 +3484,46 @@ napi_status NAPI_CDECL default_jsr_create_prepared_script(
|
|
|
2843
3484
|
void *deleter_data,
|
|
2844
3485
|
const char * /*source_url*/,
|
|
2845
3486
|
jsr_prepared_script *result) {
|
|
2846
|
-
Microsoft::NodeApiJsi::JSRuntimeApi *jsrApi =
|
|
3487
|
+
Microsoft::NodeApiJsi::JSRuntimeApi *jsrApi =
|
|
3488
|
+
Microsoft::NodeApiJsi::JSRuntimeApi::current();
|
|
2847
3489
|
napi_value script{}, obj{};
|
|
2848
|
-
// Do not use NAPI_CALL - we must finalize the buffer right after we attempted
|
|
2849
|
-
|
|
2850
|
-
|
|
3490
|
+
// Do not use NAPI_CALL - we must finalize the buffer right after we attempted
|
|
3491
|
+
// the string creation.
|
|
3492
|
+
napi_status status = jsrApi->napi_create_string_utf8(
|
|
3493
|
+
env, reinterpret_cast<const char *>(script_data), script_length, &script);
|
|
2851
3494
|
if (script_delete_cb != nullptr) {
|
|
2852
3495
|
script_delete_cb(const_cast<uint8_t *>(script_data), deleter_data);
|
|
2853
3496
|
}
|
|
2854
3497
|
NAPI_CALL(status);
|
|
2855
3498
|
NAPI_CALL(jsrApi->napi_create_object(env, &obj));
|
|
2856
3499
|
NAPI_CALL(jsrApi->napi_set_named_property(env, obj, "script", script));
|
|
2857
|
-
return jsrApi->napi_create_reference(
|
|
3500
|
+
return jsrApi->napi_create_reference(
|
|
3501
|
+
env, obj, 1, reinterpret_cast<napi_ref *>(result));
|
|
2858
3502
|
}
|
|
2859
3503
|
|
|
2860
|
-
// Default implementation of jsr_delete_prepared_script if it is not provided by
|
|
2861
|
-
// It deletes prepared_script as a napi_ref.
|
|
2862
|
-
napi_status NAPI_CDECL default_jsr_delete_prepared_script(
|
|
2863
|
-
|
|
2864
|
-
|
|
3504
|
+
// Default implementation of jsr_delete_prepared_script if it is not provided by
|
|
3505
|
+
// JS engine. It deletes prepared_script as a napi_ref.
|
|
3506
|
+
napi_status NAPI_CDECL default_jsr_delete_prepared_script(
|
|
3507
|
+
napi_env env,
|
|
3508
|
+
jsr_prepared_script prepared_script) {
|
|
3509
|
+
Microsoft::NodeApiJsi::JSRuntimeApi *jsrApi =
|
|
3510
|
+
Microsoft::NodeApiJsi::JSRuntimeApi::current();
|
|
3511
|
+
return jsrApi->napi_delete_reference(
|
|
3512
|
+
env, reinterpret_cast<napi_ref>(prepared_script));
|
|
2865
3513
|
}
|
|
2866
3514
|
|
|
2867
|
-
// Default implementation of jsr_prepared_script_run if it is not provided by JS
|
|
2868
|
-
// It interprets prepared_script as a napi_ref to an object with a
|
|
2869
|
-
|
|
2870
|
-
default_jsr_prepared_script_run(
|
|
2871
|
-
|
|
3515
|
+
// Default implementation of jsr_prepared_script_run if it is not provided by JS
|
|
3516
|
+
// engine. It interprets prepared_script as a napi_ref to an object with a
|
|
3517
|
+
// "script" property string.
|
|
3518
|
+
napi_status NAPI_CDECL default_jsr_prepared_script_run(
|
|
3519
|
+
napi_env env,
|
|
3520
|
+
jsr_prepared_script prepared_script,
|
|
3521
|
+
napi_value *result) {
|
|
3522
|
+
Microsoft::NodeApiJsi::JSRuntimeApi *jsrApi =
|
|
3523
|
+
Microsoft::NodeApiJsi::JSRuntimeApi::current();
|
|
2872
3524
|
napi_value obj{}, script{};
|
|
2873
|
-
NAPI_CALL(jsrApi->napi_get_reference_value(
|
|
3525
|
+
NAPI_CALL(jsrApi->napi_get_reference_value(
|
|
3526
|
+
env, reinterpret_cast<napi_ref>(prepared_script), &obj));
|
|
2874
3527
|
NAPI_CALL(jsrApi->napi_get_named_property(env, obj, "script", &script));
|
|
2875
3528
|
return jsrApi->napi_run_script(env, script, result);
|
|
2876
3529
|
}
|