Add API for sync function calls
Reviewed By: javache Differential Revision: D3897526 fbshipit-source-id: cadead316996ca7c1dd2b0d60d87945f5452640c
This commit is contained in:
parent
6071e8ca2c
commit
d7a2d3a957
|
@ -55,6 +55,11 @@ class Instance {
|
|||
void callJSCallback(ExecutorToken token, uint64_t callbackId, folly::dynamic&& params);
|
||||
MethodCallResult callSerializableNativeHook(ExecutorToken token, unsigned int moduleId,
|
||||
unsigned int methodId, folly::dynamic&& args);
|
||||
// This method is experimental, and may be modified or removed.
|
||||
template <typename T>
|
||||
Value callFunctionSync(const std::string& module, const std::string& method, T&& args) {
|
||||
return nativeToJsBridge_->callFunctionSync(module, method, std::forward<T>(args));
|
||||
}
|
||||
|
||||
ExecutorToken getMainExecutorToken();
|
||||
void handleMemoryPressureUiHidden();
|
||||
|
|
|
@ -118,7 +118,6 @@ JSCExecutor::JSCExecutor(std::shared_ptr<ExecutorDelegate> delegate,
|
|||
folly::dynamic::object
|
||||
("remoteModuleConfig", std::move(nativeModuleConfig));
|
||||
|
||||
|
||||
SystraceSection t("setGlobalVariable");
|
||||
setGlobalVariable(
|
||||
"__fbBatchedBridgeConfig",
|
||||
|
@ -344,6 +343,7 @@ void JSCExecutor::bindBridge() throw(JSException) {
|
|||
m_callFunctionReturnFlushedQueueJS = batchedBridge.getProperty("callFunctionReturnFlushedQueue").asObject();
|
||||
m_invokeCallbackAndReturnFlushedQueueJS = batchedBridge.getProperty("invokeCallbackAndReturnFlushedQueue").asObject();
|
||||
m_flushedQueueJS = batchedBridge.getProperty("flushedQueue").asObject();
|
||||
m_callFunctionReturnResultAndFlushedQueueJS = batchedBridge.getProperty("callFunctionReturnResultAndFlushedQueue").asObject();
|
||||
}
|
||||
|
||||
void JSCExecutor::callNativeModules(Value&& value) {
|
||||
|
@ -405,6 +405,26 @@ void JSCExecutor::invokeCallback(const double callbackId, const folly::dynamic&
|
|||
callNativeModules(std::move(result));
|
||||
}
|
||||
|
||||
Value JSCExecutor::callFunctionSyncWithValue(
|
||||
const std::string& module, const std::string& method, Value args) {
|
||||
SystraceSection s("JSCExecutor::callFunction");
|
||||
|
||||
Object result = m_callFunctionReturnResultAndFlushedQueueJS->callAsFunction({
|
||||
Value(m_context, String::createExpectingAscii(module)),
|
||||
Value(m_context, String::createExpectingAscii(method)),
|
||||
std::move(args),
|
||||
}).asObject();
|
||||
|
||||
Value length = result.getProperty("length");
|
||||
|
||||
if (!length.isNumber() || length.asInteger() != 2) {
|
||||
std::runtime_error("Return value of a callFunction must be an array of size 2");
|
||||
}
|
||||
|
||||
callNativeModules(result.getPropertyAtIndex(1));
|
||||
return result.getPropertyAtIndex(0);
|
||||
}
|
||||
|
||||
void JSCExecutor::setGlobalVariable(std::string propName, std::unique_ptr<const JSBigString> jsonValue) {
|
||||
try {
|
||||
SystraceSection s("JSCExecutor.setGlobalVariable",
|
||||
|
|
|
@ -74,6 +74,12 @@ public:
|
|||
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,
|
||||
toValue(m_context, std::forward<T>(args)));
|
||||
}
|
||||
virtual void setGlobalVariable(
|
||||
std::string propName,
|
||||
std::unique_ptr<const JSBigString> jsonValue) override;
|
||||
|
@ -101,6 +107,7 @@ private:
|
|||
folly::Optional<Object> m_invokeCallbackAndReturnFlushedQueueJS;
|
||||
folly::Optional<Object> m_callFunctionReturnFlushedQueueJS;
|
||||
folly::Optional<Object> m_flushedQueueJS;
|
||||
folly::Optional<Object> m_callFunctionReturnResultAndFlushedQueueJS;
|
||||
|
||||
/**
|
||||
* WebWorker constructor. Must be invoked from thread this Executor will run on.
|
||||
|
@ -115,6 +122,9 @@ private:
|
|||
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&&);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "Executor.h"
|
||||
#include "ExecutorToken.h"
|
||||
#include "JSCExecutor.h"
|
||||
#include "JSModulesUnbundle.h"
|
||||
#include "MessageQueueThread.h"
|
||||
#include "MethodCall.h"
|
||||
|
@ -80,6 +81,35 @@ public:
|
|||
*/
|
||||
void invokeCallback(ExecutorToken executorToken, double callbackId, folly::dynamic&& args);
|
||||
|
||||
/**
|
||||
* Executes a JS method on the given executor synchronously, returning its
|
||||
* return value. JSException will be thrown if JS throws an exception;
|
||||
* another standard exception may be thrown for C++ bridge failures, or if
|
||||
* the executor is not capable of synchronous calls.
|
||||
*
|
||||
* This method is experimental, and may be modified or removed.
|
||||
*
|
||||
* loadApplicationScriptSync() must be called and finished executing
|
||||
* before callFunctionSync().
|
||||
*/
|
||||
template <typename T>
|
||||
Value callFunctionSync(const std::string& module, const std::string& method, T&& args) {
|
||||
if (*m_destroyed) {
|
||||
throw std::logic_error(
|
||||
folly::to<std::string>("Synchronous call to ", module, ".", method,
|
||||
" after bridge is destroyed"));
|
||||
}
|
||||
|
||||
JSCExecutor *jscExecutor = dynamic_cast<JSCExecutor*>(m_mainExecutor);
|
||||
if (!jscExecutor) {
|
||||
throw std::invalid_argument(
|
||||
folly::to<std::string>("Executor type ", typeid(*m_mainExecutor).name(),
|
||||
" does not support synchronous calls"));
|
||||
}
|
||||
|
||||
return jscExecutor->callFunctionSync(module, method, std::forward<T>(args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the JS application. If unbundle is non-null, then it is
|
||||
* used to fetch JavaScript modules as individual scripts.
|
||||
|
|
Loading…
Reference in New Issue