diff --git a/ReactAndroid/src/main/jni/react/JSCExecutor.cpp b/ReactAndroid/src/main/jni/react/JSCExecutor.cpp index a26a79742..c76c24ed1 100644 --- a/ReactAndroid/src/main/jni/react/JSCExecutor.cpp +++ b/ReactAndroid/src/main/jni/react/JSCExecutor.cpp @@ -68,25 +68,6 @@ static JSValueRef nativeInjectHMRUpdate( const JSValueRef arguments[], JSValueRef *exception); -static std::string executeJSCallWithJSC( - JSGlobalContextRef ctx, - const std::string& methodName, - const std::vector& arguments) { - #ifdef WITH_FBSYSTRACE - FbSystraceSection s( - TRACE_TAG_REACT_CXX_BRIDGE, "JSCExecutor.executeJSCall", - "method", methodName); - #endif - - // Evaluate script with JSC - folly::dynamic jsonArgs(arguments.begin(), arguments.end()); - auto js = folly::to( - "__fbBatchedBridge.", methodName, ".apply(null, ", - folly::toJson(jsonArgs), ")"); - auto result = evaluateScript(ctx, String(js.c_str()), nullptr); - return Value(ctx, result).toJSONString(); -} - std::unique_ptr JSCExecutorFactory::createJSExecutor(Bridge *bridge) { return std::unique_ptr(new JSCExecutor(bridge, cacheDir_, m_jscConfig)); } @@ -202,6 +183,8 @@ void JSCExecutor::terminateOnJSVMThread() { m_batchedBridge.reset(); m_flushedQueueObj.reset(); + m_callFunctionObj.reset(); + m_invokeCallbackObj.reset(); s_globalContextRefToJSCExecutor.erase(m_context); JSGlobalContextRelease(m_context); @@ -266,6 +249,8 @@ bool JSCExecutor::ensureBatchedBridgeObject() { } m_batchedBridge = folly::make_unique(batchedBridgeValue.asObject()); m_flushedQueueObj = folly::make_unique(m_batchedBridge->getProperty("flushedQueue").asObject()); + m_callFunctionObj = folly::make_unique(m_batchedBridge->getProperty("callFunctionReturnFlushedQueue").asObject()); + m_invokeCallbackObj = folly::make_unique(m_batchedBridge->getProperty("invokeCallbackAndReturnFlushedQueue").asObject()); return true; } @@ -290,6 +275,10 @@ void JSCExecutor::flush() { } void JSCExecutor::callFunction(const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) { +#ifdef WITH_FBSYSTRACE + FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "JSCExecutor.callFunction"); +#endif + if (!ensureBatchedBridgeObject()) { throwJSExecutionException( "Couldn't call JS module %s, method %s: bridge configuration isn't available. This " @@ -298,27 +287,35 @@ void JSCExecutor::callFunction(const std::string& moduleId, const std::string& m methodId.c_str()); } - std::vector call { - moduleId, - methodId, - std::move(arguments), + String argsString = String(folly::toJson(std::move(arguments)).c_str()); + String moduleIdStr(moduleId.c_str()); + String methodIdStr(methodId.c_str()); + JSValueRef args[] = { + JSValueMakeString(m_context, moduleIdStr), + JSValueMakeString(m_context, methodIdStr), + Value::fromJSON(m_context, argsString) }; - std::string calls = executeJSCallWithJSC(m_context, "callFunctionReturnFlushedQueue", std::move(call)); - m_bridge->callNativeModules(*this, calls, true); + auto result = m_callFunctionObj->callAsFunction(3, args); + m_bridge->callNativeModules(*this, result.toJSONString(), true); } void JSCExecutor::invokeCallback(const double callbackId, const folly::dynamic& arguments) { +#ifdef WITH_FBSYSTRACE + FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "JSCExecutor.invokeCallback"); +#endif + if (!ensureBatchedBridgeObject()) { throwJSExecutionException( "Couldn't invoke JS callback %d: bridge configuration isn't available. This shouldn't be possible. Congratulations.", (int) callbackId); } - std::vector call { - (double) callbackId, - std::move(arguments) + String argsString = String(folly::toJson(std::move(arguments)).c_str()); + JSValueRef args[] = { + JSValueMakeNumber(m_context, callbackId), + Value::fromJSON(m_context, argsString) }; - std::string calls = executeJSCallWithJSC(m_context, "invokeCallbackAndReturnFlushedQueue", std::move(call)); - m_bridge->callNativeModules(*this, calls, true); + auto result = m_invokeCallbackObj->callAsFunction(2, args); + m_bridge->callNativeModules(*this, result.toJSONString(), true); } void JSCExecutor::setGlobalVariable(const std::string& propName, const std::string& jsonValue) { diff --git a/ReactAndroid/src/main/jni/react/JSCExecutor.h b/ReactAndroid/src/main/jni/react/JSCExecutor.h index acd6d14cc..5faca08ba 100644 --- a/ReactAndroid/src/main/jni/react/JSCExecutor.h +++ b/ReactAndroid/src/main/jni/react/JSCExecutor.h @@ -91,6 +91,8 @@ private: folly::dynamic m_jscConfig; std::unique_ptr m_batchedBridge; std::unique_ptr m_flushedQueueObj; + std::unique_ptr m_callFunctionObj; + std::unique_ptr m_invokeCallbackObj; /** * WebWorker constructor. Must be invoked from thread this Executor will run on.