164f5c95fSŁukasz Kosmaty // Copyright © 2021-present 650 Industries, Inc. (aka Expo) 264f5c95fSŁukasz Kosmaty 364f5c95fSŁukasz Kosmaty #pragma once 464f5c95fSŁukasz Kosmaty 529e8b6f8SŁukasz Kosmaty #include "JNIDeallocator.h" 629e8b6f8SŁukasz Kosmaty 764f5c95fSŁukasz Kosmaty #include <jsi/jsi.h> 8a416e6dbSŁukasz Kosmaty #include <fbjni/fbjni.h> 9a416e6dbSŁukasz Kosmaty #include <ReactCommon/CallInvoker.h> 1064f5c95fSŁukasz Kosmaty 1164f5c95fSŁukasz Kosmaty namespace jsi = facebook::jsi; 12a416e6dbSŁukasz Kosmaty namespace jni = facebook::jni; 13a416e6dbSŁukasz Kosmaty namespace react = facebook::react; 1464f5c95fSŁukasz Kosmaty 1514c0f05dSŁukasz Kosmaty namespace expo { 16db6683c6SKudo Chien 1714c0f05dSŁukasz Kosmaty class JavaScriptValue; 18*12cf8561Slukmccall 1914c0f05dSŁukasz Kosmaty class JavaScriptObject; 20*12cf8561Slukmccall 21879827bbSŁukasz Kosmaty class JSIInteropModuleRegistry; 22879827bbSŁukasz Kosmaty 23db6683c6SKudo Chien #if REACT_NATIVE_TARGET_VERSION >= 73 24db6683c6SKudo Chien using NativeMethodCallInvokerCompatible = react::NativeMethodCallInvoker; 25db6683c6SKudo Chien #else 26db6683c6SKudo Chien using NativeMethodCallInvokerCompatible = react::CallInvoker; 27db6683c6SKudo Chien #endif 28e3d1d66aSŁukasz Kosmaty 29e3d1d66aSŁukasz Kosmaty /** 30a416e6dbSŁukasz Kosmaty * A wrapper for the jsi::Runtime. 31a416e6dbSŁukasz Kosmaty * This class is used as a bridge between CPP and Kotlin and to encapsulate common runtime helper functions. 32a416e6dbSŁukasz Kosmaty * 33a416e6dbSŁukasz Kosmaty * Instances of this class should be managed using a shared smart pointer. 34a416e6dbSŁukasz Kosmaty * To pass runtime information to all of `JavaScriptValue` and `JavaScriptObject` we use `weak_from_this()` 35a416e6dbSŁukasz Kosmaty * that requires that the object is held via a smart pointer. Otherwise, `weak_from_this()` returns `nullptr`. 36a416e6dbSŁukasz Kosmaty */ 37a416e6dbSŁukasz Kosmaty class JavaScriptRuntime : public std::enable_shared_from_this<JavaScriptRuntime> { 3864f5c95fSŁukasz Kosmaty public: 39a416e6dbSŁukasz Kosmaty /** 40a416e6dbSŁukasz Kosmaty * Initializes a runtime that is independent from React Native and its runtime initialization. 41e3d1d66aSŁukasz Kosmaty * This flow is mostly intended for tests. The JS call invoker is set to `SyncCallInvoker`. 42db6683c6SKudo Chien * See **JavaScriptRuntime.cpp** for the `SyncCallInvoker` implementation. 43a416e6dbSŁukasz Kosmaty */ 44879827bbSŁukasz Kosmaty JavaScriptRuntime( 45879827bbSŁukasz Kosmaty JSIInteropModuleRegistry *jsiInteropModuleRegistry 46879827bbSŁukasz Kosmaty ); 4764f5c95fSŁukasz Kosmaty 48a416e6dbSŁukasz Kosmaty JavaScriptRuntime( 49879827bbSŁukasz Kosmaty JSIInteropModuleRegistry *jsiInteropModuleRegistry, 50a416e6dbSŁukasz Kosmaty jsi::Runtime *runtime, 51a416e6dbSŁukasz Kosmaty std::shared_ptr<react::CallInvoker> jsInvoker, 52db6683c6SKudo Chien std::shared_ptr<NativeMethodCallInvokerCompatible> nativeInvoker 53a416e6dbSŁukasz Kosmaty ); 54a416e6dbSŁukasz Kosmaty 55a416e6dbSŁukasz Kosmaty /** 56a416e6dbSŁukasz Kosmaty * Returns the underlying runtime object. 57a416e6dbSŁukasz Kosmaty */ 58256b5942SŁukasz Kosmaty jsi::Runtime &get() const; 5964f5c95fSŁukasz Kosmaty 60a416e6dbSŁukasz Kosmaty /** 61a416e6dbSŁukasz Kosmaty * Evaluates given JavaScript source code. 62a416e6dbSŁukasz Kosmaty * @throws if the input format is unknown, or evaluation causes an error, 63a416e6dbSŁukasz Kosmaty * a jni::JniException<JavaScriptEvaluateException> will be thrown. 64a416e6dbSŁukasz Kosmaty */ 6529e8b6f8SŁukasz Kosmaty jni::local_ref<jni::HybridClass<JavaScriptValue, Destructible>::javaobject> evaluateScript( 66e3d1d66aSŁukasz Kosmaty const std::string &script 67e3d1d66aSŁukasz Kosmaty ); 68a416e6dbSŁukasz Kosmaty 69a416e6dbSŁukasz Kosmaty /** 70a416e6dbSŁukasz Kosmaty * Returns the runtime global object for use in Kotlin. 71a416e6dbSŁukasz Kosmaty */ 7229e8b6f8SŁukasz Kosmaty jni::local_ref<jni::HybridClass<JavaScriptObject, Destructible>::javaobject> global(); 73a416e6dbSŁukasz Kosmaty 74342f32d0SŁukasz Kosmaty /** 75342f32d0SŁukasz Kosmaty * Creates a new object for use in Kotlin. 76342f32d0SŁukasz Kosmaty */ 7729e8b6f8SŁukasz Kosmaty jni::local_ref<jni::HybridClass<JavaScriptObject, Destructible>::javaobject> createObject(); 78342f32d0SŁukasz Kosmaty 79a89667b6SŁukasz Kosmaty /** 80a89667b6SŁukasz Kosmaty * Drains the JavaScript VM internal Microtask (a.k.a. event loop) queue. 81a89667b6SŁukasz Kosmaty */ 82a89667b6SŁukasz Kosmaty void drainJSEventLoop(); 83a89667b6SŁukasz Kosmaty 84*12cf8561Slukmccall void installMainObject(); 85*12cf8561Slukmccall 86a416e6dbSŁukasz Kosmaty std::shared_ptr<react::CallInvoker> jsInvoker; 87db6683c6SKudo Chien std::shared_ptr<NativeMethodCallInvokerCompatible> nativeInvoker; 88dedc0ffdSŁukasz Kosmaty 89dedc0ffdSŁukasz Kosmaty std::shared_ptr<jsi::Object> getMainObject(); 90879827bbSŁukasz Kosmaty 91879827bbSŁukasz Kosmaty JSIInteropModuleRegistry *getModuleRegistry(); 92*12cf8561Slukmccall 936095fdc7SŁukasz Kosmaty private: 946095fdc7SŁukasz Kosmaty std::shared_ptr<jsi::Runtime> runtime; 95dedc0ffdSŁukasz Kosmaty std::shared_ptr<jsi::Object> mainObject; 96879827bbSŁukasz Kosmaty JSIInteropModuleRegistry *jsiInteropModuleRegistry; 9764f5c95fSŁukasz Kosmaty }; 9864f5c95fSŁukasz Kosmaty } // namespace expo 99