react-native-windows 0.68.3 → 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.
Files changed (378) hide show
  1. package/.flowconfig +1 -3
  2. package/Chakra/ChakraHelpers.cpp +0 -1
  3. package/Directory.Build.props +3 -0
  4. package/Directory.Build.targets +1 -1
  5. package/Folly/TEMP_UntilFollyUpdate/dynamic-inl.h +1411 -0
  6. package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.cpp +336 -0
  7. package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h +182 -0
  8. package/Libraries/ActionSheetIOS/ActionSheetIOS.js +7 -0
  9. package/Libraries/ActionSheetIOS/NativeActionSheetManager.js +1 -0
  10. package/Libraries/Alert/Alert.windows.js +2 -2
  11. package/Libraries/Animated/AnimatedImplementation.js +1 -1
  12. package/Libraries/Animated/NativeAnimatedHelper.js +55 -9
  13. package/Libraries/Animated/NativeAnimatedModule.js +1 -0
  14. package/Libraries/Animated/NativeAnimatedTurboModule.js +1 -0
  15. package/Libraries/Animated/animations/TimingAnimation.js +6 -11
  16. package/Libraries/Animated/createAnimatedComponent.js +2 -2
  17. package/Libraries/Animated/nodes/AnimatedColor.js +95 -29
  18. package/Libraries/Animated/nodes/AnimatedInterpolation.js +19 -22
  19. package/Libraries/Animated/nodes/AnimatedNode.js +2 -2
  20. package/Libraries/Animated/nodes/AnimatedValue.js +1 -1
  21. package/Libraries/AppState/AppState.js +1 -1
  22. package/Libraries/Blob/URL.js +7 -1
  23. package/Libraries/Components/Button.js +3 -0
  24. package/Libraries/Components/Button.windows.js +4 -0
  25. package/Libraries/Components/DatePickerAndroid/NativeDatePickerAndroid.js +5 -0
  26. package/Libraries/Components/Pressable/Pressable.js +3 -3
  27. package/Libraries/Components/Pressable/Pressable.windows.js +3 -3
  28. package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +47 -38
  29. package/Libraries/Components/ScrollView/ScrollContentViewNativeComponent.js +15 -7
  30. package/Libraries/Components/ScrollView/ScrollView.js +1 -1
  31. package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +16 -3
  32. package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +3 -1
  33. package/Libraries/Components/Slider/Slider.js +0 -2
  34. package/Libraries/Components/Slider/SliderNativeComponent.js +0 -1
  35. package/Libraries/Components/StatusBar/StatusBar.js +6 -1
  36. package/Libraries/Components/Switch/Switch.js +11 -1
  37. package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +114 -109
  38. package/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js +17 -9
  39. package/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js +13 -5
  40. package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +10 -0
  41. package/Libraries/Components/TextInput/TextInput.js +1 -8
  42. package/Libraries/Components/TextInput/TextInput.windows.js +4 -9
  43. package/Libraries/Components/TextInput/TextInputState.js +10 -2
  44. package/Libraries/Components/TextInput/TextInputState.windows.js +10 -3
  45. package/Libraries/Components/TextInput/WindowsTextInputNativeComponent.js +1 -1
  46. package/Libraries/Components/Touchable/TouchableBounce.js +1 -0
  47. package/Libraries/Components/Touchable/TouchableHighlight.js +1 -0
  48. package/Libraries/Components/Touchable/TouchableHighlight.windows.js +6 -5
  49. package/Libraries/Components/Touchable/TouchableNativeFeedback.js +1 -0
  50. package/Libraries/Components/Touchable/TouchableOpacity.js +7 -1
  51. package/Libraries/Components/Touchable/TouchableOpacity.windows.js +11 -5
  52. package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +2 -0
  53. package/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +2 -0
  54. package/Libraries/Components/View/ReactNativeViewAttributes.js +1 -0
  55. package/Libraries/Components/View/ReactNativeViewAttributes.windows.js +1 -0
  56. package/Libraries/Components/View/View.windows.js +33 -1
  57. package/Libraries/Components/View/ViewNativeComponent.js +68 -8
  58. package/Libraries/Components/View/ViewPropTypes.js +36 -4
  59. package/Libraries/Components/View/ViewPropTypes.windows.js +36 -4
  60. package/Libraries/Core/Devtools/parseHermesStack.js +1 -1
  61. package/Libraries/Core/ExceptionsManager.js +1 -1
  62. package/Libraries/Core/RawEventEmitter.js +38 -0
  63. package/Libraries/Core/ReactNativeVersion.js +2 -2
  64. package/Libraries/Core/polyfillPromise.js +32 -0
  65. package/Libraries/Core/setUpReactDevTools.js +3 -2
  66. package/Libraries/EventEmitter/NativeEventEmitter.js +3 -3
  67. package/Libraries/EventEmitter/RCTDeviceEventEmitter.js +2 -1
  68. package/Libraries/EventEmitter/__mocks__/NativeEventEmitter.js +3 -3
  69. package/Libraries/Events/CustomEvent.js +32 -0
  70. package/Libraries/Events/EventPolyfill.js +239 -0
  71. package/Libraries/Image/Image.android.js +0 -6
  72. package/Libraries/Image/Image.ios.js +0 -6
  73. package/Libraries/Image/Image.windows.js +2 -8
  74. package/Libraries/Image/ImageViewNativeComponent.js +18 -3
  75. package/Libraries/Image/TextInlineImageNativeComponent.js +23 -15
  76. package/Libraries/Inspector/Inspector.js +2 -4
  77. package/Libraries/Interaction/BridgeSpyStallHandler.js +4 -3
  78. package/Libraries/Interaction/InteractionManager.js +1 -12
  79. package/Libraries/Interaction/TaskQueue.js +5 -4
  80. package/Libraries/LayoutAnimation/LayoutAnimation.js +13 -0
  81. package/Libraries/Linking/Linking.js +1 -1
  82. package/Libraries/Lists/FlatList.js +27 -6
  83. package/Libraries/Lists/VirtualizedList.js +71 -55
  84. package/Libraries/Lists/VirtualizedListContext.js +7 -3
  85. package/Libraries/Lists/VirtualizedSectionList.js +2 -2
  86. package/Libraries/Lists/__tests__/{FillRateHelper-test.windows.js → FillRateHelper-test.js} +2 -2
  87. package/Libraries/Lists/__tests__/{FlatList-test.windows.js → FlatList-test.js} +2 -2
  88. package/Libraries/Lists/__tests__/{SectionList-test.windows.js → SectionList-test.js} +14 -14
  89. package/Libraries/Lists/__tests__/{VirtualizeUtils-test.windows.js → VirtualizeUtils-test.js} +3 -3
  90. package/Libraries/Lists/__tests__/{VirtualizedList-test.windows.js → VirtualizedList-test.js} +91 -42
  91. package/Libraries/Lists/__tests__/{VirtualizedSectionList-test.windows.js → VirtualizedSectionList-test.js} +13 -13
  92. package/Libraries/LogBox/Data/LogBoxData.js +2 -2
  93. package/Libraries/LogBox/Data/LogBoxLog.js +1 -1
  94. package/Libraries/LogBox/Data/LogBoxSymbolication.js +1 -1
  95. package/Libraries/LogBox/Data/parseLogBoxLog.js +1 -1
  96. package/Libraries/LogBox/LogBox.js +2 -21
  97. package/Libraries/LogBox/UI/LogBoxInspectorFooter.js +1 -0
  98. package/Libraries/LogBox/UI/LogBoxInspectorHeader.js +2 -1
  99. package/Libraries/NativeComponent/BaseViewConfig.android.js +295 -0
  100. package/Libraries/NativeComponent/BaseViewConfig.ios.js +333 -0
  101. package/Libraries/NativeComponent/BaseViewConfig.windows.js +334 -0
  102. package/Libraries/NativeComponent/NativeComponentRegistry.js +0 -2
  103. package/Libraries/NativeComponent/PlatformBaseViewConfig.js +24 -0
  104. package/Libraries/NativeComponent/StaticViewConfigValidator.js +7 -42
  105. package/Libraries/NativeComponent/ViewConfig.js +4 -4
  106. package/Libraries/NativeComponent/ViewConfigIgnore.js +54 -0
  107. package/Libraries/Network/FormData.js +7 -1
  108. package/Libraries/Pressability/Pressability.js +115 -46
  109. package/Libraries/Pressability/Pressability.windows.js +190 -74
  110. package/Libraries/Pressability/PressabilityDebug.js +5 -9
  111. package/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js +1 -0
  112. package/Libraries/ReactNative/AppContainer.js +1 -1
  113. package/Libraries/ReactNative/{DummyUIManager.js → BridgelessUIManager.js} +62 -40
  114. package/Libraries/ReactNative/PaperUIManager.windows.js +5 -5
  115. package/Libraries/ReactNative/ReactNativeFeatureFlags.js +39 -0
  116. package/Libraries/ReactNative/UIManager.js +2 -3
  117. package/Libraries/ReactNative/renderApplication.js +4 -0
  118. package/Libraries/ReactPrivate/ReactNativePrivateInterface.js +8 -0
  119. package/Libraries/Renderer/implementations/ReactFabric-dev.js +5908 -4906
  120. package/Libraries/Renderer/implementations/ReactFabric-prod.js +2100 -1918
  121. package/Libraries/Renderer/implementations/ReactFabric-profiling.js +2567 -2352
  122. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +5610 -4844
  123. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +1710 -1556
  124. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +1830 -1639
  125. package/Libraries/Renderer/shims/ReactNativeTypes.js +2 -1
  126. package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +2 -1
  127. package/Libraries/StyleSheet/EdgeInsetsPropType.js +4 -1
  128. package/Libraries/StyleSheet/StyleSheetTypes.js +59 -66
  129. package/Libraries/StyleSheet/normalizeColor.js +1 -1
  130. package/Libraries/StyleSheet/private/_StyleSheetTypesOverrides.js +15 -0
  131. package/Libraries/StyleSheet/private/_TransformStyle.js +53 -0
  132. package/Libraries/StyleSheet/processTransform.windows.js +272 -0
  133. package/Libraries/Text/Text.js +13 -7
  134. package/Libraries/Text/Text.windows.js +16 -7
  135. package/Libraries/Text/TextNativeComponent.js +2 -0
  136. package/Libraries/Text/TextProps.js +10 -0
  137. package/Libraries/Types/CoreEventTypes.js +13 -1
  138. package/Libraries/Types/CoreEventTypes.windows.js +26 -1
  139. package/Libraries/Utilities/Appearance.js +0 -8
  140. package/Libraries/Utilities/HMRClient.js +1 -1
  141. package/Libraries/Utilities/ReactNativeTestTools.js +1 -0
  142. package/Libraries/Utilities/codegenNativeComponent.js +17 -6
  143. package/Libraries/Utilities/stringifySafe.js +4 -1
  144. package/Libraries/Utilities/verifyComponentAttributeEquivalence.js +3 -3
  145. package/Libraries/WebSocket/WebSocket.js +1 -1
  146. package/Libraries/vendor/emitter/_EmitterSubscription.js +1 -1
  147. package/Libraries/vendor/emitter/_EventEmitter.js +1 -1
  148. package/Libraries/vendor/emitter/_EventSubscription.js +1 -1
  149. package/Microsoft.ReactNative/DynamicReader.cpp +3 -3
  150. package/Microsoft.ReactNative/Fabric/ComponentView.h +1 -0
  151. package/Microsoft.ReactNative/Fabric/ComponentViewRegistry.cpp +36 -2
  152. package/Microsoft.ReactNative/Fabric/ComponentViewRegistry.h +1 -0
  153. package/Microsoft.ReactNative/Fabric/DWriteHelpers.cpp +19 -0
  154. package/Microsoft.ReactNative/Fabric/DWriteHelpers.h +13 -0
  155. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +65 -19
  156. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +2 -0
  157. package/Microsoft.ReactNative/Fabric/ParagraphComponentView.cpp +36 -10
  158. package/Microsoft.ReactNative/Fabric/ScrollViewComponentView.cpp +2 -0
  159. package/Microsoft.ReactNative/Fabric/SliderComponentView.cpp +107 -0
  160. package/Microsoft.ReactNative/Fabric/SliderComponentView.h +51 -0
  161. package/Microsoft.ReactNative/Fabric/SwitchComponentView.cpp +109 -0
  162. package/Microsoft.ReactNative/Fabric/SwitchComponentView.h +52 -0
  163. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputComponentDescriptor.h +197 -0
  164. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputComponentView.cpp +308 -0
  165. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputComponentView.h +52 -0
  166. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputEventEmitter.cpp +31 -0
  167. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputEventEmitter.h +33 -0
  168. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputProps.cpp +81 -0
  169. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputProps.h +132 -0
  170. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputShadowNode.cpp +193 -0
  171. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputShadowNode.h +85 -0
  172. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputState.cpp +76 -0
  173. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputState.h +99 -0
  174. package/Microsoft.ReactNative/Fabric/ViewComponentView.cpp +35 -3
  175. package/Microsoft.ReactNative/Fabric/ViewComponentView.h +1 -0
  176. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/rncore/EventEmitters.h +5 -0
  177. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/rncore/Props.h +5 -0
  178. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/slider/SliderMeasurementsManager.cpp +46 -0
  179. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/slider/SliderMeasurementsManager.h +30 -0
  180. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/Color.cpp +2 -0
  181. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/conversions.h +1 -9
  182. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.h +3 -1
  183. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +119 -57
  184. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.h +18 -1
  185. package/Microsoft.ReactNative/IViewManager.idl +3 -3
  186. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +13 -107
  187. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +2 -2
  188. package/Microsoft.ReactNative/Modules/AppStateModule.cpp +2 -0
  189. package/Microsoft.ReactNative/Modules/AppStateModule.h +2 -0
  190. package/Microsoft.ReactNative/Modules/CreateModules.cpp +3 -3
  191. package/Microsoft.ReactNative/Modules/NativeUIManager.cpp +7 -5
  192. package/Microsoft.ReactNative/Modules/TimingModule.cpp +2 -2
  193. package/Microsoft.ReactNative/Modules/TimingModule.h +2 -2
  194. package/Microsoft.ReactNative/ReactHost/{ReactContext.cpp → MsoReactContext.cpp} +1 -1
  195. package/Microsoft.ReactNative/ReactHost/{ReactContext.h → MsoReactContext.h} +0 -0
  196. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +14 -1
  197. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
  198. package/Microsoft.ReactNative/ReactHost/ReactNativeHeaders.h +1 -1
  199. package/Microsoft.ReactNative/ReactRootView.cpp +2 -1
  200. package/Microsoft.ReactNative/RedBox.cpp +3 -2
  201. package/Microsoft.ReactNative/Utils/ValueUtils.cpp +3 -2
  202. package/Microsoft.ReactNative/Views/ControlViewManager.cpp +32 -0
  203. package/Microsoft.ReactNative/Views/ControlViewManager.h +11 -0
  204. package/Microsoft.ReactNative/Views/DevMenu.cpp +2 -2
  205. package/Microsoft.ReactNative/Views/FrameworkElementTransferProperties.cpp +13 -2
  206. package/Microsoft.ReactNative/Views/FrameworkElementViewManager.cpp +149 -22
  207. package/Microsoft.ReactNative/Views/Image/ImageViewManager.cpp +1 -1
  208. package/Microsoft.ReactNative/Views/Image/Microsoft.UI.Composition.Effects_Impl.h +5 -11
  209. package/Microsoft.ReactNative/Views/Image/ReactImage.cpp +2 -1
  210. package/Microsoft.ReactNative/Views/SliderViewManager.cpp +12 -4
  211. package/Microsoft.ReactNative/Views/TextInputViewManager.cpp +1 -1
  212. package/Microsoft.ReactNative/Views/TextViewManager.cpp +2 -2
  213. package/Microsoft.ReactNative/Views/TouchEventHandler.cpp +163 -37
  214. package/Microsoft.ReactNative/Views/TouchEventHandler.h +11 -4
  215. package/Microsoft.ReactNative/Views/ViewPanel.cpp +3 -23
  216. package/Microsoft.ReactNative/Views/ViewPanel.h +2 -3
  217. package/Microsoft.ReactNative/Views/ViewViewManager.cpp +21 -0
  218. package/Microsoft.ReactNative/XamlUIService.cpp +1 -1
  219. package/Microsoft.ReactNative/XamlView.h +8 -3
  220. package/Microsoft.ReactNative.Cxx/CppWinRTIncludes.h +3 -5
  221. package/Microsoft.ReactNative.Cxx/DesktopWindowBridge.h +1 -1
  222. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +11 -2
  223. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +1 -0
  224. package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.cpp +10 -1
  225. package/Microsoft.ReactNative.Cxx/JSValueReader.h +2 -2
  226. package/Microsoft.ReactNative.Cxx/JSValueWriter.h +5 -5
  227. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +5 -1
  228. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +2 -3
  229. package/Microsoft.ReactNative.Cxx/NativeModules.h +1 -1
  230. package/Microsoft.ReactNative.Cxx/ReactContext.h +3 -3
  231. package/Microsoft.ReactNative.Cxx/ReactNonAbiValue.h +3 -3
  232. package/Microsoft.ReactNative.Cxx/XamlUtils.h +44 -5
  233. package/Microsoft.ReactNative.Managed/Microsoft.ReactNative.Managed.csproj +0 -6
  234. package/Mso/activeObject/activeObject.h +2 -2
  235. package/Mso/compilerAdapters/cppMacros.h +3 -5
  236. package/Mso/errorCode/errorProvider.h +2 -2
  237. package/Mso/errorCode/maybe.h +4 -4
  238. package/Mso/functional/functor.h +6 -6
  239. package/Mso/functional/functorRef.h +2 -2
  240. package/Mso/future/details/executor.h +2 -2
  241. package/Mso/future/details/futureFuncInl.h +4 -4
  242. package/Mso/future/details/ifuture.h +3 -3
  243. package/Mso/future/details/maybeInvoker.h +6 -6
  244. package/Mso/future/details/promiseGroupInl.h +4 -4
  245. package/Mso/future/details/promiseInl.h +4 -4
  246. package/Mso/future/details/resultTraits.h +4 -4
  247. package/Mso/future/details/whenAllInl.h +1 -1
  248. package/Mso/future/future.h +13 -13
  249. package/Mso/guid/msoGuidDetails.h +1 -1
  250. package/Mso/memoryApi/memoryApi.h +13 -7
  251. package/Mso/motifCpp/gTestAdapter.h +1 -1
  252. package/Mso/motifCpp/testInfo.h +7 -9
  253. package/Mso/object/make.h +8 -8
  254. package/Mso/object/objectRefCount.h +3 -5
  255. package/Mso/object/objectWithWeakRef.h +10 -14
  256. package/Mso/object/queryCast.h +4 -4
  257. package/Mso/object/refCountedObject.h +4 -4
  258. package/Mso/object/unknownObject.h +7 -7
  259. package/Mso/platformAdapters/windowsFirst.h +1 -1
  260. package/Mso/smartPtr/cntPtr.h +8 -8
  261. package/Mso/src/dispatchQueue/uiScheduler_winrt.cpp +2 -2
  262. package/Mso/src/future/futureImpl.h +1 -1
  263. package/Mso/src/memoryApi/memoryApi.cpp +4 -4
  264. package/PropertySheets/CppAppConsumeCSharpModule.props +3 -0
  265. package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.CSharpApp.props +26 -0
  266. package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.Common.props +12 -0
  267. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  268. package/PropertySheets/React.Cpp.props +13 -0
  269. package/PropertySheets/WinUI.props +3 -6
  270. package/ReactCommon/ReactCommon.vcxproj +2 -4
  271. package/ReactCommon/ReactCommon.vcxproj.filters +4 -1
  272. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/JSCRuntime.cpp +1480 -0
  273. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/decorator.h +753 -0
  274. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h +1331 -0
  275. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp +1431 -0
  276. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/bridging/CallbackWrapper.h +103 -0
  277. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModule.h +87 -0
  278. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModuleUtils.h +61 -0
  279. package/ReactCommon/Yoga.cpp +1 -1
  280. package/Scripts/{Microsoft.ReactNative.ProjectReunion.nuspec → Microsoft.ReactNative.WindowsAppSDK.nuspec} +7 -9
  281. package/Scripts/OfficeReact.Win32.nuspec +1 -3
  282. package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +2 -1
  283. package/Scripts/copyRNLibraries.js +8 -8
  284. package/Scripts/just.js +1 -1
  285. package/Scripts/rnw-dependencies.ps1 +41 -10
  286. package/Scripts/run-desktop-integration-tests.js +6 -6
  287. package/Shared/AbiSafe.h +3 -3
  288. package/Shared/BaseScriptStoreImpl.cpp +1 -1
  289. package/Shared/CppRuntimeOptions.h +50 -0
  290. package/Shared/DevSupportManager.cpp +32 -36
  291. package/Shared/DevSupportManager.h +1 -2
  292. package/Shared/HermesRuntimeHolder.cpp +23 -14
  293. package/Shared/HermesRuntimeHolder.h +8 -2
  294. package/Shared/IDevSupportManager.h +1 -2
  295. package/Shared/InspectorPackagerConnection.cpp +7 -5
  296. package/Shared/InspectorPackagerConnection.h +2 -2
  297. package/Shared/JSI/ChakraApi.cpp +0 -1
  298. package/Shared/JSI/ChakraRuntime.cpp +1 -2
  299. package/Shared/JSI/RuntimeHolder.h +2 -0
  300. package/Shared/Modules/HttpModule.cpp +1 -1
  301. package/Shared/Modules/HttpModule.h +2 -2
  302. package/Shared/Modules/WebSocketModule.cpp +1 -1
  303. package/Shared/Modules/WebSocketModule.h +8 -5
  304. package/Shared/{IHttpResource.h → Networking/IHttpResource.h} +4 -4
  305. package/Shared/{IWebSocketResource.h → Networking/IWebSocketResource.h} +2 -2
  306. package/Shared/Networking/OriginPolicy.h +15 -0
  307. package/Shared/Networking/OriginPolicyHttpFilter.cpp +746 -0
  308. package/Shared/Networking/OriginPolicyHttpFilter.h +112 -0
  309. package/Shared/{WinRTHttpResource.cpp → Networking/WinRTHttpResource.cpp} +129 -99
  310. package/Shared/{WinRTHttpResource.h → Networking/WinRTHttpResource.h} +8 -12
  311. package/Shared/Networking/WinRTTypes.h +30 -0
  312. package/Shared/{WinRTWebSocketResource.cpp → Networking/WinRTWebSocketResource.cpp} +2 -2
  313. package/Shared/{WinRTWebSocketResource.h → Networking/WinRTWebSocketResource.h} +3 -3
  314. package/Shared/OInstance.cpp +5 -5
  315. package/Shared/RuntimeOptions.cpp +93 -15
  316. package/Shared/RuntimeOptions.h +22 -9
  317. package/Shared/Shared.vcxitems +122 -7
  318. package/Shared/Shared.vcxitems.filters +40 -21
  319. package/Shared/Threading/BatchingQueueThread.cpp +1 -1
  320. package/Shared/tracing/fbsystrace.h +2 -2
  321. package/codegen/NativeActionSheetManagerSpec.g.h +6 -0
  322. package/codegen/NativeAnimatedModuleSpec.g.h +43 -37
  323. package/codegen/NativeAnimatedTurboModuleSpec.g.h +43 -37
  324. package/codegen/NativePushNotificationManagerIOSSpec.g.h +2 -0
  325. package/codegen/react/components/rnwcore/ComponentDescriptors.h +0 -1
  326. package/codegen/react/components/rnwcore/EventEmitters.cpp +133 -0
  327. package/codegen/react/components/rnwcore/EventEmitters.h +0 -18
  328. package/codegen/react/components/rnwcore/Props.cpp +0 -13
  329. package/codegen/react/components/rnwcore/Props.h +0 -16
  330. package/codegen/react/components/rnwcore/ShadowNodes.cpp +0 -1
  331. package/codegen/react/components/rnwcore/ShadowNodes.h +0 -10
  332. package/include/Shared/cdebug.h +9 -9
  333. package/index.js +30 -25
  334. package/index.windows.js +30 -25
  335. package/jest/preprocessor.js +24 -107
  336. package/jest/preprocessor_DO_NOT_USE.js +122 -0
  337. package/metro.config.js +3 -70
  338. package/package.json +29 -28
  339. package/react-native.config.js +40 -6
  340. package/rntypes/index.d.ts +19 -7
  341. package/stubs/glog/logging.h +1 -1
  342. package/template/cpp-app/src/App.h +0 -4
  343. package/template/cs-app/src/App.xaml.cs +0 -5
  344. package/template/cs-app/src/MainPage.xaml.cs +1 -10
  345. package/template/cs-app-WinAppSDK/MyApp/App.xaml +16 -0
  346. package/template/cs-app-WinAppSDK/MyApp/App.xaml.cs +70 -0
  347. package/template/cs-app-WinAppSDK/MyApp/MainWindow.xaml +14 -0
  348. package/template/cs-app-WinAppSDK/MyApp/MainWindow.xaml.cs +38 -0
  349. package/template/cs-app-WinAppSDK/MyApp/Package.appxmanifest +48 -0
  350. package/template/cs-app-WinAppSDK/MyApp/Properties/PublishProfiles/win10-arm64.pubxml +19 -0
  351. package/template/cs-app-WinAppSDK/MyApp/Properties/PublishProfiles/win10-x64.pubxml +19 -0
  352. package/template/cs-app-WinAppSDK/MyApp/Properties/PublishProfiles/win10-x86.pubxml +19 -0
  353. package/template/cs-app-WinAppSDK/MyApp/Properties/launchSettings.json +10 -0
  354. package/template/cs-app-WinAppSDK/MyApp/app.manifest +15 -0
  355. package/template/cs-app-WinAppSDK/proj/ExperimentalFeatures.props +23 -0
  356. package/template/cs-app-WinAppSDK/proj/MyApp.csproj +49 -0
  357. package/template/cs-app-WinAppSDK/proj/MyApp.sln +43 -0
  358. package/template/cs-app-WinAppSDK/proj/NuGet.Config +17 -0
  359. package/template/metro.devMode.config.js +2 -51
  360. package/typings-index.js +5 -1
  361. package/typings-index.js.map +1 -1
  362. package/Libraries/Components/SegmentedControlIOS/RCTSegmentedControlNativeComponent.js +0 -44
  363. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js +0 -45
  364. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js +0 -123
  365. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.windows.js +0 -45
  366. package/Libraries/Components/View/ReactNativeViewViewConfig.js +0 -360
  367. package/Libraries/Components/View/ReactNativeViewViewConfig.windows.js +0 -390
  368. package/Libraries/Components/View/ReactNativeViewViewConfigAndroid.js +0 -83
  369. package/Libraries/ReactNative/UIManagerInjection.js +0 -15
  370. package/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +0 -24527
  371. package/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +0 -8309
  372. package/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +0 -8961
  373. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +0 -24948
  374. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +0 -8400
  375. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +0 -9049
  376. package/PropertySheets/CppEnablePackageReferences.props +0 -13
  377. package/Shared/cdebug.cpp +0 -6
  378. 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