// Copyright 2004-present Facebook. All Rights Reserved. #pragma once #include #include #include #include #include #include #include "Executor.h" #include "ExecutorToken.h" #include "JSCHelpers.h" #include "Value.h" namespace facebook { namespace react { class MessageQueueThread; class 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; }; class 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) throw(JSException) override; #ifdef WITH_FBJSCEXTENSIONS virtual void loadApplicationScript( std::string bundlePath, std::string sourceURL, int flags) override; #endif 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; 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; 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; folly::dynamic m_jscConfig; folly::Optional m_invokeCallbackAndReturnFlushedQueueJS; folly::Optional m_callFunctionReturnFlushedQueueJS; folly::Optional m_flushedQueueJS; /** * 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); void terminateOnJSVMThread(); void bindBridge() throw(JSException); void flush(); void flushQueueImmediate(std::string queueJSON); 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< JSValueRef (JSCExecutor::*method)(size_t, const JSValueRef[])> void installNativeHook(const char* name); JSValueRef nativeRequireModuleConfig( size_t argumentCount, const JSValueRef arguments[]); 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[]); }; } }