1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo) 2 3 #include "JavaScriptRuntime.h" 4 #include "JavaScriptValue.h" 5 #include "JavaScriptObject.h" 6 #include "Exceptions.h" 7 8 #if FOR_HERMES 9 10 #include <hermes/hermes.h> 11 12 #include <utility> 13 14 #else 15 16 #include <jsi/JSCRuntime.h> 17 18 #endif 19 20 namespace expo { 21 22 namespace jsi = facebook::jsi; 23 24 JavaScriptRuntime::JavaScriptRuntime() { 25 #if FOR_HERMES 26 auto config = ::hermes::vm::RuntimeConfig::Builder().withEnableSampleProfiling(false); 27 runtime = facebook::hermes::makeHermesRuntime(config.build()); 28 #else 29 runtime = facebook::jsc::makeJSCRuntime(); 30 #endif 31 } 32 33 JavaScriptRuntime::JavaScriptRuntime( 34 jsi::Runtime *runtime, 35 std::shared_ptr<react::CallInvoker> jsInvoker, 36 std::shared_ptr<react::CallInvoker> nativeInvoker 37 ) : jsInvoker(std::move(jsInvoker)), nativeInvoker(std::move(nativeInvoker)) { 38 // Creating a shared pointer that points to the runtime but doesn't own it, thus doesn't release it. 39 // In this code flow, the runtime should be owned by something else like the CatalystInstance. 40 // See explanation for constructor (8): https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr 41 this->runtime = std::shared_ptr<jsi::Runtime>(std::shared_ptr<jsi::Runtime>(), runtime); 42 } 43 44 jsi::Runtime *JavaScriptRuntime::get() { 45 return runtime.get(); 46 } 47 48 jni::local_ref<JavaScriptValue::javaobject> 49 JavaScriptRuntime::evaluateScript(const std::string &script) { 50 auto scriptBuffer = std::make_shared<jsi::StringBuffer>(script); 51 std::shared_ptr<jsi::Value> result; 52 try { 53 result = std::make_shared<jsi::Value>( 54 runtime->evaluateJavaScript(scriptBuffer, "<<evaluated>>") 55 ); 56 } catch (const jsi::JSError &error) { 57 jni::throwNewJavaException( 58 JavaScriptEvaluateException::create( 59 error.getMessage(), 60 error.getStack() 61 ).get() 62 ); 63 } catch (const jsi::JSIException &error) { 64 jni::throwNewJavaException( 65 JavaScriptEvaluateException::create( 66 error.what(), 67 "" 68 ).get() 69 ); 70 } 71 72 return JavaScriptValue::newObjectCxxArgs(weak_from_this(), result); 73 } 74 75 jni::local_ref<JavaScriptObject::javaobject> JavaScriptRuntime::global() { 76 auto global = std::make_shared<jsi::Object>(runtime->global()); 77 return JavaScriptObject::newObjectCxxArgs(weak_from_this(), global); 78 } 79 80 jni::local_ref<JavaScriptObject::javaobject> JavaScriptRuntime::createObject() { 81 auto newObject = std::make_shared<jsi::Object>(*runtime); 82 return JavaScriptObject::newObjectCxxArgs(weak_from_this(), newObject); 83 } 84 } // namespace expo 85