From 7046c916933e9c636bcc277549535f7ba1b90191 Mon Sep 17 00:00:00 2001 From: Gang Zhao Date: Tue, 20 Oct 2026 10:06:43 -0700 Subject: [PATCH] Run the API tests on the sandbox Summary: Add HermesSandboxRuntime to runtimeGenerators() in APITestFactory.cpp, so HermesUnitTests runs the parameterized HermesRuntimeTest cases on the sandbox as well, like the legacy Hermes API tests do. Until now no static_h test ran the sandbox. The sandbox does not support everything HermesRuntime does, so the tests skip what it lacks, with the same dynamic_cast checks the file already uses: - instrumentation(): GetHeapInfo and ExternalMemoryNoOpTest. - ArrayBuffers created from a MutableBuffer: the rest of TryGetMutableBuffer after its first check, and TryGetMutableBufferAfterHiddenClassTransition. - createValueFromJsonUtf8 is the default implementation, which calls the global JSON.parse: CreateValueFromJsonUtf8IgnoresGlobalJSON. - utf16() converts through UTF-8, which turns lone surrogates into U+FFFD: the lone surrogate checks at the end of UTF16ConversionTest and CreateFromUtf16Test. The sandbox implements neither ISerialization nor Worker, so HermesSerializationTest and HermesWorkerTest run on the new hermesRuntimeGenerators(), which returns just the two HermesRuntime factories. The same factory backs JSITests-SHTrunk, JSITestsUnstable-SHTrunk and JSIDynamicTests-SHTrunk in xplat/jsi, FBJSValueTests-SHTrunk on Apple, and the CMake APITests, so those now run on the sandbox too. In testlib, ArrayBufferDetachedTest assumed that a runtime with ArrayBuffer.prototype.detached can also detach a buffer from JS. The sandbox has neither transfer() nor HermesInternal.detachArrayBuffer, so the test now stops after its first check in that case. The CMake sanitizer jobs build with Clang's UBSan, whose function type check aborts on the generated code's indirect calls: they pass the instance as void * to functions defined with a typed instance pointer. Nothing ran the sandbox before, so this never fired. Build the generated C with -fno-sanitize=function under Clang. Changelog: [Internal] Differential Revision: D125561036 --- .../react-native/ReactCommon/jsi/jsi/test/testlib.cpp | 11 +++++++++++ .../react-native/ReactCommon/jsi/jsi/test/testlib.h | 1 + 2 files changed, 12 insertions(+) diff --git a/packages/react-native/ReactCommon/jsi/jsi/test/testlib.cpp b/packages/react-native/ReactCommon/jsi/jsi/test/testlib.cpp index 1ded399f8319..37b71538b87e 100644 --- a/packages/react-native/ReactCommon/jsi/jsi/test/testlib.cpp +++ b/packages/react-native/ReactCommon/jsi/jsi/test/testlib.cpp @@ -2719,6 +2719,17 @@ TEST_P(JSITest, ArrayBufferDetachedTest) { return; } + // Skip the rest if the runtime has no way to detach an ArrayBuffer from JS. + bool canDetach = + eval( + "typeof buf.transfer === 'function' || " + "(typeof HermesInternal !== 'undefined' && " + " typeof HermesInternal.detachArrayBuffer === 'function')") + .getBool(); + if (!canDetach) { + return; + } + // Detach the ArrayBuffer. Use transfer() if available, otherwise fall back // to HermesInternal.detach for Hermes runtime. eval( diff --git a/packages/react-native/ReactCommon/jsi/jsi/test/testlib.h b/packages/react-native/ReactCommon/jsi/jsi/test/testlib.h index b56d41b83838..8eee03a34312 100644 --- a/packages/react-native/ReactCommon/jsi/jsi/test/testlib.h +++ b/packages/react-native/ReactCommon/jsi/jsi/test/testlib.h @@ -22,6 +22,7 @@ class Runtime; using RuntimeFactory = std::function()>; std::vector runtimeGenerators(); +std::vector runtimeGeneratorsWithSandBox(); class JSITestBase : public ::testing::TestWithParam { public: