react-native-windows 0.68.1 → 0.69.0-preview.1
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/.flowconfig +1 -3
- package/Chakra/ChakraHelpers.cpp +0 -1
- package/Directory.Build.props +3 -0
- package/Directory.Build.targets +1 -1
- package/Folly/TEMP_UntilFollyUpdate/dynamic-inl.h +1411 -0
- package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.cpp +336 -0
- package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h +182 -0
- package/Libraries/ActionSheetIOS/ActionSheetIOS.js +7 -0
- package/Libraries/ActionSheetIOS/NativeActionSheetManager.js +1 -0
- package/Libraries/Alert/Alert.windows.js +2 -2
- package/Libraries/Animated/AnimatedImplementation.js +1 -1
- package/Libraries/Animated/NativeAnimatedHelper.js +55 -9
- package/Libraries/Animated/NativeAnimatedModule.js +1 -0
- package/Libraries/Animated/NativeAnimatedTurboModule.js +1 -0
- package/Libraries/Animated/animations/TimingAnimation.js +6 -11
- package/Libraries/Animated/createAnimatedComponent.js +2 -2
- package/Libraries/Animated/nodes/AnimatedColor.js +95 -29
- package/Libraries/Animated/nodes/AnimatedInterpolation.js +19 -22
- package/Libraries/Animated/nodes/AnimatedNode.js +2 -2
- package/Libraries/Animated/nodes/AnimatedValue.js +1 -1
- package/Libraries/AppState/AppState.js +1 -1
- package/Libraries/Blob/URL.js +7 -1
- package/Libraries/Components/Button.js +3 -0
- package/Libraries/Components/Button.windows.js +4 -0
- package/Libraries/Components/DatePickerAndroid/NativeDatePickerAndroid.js +5 -0
- package/Libraries/Components/Pressable/Pressable.js +3 -3
- package/Libraries/Components/Pressable/Pressable.windows.js +3 -3
- package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +47 -38
- package/Libraries/Components/ScrollView/ScrollContentViewNativeComponent.js +15 -7
- package/Libraries/Components/ScrollView/ScrollView.js +1 -1
- package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +16 -3
- package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +3 -1
- package/Libraries/Components/Slider/Slider.js +0 -2
- package/Libraries/Components/Slider/SliderNativeComponent.js +0 -1
- package/Libraries/Components/StatusBar/StatusBar.js +6 -1
- package/Libraries/Components/Switch/Switch.js +11 -1
- package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +114 -109
- package/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js +17 -9
- package/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js +13 -5
- package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +10 -0
- package/Libraries/Components/TextInput/TextInput.js +1 -8
- package/Libraries/Components/TextInput/TextInput.windows.js +4 -9
- package/Libraries/Components/TextInput/TextInputState.js +10 -2
- package/Libraries/Components/TextInput/TextInputState.windows.js +10 -3
- package/Libraries/Components/TextInput/WindowsTextInputNativeComponent.js +1 -1
- package/Libraries/Components/Touchable/TouchableBounce.js +1 -0
- package/Libraries/Components/Touchable/TouchableHighlight.js +1 -0
- package/Libraries/Components/Touchable/TouchableHighlight.windows.js +6 -5
- package/Libraries/Components/Touchable/TouchableNativeFeedback.js +1 -0
- package/Libraries/Components/Touchable/TouchableOpacity.js +7 -1
- package/Libraries/Components/Touchable/TouchableOpacity.windows.js +11 -5
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +2 -0
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +2 -0
- package/Libraries/Components/View/ReactNativeViewAttributes.js +1 -0
- package/Libraries/Components/View/ReactNativeViewAttributes.windows.js +1 -0
- package/Libraries/Components/View/View.windows.js +33 -1
- package/Libraries/Components/View/ViewNativeComponent.js +68 -8
- package/Libraries/Components/View/ViewPropTypes.js +36 -4
- package/Libraries/Components/View/ViewPropTypes.windows.js +36 -4
- package/Libraries/Core/Devtools/parseHermesStack.js +1 -1
- package/Libraries/Core/ExceptionsManager.js +1 -1
- package/Libraries/Core/RawEventEmitter.js +38 -0
- package/Libraries/Core/ReactNativeVersion.js +2 -2
- package/Libraries/Core/polyfillPromise.js +32 -0
- package/Libraries/Core/setUpReactDevTools.js +3 -2
- package/Libraries/EventEmitter/NativeEventEmitter.js +3 -3
- package/Libraries/EventEmitter/RCTDeviceEventEmitter.js +2 -1
- package/Libraries/EventEmitter/__mocks__/NativeEventEmitter.js +3 -3
- package/Libraries/Events/CustomEvent.js +32 -0
- package/Libraries/Events/EventPolyfill.js +239 -0
- package/Libraries/Image/Image.android.js +0 -6
- package/Libraries/Image/Image.ios.js +0 -6
- package/Libraries/Image/Image.windows.js +2 -8
- package/Libraries/Image/ImageViewNativeComponent.js +18 -3
- package/Libraries/Image/TextInlineImageNativeComponent.js +23 -15
- package/Libraries/Inspector/Inspector.js +2 -4
- package/Libraries/Interaction/BridgeSpyStallHandler.js +4 -3
- package/Libraries/Interaction/InteractionManager.js +1 -12
- package/Libraries/Interaction/TaskQueue.js +5 -4
- package/Libraries/LayoutAnimation/LayoutAnimation.js +13 -0
- package/Libraries/Linking/Linking.js +1 -1
- package/Libraries/Lists/FlatList.js +27 -6
- package/Libraries/Lists/VirtualizedList.js +71 -55
- package/Libraries/Lists/VirtualizedListContext.js +7 -3
- package/Libraries/Lists/VirtualizedSectionList.js +2 -2
- package/Libraries/Lists/__tests__/{FillRateHelper-test.windows.js → FillRateHelper-test.js} +2 -2
- package/Libraries/Lists/__tests__/{FlatList-test.windows.js → FlatList-test.js} +2 -2
- package/Libraries/Lists/__tests__/{SectionList-test.windows.js → SectionList-test.js} +14 -14
- package/Libraries/Lists/__tests__/{VirtualizeUtils-test.windows.js → VirtualizeUtils-test.js} +3 -3
- package/Libraries/Lists/__tests__/{VirtualizedList-test.windows.js → VirtualizedList-test.js} +91 -42
- package/Libraries/Lists/__tests__/{VirtualizedSectionList-test.windows.js → VirtualizedSectionList-test.js} +13 -13
- package/Libraries/LogBox/Data/LogBoxData.js +2 -2
- package/Libraries/LogBox/Data/LogBoxLog.js +1 -1
- package/Libraries/LogBox/Data/LogBoxSymbolication.js +1 -1
- package/Libraries/LogBox/Data/parseLogBoxLog.js +1 -1
- package/Libraries/LogBox/LogBox.js +2 -21
- package/Libraries/LogBox/UI/LogBoxInspectorFooter.js +1 -0
- package/Libraries/LogBox/UI/LogBoxInspectorHeader.js +2 -1
- package/Libraries/NativeComponent/BaseViewConfig.android.js +295 -0
- package/Libraries/NativeComponent/BaseViewConfig.ios.js +333 -0
- package/Libraries/NativeComponent/BaseViewConfig.windows.js +334 -0
- package/Libraries/NativeComponent/NativeComponentRegistry.js +0 -2
- package/Libraries/NativeComponent/PlatformBaseViewConfig.js +24 -0
- package/Libraries/NativeComponent/StaticViewConfigValidator.js +7 -42
- package/Libraries/NativeComponent/ViewConfig.js +4 -4
- package/Libraries/NativeComponent/ViewConfigIgnore.js +54 -0
- package/Libraries/Network/FormData.js +7 -1
- package/Libraries/Pressability/Pressability.js +115 -46
- package/Libraries/Pressability/Pressability.windows.js +190 -74
- package/Libraries/Pressability/PressabilityDebug.js +5 -9
- package/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js +1 -0
- package/Libraries/ReactNative/AppContainer.js +1 -1
- package/Libraries/ReactNative/{DummyUIManager.js → BridgelessUIManager.js} +62 -40
- package/Libraries/ReactNative/PaperUIManager.windows.js +5 -5
- package/Libraries/ReactNative/ReactNativeFeatureFlags.js +39 -0
- package/Libraries/ReactNative/UIManager.js +2 -3
- package/Libraries/ReactNative/renderApplication.js +4 -0
- package/Libraries/ReactPrivate/ReactNativePrivateInterface.js +8 -0
- package/Libraries/Renderer/implementations/ReactFabric-dev.js +5908 -4906
- package/Libraries/Renderer/implementations/ReactFabric-prod.js +2100 -1918
- package/Libraries/Renderer/implementations/ReactFabric-profiling.js +2567 -2352
- package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +5610 -4844
- package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +1710 -1556
- package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +1830 -1639
- package/Libraries/Renderer/shims/ReactNativeTypes.js +2 -1
- package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +2 -1
- package/Libraries/StyleSheet/EdgeInsetsPropType.js +4 -1
- package/Libraries/StyleSheet/StyleSheetTypes.js +59 -66
- package/Libraries/StyleSheet/normalizeColor.js +1 -1
- package/Libraries/StyleSheet/private/_StyleSheetTypesOverrides.js +15 -0
- package/Libraries/StyleSheet/private/_TransformStyle.js +53 -0
- package/Libraries/StyleSheet/processTransform.windows.js +272 -0
- package/Libraries/Text/Text.js +13 -7
- package/Libraries/Text/Text.windows.js +16 -7
- package/Libraries/Text/TextNativeComponent.js +2 -0
- package/Libraries/Text/TextProps.js +10 -0
- package/Libraries/Types/CoreEventTypes.js +13 -1
- package/Libraries/Types/CoreEventTypes.windows.js +26 -1
- package/Libraries/Utilities/Appearance.js +0 -8
- package/Libraries/Utilities/HMRClient.js +1 -1
- package/Libraries/Utilities/ReactNativeTestTools.js +1 -0
- package/Libraries/Utilities/codegenNativeComponent.js +17 -6
- package/Libraries/Utilities/stringifySafe.js +4 -1
- package/Libraries/Utilities/verifyComponentAttributeEquivalence.js +3 -3
- package/Libraries/WebSocket/WebSocket.js +1 -1
- package/Libraries/vendor/emitter/_EmitterSubscription.js +1 -1
- package/Libraries/vendor/emitter/_EventEmitter.js +1 -1
- package/Libraries/vendor/emitter/_EventSubscription.js +1 -1
- package/Microsoft.ReactNative/Base/CoreNativeModules.cpp +1 -4
- package/Microsoft.ReactNative/DynamicReader.cpp +3 -3
- package/Microsoft.ReactNative/Fabric/ComponentView.h +1 -0
- package/Microsoft.ReactNative/Fabric/ComponentViewRegistry.cpp +36 -2
- package/Microsoft.ReactNative/Fabric/ComponentViewRegistry.h +1 -0
- package/Microsoft.ReactNative/Fabric/DWriteHelpers.cpp +19 -0
- package/Microsoft.ReactNative/Fabric/DWriteHelpers.h +13 -0
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +65 -19
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +2 -0
- package/Microsoft.ReactNative/Fabric/ParagraphComponentView.cpp +36 -10
- package/Microsoft.ReactNative/Fabric/ScrollViewComponentView.cpp +2 -0
- package/Microsoft.ReactNative/Fabric/SliderComponentView.cpp +107 -0
- package/Microsoft.ReactNative/Fabric/SliderComponentView.h +51 -0
- package/Microsoft.ReactNative/Fabric/SwitchComponentView.cpp +109 -0
- package/Microsoft.ReactNative/Fabric/SwitchComponentView.h +52 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputComponentDescriptor.h +197 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputComponentView.cpp +308 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputComponentView.h +52 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputEventEmitter.cpp +31 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputEventEmitter.h +33 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputProps.cpp +81 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputProps.h +132 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputShadowNode.cpp +193 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputShadowNode.h +85 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputState.cpp +76 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputState.h +99 -0
- package/Microsoft.ReactNative/Fabric/ViewComponentView.cpp +35 -3
- package/Microsoft.ReactNative/Fabric/ViewComponentView.h +1 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/rncore/EventEmitters.h +5 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/rncore/Props.h +5 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/slider/SliderMeasurementsManager.cpp +46 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/slider/SliderMeasurementsManager.h +30 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/Color.cpp +2 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/conversions.h +1 -9
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.h +3 -1
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +119 -57
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.h +18 -1
- package/Microsoft.ReactNative/IViewManager.idl +3 -3
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +13 -107
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +2 -2
- package/Microsoft.ReactNative/Modules/AppStateModule.cpp +2 -0
- package/Microsoft.ReactNative/Modules/AppStateModule.h +2 -0
- package/Microsoft.ReactNative/Modules/CreateModules.cpp +3 -3
- package/Microsoft.ReactNative/Modules/NativeUIManager.cpp +7 -5
- package/Microsoft.ReactNative/Modules/TimingModule.cpp +2 -2
- package/Microsoft.ReactNative/Modules/TimingModule.h +2 -2
- package/Microsoft.ReactNative/ReactHost/{ReactContext.cpp → MsoReactContext.cpp} +1 -1
- package/Microsoft.ReactNative/ReactHost/{ReactContext.h → MsoReactContext.h} +0 -0
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +15 -2
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
- package/Microsoft.ReactNative/ReactHost/ReactNativeHeaders.h +1 -1
- package/Microsoft.ReactNative/ReactInstanceSettings.idl +12 -2
- package/Microsoft.ReactNative/ReactPackageBuilder.cpp +1 -1
- package/Microsoft.ReactNative/ReactRootView.cpp +2 -1
- package/Microsoft.ReactNative/RedBox.cpp +3 -2
- package/Microsoft.ReactNative/TurboModulesProvider.cpp +3 -2
- package/Microsoft.ReactNative/TurboModulesProvider.h +4 -1
- package/Microsoft.ReactNative/Utils/LocalBundleReader.cpp +41 -0
- package/Microsoft.ReactNative/Utils/ValueUtils.cpp +3 -2
- package/Microsoft.ReactNative/Views/ControlViewManager.cpp +32 -0
- package/Microsoft.ReactNative/Views/ControlViewManager.h +11 -0
- package/Microsoft.ReactNative/Views/DevMenu.cpp +2 -2
- package/Microsoft.ReactNative/Views/FrameworkElementTransferProperties.cpp +13 -2
- package/Microsoft.ReactNative/Views/FrameworkElementViewManager.cpp +149 -22
- package/Microsoft.ReactNative/Views/Image/ImageViewManager.cpp +1 -1
- package/Microsoft.ReactNative/Views/Image/Microsoft.UI.Composition.Effects_Impl.h +5 -11
- package/Microsoft.ReactNative/Views/Image/ReactImage.cpp +2 -1
- package/Microsoft.ReactNative/Views/SliderViewManager.cpp +12 -4
- package/Microsoft.ReactNative/Views/TextInputViewManager.cpp +1 -1
- package/Microsoft.ReactNative/Views/TextViewManager.cpp +2 -2
- package/Microsoft.ReactNative/Views/TouchEventHandler.cpp +163 -37
- package/Microsoft.ReactNative/Views/TouchEventHandler.h +11 -4
- package/Microsoft.ReactNative/Views/ViewPanel.cpp +3 -23
- package/Microsoft.ReactNative/Views/ViewPanel.h +2 -3
- package/Microsoft.ReactNative/Views/ViewViewManager.cpp +21 -0
- package/Microsoft.ReactNative/XamlUIService.cpp +1 -1
- package/Microsoft.ReactNative/XamlView.h +8 -3
- package/Microsoft.ReactNative.Cxx/CppWinRTIncludes.h +3 -5
- package/Microsoft.ReactNative.Cxx/DesktopWindowBridge.h +1 -1
- package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +11 -2
- package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +1 -0
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.cpp +19 -14
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.h +4 -0
- package/Microsoft.ReactNative.Cxx/JSValueReader.h +2 -2
- package/Microsoft.ReactNative.Cxx/JSValueWriter.h +5 -5
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +5 -1
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +2 -3
- package/Microsoft.ReactNative.Cxx/NativeModules.h +3 -3
- package/Microsoft.ReactNative.Cxx/ReactContext.h +3 -3
- package/Microsoft.ReactNative.Cxx/ReactNonAbiValue.h +3 -3
- package/Microsoft.ReactNative.Cxx/XamlUtils.h +44 -5
- package/Microsoft.ReactNative.Managed/Microsoft.ReactNative.Managed.csproj +0 -6
- package/Mso/activeObject/activeObject.h +2 -2
- package/Mso/compilerAdapters/cppMacros.h +3 -5
- package/Mso/errorCode/errorProvider.h +2 -2
- package/Mso/errorCode/maybe.h +4 -4
- package/Mso/functional/functor.h +6 -6
- package/Mso/functional/functorRef.h +2 -2
- package/Mso/future/details/executor.h +2 -2
- package/Mso/future/details/futureFuncInl.h +4 -4
- package/Mso/future/details/ifuture.h +3 -3
- package/Mso/future/details/maybeInvoker.h +6 -6
- package/Mso/future/details/promiseGroupInl.h +4 -4
- package/Mso/future/details/promiseInl.h +4 -4
- package/Mso/future/details/resultTraits.h +4 -4
- package/Mso/future/details/whenAllInl.h +1 -1
- package/Mso/future/future.h +13 -13
- package/Mso/guid/msoGuidDetails.h +1 -1
- package/Mso/memoryApi/memoryApi.h +13 -7
- package/Mso/motifCpp/gTestAdapter.h +1 -1
- package/Mso/motifCpp/testInfo.h +7 -9
- package/Mso/object/make.h +8 -8
- package/Mso/object/objectRefCount.h +3 -5
- package/Mso/object/objectWithWeakRef.h +10 -14
- package/Mso/object/queryCast.h +4 -4
- package/Mso/object/refCountedObject.h +4 -4
- package/Mso/object/unknownObject.h +7 -7
- package/Mso/platformAdapters/windowsFirst.h +1 -1
- package/Mso/smartPtr/cntPtr.h +8 -8
- package/Mso/src/dispatchQueue/threadPoolScheduler_win.cpp +96 -4
- package/Mso/src/dispatchQueue/uiScheduler_winrt.cpp +2 -2
- package/Mso/src/future/futureImpl.h +1 -1
- package/Mso/src/memoryApi/memoryApi.cpp +4 -4
- package/PropertySheets/CppAppConsumeCSharpModule.props +3 -0
- package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.CSharpApp.props +26 -0
- package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.Common.props +12 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +1 -1
- package/PropertySheets/React.Cpp.props +13 -0
- package/PropertySheets/WinUI.props +3 -6
- package/ReactCommon/ReactCommon.vcxproj +2 -4
- package/ReactCommon/ReactCommon.vcxproj.filters +4 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/JSCRuntime.cpp +1480 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/decorator.h +753 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h +1331 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp +1431 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/bridging/CallbackWrapper.h +103 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModule.h +87 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModuleUtils.h +61 -0
- package/ReactCommon/Yoga.cpp +1 -1
- package/Scripts/{Microsoft.ReactNative.ProjectReunion.nuspec → Microsoft.ReactNative.WindowsAppSDK.nuspec} +7 -9
- package/Scripts/OfficeReact.Win32.nuspec +1 -3
- package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +2 -1
- package/Scripts/copyRNLibraries.js +8 -8
- package/Scripts/just.js +1 -1
- package/Scripts/rnw-dependencies.ps1 +41 -10
- package/Scripts/run-desktop-integration-tests.js +6 -6
- package/Shared/AbiSafe.h +3 -3
- package/Shared/BaseScriptStoreImpl.cpp +1 -1
- package/Shared/CppRuntimeOptions.h +50 -0
- package/Shared/CreateModules.h +4 -0
- package/Shared/DevSupportManager.cpp +34 -33
- package/Shared/DevSupportManager.h +1 -2
- package/Shared/HermesRuntimeHolder.cpp +23 -14
- package/Shared/HermesRuntimeHolder.h +8 -2
- package/Shared/IDevSupportManager.h +1 -2
- package/Shared/InspectorPackagerConnection.cpp +7 -5
- package/Shared/InspectorPackagerConnection.h +2 -2
- package/Shared/JSI/ChakraApi.cpp +0 -1
- package/Shared/JSI/ChakraRuntime.cpp +1 -2
- package/Shared/JSI/NapiJsiV8RuntimeHolder.h +1 -1
- package/Shared/JSI/RuntimeHolder.h +2 -0
- package/Shared/Modules/HttpModule.cpp +198 -0
- package/Shared/Modules/HttpModule.h +53 -0
- package/Shared/Modules/WebSocketModule.cpp +5 -1
- package/Shared/Modules/WebSocketModule.h +8 -5
- package/Shared/Networking/IHttpResource.h +53 -0
- package/Shared/{IWebSocketResource.h → Networking/IWebSocketResource.h} +3 -3
- package/Shared/Networking/OriginPolicy.h +15 -0
- package/Shared/Networking/OriginPolicyHttpFilter.cpp +746 -0
- package/Shared/Networking/OriginPolicyHttpFilter.h +112 -0
- package/Shared/Networking/WinRTHttpResource.cpp +347 -0
- package/Shared/Networking/WinRTHttpResource.h +67 -0
- package/Shared/Networking/WinRTTypes.h +30 -0
- package/Shared/{WinRTWebSocketResource.cpp → Networking/WinRTWebSocketResource.cpp} +31 -22
- package/Shared/{WinRTWebSocketResource.h → Networking/WinRTWebSocketResource.h} +3 -3
- package/Shared/OInstance.cpp +37 -11
- package/Shared/RuntimeOptions.cpp +93 -15
- package/Shared/RuntimeOptions.h +22 -9
- package/Shared/Shared.vcxitems +126 -5
- package/Shared/Shared.vcxitems.filters +55 -15
- package/Shared/Threading/BatchingQueueThread.cpp +1 -1
- package/Shared/Utils/WinRTConversions.cpp +22 -0
- package/Shared/Utils/WinRTConversions.h +15 -0
- package/Shared/tracing/fbsystrace.h +2 -2
- package/codegen/NativeActionSheetManagerSpec.g.h +6 -0
- package/codegen/NativeAnimatedModuleSpec.g.h +43 -37
- package/codegen/NativeAnimatedTurboModuleSpec.g.h +43 -37
- package/codegen/NativePushNotificationManagerIOSSpec.g.h +2 -0
- package/codegen/react/components/rnwcore/ComponentDescriptors.h +0 -1
- package/codegen/react/components/rnwcore/EventEmitters.cpp +133 -0
- package/codegen/react/components/rnwcore/EventEmitters.h +0 -18
- package/codegen/react/components/rnwcore/Props.cpp +0 -13
- package/codegen/react/components/rnwcore/Props.h +0 -16
- package/codegen/react/components/rnwcore/ShadowNodes.cpp +0 -1
- package/codegen/react/components/rnwcore/ShadowNodes.h +0 -10
- package/include/Shared/cdebug.h +9 -9
- package/index.js +30 -25
- package/index.windows.js +30 -25
- package/jest/preprocessor.js +24 -107
- package/jest/preprocessor_DO_NOT_USE.js +122 -0
- package/metro.config.js +3 -70
- package/package.json +29 -28
- package/react-native.config.js +40 -6
- package/rntypes/index.d.ts +19 -7
- package/stubs/glog/logging.h +1 -1
- package/template/cpp-app/src/App.h +0 -4
- package/template/cs-app/src/App.xaml.cs +0 -5
- package/template/cs-app/src/MainPage.xaml.cs +1 -10
- package/template/cs-app-WinAppSDK/MyApp/App.xaml +16 -0
- package/template/cs-app-WinAppSDK/MyApp/App.xaml.cs +70 -0
- package/template/cs-app-WinAppSDK/MyApp/MainWindow.xaml +14 -0
- package/template/cs-app-WinAppSDK/MyApp/MainWindow.xaml.cs +38 -0
- package/template/cs-app-WinAppSDK/MyApp/Package.appxmanifest +48 -0
- package/template/cs-app-WinAppSDK/MyApp/Properties/PublishProfiles/win10-arm64.pubxml +19 -0
- package/template/cs-app-WinAppSDK/MyApp/Properties/PublishProfiles/win10-x64.pubxml +19 -0
- package/template/cs-app-WinAppSDK/MyApp/Properties/PublishProfiles/win10-x86.pubxml +19 -0
- package/template/cs-app-WinAppSDK/MyApp/Properties/launchSettings.json +10 -0
- package/template/cs-app-WinAppSDK/MyApp/app.manifest +15 -0
- package/template/cs-app-WinAppSDK/proj/ExperimentalFeatures.props +23 -0
- package/template/cs-app-WinAppSDK/proj/MyApp.csproj +49 -0
- package/template/cs-app-WinAppSDK/proj/MyApp.sln +43 -0
- package/template/cs-app-WinAppSDK/proj/NuGet.Config +17 -0
- package/template/metro.devMode.config.js +2 -51
- package/typings-index.js +5 -1
- package/typings-index.js.map +1 -1
- package/Libraries/Components/SegmentedControlIOS/RCTSegmentedControlNativeComponent.js +0 -44
- package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js +0 -45
- package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js +0 -123
- package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.windows.js +0 -45
- package/Libraries/Components/View/ReactNativeViewViewConfig.js +0 -360
- package/Libraries/Components/View/ReactNativeViewViewConfig.windows.js +0 -390
- package/Libraries/Components/View/ReactNativeViewViewConfigAndroid.js +0 -83
- package/Libraries/ReactNative/UIManagerInjection.js +0 -15
- package/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +0 -24527
- package/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +0 -8309
- package/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +0 -8961
- package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +0 -24948
- package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +0 -8400
- package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +0 -9049
- package/PropertySheets/CppEnablePackageReferences.props +0 -13
- package/Shared/IHttpResource.h +0 -34
- package/Shared/cdebug.cpp +0 -6
- package/include/Shared/ViewManager.h +0 -34
|
@@ -0,0 +1,1480 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include "JSCRuntime.h"
|
|
9
|
+
|
|
10
|
+
#include <JavaScriptCore/JavaScript.h>
|
|
11
|
+
#include <jsi/jsilib.h>
|
|
12
|
+
#include <array>
|
|
13
|
+
#include <atomic>
|
|
14
|
+
#include <condition_variable>
|
|
15
|
+
#include <cstdlib>
|
|
16
|
+
#include <mutex>
|
|
17
|
+
#include <queue>
|
|
18
|
+
#include <sstream>
|
|
19
|
+
#include <thread>
|
|
20
|
+
|
|
21
|
+
namespace facebook {
|
|
22
|
+
namespace jsc {
|
|
23
|
+
|
|
24
|
+
namespace detail {
|
|
25
|
+
class ArgsConverter;
|
|
26
|
+
} // namespace detail
|
|
27
|
+
|
|
28
|
+
class JSCRuntime;
|
|
29
|
+
|
|
30
|
+
struct Lock {
|
|
31
|
+
void lock(const jsc::JSCRuntime &) const {}
|
|
32
|
+
void unlock(const jsc::JSCRuntime &) const {}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
class JSCRuntime : public jsi::Runtime {
|
|
36
|
+
public:
|
|
37
|
+
// Creates new context in new context group
|
|
38
|
+
JSCRuntime();
|
|
39
|
+
// Retains ctx
|
|
40
|
+
JSCRuntime(JSGlobalContextRef ctx);
|
|
41
|
+
~JSCRuntime();
|
|
42
|
+
|
|
43
|
+
std::shared_ptr<const jsi::PreparedJavaScript> prepareJavaScript(
|
|
44
|
+
const std::shared_ptr<const jsi::Buffer> &buffer,
|
|
45
|
+
std::string sourceURL) override;
|
|
46
|
+
|
|
47
|
+
jsi::Value evaluatePreparedJavaScript(
|
|
48
|
+
const std::shared_ptr<const jsi::PreparedJavaScript> &js) override;
|
|
49
|
+
|
|
50
|
+
jsi::Value evaluateJavaScript(
|
|
51
|
+
const std::shared_ptr<const jsi::Buffer> &buffer,
|
|
52
|
+
const std::string &sourceURL) override;
|
|
53
|
+
|
|
54
|
+
bool drainMicrotasks(int maxMicrotasksHint = -1) override;
|
|
55
|
+
|
|
56
|
+
jsi::Object global() override;
|
|
57
|
+
|
|
58
|
+
std::string description() override;
|
|
59
|
+
|
|
60
|
+
bool isInspectable() override;
|
|
61
|
+
|
|
62
|
+
void setDescription(const std::string &desc);
|
|
63
|
+
|
|
64
|
+
// Please don't use the following two functions, only exposed for
|
|
65
|
+
// integration efforts.
|
|
66
|
+
JSGlobalContextRef getContext() {
|
|
67
|
+
return ctx_;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// JSValueRef->JSValue (needs make.*Value so it must be member function)
|
|
71
|
+
jsi::Value createValue(JSValueRef value) const;
|
|
72
|
+
|
|
73
|
+
// Value->JSValueRef (similar to above)
|
|
74
|
+
JSValueRef valueRef(const jsi::Value &value);
|
|
75
|
+
|
|
76
|
+
protected:
|
|
77
|
+
friend class detail::ArgsConverter;
|
|
78
|
+
class JSCSymbolValue final : public PointerValue {
|
|
79
|
+
#ifndef NDEBUG
|
|
80
|
+
JSCSymbolValue(
|
|
81
|
+
JSGlobalContextRef ctx,
|
|
82
|
+
const std::atomic<bool> &ctxInvalid,
|
|
83
|
+
JSValueRef sym,
|
|
84
|
+
std::atomic<intptr_t> &counter);
|
|
85
|
+
#else
|
|
86
|
+
JSCSymbolValue(
|
|
87
|
+
JSGlobalContextRef ctx,
|
|
88
|
+
const std::atomic<bool> &ctxInvalid,
|
|
89
|
+
JSValueRef sym);
|
|
90
|
+
#endif
|
|
91
|
+
void invalidate() override;
|
|
92
|
+
|
|
93
|
+
JSGlobalContextRef ctx_;
|
|
94
|
+
const std::atomic<bool> &ctxInvalid_;
|
|
95
|
+
// There is no C type in the JSC API to represent Symbol, so this stored
|
|
96
|
+
// a JSValueRef which contains the Symbol.
|
|
97
|
+
JSValueRef sym_;
|
|
98
|
+
#ifndef NDEBUG
|
|
99
|
+
std::atomic<intptr_t> &counter_;
|
|
100
|
+
#endif
|
|
101
|
+
protected:
|
|
102
|
+
friend class JSCRuntime;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
class JSCStringValue final : public PointerValue {
|
|
106
|
+
#ifndef NDEBUG
|
|
107
|
+
JSCStringValue(JSStringRef str, std::atomic<intptr_t> &counter);
|
|
108
|
+
#else
|
|
109
|
+
JSCStringValue(JSStringRef str);
|
|
110
|
+
#endif
|
|
111
|
+
void invalidate() override;
|
|
112
|
+
|
|
113
|
+
JSStringRef str_;
|
|
114
|
+
#ifndef NDEBUG
|
|
115
|
+
std::atomic<intptr_t> &counter_;
|
|
116
|
+
#endif
|
|
117
|
+
protected:
|
|
118
|
+
friend class JSCRuntime;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
class JSCObjectValue final : public PointerValue {
|
|
122
|
+
JSCObjectValue(
|
|
123
|
+
JSGlobalContextRef ctx,
|
|
124
|
+
const std::atomic<bool> &ctxInvalid,
|
|
125
|
+
JSObjectRef obj
|
|
126
|
+
#ifndef NDEBUG
|
|
127
|
+
,
|
|
128
|
+
std::atomic<intptr_t> &counter
|
|
129
|
+
#endif
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
void invalidate() override;
|
|
133
|
+
|
|
134
|
+
JSGlobalContextRef ctx_;
|
|
135
|
+
const std::atomic<bool> &ctxInvalid_;
|
|
136
|
+
JSObjectRef obj_;
|
|
137
|
+
#ifndef NDEBUG
|
|
138
|
+
std::atomic<intptr_t> &counter_;
|
|
139
|
+
#endif
|
|
140
|
+
protected:
|
|
141
|
+
friend class JSCRuntime;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
PointerValue *cloneSymbol(const Runtime::PointerValue *pv) override;
|
|
145
|
+
PointerValue *cloneString(const Runtime::PointerValue *pv) override;
|
|
146
|
+
PointerValue *cloneObject(const Runtime::PointerValue *pv) override;
|
|
147
|
+
PointerValue *clonePropNameID(const Runtime::PointerValue *pv) override;
|
|
148
|
+
|
|
149
|
+
jsi::PropNameID createPropNameIDFromAscii(const char *str, size_t length)
|
|
150
|
+
override;
|
|
151
|
+
jsi::PropNameID createPropNameIDFromUtf8(const uint8_t *utf8, size_t length)
|
|
152
|
+
override;
|
|
153
|
+
jsi::PropNameID createPropNameIDFromString(const jsi::String &str) override;
|
|
154
|
+
std::string utf8(const jsi::PropNameID &) override;
|
|
155
|
+
bool compare(const jsi::PropNameID &, const jsi::PropNameID &) override;
|
|
156
|
+
|
|
157
|
+
std::string symbolToString(const jsi::Symbol &) override;
|
|
158
|
+
|
|
159
|
+
jsi::String createStringFromAscii(const char *str, size_t length) override;
|
|
160
|
+
jsi::String createStringFromUtf8(const uint8_t *utf8, size_t length) override;
|
|
161
|
+
std::string utf8(const jsi::String &) override;
|
|
162
|
+
|
|
163
|
+
jsi::Object createObject() override;
|
|
164
|
+
jsi::Object createObject(std::shared_ptr<jsi::HostObject> ho) override;
|
|
165
|
+
virtual std::shared_ptr<jsi::HostObject> getHostObject(
|
|
166
|
+
const jsi::Object &) override;
|
|
167
|
+
jsi::HostFunctionType &getHostFunction(const jsi::Function &) override;
|
|
168
|
+
|
|
169
|
+
jsi::Value getProperty(const jsi::Object &, const jsi::String &name) override;
|
|
170
|
+
jsi::Value getProperty(const jsi::Object &, const jsi::PropNameID &name)
|
|
171
|
+
override;
|
|
172
|
+
bool hasProperty(const jsi::Object &, const jsi::String &name) override;
|
|
173
|
+
bool hasProperty(const jsi::Object &, const jsi::PropNameID &name) override;
|
|
174
|
+
void setPropertyValue(
|
|
175
|
+
jsi::Object &,
|
|
176
|
+
const jsi::String &name,
|
|
177
|
+
const jsi::Value &value) override;
|
|
178
|
+
void setPropertyValue(
|
|
179
|
+
jsi::Object &,
|
|
180
|
+
const jsi::PropNameID &name,
|
|
181
|
+
const jsi::Value &value) override;
|
|
182
|
+
bool isArray(const jsi::Object &) const override;
|
|
183
|
+
bool isArrayBuffer(const jsi::Object &) const override;
|
|
184
|
+
bool isFunction(const jsi::Object &) const override;
|
|
185
|
+
bool isHostObject(const jsi::Object &) const override;
|
|
186
|
+
bool isHostFunction(const jsi::Function &) const override;
|
|
187
|
+
jsi::Array getPropertyNames(const jsi::Object &) override;
|
|
188
|
+
|
|
189
|
+
// TODO: revisit this implementation
|
|
190
|
+
jsi::WeakObject createWeakObject(const jsi::Object &) override;
|
|
191
|
+
jsi::Value lockWeakObject(jsi::WeakObject &) override;
|
|
192
|
+
|
|
193
|
+
jsi::Array createArray(size_t length) override;
|
|
194
|
+
size_t size(const jsi::Array &) override;
|
|
195
|
+
size_t size(const jsi::ArrayBuffer &) override;
|
|
196
|
+
uint8_t *data(const jsi::ArrayBuffer &) override;
|
|
197
|
+
jsi::Value getValueAtIndex(const jsi::Array &, size_t i) override;
|
|
198
|
+
void setValueAtIndexImpl(jsi::Array &, size_t i, const jsi::Value &value)
|
|
199
|
+
override;
|
|
200
|
+
|
|
201
|
+
jsi::Function createFunctionFromHostFunction(
|
|
202
|
+
const jsi::PropNameID &name,
|
|
203
|
+
unsigned int paramCount,
|
|
204
|
+
jsi::HostFunctionType func) override;
|
|
205
|
+
jsi::Value call(
|
|
206
|
+
const jsi::Function &,
|
|
207
|
+
const jsi::Value &jsThis,
|
|
208
|
+
const jsi::Value *args,
|
|
209
|
+
size_t count) override;
|
|
210
|
+
jsi::Value callAsConstructor(
|
|
211
|
+
const jsi::Function &,
|
|
212
|
+
const jsi::Value *args,
|
|
213
|
+
size_t count) override;
|
|
214
|
+
|
|
215
|
+
bool strictEquals(const jsi::Symbol &a, const jsi::Symbol &b) const override;
|
|
216
|
+
bool strictEquals(const jsi::String &a, const jsi::String &b) const override;
|
|
217
|
+
bool strictEquals(const jsi::Object &a, const jsi::Object &b) const override;
|
|
218
|
+
bool instanceOf(const jsi::Object &o, const jsi::Function &f) override;
|
|
219
|
+
|
|
220
|
+
private:
|
|
221
|
+
// Basically convenience casts
|
|
222
|
+
static JSValueRef symbolRef(const jsi::Symbol &str);
|
|
223
|
+
static JSStringRef stringRef(const jsi::String &str);
|
|
224
|
+
static JSStringRef stringRef(const jsi::PropNameID &sym);
|
|
225
|
+
static JSObjectRef objectRef(const jsi::Object &obj);
|
|
226
|
+
|
|
227
|
+
#ifdef RN_FABRIC_ENABLED
|
|
228
|
+
static JSObjectRef objectRef(const jsi::WeakObject &obj);
|
|
229
|
+
#endif
|
|
230
|
+
|
|
231
|
+
// Factory methods for creating String/Object
|
|
232
|
+
jsi::Symbol createSymbol(JSValueRef symbolRef) const;
|
|
233
|
+
jsi::String createString(JSStringRef stringRef) const;
|
|
234
|
+
jsi::PropNameID createPropNameID(JSStringRef stringRef);
|
|
235
|
+
jsi::Object createObject(JSObjectRef objectRef) const;
|
|
236
|
+
|
|
237
|
+
// Used by factory methods and clone methods
|
|
238
|
+
jsi::Runtime::PointerValue *makeSymbolValue(JSValueRef sym) const;
|
|
239
|
+
jsi::Runtime::PointerValue *makeStringValue(JSStringRef str) const;
|
|
240
|
+
jsi::Runtime::PointerValue *makeObjectValue(JSObjectRef obj) const;
|
|
241
|
+
|
|
242
|
+
void checkException(JSValueRef exc);
|
|
243
|
+
void checkException(JSValueRef res, JSValueRef exc);
|
|
244
|
+
void checkException(JSValueRef exc, const char *msg);
|
|
245
|
+
void checkException(JSValueRef res, JSValueRef exc, const char *msg);
|
|
246
|
+
|
|
247
|
+
JSGlobalContextRef ctx_;
|
|
248
|
+
std::atomic<bool> ctxInvalid_;
|
|
249
|
+
std::string desc_;
|
|
250
|
+
#ifndef NDEBUG
|
|
251
|
+
mutable std::atomic<intptr_t> objectCounter_;
|
|
252
|
+
mutable std::atomic<intptr_t> symbolCounter_;
|
|
253
|
+
mutable std::atomic<intptr_t> stringCounter_;
|
|
254
|
+
#endif
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
#ifndef __has_builtin
|
|
258
|
+
#define __has_builtin(x) 0
|
|
259
|
+
#endif
|
|
260
|
+
|
|
261
|
+
#if __has_builtin(__builtin_expect) || defined(__GNUC__)
|
|
262
|
+
#define JSC_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
|
|
263
|
+
#define JSC_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
|
|
264
|
+
#else
|
|
265
|
+
#define JSC_LIKELY(EXPR) (EXPR)
|
|
266
|
+
#define JSC_UNLIKELY(EXPR) (EXPR)
|
|
267
|
+
#endif
|
|
268
|
+
|
|
269
|
+
#define JSC_ASSERT(x) \
|
|
270
|
+
do { \
|
|
271
|
+
if (JSC_UNLIKELY(!!(x))) { \
|
|
272
|
+
abort(); \
|
|
273
|
+
} \
|
|
274
|
+
} while (0)
|
|
275
|
+
|
|
276
|
+
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
|
277
|
+
// This takes care of watch and tvos (due to backwards compatibility in
|
|
278
|
+
// Availability.h
|
|
279
|
+
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0
|
|
280
|
+
#define _JSC_FAST_IS_ARRAY
|
|
281
|
+
#endif
|
|
282
|
+
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0
|
|
283
|
+
#define _JSC_NO_ARRAY_BUFFERS
|
|
284
|
+
#endif
|
|
285
|
+
#endif
|
|
286
|
+
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
|
|
287
|
+
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_11
|
|
288
|
+
// Only one of these should be set for a build. If somehow that's not
|
|
289
|
+
// true, this will be a compile-time error and it can be resolved when
|
|
290
|
+
// we understand why.
|
|
291
|
+
#define _JSC_FAST_IS_ARRAY
|
|
292
|
+
#endif
|
|
293
|
+
#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12
|
|
294
|
+
#define _JSC_NO_ARRAY_BUFFERS
|
|
295
|
+
#endif
|
|
296
|
+
#endif
|
|
297
|
+
|
|
298
|
+
// JSStringRef utilities
|
|
299
|
+
namespace {
|
|
300
|
+
std::string JSStringToSTLString(JSStringRef str) {
|
|
301
|
+
// Small string optimization: Avoid one heap allocation for strings that fit
|
|
302
|
+
// in stackBuffer.size() bytes of UTF-8 (including the null terminator).
|
|
303
|
+
std::array<char, 20> stackBuffer;
|
|
304
|
+
std::unique_ptr<char[]> heapBuffer;
|
|
305
|
+
char *buffer;
|
|
306
|
+
// NOTE: By definition, maxBytes >= 1 since the null terminator is included.
|
|
307
|
+
size_t maxBytes = JSStringGetMaximumUTF8CStringSize(str);
|
|
308
|
+
if (maxBytes <= stackBuffer.size()) {
|
|
309
|
+
buffer = stackBuffer.data();
|
|
310
|
+
} else {
|
|
311
|
+
heapBuffer = std::make_unique<char[]>(maxBytes);
|
|
312
|
+
buffer = heapBuffer.get();
|
|
313
|
+
}
|
|
314
|
+
size_t actualBytes = JSStringGetUTF8CString(str, buffer, maxBytes);
|
|
315
|
+
if (!actualBytes) {
|
|
316
|
+
// Happens if maxBytes == 0 (never the case here) or if str contains
|
|
317
|
+
// invalid UTF-16 data, since JSStringGetUTF8CString attempts a strict
|
|
318
|
+
// conversion.
|
|
319
|
+
// When converting an invalid string, JSStringGetUTF8CString writes a null
|
|
320
|
+
// terminator before returning. So we can reliably treat our buffer as a C
|
|
321
|
+
// string and return the truncated data to our caller. This is slightly
|
|
322
|
+
// slower than if we knew the length (like below) but better than crashing.
|
|
323
|
+
// TODO(T62295565): Perform a non-strict, best effort conversion of the
|
|
324
|
+
// full string instead, like we did before the JSI migration.
|
|
325
|
+
return std::string(buffer);
|
|
326
|
+
}
|
|
327
|
+
return std::string(buffer, actualBytes - 1);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
JSStringRef getLengthString() {
|
|
331
|
+
static JSStringRef length = JSStringCreateWithUTF8CString("length");
|
|
332
|
+
return length;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
JSStringRef getNameString() {
|
|
336
|
+
static JSStringRef name = JSStringCreateWithUTF8CString("name");
|
|
337
|
+
return name;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
JSStringRef getFunctionString() {
|
|
341
|
+
static JSStringRef func = JSStringCreateWithUTF8CString("Function");
|
|
342
|
+
return func;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
#if !defined(_JSC_FAST_IS_ARRAY)
|
|
346
|
+
JSStringRef getArrayString() {
|
|
347
|
+
static JSStringRef array = JSStringCreateWithUTF8CString("Array");
|
|
348
|
+
return array;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
JSStringRef getIsArrayString() {
|
|
352
|
+
static JSStringRef isArray = JSStringCreateWithUTF8CString("isArray");
|
|
353
|
+
return isArray;
|
|
354
|
+
}
|
|
355
|
+
#endif
|
|
356
|
+
} // namespace
|
|
357
|
+
|
|
358
|
+
// std::string utility
|
|
359
|
+
namespace {
|
|
360
|
+
std::string to_string(void *value) {
|
|
361
|
+
std::ostringstream ss;
|
|
362
|
+
ss << value;
|
|
363
|
+
return ss.str();
|
|
364
|
+
}
|
|
365
|
+
} // namespace
|
|
366
|
+
|
|
367
|
+
JSCRuntime::JSCRuntime()
|
|
368
|
+
: JSCRuntime(JSGlobalContextCreateInGroup(nullptr, nullptr)) {
|
|
369
|
+
JSGlobalContextRelease(ctx_);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
JSCRuntime::JSCRuntime(JSGlobalContextRef ctx)
|
|
373
|
+
: ctx_(JSGlobalContextRetain(ctx)),
|
|
374
|
+
ctxInvalid_(false)
|
|
375
|
+
#ifndef NDEBUG
|
|
376
|
+
,
|
|
377
|
+
objectCounter_(0),
|
|
378
|
+
stringCounter_(0)
|
|
379
|
+
#endif
|
|
380
|
+
{
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
JSCRuntime::~JSCRuntime() {
|
|
384
|
+
// On shutting down and cleaning up: when JSC is actually torn down,
|
|
385
|
+
// it calls JSC::Heap::lastChanceToFinalize internally which
|
|
386
|
+
// finalizes anything left over. But at this point,
|
|
387
|
+
// JSValueUnprotect() can no longer be called. We use an
|
|
388
|
+
// atomic<bool> to avoid unsafe unprotects happening after shutdown
|
|
389
|
+
// has started.
|
|
390
|
+
ctxInvalid_ = true;
|
|
391
|
+
JSGlobalContextRelease(ctx_);
|
|
392
|
+
#ifndef NDEBUG
|
|
393
|
+
assert(
|
|
394
|
+
objectCounter_ == 0 && "JSCRuntime destroyed with a dangling API object");
|
|
395
|
+
assert(
|
|
396
|
+
stringCounter_ == 0 && "JSCRuntime destroyed with a dangling API string");
|
|
397
|
+
#endif
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
std::shared_ptr<const jsi::PreparedJavaScript> JSCRuntime::prepareJavaScript(
|
|
401
|
+
const std::shared_ptr<const jsi::Buffer> &buffer,
|
|
402
|
+
std::string sourceURL) {
|
|
403
|
+
return std::make_shared<jsi::SourceJavaScriptPreparation>(
|
|
404
|
+
buffer, std::move(sourceURL));
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
jsi::Value JSCRuntime::evaluatePreparedJavaScript(
|
|
408
|
+
const std::shared_ptr<const jsi::PreparedJavaScript> &js) {
|
|
409
|
+
assert(
|
|
410
|
+
dynamic_cast<const jsi::SourceJavaScriptPreparation *>(js.get()) &&
|
|
411
|
+
"preparedJavaScript must be a SourceJavaScriptPreparation");
|
|
412
|
+
auto sourceJs =
|
|
413
|
+
std::static_pointer_cast<const jsi::SourceJavaScriptPreparation>(js);
|
|
414
|
+
return evaluateJavaScript(sourceJs, sourceJs->sourceURL());
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
jsi::Value JSCRuntime::evaluateJavaScript(
|
|
418
|
+
const std::shared_ptr<const jsi::Buffer> &buffer,
|
|
419
|
+
const std::string &sourceURL) {
|
|
420
|
+
std::string tmp(
|
|
421
|
+
reinterpret_cast<const char *>(buffer->data()), buffer->size());
|
|
422
|
+
JSStringRef sourceRef = JSStringCreateWithUTF8CString(tmp.c_str());
|
|
423
|
+
JSStringRef sourceURLRef = nullptr;
|
|
424
|
+
if (!sourceURL.empty()) {
|
|
425
|
+
sourceURLRef = JSStringCreateWithUTF8CString(sourceURL.c_str());
|
|
426
|
+
}
|
|
427
|
+
JSValueRef exc = nullptr;
|
|
428
|
+
JSValueRef res =
|
|
429
|
+
JSEvaluateScript(ctx_, sourceRef, nullptr, sourceURLRef, 0, &exc);
|
|
430
|
+
JSStringRelease(sourceRef);
|
|
431
|
+
if (sourceURLRef) {
|
|
432
|
+
JSStringRelease(sourceURLRef);
|
|
433
|
+
}
|
|
434
|
+
checkException(res, exc);
|
|
435
|
+
return createValue(res);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
bool JSCRuntime::drainMicrotasks(int maxMicrotasksHint) {
|
|
439
|
+
return true;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
jsi::Object JSCRuntime::global() {
|
|
443
|
+
return createObject(JSContextGetGlobalObject(ctx_));
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
std::string JSCRuntime::description() {
|
|
447
|
+
if (desc_.empty()) {
|
|
448
|
+
desc_ = std::string("<JSCRuntime@") + to_string(this) + ">";
|
|
449
|
+
}
|
|
450
|
+
return desc_;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
bool JSCRuntime::isInspectable() {
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
namespace {
|
|
458
|
+
|
|
459
|
+
bool smellsLikeES6Symbol(JSGlobalContextRef ctx, JSValueRef ref) {
|
|
460
|
+
// Since iOS 13, JSValueGetType will return kJSTypeSymbol
|
|
461
|
+
// Before: Empirically, an es6 Symbol is not an object, but its type is
|
|
462
|
+
// object. This makes no sense, but we'll run with it.
|
|
463
|
+
// https://github.com/WebKit/webkit/blob/master/Source/JavaScriptCore/API/JSValueRef.cpp#L79-L82
|
|
464
|
+
|
|
465
|
+
JSType type = JSValueGetType(ctx, ref);
|
|
466
|
+
|
|
467
|
+
if (type == /* kJSTypeSymbol */ 6) {
|
|
468
|
+
return true;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
return (!JSValueIsObject(ctx, ref) && type == kJSTypeObject);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
} // namespace
|
|
475
|
+
|
|
476
|
+
JSCRuntime::JSCSymbolValue::JSCSymbolValue(
|
|
477
|
+
JSGlobalContextRef ctx,
|
|
478
|
+
const std::atomic<bool> &ctxInvalid,
|
|
479
|
+
JSValueRef sym
|
|
480
|
+
#ifndef NDEBUG
|
|
481
|
+
,
|
|
482
|
+
std::atomic<intptr_t> &counter
|
|
483
|
+
#endif
|
|
484
|
+
)
|
|
485
|
+
: ctx_(ctx),
|
|
486
|
+
ctxInvalid_(ctxInvalid),
|
|
487
|
+
sym_(sym)
|
|
488
|
+
#ifndef NDEBUG
|
|
489
|
+
,
|
|
490
|
+
counter_(counter)
|
|
491
|
+
#endif
|
|
492
|
+
{
|
|
493
|
+
assert(smellsLikeES6Symbol(ctx_, sym_));
|
|
494
|
+
JSValueProtect(ctx_, sym_);
|
|
495
|
+
#ifndef NDEBUG
|
|
496
|
+
counter_ += 1;
|
|
497
|
+
#endif
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
void JSCRuntime::JSCSymbolValue::invalidate() {
|
|
501
|
+
#ifndef NDEBUG
|
|
502
|
+
counter_ -= 1;
|
|
503
|
+
#endif
|
|
504
|
+
|
|
505
|
+
if (!ctxInvalid_) {
|
|
506
|
+
JSValueUnprotect(ctx_, sym_);
|
|
507
|
+
}
|
|
508
|
+
delete this;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
#ifndef NDEBUG
|
|
512
|
+
JSCRuntime::JSCStringValue::JSCStringValue(
|
|
513
|
+
JSStringRef str,
|
|
514
|
+
std::atomic<intptr_t> &counter)
|
|
515
|
+
: str_(JSStringRetain(str)), counter_(counter) {
|
|
516
|
+
// Since std::atomic returns a copy instead of a reference when calling
|
|
517
|
+
// operator+= we must do this explicitly in the constructor
|
|
518
|
+
counter_ += 1;
|
|
519
|
+
}
|
|
520
|
+
#else
|
|
521
|
+
JSCRuntime::JSCStringValue::JSCStringValue(JSStringRef str)
|
|
522
|
+
: str_(JSStringRetain(str)) {}
|
|
523
|
+
#endif
|
|
524
|
+
|
|
525
|
+
void JSCRuntime::JSCStringValue::invalidate() {
|
|
526
|
+
// These JSC{String,Object}Value objects are implicitly owned by the
|
|
527
|
+
// {String,Object} objects, thus when a String/Object is destructed
|
|
528
|
+
// the JSC{String,Object}Value should be released.
|
|
529
|
+
#ifndef NDEBUG
|
|
530
|
+
counter_ -= 1;
|
|
531
|
+
#endif
|
|
532
|
+
JSStringRelease(str_);
|
|
533
|
+
// Angery reaccs only
|
|
534
|
+
delete this;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
JSCRuntime::JSCObjectValue::JSCObjectValue(
|
|
538
|
+
JSGlobalContextRef ctx,
|
|
539
|
+
const std::atomic<bool> &ctxInvalid,
|
|
540
|
+
JSObjectRef obj
|
|
541
|
+
#ifndef NDEBUG
|
|
542
|
+
,
|
|
543
|
+
std::atomic<intptr_t> &counter
|
|
544
|
+
#endif
|
|
545
|
+
)
|
|
546
|
+
: ctx_(ctx),
|
|
547
|
+
ctxInvalid_(ctxInvalid),
|
|
548
|
+
obj_(obj)
|
|
549
|
+
#ifndef NDEBUG
|
|
550
|
+
,
|
|
551
|
+
counter_(counter)
|
|
552
|
+
#endif
|
|
553
|
+
{
|
|
554
|
+
JSValueProtect(ctx_, obj_);
|
|
555
|
+
#ifndef NDEBUG
|
|
556
|
+
counter_ += 1;
|
|
557
|
+
#endif
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
void JSCRuntime::JSCObjectValue::invalidate() {
|
|
561
|
+
#ifndef NDEBUG
|
|
562
|
+
counter_ -= 1;
|
|
563
|
+
#endif
|
|
564
|
+
// When shutting down the VM, if there is a HostObject which
|
|
565
|
+
// contains or otherwise owns a jsi::Object, then the final GC will
|
|
566
|
+
// finalize the HostObject, leading to a call to invalidate(). But
|
|
567
|
+
// at that point, making calls to JSValueUnprotect will crash.
|
|
568
|
+
// It is up to the application to make sure that any other calls to
|
|
569
|
+
// invalidate() happen before VM destruction; see the comment on
|
|
570
|
+
// jsi::Runtime.
|
|
571
|
+
//
|
|
572
|
+
// Another potential concern here is that in the non-shutdown case,
|
|
573
|
+
// if a HostObject is GCd, JSValueUnprotect will be called from the
|
|
574
|
+
// JSC finalizer. The documentation warns against this: "You must
|
|
575
|
+
// not call any function that may cause a garbage collection or an
|
|
576
|
+
// allocation of a garbage collected object from within a
|
|
577
|
+
// JSObjectFinalizeCallback. This includes all functions that have a
|
|
578
|
+
// JSContextRef parameter." However, an audit of the source code for
|
|
579
|
+
// JSValueUnprotect in late 2018 shows that it cannot cause
|
|
580
|
+
// allocation or a GC, and further, this code has not changed in
|
|
581
|
+
// about two years. In the future, we may choose to reintroduce the
|
|
582
|
+
// mechanism previously used here which uses a separate thread for
|
|
583
|
+
// JSValueUnprotect, in order to conform to the documented API, but
|
|
584
|
+
// use the "unsafe" synchronous version on iOS 11 and earlier.
|
|
585
|
+
|
|
586
|
+
if (!ctxInvalid_) {
|
|
587
|
+
JSValueUnprotect(ctx_, obj_);
|
|
588
|
+
}
|
|
589
|
+
delete this;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
jsi::Runtime::PointerValue *JSCRuntime::cloneSymbol(
|
|
593
|
+
const jsi::Runtime::PointerValue *pv) {
|
|
594
|
+
if (!pv) {
|
|
595
|
+
return nullptr;
|
|
596
|
+
}
|
|
597
|
+
const JSCSymbolValue *symbol = static_cast<const JSCSymbolValue *>(pv);
|
|
598
|
+
return makeSymbolValue(symbol->sym_);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
jsi::Runtime::PointerValue *JSCRuntime::cloneString(
|
|
602
|
+
const jsi::Runtime::PointerValue *pv) {
|
|
603
|
+
if (!pv) {
|
|
604
|
+
return nullptr;
|
|
605
|
+
}
|
|
606
|
+
const JSCStringValue *string = static_cast<const JSCStringValue *>(pv);
|
|
607
|
+
return makeStringValue(string->str_);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
jsi::Runtime::PointerValue *JSCRuntime::cloneObject(
|
|
611
|
+
const jsi::Runtime::PointerValue *pv) {
|
|
612
|
+
if (!pv) {
|
|
613
|
+
return nullptr;
|
|
614
|
+
}
|
|
615
|
+
const JSCObjectValue *object = static_cast<const JSCObjectValue *>(pv);
|
|
616
|
+
assert(
|
|
617
|
+
object->ctx_ == ctx_ &&
|
|
618
|
+
"Don't try to clone an object backed by a different Runtime");
|
|
619
|
+
return makeObjectValue(object->obj_);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
jsi::Runtime::PointerValue *JSCRuntime::clonePropNameID(
|
|
623
|
+
const jsi::Runtime::PointerValue *pv) {
|
|
624
|
+
if (!pv) {
|
|
625
|
+
return nullptr;
|
|
626
|
+
}
|
|
627
|
+
const JSCStringValue *string = static_cast<const JSCStringValue *>(pv);
|
|
628
|
+
return makeStringValue(string->str_);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
jsi::PropNameID JSCRuntime::createPropNameIDFromAscii(
|
|
632
|
+
const char *str,
|
|
633
|
+
size_t length) {
|
|
634
|
+
// For system JSC this must is identical to a string
|
|
635
|
+
std::string tmp(str, length);
|
|
636
|
+
JSStringRef strRef = JSStringCreateWithUTF8CString(tmp.c_str());
|
|
637
|
+
auto res = createPropNameID(strRef);
|
|
638
|
+
JSStringRelease(strRef);
|
|
639
|
+
return res;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
jsi::PropNameID JSCRuntime::createPropNameIDFromUtf8(
|
|
643
|
+
const uint8_t *utf8,
|
|
644
|
+
size_t length) {
|
|
645
|
+
std::string tmp(reinterpret_cast<const char *>(utf8), length);
|
|
646
|
+
JSStringRef strRef = JSStringCreateWithUTF8CString(tmp.c_str());
|
|
647
|
+
auto res = createPropNameID(strRef);
|
|
648
|
+
JSStringRelease(strRef);
|
|
649
|
+
return res;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
jsi::PropNameID JSCRuntime::createPropNameIDFromString(const jsi::String &str) {
|
|
653
|
+
return createPropNameID(stringRef(str));
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
std::string JSCRuntime::utf8(const jsi::PropNameID &sym) {
|
|
657
|
+
return JSStringToSTLString(stringRef(sym));
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
bool JSCRuntime::compare(const jsi::PropNameID &a, const jsi::PropNameID &b) {
|
|
661
|
+
return JSStringIsEqual(stringRef(a), stringRef(b));
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
std::string JSCRuntime::symbolToString(const jsi::Symbol &sym) {
|
|
665
|
+
return jsi::Value(*this, sym).toString(*this).utf8(*this);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
jsi::String JSCRuntime::createStringFromAscii(const char *str, size_t length) {
|
|
669
|
+
// Yes we end up double casting for semantic reasons (UTF8 contains ASCII,
|
|
670
|
+
// not the other way around)
|
|
671
|
+
return this->createStringFromUtf8(
|
|
672
|
+
reinterpret_cast<const uint8_t *>(str), length);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
jsi::String JSCRuntime::createStringFromUtf8(
|
|
676
|
+
const uint8_t *str,
|
|
677
|
+
size_t length) {
|
|
678
|
+
std::string tmp(reinterpret_cast<const char *>(str), length);
|
|
679
|
+
JSStringRef stringRef = JSStringCreateWithUTF8CString(tmp.c_str());
|
|
680
|
+
auto result = createString(stringRef);
|
|
681
|
+
JSStringRelease(stringRef);
|
|
682
|
+
return result;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
std::string JSCRuntime::utf8(const jsi::String &str) {
|
|
686
|
+
return JSStringToSTLString(stringRef(str));
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
jsi::Object JSCRuntime::createObject() {
|
|
690
|
+
return createObject(static_cast<JSObjectRef>(nullptr));
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
// HostObject details
|
|
694
|
+
namespace detail {
|
|
695
|
+
struct HostObjectProxyBase {
|
|
696
|
+
HostObjectProxyBase(
|
|
697
|
+
JSCRuntime &rt,
|
|
698
|
+
const std::shared_ptr<jsi::HostObject> &sho)
|
|
699
|
+
: runtime(rt), hostObject(sho) {}
|
|
700
|
+
|
|
701
|
+
JSCRuntime &runtime;
|
|
702
|
+
std::shared_ptr<jsi::HostObject> hostObject;
|
|
703
|
+
};
|
|
704
|
+
} // namespace detail
|
|
705
|
+
|
|
706
|
+
namespace {
|
|
707
|
+
std::once_flag hostObjectClassOnceFlag;
|
|
708
|
+
JSClassRef hostObjectClass{};
|
|
709
|
+
} // namespace
|
|
710
|
+
|
|
711
|
+
jsi::Object JSCRuntime::createObject(std::shared_ptr<jsi::HostObject> ho) {
|
|
712
|
+
struct HostObjectProxy : public detail::HostObjectProxyBase {
|
|
713
|
+
static JSValueRef getProperty(
|
|
714
|
+
JSContextRef ctx,
|
|
715
|
+
JSObjectRef object,
|
|
716
|
+
JSStringRef propName,
|
|
717
|
+
JSValueRef *exception) {
|
|
718
|
+
auto proxy = static_cast<HostObjectProxy *>(JSObjectGetPrivate(object));
|
|
719
|
+
auto &rt = proxy->runtime;
|
|
720
|
+
jsi::PropNameID sym = rt.createPropNameID(propName);
|
|
721
|
+
jsi::Value ret;
|
|
722
|
+
try {
|
|
723
|
+
ret = proxy->hostObject->get(rt, sym);
|
|
724
|
+
} catch (const jsi::JSError &error) {
|
|
725
|
+
*exception = rt.valueRef(error.value());
|
|
726
|
+
return JSValueMakeUndefined(ctx);
|
|
727
|
+
} catch (const std::exception &ex) {
|
|
728
|
+
auto excValue =
|
|
729
|
+
rt.global()
|
|
730
|
+
.getPropertyAsFunction(rt, "Error")
|
|
731
|
+
.call(
|
|
732
|
+
rt,
|
|
733
|
+
std::string("Exception in HostObject::get(propName:") +
|
|
734
|
+
JSStringToSTLString(propName) + std::string("): ") +
|
|
735
|
+
ex.what());
|
|
736
|
+
*exception = rt.valueRef(excValue);
|
|
737
|
+
return JSValueMakeUndefined(ctx);
|
|
738
|
+
} catch (...) {
|
|
739
|
+
auto excValue =
|
|
740
|
+
rt.global()
|
|
741
|
+
.getPropertyAsFunction(rt, "Error")
|
|
742
|
+
.call(
|
|
743
|
+
rt,
|
|
744
|
+
std::string("Exception in HostObject::get(propName:") +
|
|
745
|
+
JSStringToSTLString(propName) +
|
|
746
|
+
std::string("): <unknown>"));
|
|
747
|
+
*exception = rt.valueRef(excValue);
|
|
748
|
+
return JSValueMakeUndefined(ctx);
|
|
749
|
+
}
|
|
750
|
+
return rt.valueRef(ret);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
#define JSC_UNUSED(x) (void)(x);
|
|
754
|
+
|
|
755
|
+
static bool setProperty(
|
|
756
|
+
JSContextRef ctx,
|
|
757
|
+
JSObjectRef object,
|
|
758
|
+
JSStringRef propName,
|
|
759
|
+
JSValueRef value,
|
|
760
|
+
JSValueRef *exception) {
|
|
761
|
+
JSC_UNUSED(ctx);
|
|
762
|
+
auto proxy = static_cast<HostObjectProxy *>(JSObjectGetPrivate(object));
|
|
763
|
+
auto &rt = proxy->runtime;
|
|
764
|
+
jsi::PropNameID sym = rt.createPropNameID(propName);
|
|
765
|
+
try {
|
|
766
|
+
proxy->hostObject->set(rt, sym, rt.createValue(value));
|
|
767
|
+
} catch (const jsi::JSError &error) {
|
|
768
|
+
*exception = rt.valueRef(error.value());
|
|
769
|
+
return false;
|
|
770
|
+
} catch (const std::exception &ex) {
|
|
771
|
+
auto excValue =
|
|
772
|
+
rt.global()
|
|
773
|
+
.getPropertyAsFunction(rt, "Error")
|
|
774
|
+
.call(
|
|
775
|
+
rt,
|
|
776
|
+
std::string("Exception in HostObject::set(propName:") +
|
|
777
|
+
JSStringToSTLString(propName) + std::string("): ") +
|
|
778
|
+
ex.what());
|
|
779
|
+
*exception = rt.valueRef(excValue);
|
|
780
|
+
return false;
|
|
781
|
+
} catch (...) {
|
|
782
|
+
auto excValue =
|
|
783
|
+
rt.global()
|
|
784
|
+
.getPropertyAsFunction(rt, "Error")
|
|
785
|
+
.call(
|
|
786
|
+
rt,
|
|
787
|
+
std::string("Exception in HostObject::set(propName:") +
|
|
788
|
+
JSStringToSTLString(propName) +
|
|
789
|
+
std::string("): <unknown>"));
|
|
790
|
+
*exception = rt.valueRef(excValue);
|
|
791
|
+
return false;
|
|
792
|
+
}
|
|
793
|
+
return true;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// JSC does not provide means to communicate errors from this callback,
|
|
797
|
+
// so the error handling strategy is very brutal - we'll just crash
|
|
798
|
+
// due to noexcept.
|
|
799
|
+
static void getPropertyNames(
|
|
800
|
+
JSContextRef ctx,
|
|
801
|
+
JSObjectRef object,
|
|
802
|
+
JSPropertyNameAccumulatorRef propertyNames) noexcept {
|
|
803
|
+
JSC_UNUSED(ctx);
|
|
804
|
+
auto proxy = static_cast<HostObjectProxy *>(JSObjectGetPrivate(object));
|
|
805
|
+
auto &rt = proxy->runtime;
|
|
806
|
+
auto names = proxy->hostObject->getPropertyNames(rt);
|
|
807
|
+
for (auto &name : names) {
|
|
808
|
+
JSPropertyNameAccumulatorAddName(propertyNames, stringRef(name));
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
#undef JSC_UNUSED
|
|
813
|
+
|
|
814
|
+
static void finalize(JSObjectRef obj) {
|
|
815
|
+
auto hostObject = static_cast<HostObjectProxy *>(JSObjectGetPrivate(obj));
|
|
816
|
+
JSObjectSetPrivate(obj, nullptr);
|
|
817
|
+
delete hostObject;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
using HostObjectProxyBase::HostObjectProxyBase;
|
|
821
|
+
};
|
|
822
|
+
|
|
823
|
+
std::call_once(hostObjectClassOnceFlag, []() {
|
|
824
|
+
JSClassDefinition hostObjectClassDef = kJSClassDefinitionEmpty;
|
|
825
|
+
hostObjectClassDef.version = 0;
|
|
826
|
+
hostObjectClassDef.attributes = kJSClassAttributeNoAutomaticPrototype;
|
|
827
|
+
hostObjectClassDef.finalize = HostObjectProxy::finalize;
|
|
828
|
+
hostObjectClassDef.getProperty = HostObjectProxy::getProperty;
|
|
829
|
+
hostObjectClassDef.setProperty = HostObjectProxy::setProperty;
|
|
830
|
+
hostObjectClassDef.getPropertyNames = HostObjectProxy::getPropertyNames;
|
|
831
|
+
hostObjectClass = JSClassCreate(&hostObjectClassDef);
|
|
832
|
+
});
|
|
833
|
+
|
|
834
|
+
JSObjectRef obj =
|
|
835
|
+
JSObjectMake(ctx_, hostObjectClass, new HostObjectProxy(*this, ho));
|
|
836
|
+
return createObject(obj);
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
std::shared_ptr<jsi::HostObject> JSCRuntime::getHostObject(
|
|
840
|
+
const jsi::Object &obj) {
|
|
841
|
+
// We are guaranteed at this point to have isHostObject(obj) == true
|
|
842
|
+
// so the private data should be HostObjectMetadata
|
|
843
|
+
JSObjectRef object = objectRef(obj);
|
|
844
|
+
auto metadata =
|
|
845
|
+
static_cast<detail::HostObjectProxyBase *>(JSObjectGetPrivate(object));
|
|
846
|
+
assert(metadata);
|
|
847
|
+
return metadata->hostObject;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
jsi::Value JSCRuntime::getProperty(
|
|
851
|
+
const jsi::Object &obj,
|
|
852
|
+
const jsi::String &name) {
|
|
853
|
+
JSObjectRef objRef = objectRef(obj);
|
|
854
|
+
JSValueRef exc = nullptr;
|
|
855
|
+
JSValueRef res = JSObjectGetProperty(ctx_, objRef, stringRef(name), &exc);
|
|
856
|
+
checkException(exc);
|
|
857
|
+
return createValue(res);
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
jsi::Value JSCRuntime::getProperty(
|
|
861
|
+
const jsi::Object &obj,
|
|
862
|
+
const jsi::PropNameID &name) {
|
|
863
|
+
JSObjectRef objRef = objectRef(obj);
|
|
864
|
+
JSValueRef exc = nullptr;
|
|
865
|
+
JSValueRef res = JSObjectGetProperty(ctx_, objRef, stringRef(name), &exc);
|
|
866
|
+
checkException(exc);
|
|
867
|
+
return createValue(res);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
bool JSCRuntime::hasProperty(const jsi::Object &obj, const jsi::String &name) {
|
|
871
|
+
JSObjectRef objRef = objectRef(obj);
|
|
872
|
+
return JSObjectHasProperty(ctx_, objRef, stringRef(name));
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
bool JSCRuntime::hasProperty(
|
|
876
|
+
const jsi::Object &obj,
|
|
877
|
+
const jsi::PropNameID &name) {
|
|
878
|
+
JSObjectRef objRef = objectRef(obj);
|
|
879
|
+
return JSObjectHasProperty(ctx_, objRef, stringRef(name));
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
void JSCRuntime::setPropertyValue(
|
|
883
|
+
jsi::Object &object,
|
|
884
|
+
const jsi::PropNameID &name,
|
|
885
|
+
const jsi::Value &value) {
|
|
886
|
+
JSValueRef exc = nullptr;
|
|
887
|
+
JSObjectSetProperty(
|
|
888
|
+
ctx_,
|
|
889
|
+
objectRef(object),
|
|
890
|
+
stringRef(name),
|
|
891
|
+
valueRef(value),
|
|
892
|
+
kJSPropertyAttributeNone,
|
|
893
|
+
&exc);
|
|
894
|
+
checkException(exc);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
void JSCRuntime::setPropertyValue(
|
|
898
|
+
jsi::Object &object,
|
|
899
|
+
const jsi::String &name,
|
|
900
|
+
const jsi::Value &value) {
|
|
901
|
+
JSValueRef exc = nullptr;
|
|
902
|
+
JSObjectSetProperty(
|
|
903
|
+
ctx_,
|
|
904
|
+
objectRef(object),
|
|
905
|
+
stringRef(name),
|
|
906
|
+
valueRef(value),
|
|
907
|
+
kJSPropertyAttributeNone,
|
|
908
|
+
&exc);
|
|
909
|
+
checkException(exc);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
bool JSCRuntime::isArray(const jsi::Object &obj) const {
|
|
913
|
+
#if !defined(_JSC_FAST_IS_ARRAY)
|
|
914
|
+
JSObjectRef global = JSContextGetGlobalObject(ctx_);
|
|
915
|
+
JSStringRef arrayString = getArrayString();
|
|
916
|
+
JSValueRef exc = nullptr;
|
|
917
|
+
JSValueRef arrayCtorValue =
|
|
918
|
+
JSObjectGetProperty(ctx_, global, arrayString, &exc);
|
|
919
|
+
JSC_ASSERT(exc);
|
|
920
|
+
JSObjectRef arrayCtor = JSValueToObject(ctx_, arrayCtorValue, &exc);
|
|
921
|
+
JSC_ASSERT(exc);
|
|
922
|
+
JSStringRef isArrayString = getIsArrayString();
|
|
923
|
+
JSValueRef isArrayValue =
|
|
924
|
+
JSObjectGetProperty(ctx_, arrayCtor, isArrayString, &exc);
|
|
925
|
+
JSC_ASSERT(exc);
|
|
926
|
+
JSObjectRef isArray = JSValueToObject(ctx_, isArrayValue, &exc);
|
|
927
|
+
JSC_ASSERT(exc);
|
|
928
|
+
JSValueRef arg = objectRef(obj);
|
|
929
|
+
JSValueRef result =
|
|
930
|
+
JSObjectCallAsFunction(ctx_, isArray, nullptr, 1, &arg, &exc);
|
|
931
|
+
JSC_ASSERT(exc);
|
|
932
|
+
return JSValueToBoolean(ctx_, result);
|
|
933
|
+
#else
|
|
934
|
+
return JSValueIsArray(ctx_, objectRef(obj));
|
|
935
|
+
#endif
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
bool JSCRuntime::isArrayBuffer(const jsi::Object &obj) const {
|
|
939
|
+
#if defined(_JSC_NO_ARRAY_BUFFERS)
|
|
940
|
+
throw std::runtime_error("Unsupported");
|
|
941
|
+
#else
|
|
942
|
+
auto typedArrayType = JSValueGetTypedArrayType(ctx_, objectRef(obj), nullptr);
|
|
943
|
+
return typedArrayType == kJSTypedArrayTypeArrayBuffer;
|
|
944
|
+
#endif
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
uint8_t *JSCRuntime::data(const jsi::ArrayBuffer &obj) {
|
|
948
|
+
#if defined(_JSC_NO_ARRAY_BUFFERS)
|
|
949
|
+
throw std::runtime_error("Unsupported");
|
|
950
|
+
#else
|
|
951
|
+
return static_cast<uint8_t *>(
|
|
952
|
+
JSObjectGetArrayBufferBytesPtr(ctx_, objectRef(obj), nullptr));
|
|
953
|
+
#endif
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
size_t JSCRuntime::size(const jsi::ArrayBuffer &obj) {
|
|
957
|
+
#if defined(_JSC_NO_ARRAY_BUFFERS)
|
|
958
|
+
throw std::runtime_error("Unsupported");
|
|
959
|
+
#else
|
|
960
|
+
return JSObjectGetArrayBufferByteLength(ctx_, objectRef(obj), nullptr);
|
|
961
|
+
#endif
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
bool JSCRuntime::isFunction(const jsi::Object &obj) const {
|
|
965
|
+
return JSObjectIsFunction(ctx_, objectRef(obj));
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
bool JSCRuntime::isHostObject(const jsi::Object &obj) const {
|
|
969
|
+
auto cls = hostObjectClass;
|
|
970
|
+
return cls != nullptr && JSValueIsObjectOfClass(ctx_, objectRef(obj), cls);
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
// Very expensive
|
|
974
|
+
jsi::Array JSCRuntime::getPropertyNames(const jsi::Object &obj) {
|
|
975
|
+
JSPropertyNameArrayRef names =
|
|
976
|
+
JSObjectCopyPropertyNames(ctx_, objectRef(obj));
|
|
977
|
+
size_t len = JSPropertyNameArrayGetCount(names);
|
|
978
|
+
// Would be better if we could create an array with explicit elements
|
|
979
|
+
auto result = createArray(len);
|
|
980
|
+
for (size_t i = 0; i < len; i++) {
|
|
981
|
+
JSStringRef str = JSPropertyNameArrayGetNameAtIndex(names, i);
|
|
982
|
+
result.setValueAtIndex(*this, i, createString(str));
|
|
983
|
+
}
|
|
984
|
+
JSPropertyNameArrayRelease(names);
|
|
985
|
+
return result;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
jsi::WeakObject JSCRuntime::createWeakObject(const jsi::Object &obj) {
|
|
989
|
+
#ifdef RN_FABRIC_ENABLED
|
|
990
|
+
// TODO: revisit this implementation
|
|
991
|
+
JSObjectRef objRef = objectRef(obj);
|
|
992
|
+
return make<jsi::WeakObject>(makeObjectValue(objRef));
|
|
993
|
+
#else
|
|
994
|
+
throw std::logic_error("Not implemented");
|
|
995
|
+
#endif
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
jsi::Value JSCRuntime::lockWeakObject(jsi::WeakObject &obj) {
|
|
999
|
+
#ifdef RN_FABRIC_ENABLED
|
|
1000
|
+
// TODO: revisit this implementation
|
|
1001
|
+
JSObjectRef objRef = objectRef(obj);
|
|
1002
|
+
return jsi::Value(createObject(objRef));
|
|
1003
|
+
#else
|
|
1004
|
+
throw std::logic_error("Not implemented");
|
|
1005
|
+
#endif
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
jsi::Array JSCRuntime::createArray(size_t length) {
|
|
1009
|
+
JSValueRef exc = nullptr;
|
|
1010
|
+
JSObjectRef obj = JSObjectMakeArray(ctx_, 0, nullptr, &exc);
|
|
1011
|
+
checkException(obj, exc);
|
|
1012
|
+
JSObjectSetProperty(
|
|
1013
|
+
ctx_,
|
|
1014
|
+
obj,
|
|
1015
|
+
getLengthString(),
|
|
1016
|
+
JSValueMakeNumber(ctx_, static_cast<double>(length)),
|
|
1017
|
+
0,
|
|
1018
|
+
&exc);
|
|
1019
|
+
checkException(exc);
|
|
1020
|
+
return createObject(obj).getArray(*this);
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
size_t JSCRuntime::size(const jsi::Array &arr) {
|
|
1024
|
+
return static_cast<size_t>(
|
|
1025
|
+
getProperty(arr, createPropNameID(getLengthString())).getNumber());
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
jsi::Value JSCRuntime::getValueAtIndex(const jsi::Array &arr, size_t i) {
|
|
1029
|
+
JSValueRef exc = nullptr;
|
|
1030
|
+
auto res = JSObjectGetPropertyAtIndex(ctx_, objectRef(arr), (int)i, &exc);
|
|
1031
|
+
checkException(exc);
|
|
1032
|
+
return createValue(res);
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
void JSCRuntime::setValueAtIndexImpl(
|
|
1036
|
+
jsi::Array &arr,
|
|
1037
|
+
size_t i,
|
|
1038
|
+
const jsi::Value &value) {
|
|
1039
|
+
JSValueRef exc = nullptr;
|
|
1040
|
+
JSObjectSetPropertyAtIndex(
|
|
1041
|
+
ctx_, objectRef(arr), (int)i, valueRef(value), &exc);
|
|
1042
|
+
checkException(exc);
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
namespace {
|
|
1046
|
+
std::once_flag hostFunctionClassOnceFlag;
|
|
1047
|
+
JSClassRef hostFunctionClass{};
|
|
1048
|
+
|
|
1049
|
+
class HostFunctionProxy {
|
|
1050
|
+
public:
|
|
1051
|
+
HostFunctionProxy(jsi::HostFunctionType hostFunction)
|
|
1052
|
+
: hostFunction_(hostFunction) {}
|
|
1053
|
+
|
|
1054
|
+
jsi::HostFunctionType &getHostFunction() {
|
|
1055
|
+
return hostFunction_;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
protected:
|
|
1059
|
+
jsi::HostFunctionType hostFunction_;
|
|
1060
|
+
};
|
|
1061
|
+
} // namespace
|
|
1062
|
+
|
|
1063
|
+
jsi::Function JSCRuntime::createFunctionFromHostFunction(
|
|
1064
|
+
const jsi::PropNameID &name,
|
|
1065
|
+
unsigned int paramCount,
|
|
1066
|
+
jsi::HostFunctionType func) {
|
|
1067
|
+
class HostFunctionMetadata : public HostFunctionProxy {
|
|
1068
|
+
public:
|
|
1069
|
+
static void initialize(JSContextRef ctx, JSObjectRef object) {
|
|
1070
|
+
// We need to set up the prototype chain properly here. In theory we
|
|
1071
|
+
// could set func.prototype.prototype = Function.prototype to get the
|
|
1072
|
+
// same result. Not sure which approach is better.
|
|
1073
|
+
HostFunctionMetadata *metadata =
|
|
1074
|
+
static_cast<HostFunctionMetadata *>(JSObjectGetPrivate(object));
|
|
1075
|
+
|
|
1076
|
+
JSValueRef exc = nullptr;
|
|
1077
|
+
JSObjectSetProperty(
|
|
1078
|
+
ctx,
|
|
1079
|
+
object,
|
|
1080
|
+
getLengthString(),
|
|
1081
|
+
JSValueMakeNumber(ctx, metadata->argCount),
|
|
1082
|
+
kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum |
|
|
1083
|
+
kJSPropertyAttributeDontDelete,
|
|
1084
|
+
&exc);
|
|
1085
|
+
if (exc) {
|
|
1086
|
+
// Silently fail to set length
|
|
1087
|
+
exc = nullptr;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
JSStringRef name = nullptr;
|
|
1091
|
+
std::swap(metadata->name, name);
|
|
1092
|
+
JSObjectSetProperty(
|
|
1093
|
+
ctx,
|
|
1094
|
+
object,
|
|
1095
|
+
getNameString(),
|
|
1096
|
+
JSValueMakeString(ctx, name),
|
|
1097
|
+
kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum |
|
|
1098
|
+
kJSPropertyAttributeDontDelete,
|
|
1099
|
+
&exc);
|
|
1100
|
+
JSStringRelease(name);
|
|
1101
|
+
if (exc) {
|
|
1102
|
+
// Silently fail to set name
|
|
1103
|
+
exc = nullptr;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
JSObjectRef global = JSContextGetGlobalObject(ctx);
|
|
1107
|
+
JSValueRef value =
|
|
1108
|
+
JSObjectGetProperty(ctx, global, getFunctionString(), &exc);
|
|
1109
|
+
// If we don't have Function then something bad is going on.
|
|
1110
|
+
if (JSC_UNLIKELY(exc)) {
|
|
1111
|
+
abort();
|
|
1112
|
+
}
|
|
1113
|
+
JSObjectRef funcCtor = JSValueToObject(ctx, value, &exc);
|
|
1114
|
+
if (!funcCtor) {
|
|
1115
|
+
// We can't do anything if Function is not an object
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1118
|
+
JSValueRef funcProto = JSObjectGetPrototype(ctx, funcCtor);
|
|
1119
|
+
JSObjectSetPrototype(ctx, object, funcProto);
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
static JSValueRef makeError(JSCRuntime &rt, const std::string &desc) {
|
|
1123
|
+
jsi::Value value =
|
|
1124
|
+
rt.global().getPropertyAsFunction(rt, "Error").call(rt, desc);
|
|
1125
|
+
return rt.valueRef(value);
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
static JSValueRef call(
|
|
1129
|
+
JSContextRef ctx,
|
|
1130
|
+
JSObjectRef function,
|
|
1131
|
+
JSObjectRef thisObject,
|
|
1132
|
+
size_t argumentCount,
|
|
1133
|
+
const JSValueRef arguments[],
|
|
1134
|
+
JSValueRef *exception) {
|
|
1135
|
+
HostFunctionMetadata *metadata =
|
|
1136
|
+
static_cast<HostFunctionMetadata *>(JSObjectGetPrivate(function));
|
|
1137
|
+
JSCRuntime &rt = *(metadata->runtime);
|
|
1138
|
+
const unsigned maxStackArgCount = 8;
|
|
1139
|
+
jsi::Value stackArgs[maxStackArgCount];
|
|
1140
|
+
std::unique_ptr<jsi::Value[]> heapArgs;
|
|
1141
|
+
jsi::Value *args;
|
|
1142
|
+
if (argumentCount > maxStackArgCount) {
|
|
1143
|
+
heapArgs = std::make_unique<jsi::Value[]>(argumentCount);
|
|
1144
|
+
for (size_t i = 0; i < argumentCount; i++) {
|
|
1145
|
+
heapArgs[i] = rt.createValue(arguments[i]);
|
|
1146
|
+
}
|
|
1147
|
+
args = heapArgs.get();
|
|
1148
|
+
} else {
|
|
1149
|
+
for (size_t i = 0; i < argumentCount; i++) {
|
|
1150
|
+
stackArgs[i] = rt.createValue(arguments[i]);
|
|
1151
|
+
}
|
|
1152
|
+
args = stackArgs;
|
|
1153
|
+
}
|
|
1154
|
+
JSValueRef res;
|
|
1155
|
+
jsi::Value thisVal(rt.createObject(thisObject));
|
|
1156
|
+
try {
|
|
1157
|
+
res = rt.valueRef(
|
|
1158
|
+
metadata->hostFunction_(rt, thisVal, args, argumentCount));
|
|
1159
|
+
} catch (const jsi::JSError &error) {
|
|
1160
|
+
*exception = rt.valueRef(error.value());
|
|
1161
|
+
res = JSValueMakeUndefined(ctx);
|
|
1162
|
+
} catch (const std::exception &ex) {
|
|
1163
|
+
std::string exceptionString("Exception in HostFunction: ");
|
|
1164
|
+
exceptionString += ex.what();
|
|
1165
|
+
*exception = makeError(rt, exceptionString);
|
|
1166
|
+
res = JSValueMakeUndefined(ctx);
|
|
1167
|
+
} catch (...) {
|
|
1168
|
+
std::string exceptionString("Exception in HostFunction: <unknown>");
|
|
1169
|
+
*exception = makeError(rt, exceptionString);
|
|
1170
|
+
res = JSValueMakeUndefined(ctx);
|
|
1171
|
+
}
|
|
1172
|
+
return res;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
static void finalize(JSObjectRef object) {
|
|
1176
|
+
HostFunctionMetadata *metadata =
|
|
1177
|
+
static_cast<HostFunctionMetadata *>(JSObjectGetPrivate(object));
|
|
1178
|
+
JSObjectSetPrivate(object, nullptr);
|
|
1179
|
+
delete metadata;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
HostFunctionMetadata(
|
|
1183
|
+
JSCRuntime *rt,
|
|
1184
|
+
jsi::HostFunctionType hf,
|
|
1185
|
+
unsigned ac,
|
|
1186
|
+
JSStringRef n)
|
|
1187
|
+
: HostFunctionProxy(hf),
|
|
1188
|
+
runtime(rt),
|
|
1189
|
+
argCount(ac),
|
|
1190
|
+
name(JSStringRetain(n)) {}
|
|
1191
|
+
|
|
1192
|
+
JSCRuntime *runtime;
|
|
1193
|
+
unsigned argCount;
|
|
1194
|
+
JSStringRef name;
|
|
1195
|
+
};
|
|
1196
|
+
|
|
1197
|
+
std::call_once(hostFunctionClassOnceFlag, []() {
|
|
1198
|
+
JSClassDefinition functionClass = kJSClassDefinitionEmpty;
|
|
1199
|
+
functionClass.version = 0;
|
|
1200
|
+
functionClass.attributes = kJSClassAttributeNoAutomaticPrototype;
|
|
1201
|
+
functionClass.initialize = HostFunctionMetadata::initialize;
|
|
1202
|
+
functionClass.finalize = HostFunctionMetadata::finalize;
|
|
1203
|
+
functionClass.callAsFunction = HostFunctionMetadata::call;
|
|
1204
|
+
|
|
1205
|
+
hostFunctionClass = JSClassCreate(&functionClass);
|
|
1206
|
+
});
|
|
1207
|
+
|
|
1208
|
+
JSObjectRef funcRef = JSObjectMake(
|
|
1209
|
+
ctx_,
|
|
1210
|
+
hostFunctionClass,
|
|
1211
|
+
new HostFunctionMetadata(this, func, paramCount, stringRef(name)));
|
|
1212
|
+
return createObject(funcRef).getFunction(*this);
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
namespace detail {
|
|
1216
|
+
|
|
1217
|
+
class ArgsConverter {
|
|
1218
|
+
public:
|
|
1219
|
+
ArgsConverter(JSCRuntime &rt, const jsi::Value *args, size_t count) {
|
|
1220
|
+
JSValueRef *destination = inline_;
|
|
1221
|
+
if (count > maxStackArgs) {
|
|
1222
|
+
outOfLine_ = std::make_unique<JSValueRef[]>(count);
|
|
1223
|
+
destination = outOfLine_.get();
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
for (size_t i = 0; i < count; ++i) {
|
|
1227
|
+
destination[i] = rt.valueRef(args[i]);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
operator JSValueRef *() {
|
|
1232
|
+
return outOfLine_ ? outOfLine_.get() : inline_;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
private:
|
|
1236
|
+
constexpr static unsigned maxStackArgs = 8;
|
|
1237
|
+
JSValueRef inline_[maxStackArgs];
|
|
1238
|
+
std::unique_ptr<JSValueRef[]> outOfLine_;
|
|
1239
|
+
};
|
|
1240
|
+
} // namespace detail
|
|
1241
|
+
|
|
1242
|
+
bool JSCRuntime::isHostFunction(const jsi::Function &obj) const {
|
|
1243
|
+
auto cls = hostFunctionClass;
|
|
1244
|
+
return cls != nullptr && JSValueIsObjectOfClass(ctx_, objectRef(obj), cls);
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
jsi::HostFunctionType &JSCRuntime::getHostFunction(const jsi::Function &obj) {
|
|
1248
|
+
// We know that isHostFunction(obj) is true here, so its safe to proceed
|
|
1249
|
+
auto proxy =
|
|
1250
|
+
static_cast<HostFunctionProxy *>(JSObjectGetPrivate(objectRef(obj)));
|
|
1251
|
+
return proxy->getHostFunction();
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
jsi::Value JSCRuntime::call(
|
|
1255
|
+
const jsi::Function &f,
|
|
1256
|
+
const jsi::Value &jsThis,
|
|
1257
|
+
const jsi::Value *args,
|
|
1258
|
+
size_t count) {
|
|
1259
|
+
JSValueRef exc = nullptr;
|
|
1260
|
+
auto res = JSObjectCallAsFunction(
|
|
1261
|
+
ctx_,
|
|
1262
|
+
objectRef(f),
|
|
1263
|
+
jsThis.isUndefined() ? nullptr : objectRef(jsThis.getObject(*this)),
|
|
1264
|
+
count,
|
|
1265
|
+
detail::ArgsConverter(*this, args, count),
|
|
1266
|
+
&exc);
|
|
1267
|
+
checkException(exc);
|
|
1268
|
+
return createValue(res);
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
jsi::Value JSCRuntime::callAsConstructor(
|
|
1272
|
+
const jsi::Function &f,
|
|
1273
|
+
const jsi::Value *args,
|
|
1274
|
+
size_t count) {
|
|
1275
|
+
JSValueRef exc = nullptr;
|
|
1276
|
+
auto res = JSObjectCallAsConstructor(
|
|
1277
|
+
ctx_,
|
|
1278
|
+
objectRef(f),
|
|
1279
|
+
count,
|
|
1280
|
+
detail::ArgsConverter(*this, args, count),
|
|
1281
|
+
&exc);
|
|
1282
|
+
checkException(exc);
|
|
1283
|
+
return createValue(res);
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
bool JSCRuntime::strictEquals(const jsi::Symbol &a, const jsi::Symbol &b)
|
|
1287
|
+
const {
|
|
1288
|
+
JSValueRef exc = nullptr;
|
|
1289
|
+
bool ret = JSValueIsEqual(ctx_, symbolRef(a), symbolRef(b), &exc);
|
|
1290
|
+
const_cast<JSCRuntime *>(this)->checkException(exc);
|
|
1291
|
+
return ret;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
bool JSCRuntime::strictEquals(const jsi::String &a, const jsi::String &b)
|
|
1295
|
+
const {
|
|
1296
|
+
return JSStringIsEqual(stringRef(a), stringRef(b));
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
bool JSCRuntime::strictEquals(const jsi::Object &a, const jsi::Object &b)
|
|
1300
|
+
const {
|
|
1301
|
+
return objectRef(a) == objectRef(b);
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
bool JSCRuntime::instanceOf(const jsi::Object &o, const jsi::Function &f) {
|
|
1305
|
+
JSValueRef exc = nullptr;
|
|
1306
|
+
bool res =
|
|
1307
|
+
JSValueIsInstanceOfConstructor(ctx_, objectRef(o), objectRef(f), &exc);
|
|
1308
|
+
checkException(exc);
|
|
1309
|
+
return res;
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
jsi::Runtime::PointerValue *JSCRuntime::makeSymbolValue(
|
|
1313
|
+
JSValueRef symbolRef) const {
|
|
1314
|
+
#ifndef NDEBUG
|
|
1315
|
+
return new JSCSymbolValue(ctx_, ctxInvalid_, symbolRef, symbolCounter_);
|
|
1316
|
+
#else
|
|
1317
|
+
return new JSCSymbolValue(ctx_, ctxInvalid_, symbolRef);
|
|
1318
|
+
#endif
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
namespace {
|
|
1322
|
+
JSStringRef getEmptyString() {
|
|
1323
|
+
static JSStringRef empty = JSStringCreateWithUTF8CString("");
|
|
1324
|
+
return empty;
|
|
1325
|
+
}
|
|
1326
|
+
} // namespace
|
|
1327
|
+
|
|
1328
|
+
jsi::Runtime::PointerValue *JSCRuntime::makeStringValue(
|
|
1329
|
+
JSStringRef stringRef) const {
|
|
1330
|
+
if (!stringRef) {
|
|
1331
|
+
stringRef = getEmptyString();
|
|
1332
|
+
}
|
|
1333
|
+
#ifndef NDEBUG
|
|
1334
|
+
return new JSCStringValue(stringRef, stringCounter_);
|
|
1335
|
+
#else
|
|
1336
|
+
return new JSCStringValue(stringRef);
|
|
1337
|
+
#endif
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
jsi::Symbol JSCRuntime::createSymbol(JSValueRef sym) const {
|
|
1341
|
+
return make<jsi::Symbol>(makeSymbolValue(sym));
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
jsi::String JSCRuntime::createString(JSStringRef str) const {
|
|
1345
|
+
return make<jsi::String>(makeStringValue(str));
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
jsi::PropNameID JSCRuntime::createPropNameID(JSStringRef str) {
|
|
1349
|
+
return make<jsi::PropNameID>(makeStringValue(str));
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
jsi::Runtime::PointerValue *JSCRuntime::makeObjectValue(
|
|
1353
|
+
JSObjectRef objectRef) const {
|
|
1354
|
+
if (!objectRef) {
|
|
1355
|
+
objectRef = JSObjectMake(ctx_, nullptr, nullptr);
|
|
1356
|
+
}
|
|
1357
|
+
#ifndef NDEBUG
|
|
1358
|
+
return new JSCObjectValue(ctx_, ctxInvalid_, objectRef, objectCounter_);
|
|
1359
|
+
#else
|
|
1360
|
+
return new JSCObjectValue(ctx_, ctxInvalid_, objectRef);
|
|
1361
|
+
#endif
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
jsi::Object JSCRuntime::createObject(JSObjectRef obj) const {
|
|
1365
|
+
return make<jsi::Object>(makeObjectValue(obj));
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
jsi::Value JSCRuntime::createValue(JSValueRef value) const {
|
|
1369
|
+
JSType type = JSValueGetType(ctx_, value);
|
|
1370
|
+
|
|
1371
|
+
switch (type) {
|
|
1372
|
+
case kJSTypeNumber:
|
|
1373
|
+
return jsi::Value(JSValueToNumber(ctx_, value, nullptr));
|
|
1374
|
+
case kJSTypeBoolean:
|
|
1375
|
+
return jsi::Value(JSValueToBoolean(ctx_, value));
|
|
1376
|
+
case kJSTypeNull:
|
|
1377
|
+
return jsi::Value(nullptr);
|
|
1378
|
+
case kJSTypeUndefined:
|
|
1379
|
+
return jsi::Value();
|
|
1380
|
+
case kJSTypeString: {
|
|
1381
|
+
JSStringRef str = JSValueToStringCopy(ctx_, value, nullptr);
|
|
1382
|
+
auto result = jsi::Value(createString(str));
|
|
1383
|
+
JSStringRelease(str);
|
|
1384
|
+
return result;
|
|
1385
|
+
}
|
|
1386
|
+
case kJSTypeObject: {
|
|
1387
|
+
JSObjectRef objRef = JSValueToObject(ctx_, value, nullptr);
|
|
1388
|
+
return jsi::Value(createObject(objRef));
|
|
1389
|
+
}
|
|
1390
|
+
// TODO: Uncomment this when all supported JSC versions have this symbol
|
|
1391
|
+
// case kJSTypeSymbol:
|
|
1392
|
+
default: {
|
|
1393
|
+
if (smellsLikeES6Symbol(ctx_, value)) {
|
|
1394
|
+
return jsi::Value(createSymbol(value));
|
|
1395
|
+
} else {
|
|
1396
|
+
// WHAT ARE YOU
|
|
1397
|
+
abort();
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
JSValueRef JSCRuntime::valueRef(const jsi::Value &value) {
|
|
1404
|
+
// I would rather switch on value.kind_
|
|
1405
|
+
if (value.isUndefined()) {
|
|
1406
|
+
return JSValueMakeUndefined(ctx_);
|
|
1407
|
+
} else if (value.isNull()) {
|
|
1408
|
+
return JSValueMakeNull(ctx_);
|
|
1409
|
+
} else if (value.isBool()) {
|
|
1410
|
+
return JSValueMakeBoolean(ctx_, value.getBool());
|
|
1411
|
+
} else if (value.isNumber()) {
|
|
1412
|
+
return JSValueMakeNumber(ctx_, value.getNumber());
|
|
1413
|
+
} else if (value.isSymbol()) {
|
|
1414
|
+
return symbolRef(value.getSymbol(*this));
|
|
1415
|
+
} else if (value.isString()) {
|
|
1416
|
+
return JSValueMakeString(ctx_, stringRef(value.getString(*this)));
|
|
1417
|
+
} else if (value.isObject()) {
|
|
1418
|
+
return objectRef(value.getObject(*this));
|
|
1419
|
+
} else {
|
|
1420
|
+
// What are you?
|
|
1421
|
+
abort();
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
JSValueRef JSCRuntime::symbolRef(const jsi::Symbol &sym) {
|
|
1426
|
+
return static_cast<const JSCSymbolValue *>(getPointerValue(sym))->sym_;
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
JSStringRef JSCRuntime::stringRef(const jsi::String &str) {
|
|
1430
|
+
return static_cast<const JSCStringValue *>(getPointerValue(str))->str_;
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
JSStringRef JSCRuntime::stringRef(const jsi::PropNameID &sym) {
|
|
1434
|
+
return static_cast<const JSCStringValue *>(getPointerValue(sym))->str_;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
JSObjectRef JSCRuntime::objectRef(const jsi::Object &obj) {
|
|
1438
|
+
return static_cast<const JSCObjectValue *>(getPointerValue(obj))->obj_;
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
#ifdef RN_FABRIC_ENABLED
|
|
1442
|
+
JSObjectRef JSCRuntime::objectRef(const jsi::WeakObject &obj) {
|
|
1443
|
+
// TODO: revisit this implementation
|
|
1444
|
+
return static_cast<const JSCObjectValue *>(getPointerValue(obj))->obj_;
|
|
1445
|
+
}
|
|
1446
|
+
#endif
|
|
1447
|
+
|
|
1448
|
+
void JSCRuntime::checkException(JSValueRef exc) {
|
|
1449
|
+
if (JSC_UNLIKELY(exc)) {
|
|
1450
|
+
throw jsi::JSError(*this, createValue(exc));
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
void JSCRuntime::checkException(JSValueRef res, JSValueRef exc) {
|
|
1455
|
+
if (JSC_UNLIKELY(!res)) {
|
|
1456
|
+
throw jsi::JSError(*this, createValue(exc));
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
void JSCRuntime::checkException(JSValueRef exc, const char *msg) {
|
|
1461
|
+
if (JSC_UNLIKELY(exc)) {
|
|
1462
|
+
throw jsi::JSError(std::string(msg), *this, createValue(exc));
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
void JSCRuntime::checkException(
|
|
1467
|
+
JSValueRef res,
|
|
1468
|
+
JSValueRef exc,
|
|
1469
|
+
const char *msg) {
|
|
1470
|
+
if (JSC_UNLIKELY(!res)) {
|
|
1471
|
+
throw jsi::JSError(std::string(msg), *this, createValue(exc));
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
std::unique_ptr<jsi::Runtime> makeJSCRuntime() {
|
|
1476
|
+
return std::make_unique<JSCRuntime>();
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
} // namespace jsc
|
|
1480
|
+
} // namespace facebook
|