#include "ReanimatedHermesRuntime.h" // Only include this file in Hermes-enabled builds as some platforms (like tvOS) // don't support hermes and it causes the compilation to fail. #if JS_RUNTIME_HERMES #include #include #include #include #include #include #if __has_include() #include #else // __has_include() || ANDROID #include #endif namespace reanimated { using namespace facebook; using namespace react; #if HERMES_ENABLE_DEBUGGER #if REACT_NATIVE_MINOR_VERSION >= 73 using namespace facebook::hermes::inspector_modern; #else using namespace facebook::hermes::inspector; #endif #endif // HERMES_ENABLE_DEBUGGER #if HERMES_ENABLE_DEBUGGER class HermesExecutorRuntimeAdapter : public RuntimeAdapter { public: explicit HermesExecutorRuntimeAdapter( facebook::hermes::HermesRuntime &hermesRuntime, const std::shared_ptr &thread) : hermesRuntime_(hermesRuntime), thread_(std::move(thread)) {} virtual ~HermesExecutorRuntimeAdapter() { // This is required by iOS, because there is an assertion in the destructor // that the thread was indeed `quit` before thread_->quitSynchronous(); } #if REACT_NATIVE_MINOR_VERSION >= 71 facebook::hermes::HermesRuntime &getRuntime() override { return hermesRuntime_; } #else facebook::jsi::Runtime &getRuntime() override { return hermesRuntime_; } facebook::hermes::debugger::Debugger &getDebugger() override { return hermesRuntime_.getDebugger(); } #endif // REACT_NATIVE_MINOR_VERSION // This is not empty in the original implementation, but we decided to tickle // the runtime by running a small piece of code on every frame as using this // required us to hold a refernce to the runtime inside this adapter which // caused issues while reloading the app. void tickleJs() override {} public: facebook::hermes::HermesRuntime &hermesRuntime_; std::shared_ptr thread_; }; #endif // HERMES_ENABLE_DEBUGGER ReanimatedHermesRuntime::ReanimatedHermesRuntime( std::unique_ptr runtime, const std::shared_ptr &jsQueue, const std::string &name) : jsi::WithRuntimeDecorator( *runtime, reentrancyCheck_), runtime_(std::move(runtime)) { #if HERMES_ENABLE_DEBUGGER auto adapter = std::make_unique(*runtime_, jsQueue); #if REACT_NATIVE_MINOR_VERSION >= 71 debugToken_ = chrome::enableDebugging(std::move(adapter), name); #else chrome::enableDebugging(std::move(adapter), name); #endif // REACT_NATIVE_MINOR_VERSION #else // This is required by iOS, because there is an assertion in the destructor // that the thread was indeed `quit` before jsQueue->quitSynchronous(); #endif // HERMES_ENABLE_DEBUGGER #ifndef NDEBUG facebook::hermes::HermesRuntime *wrappedRuntime = runtime_.get(); jsi::Value evalWithSourceMap = jsi::Function::createFromHostFunction( *runtime_, jsi::PropNameID::forAscii(*runtime_, "evalWithSourceMap"), 3, [wrappedRuntime]( jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value { auto code = std::make_shared( args[0].asString(rt).utf8(rt)); std::string sourceURL; if (count > 1 && args[1].isString()) { sourceURL = args[1].asString(rt).utf8(rt); } std::shared_ptr sourceMap; if (count > 2 && args[2].isString()) { sourceMap = std::make_shared( args[2].asString(rt).utf8(rt)); } return wrappedRuntime->evaluateJavaScriptWithSourceMap( code, sourceMap, sourceURL); }); runtime_->global().setProperty( *runtime_, "evalWithSourceMap", evalWithSourceMap); #endif // NDEBUG } ReanimatedHermesRuntime::~ReanimatedHermesRuntime() { #if HERMES_ENABLE_DEBUGGER // We have to disable debugging before the runtime is destroyed. #if REACT_NATIVE_MINOR_VERSION >= 71 chrome::disableDebugging(debugToken_); #else chrome::disableDebugging(*runtime_); #endif // REACT_NATIVE_MINOR_VERSION #endif // HERMES_ENABLE_DEBUGGER } } // namespace reanimated #endif // JS_RUNTIME_HERMES