// Copyright 2004-present Facebook. All Rights Reserved. #pragma once #include #include #include #include #include #include #include #include #include #include #include namespace facebook { namespace react { class MessageQueueThread; class RN_EXPORT JSCExecutorFactory : public JSExecutorFactory { public: JSCExecutorFactory(const std::string& cacheDir, const folly::dynamic& jscConfig) : m_cacheDir(cacheDir), m_jscConfig(jscConfig) {} virtual std::unique_ptr createJSExecutor( std::shared_ptr delegate, std::shared_ptr jsQueue) override; private: std::string m_cacheDir; folly::dynamic m_jscConfig; }; class JSCExecutor; class WorkerRegistration : public noncopyable { public: explicit WorkerRegistration(JSCExecutor* executor_, Object jsObj_) : executor(executor_), jsObj(std::move(jsObj_)) {} JSCExecutor *executor; Object jsObj; }; template struct ValueEncoder; class RN_EXPORT JSCExecutor : public JSExecutor { public: /** * Must be invoked from thread this Executor will run on. */ explicit JSCExecutor(std::shared_ptr delegate, std::shared_ptr messageQueueThread, const std::string& cacheDir, const folly::dynamic& jscConfig) throw(JSException); ~JSCExecutor() override; virtual void loadApplicationScript( std::unique_ptr script, std::string sourceURL) override; virtual void setJSModulesUnbundle( std::unique_ptr unbundle) override; virtual void callFunction( const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) override; virtual void invokeCallback( const double callbackId, const folly::dynamic& arguments) override; template Value callFunctionSync( const std::string& module, const std::string& method, T&& args) { return callFunctionSyncWithValue( module, method, ValueEncoder::type>::toValue( m_context, std::forward(args))); } virtual void setGlobalVariable( std::string propName, std::unique_ptr jsonValue) override; virtual void* getJavaScriptContext() override; virtual bool supportsProfiling() override; virtual void startProfiler(const std::string &titleString) override; virtual void stopProfiler(const std::string &titleString, const std::string &filename) override; virtual void handleMemoryPressureUiHidden() override; virtual void handleMemoryPressureModerate() override; virtual void handleMemoryPressureCritical() override; virtual void destroy() override; void setContextName(const std::string& name); private: JSGlobalContextRef m_context; std::shared_ptr m_delegate; int m_workerId = 0; // if this is a worker executor, this is non-zero JSCExecutor *m_owner = nullptr; // if this is a worker executor, this is non-null std::shared_ptr m_isDestroyed = std::shared_ptr(new bool(false)); std::unordered_map m_ownedWorkers; std::string m_deviceCacheDir; std::shared_ptr m_messageQueueThread; std::unique_ptr m_unbundle; JSCNativeModules m_nativeModules; folly::dynamic m_jscConfig; folly::Optional m_invokeCallbackAndReturnFlushedQueueJS; folly::Optional m_callFunctionReturnFlushedQueueJS; folly::Optional m_flushedQueueJS; folly::Optional m_callFunctionReturnResultAndFlushedQueueJS; /** * WebWorker constructor. Must be invoked from thread this Executor will run on. */ JSCExecutor( std::shared_ptr delegate, std::shared_ptr messageQueueThread, int workerId, JSCExecutor *owner, std::string scriptURL, std::unordered_map globalObjAsJSON, const folly::dynamic& jscConfig); void initOnJSVMThread() throw(JSException); // This method is experimental, and may be modified or removed. Value callFunctionSyncWithValue( const std::string& module, const std::string& method, Value value); void terminateOnJSVMThread(); void bindBridge() throw(JSException); void callNativeModules(Value&&); void flush(); void flushQueueImmediate(Value&&); void loadModule(uint32_t moduleId); int addWebWorker(std::string scriptURL, JSValueRef workerRef, JSValueRef globalObjRef); void postMessageToOwnedWebWorker(int worker, JSValueRef message); void postMessageToOwner(JSValueRef result); void receiveMessageFromOwnedWebWorker(int workerId, const std::string& message); void receiveMessageFromOwner(const std::string &msgString); void terminateOwnedWebWorker(int worker); Object createMessageObject(const std::string& msgData); template void installNativeHook(const char* name); JSValueRef getNativeModule(JSObjectRef object, JSStringRef propertyName); JSValueRef nativeStartWorker( size_t argumentCount, const JSValueRef arguments[]); JSValueRef nativePostMessageToWorker( size_t argumentCount, const JSValueRef arguments[]); JSValueRef nativeTerminateWorker( size_t argumentCount, const JSValueRef arguments[]); JSValueRef nativePostMessage( size_t argumentCount, const JSValueRef arguments[]); JSValueRef nativeRequire( size_t argumentCount, const JSValueRef arguments[]); JSValueRef nativeFlushQueueImmediate( size_t argumentCount, const JSValueRef arguments[]); JSValueRef nativeCallSyncHook( size_t argumentCount, const JSValueRef arguments[]); }; } }