JSCExecutor.h
5.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright 2004-present Facebook. All Rights Reserved.
#pragma once
#include <cstdint>
#include <memory>
#include <mutex>
#include <cxxreact/JSCNativeModules.h>
#include <cxxreact/JSExecutor.h>
#include <folly/Optional.h>
#include <folly/json.h>
#include <jschelpers/JSCHelpers.h>
#include <jschelpers/JavaScriptCore.h>
#include <jschelpers/Value.h>
#include <privatedata/PrivateDataBase.h>
#ifndef RN_EXPORT
#define RN_EXPORT __attribute__((visibility("default")))
#endif
namespace facebook {
namespace react {
class MessageQueueThread;
class RAMBundleRegistry;
class RN_EXPORT JSCExecutorFactory : public JSExecutorFactory {
public:
JSCExecutorFactory(const folly::dynamic& jscConfig, std::function<folly::dynamic(const std::string &)> provider) :
m_jscConfig(jscConfig), m_nativeExtensionsProvider(provider) {}
std::unique_ptr<JSExecutor> createJSExecutor(
std::shared_ptr<ExecutorDelegate> delegate,
std::shared_ptr<MessageQueueThread> jsQueue) override;
private:
std::string m_cacheDir;
folly::dynamic m_jscConfig;
std::function<folly::dynamic(const std::string &)> m_nativeExtensionsProvider;
};
template<typename T>
struct JSCValueEncoder {
// If you get a build error here, it means the compiler can't see the template instantation of toJSCValue
// applicable to your type.
static const Value toJSCValue(JSGlobalContextRef ctx, T&& value);
};
template<>
struct JSCValueEncoder<folly::dynamic> {
static const Value toJSCValue(JSGlobalContextRef ctx, const folly::dynamic &&value) {
return Value::fromDynamic(ctx, value);
}
};
class RN_EXPORT JSCExecutor : public JSExecutor, public PrivateDataBase {
public:
/**
* Must be invoked from thread this Executor will run on.
*/
explicit JSCExecutor(std::shared_ptr<ExecutorDelegate> delegate,
std::shared_ptr<MessageQueueThread> messageQueueThread,
const folly::dynamic& jscConfig,
std::function<folly::dynamic(const std::string &)> nativeExtensionsProvider) throw(JSException);
~JSCExecutor() override;
virtual void loadApplicationScript(
std::unique_ptr<const JSBigString> script,
std::string sourceURL) override;
virtual void setBundleRegistry(std::unique_ptr<RAMBundleRegistry> bundleRegistry) override;
virtual void registerBundle(uint32_t bundleId, const std::string& bundlePath) 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 <typename T>
Value callFunctionSync(
const std::string& module, const std::string& method, T&& args) {
return callFunctionSyncWithValue(
module, method, JSCValueEncoder<typename std::decay<T>::type>::toJSCValue(
m_context, std::forward<T>(args)));
}
virtual void setGlobalVariable(
std::string propName,
std::unique_ptr<const JSBigString> jsonValue) override;
virtual std::string getDescription() override;
virtual void* getJavaScriptContext() override;
virtual bool isInspectable() override;
#ifdef WITH_JSC_MEMORY_PRESSURE
virtual void handleMemoryPressure(int pressureLevel) override;
#endif
virtual void destroy() override;
void setContextName(const std::string& name);
private:
JSGlobalContextRef m_context;
std::shared_ptr<ExecutorDelegate> m_delegate;
std::shared_ptr<bool> m_isDestroyed = std::shared_ptr<bool>(new bool(false));
std::shared_ptr<MessageQueueThread> m_messageQueueThread;
std::unique_ptr<RAMBundleRegistry> m_bundleRegistry;
JSCNativeModules m_nativeModules;
folly::dynamic m_jscConfig;
std::once_flag m_bindFlag;
std::function<folly::dynamic(const std::string &)> m_nativeExtensionsProvider;
folly::Optional<Object> m_invokeCallbackAndReturnFlushedQueueJS;
folly::Optional<Object> m_callFunctionReturnFlushedQueueJS;
folly::Optional<Object> m_flushedQueueJS;
folly::Optional<Object> m_callFunctionReturnResultAndFlushedQueueJS;
void initOnJSVMThread() throw(JSException);
static bool isNetworkInspected(const std::string &owner, const std::string &app, const std::string &device);
// 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 bundleId, uint32_t moduleId);
String adoptString(std::unique_ptr<const JSBigString>);
template<JSValueRef (JSCExecutor::*method)(size_t, const JSValueRef[])>
void installNativeHook(const char* name);
JSValueRef getNativeModule(JSObjectRef object, JSStringRef propertyName);
JSValueRef getNativeExtension(JSObjectRef object, JSStringRef propertyName);
JSValueRef nativeRequire(
size_t argumentCount,
const JSValueRef arguments[]);
JSValueRef nativeFlushQueueImmediate(
size_t argumentCount,
const JSValueRef arguments[]);
JSValueRef nativeCallSyncHook(
size_t argumentCount,
const JSValueRef arguments[]);
};
} }