2016-05-04 02:29:58 +00:00
|
|
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
#include <memory>
|
2017-03-20 20:03:04 +00:00
|
|
|
#include <mutex>
|
2016-05-04 02:29:58 +00:00
|
|
|
#include <unordered_map>
|
|
|
|
|
2017-02-15 17:49:07 +00:00
|
|
|
#include <cxxreact/Executor.h>
|
|
|
|
#include <cxxreact/ExecutorToken.h>
|
|
|
|
#include <cxxreact/JSCNativeModules.h>
|
2016-06-21 17:08:31 +00:00
|
|
|
#include <folly/Optional.h>
|
2017-02-15 17:49:07 +00:00
|
|
|
#include <folly/json.h>
|
2016-11-01 18:38:43 +00:00
|
|
|
#include <jschelpers/JSCHelpers.h>
|
2017-02-15 17:49:07 +00:00
|
|
|
#include <jschelpers/JavaScriptCore.h>
|
2016-11-01 18:38:43 +00:00
|
|
|
#include <jschelpers/Value.h>
|
|
|
|
|
2016-05-04 02:29:58 +00:00
|
|
|
namespace facebook {
|
|
|
|
namespace react {
|
|
|
|
|
|
|
|
class MessageQueueThread;
|
|
|
|
|
2017-01-10 15:04:49 +00:00
|
|
|
class RN_EXPORT JSCExecutorFactory : public JSExecutorFactory {
|
2016-05-04 02:29:58 +00:00
|
|
|
public:
|
|
|
|
JSCExecutorFactory(const std::string& cacheDir, const folly::dynamic& jscConfig) :
|
2016-05-18 19:46:01 +00:00
|
|
|
m_cacheDir(cacheDir),
|
2016-05-04 02:29:58 +00:00
|
|
|
m_jscConfig(jscConfig) {}
|
|
|
|
virtual std::unique_ptr<JSExecutor> createJSExecutor(
|
2016-05-18 19:46:01 +00:00
|
|
|
std::shared_ptr<ExecutorDelegate> delegate,
|
|
|
|
std::shared_ptr<MessageQueueThread> jsQueue) override;
|
2016-05-04 02:29:58 +00:00
|
|
|
private:
|
2016-05-18 19:46:01 +00:00
|
|
|
std::string m_cacheDir;
|
2016-05-04 02:29:58 +00:00
|
|
|
folly::dynamic m_jscConfig;
|
|
|
|
};
|
|
|
|
|
|
|
|
class JSCExecutor;
|
|
|
|
class WorkerRegistration : public noncopyable {
|
|
|
|
public:
|
2016-05-18 19:46:01 +00:00
|
|
|
explicit WorkerRegistration(JSCExecutor* executor_, Object jsObj_) :
|
2016-05-04 02:29:58 +00:00
|
|
|
executor(executor_),
|
|
|
|
jsObj(std::move(jsObj_)) {}
|
|
|
|
|
|
|
|
JSCExecutor *executor;
|
|
|
|
Object jsObj;
|
|
|
|
};
|
|
|
|
|
2016-11-24 17:25:06 +00:00
|
|
|
template <typename T>
|
|
|
|
struct ValueEncoder;
|
|
|
|
|
2017-01-10 15:04:49 +00:00
|
|
|
class RN_EXPORT JSCExecutor : public JSExecutor {
|
2016-05-04 02:29:58 +00:00
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Must be invoked from thread this Executor will run on.
|
|
|
|
*/
|
2016-05-18 19:46:01 +00:00
|
|
|
explicit JSCExecutor(std::shared_ptr<ExecutorDelegate> delegate,
|
|
|
|
std::shared_ptr<MessageQueueThread> messageQueueThread,
|
|
|
|
const std::string& cacheDir,
|
2016-06-16 23:00:22 +00:00
|
|
|
const folly::dynamic& jscConfig) throw(JSException);
|
2016-05-04 02:29:58 +00:00
|
|
|
~JSCExecutor() override;
|
|
|
|
|
|
|
|
virtual void loadApplicationScript(
|
2016-05-14 00:15:06 +00:00
|
|
|
std::unique_ptr<const JSBigString> script,
|
2017-01-10 15:04:53 +00:00
|
|
|
std::string sourceURL) override;
|
2016-11-18 13:01:09 +00:00
|
|
|
|
2016-05-04 02:29:58 +00:00
|
|
|
virtual void setJSModulesUnbundle(
|
|
|
|
std::unique_ptr<JSModulesUnbundle> unbundle) override;
|
2016-11-18 13:01:09 +00:00
|
|
|
|
2016-05-04 02:29:58 +00:00
|
|
|
virtual void callFunction(
|
|
|
|
const std::string& moduleId,
|
|
|
|
const std::string& methodId,
|
2016-07-22 00:32:42 +00:00
|
|
|
const folly::dynamic& arguments) override;
|
2016-11-18 13:01:09 +00:00
|
|
|
|
2016-05-04 02:29:58 +00:00
|
|
|
virtual void invokeCallback(
|
|
|
|
const double callbackId,
|
2016-07-22 00:32:42 +00:00
|
|
|
const folly::dynamic& arguments) override;
|
2016-11-18 13:01:09 +00:00
|
|
|
|
2016-09-26 23:01:43 +00:00
|
|
|
template <typename T>
|
|
|
|
Value callFunctionSync(
|
|
|
|
const std::string& module, const std::string& method, T&& args) {
|
2016-11-24 17:25:06 +00:00
|
|
|
return callFunctionSyncWithValue(
|
|
|
|
module, method, ValueEncoder<typename std::decay<T>::type>::toValue(
|
|
|
|
m_context, std::forward<T>(args)));
|
2016-09-26 23:01:43 +00:00
|
|
|
}
|
2016-11-18 13:01:09 +00:00
|
|
|
|
2016-05-04 02:29:58 +00:00
|
|
|
virtual void setGlobalVariable(
|
2016-05-14 00:15:06 +00:00
|
|
|
std::string propName,
|
2016-07-22 00:32:42 +00:00
|
|
|
std::unique_ptr<const JSBigString> jsonValue) override;
|
2016-11-18 13:01:09 +00:00
|
|
|
|
2016-05-04 02:29:58 +00:00
|
|
|
virtual void* getJavaScriptContext() override;
|
2016-11-18 13:01:09 +00:00
|
|
|
|
2016-05-04 02:29:58 +00:00
|
|
|
virtual bool supportsProfiling() override;
|
|
|
|
virtual void startProfiler(const std::string &titleString) override;
|
|
|
|
virtual void stopProfiler(const std::string &titleString, const std::string &filename) override;
|
2016-11-18 13:01:09 +00:00
|
|
|
|
2016-05-26 18:07:41 +00:00
|
|
|
virtual void handleMemoryPressureUiHidden() override;
|
2016-05-04 02:29:58 +00:00
|
|
|
virtual void handleMemoryPressureModerate() override;
|
|
|
|
virtual void handleMemoryPressureCritical() override;
|
2016-11-18 13:01:09 +00:00
|
|
|
|
2016-05-04 02:29:58 +00:00
|
|
|
virtual void destroy() override;
|
2016-11-18 13:01:09 +00:00
|
|
|
|
2016-10-14 18:29:47 +00:00
|
|
|
void setContextName(const std::string& name);
|
2016-05-04 02:29:58 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
JSGlobalContextRef m_context;
|
2016-05-18 19:46:01 +00:00
|
|
|
std::shared_ptr<ExecutorDelegate> m_delegate;
|
2016-05-04 02:29:58 +00:00
|
|
|
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<bool> m_isDestroyed = std::shared_ptr<bool>(new bool(false));
|
|
|
|
std::unordered_map<int, WorkerRegistration> m_ownedWorkers;
|
|
|
|
std::string m_deviceCacheDir;
|
|
|
|
std::shared_ptr<MessageQueueThread> m_messageQueueThread;
|
|
|
|
std::unique_ptr<JSModulesUnbundle> m_unbundle;
|
2016-10-11 14:19:31 +00:00
|
|
|
JSCNativeModules m_nativeModules;
|
2016-05-04 02:29:58 +00:00
|
|
|
folly::dynamic m_jscConfig;
|
2017-03-20 20:03:04 +00:00
|
|
|
std::once_flag m_bindFlag;
|
2016-05-04 02:29:58 +00:00
|
|
|
|
2016-06-21 17:08:31 +00:00
|
|
|
folly::Optional<Object> m_invokeCallbackAndReturnFlushedQueueJS;
|
|
|
|
folly::Optional<Object> m_callFunctionReturnFlushedQueueJS;
|
|
|
|
folly::Optional<Object> m_flushedQueueJS;
|
2016-09-26 23:01:43 +00:00
|
|
|
folly::Optional<Object> m_callFunctionReturnResultAndFlushedQueueJS;
|
2016-06-21 17:08:31 +00:00
|
|
|
|
2016-05-04 02:29:58 +00:00
|
|
|
/**
|
|
|
|
* WebWorker constructor. Must be invoked from thread this Executor will run on.
|
|
|
|
*/
|
|
|
|
JSCExecutor(
|
2016-05-18 19:46:01 +00:00
|
|
|
std::shared_ptr<ExecutorDelegate> delegate,
|
2016-05-04 02:29:58 +00:00
|
|
|
std::shared_ptr<MessageQueueThread> messageQueueThread,
|
|
|
|
int workerId,
|
|
|
|
JSCExecutor *owner,
|
2016-05-14 00:15:06 +00:00
|
|
|
std::string scriptURL,
|
|
|
|
std::unordered_map<std::string, std::string> globalObjAsJSON,
|
2016-05-04 02:29:58 +00:00
|
|
|
const folly::dynamic& jscConfig);
|
|
|
|
|
2016-06-16 23:00:22 +00:00
|
|
|
void initOnJSVMThread() throw(JSException);
|
2016-09-26 23:01:43 +00:00
|
|
|
// This method is experimental, and may be modified or removed.
|
|
|
|
Value callFunctionSyncWithValue(
|
|
|
|
const std::string& module, const std::string& method, Value value);
|
2016-05-04 02:29:58 +00:00
|
|
|
void terminateOnJSVMThread();
|
2016-06-21 17:08:31 +00:00
|
|
|
void bindBridge() throw(JSException);
|
2016-09-01 21:59:25 +00:00
|
|
|
void callNativeModules(Value&&);
|
2016-07-22 00:32:42 +00:00
|
|
|
void flush();
|
2016-09-19 11:43:09 +00:00
|
|
|
void flushQueueImmediate(Value&&);
|
2016-05-04 02:29:58 +00:00
|
|
|
void loadModule(uint32_t moduleId);
|
|
|
|
|
2016-05-14 00:15:06 +00:00
|
|
|
int addWebWorker(std::string scriptURL, JSValueRef workerRef, JSValueRef globalObjRef);
|
2016-05-12 21:32:42 +00:00
|
|
|
void postMessageToOwnedWebWorker(int worker, JSValueRef message);
|
2016-05-04 02:29:58 +00:00
|
|
|
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);
|
|
|
|
|
2016-11-22 14:05:36 +00:00
|
|
|
template<JSValueRef (JSCExecutor::*method)(size_t, const JSValueRef[])>
|
2016-05-12 21:32:37 +00:00
|
|
|
void installNativeHook(const char* name);
|
2016-10-11 14:19:31 +00:00
|
|
|
JSValueRef getNativeModule(JSObjectRef object, JSStringRef propertyName);
|
2016-05-12 21:32:37 +00:00
|
|
|
|
2016-05-12 21:32:42 +00:00
|
|
|
JSValueRef nativeStartWorker(
|
2016-05-04 02:29:58 +00:00
|
|
|
size_t argumentCount,
|
2016-05-12 21:32:42 +00:00
|
|
|
const JSValueRef arguments[]);
|
|
|
|
JSValueRef nativePostMessageToWorker(
|
2016-05-04 02:29:58 +00:00
|
|
|
size_t argumentCount,
|
2016-05-12 21:32:42 +00:00
|
|
|
const JSValueRef arguments[]);
|
|
|
|
JSValueRef nativeTerminateWorker(
|
2016-05-04 02:29:58 +00:00
|
|
|
size_t argumentCount,
|
2016-05-12 21:32:42 +00:00
|
|
|
const JSValueRef arguments[]);
|
|
|
|
JSValueRef nativePostMessage(
|
2016-05-04 02:29:58 +00:00
|
|
|
size_t argumentCount,
|
2016-05-12 21:32:42 +00:00
|
|
|
const JSValueRef arguments[]);
|
|
|
|
JSValueRef nativeRequire(
|
2016-05-04 02:29:58 +00:00
|
|
|
size_t argumentCount,
|
2016-05-12 21:32:42 +00:00
|
|
|
const JSValueRef arguments[]);
|
|
|
|
JSValueRef nativeFlushQueueImmediate(
|
2016-05-04 02:29:58 +00:00
|
|
|
size_t argumentCount,
|
2016-05-12 21:32:42 +00:00
|
|
|
const JSValueRef arguments[]);
|
|
|
|
JSValueRef nativeCallSyncHook(
|
2016-05-04 02:29:58 +00:00
|
|
|
size_t argumentCount,
|
2016-05-12 21:32:42 +00:00
|
|
|
const JSValueRef arguments[]);
|
2016-05-04 02:29:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} }
|