From 9c32140068463739b91874689f741ea9630d8c3b Mon Sep 17 00:00:00 2001 From: Ryan Tremblay Date: Tue, 9 Jun 2020 01:08:42 -0700 Subject: [PATCH] Enable array buffers in JSCRuntime.cpp (#28961) Summary: The JavaScriptCore implementation of JSI [does not currently support array buffers](https://github.com/facebook/react-native/blob/master/ReactCommon/jsi/JSCRuntime.cpp#L925-L943). The comments in the code suggest the JSC version used by React Native does not work with array buffers, but this seems to be out of date since the current version of JSC used by React Native does indeed support array buffers. This change just enables array buffers in JSCRuntime.cpp. NOTE: See https://github.com/react-native-community/discussions-and-proposals/issues/91#issuecomment-632371219 for more background on this change. ## Changelog [General] [Added] - Support for array buffers in the JavaScriptCore implementation of JSI Pull Request resolved: https://github.com/facebook/react-native/pull/28961 Test Plan: To test these changes, I just made some temporary changes to RNTester to use JSI to inject a test function into the JS runtime that reads from and writes to an array buffer, and call that function from the JS of the RNTester app (see https://github.com/ryantrem/react-native/commit/28152ce3f4ae0fa906557415d106399b3f072118). For the JS side of this, specifically look at https://github.com/ryantrem/react-native/blob/28152ce3f4ae0fa906557415d106399b3f072118/RNTester/js/RNTesterApp.android.js#L13-L18 For the native side of this, specifically look at https://github.com/ryantrem/react-native/blob/28152ce3f4ae0fa906557415d106399b3f072118/RNTester/android/app/src/main/cpp/JSITest.cpp#L22-L38 Reviewed By: shergin Differential Revision: D21717995 Pulled By: tmikov fbshipit-source-id: 5788479bb33c24d01aa80fa7f509e0ff9dcefea6 --- ReactCommon/jsi/JSCRuntime.cpp | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/ReactCommon/jsi/JSCRuntime.cpp b/ReactCommon/jsi/JSCRuntime.cpp index c89f736d95b1f9..b6e6062847cc87 100644 --- a/ReactCommon/jsi/JSCRuntime.cpp +++ b/ReactCommon/jsi/JSCRuntime.cpp @@ -276,6 +276,9 @@ class JSCRuntime : public jsi::Runtime { #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0 #define _JSC_FAST_IS_ARRAY #endif +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0 +#define _JSC_NO_ARRAY_BUFFERS +#endif #endif #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_11 @@ -284,6 +287,9 @@ class JSCRuntime : public jsi::Runtime { // we understand why. #define _JSC_FAST_IS_ARRAY #endif +#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12 +#define _JSC_NO_ARRAY_BUFFERS +#endif #endif // JSStringRef utilities @@ -922,24 +928,30 @@ bool JSCRuntime::isArray(const jsi::Object &obj) const { #endif } -bool JSCRuntime::isArrayBuffer(const jsi::Object & /*obj*/) const { - // TODO: T23270523 - This would fail on builds that use our custom JSC - // auto typedArrayType = JSValueGetTypedArrayType(ctx_, objectRef(obj), - // nullptr); return typedArrayType == kJSTypedArrayTypeArrayBuffer; +bool JSCRuntime::isArrayBuffer(const jsi::Object &obj) const { +#if defined(_JSC_NO_ARRAY_BUFFERS) throw std::runtime_error("Unsupported"); +#else + auto typedArrayType = JSValueGetTypedArrayType(ctx_, objectRef(obj), nullptr); + return typedArrayType == kJSTypedArrayTypeArrayBuffer; +#endif } -uint8_t *JSCRuntime::data(const jsi::ArrayBuffer & /*obj*/) { - // TODO: T23270523 - This would fail on builds that use our custom JSC - // return static_cast( - // JSObjectGetArrayBufferBytesPtr(ctx_, objectRef(obj), nullptr)); +uint8_t *JSCRuntime::data(const jsi::ArrayBuffer &obj) { +#if defined(_JSC_NO_ARRAY_BUFFERS) throw std::runtime_error("Unsupported"); +#else + return static_cast( + JSObjectGetArrayBufferBytesPtr(ctx_, objectRef(obj), nullptr)); +#endif } -size_t JSCRuntime::size(const jsi::ArrayBuffer & /*obj*/) { - // TODO: T23270523 - This would fail on builds that use our custom JSC - // return JSObjectGetArrayBufferByteLength(ctx_, objectRef(obj), nullptr); +size_t JSCRuntime::size(const jsi::ArrayBuffer &obj) { +#if defined(_JSC_NO_ARRAY_BUFFERS) throw std::runtime_error("Unsupported"); +#else + return JSObjectGetArrayBufferByteLength(ctx_, objectRef(obj), nullptr); +#endif } bool JSCRuntime::isFunction(const jsi::Object &obj) const {