From 1d571c5ed51e40d681218605e75aacb8218af5fe Mon Sep 17 00:00:00 2001 From: Marc Horowitz Date: Thu, 1 Sep 2016 14:59:25 -0700 Subject: [PATCH] Don't use the same throw for calling into JSC, and calling into native modules Differential Revision: D3779181 fbshipit-source-id: 7fb17c9c90abd9302137dad3a326c6ce30e7ca86 --- ReactCommon/cxxreact/JSCExecutor.cpp | 62 +++++++++++++++++----------- ReactCommon/cxxreact/JSCExecutor.h | 1 + 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/ReactCommon/cxxreact/JSCExecutor.cpp b/ReactCommon/cxxreact/JSCExecutor.cpp index 57c37f5b7e6c58..b4cf66d4782593 100644 --- a/ReactCommon/cxxreact/JSCExecutor.cpp +++ b/ReactCommon/cxxreact/JSCExecutor.cpp @@ -344,15 +344,14 @@ void JSCExecutor::bindBridge() throw(JSException) { m_flushedQueueJS = batchedBridge.getProperty("flushedQueue").asObject(); } -void JSCExecutor::flush() { - auto result = m_flushedQueueJS->callAsFunction({}); +void JSCExecutor::callNativeModules(Value&& value) { try { - auto calls = Value(m_context, result).toJSONString(); + auto calls = value.toJSONString(); m_delegate->callNativeModules(*this, std::move(calls), true); } catch (...) { std::string message = "Error in flush()"; try { - message += ":" + Value(m_context, result).toString().str(); + message += ":" + value.toString().str(); } catch (...) { // ignored } @@ -360,31 +359,44 @@ void JSCExecutor::flush() { } } +void JSCExecutor::flush() { + callNativeModules(m_flushedQueueJS->callAsFunction({})); +} + void JSCExecutor::callFunction(const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) { - try { - auto result = m_callFunctionReturnFlushedQueueJS->callAsFunction({ - Value(m_context, String::createExpectingAscii(moduleId)), - Value(m_context, String::createExpectingAscii(methodId)), - Value::fromDynamic(m_context, std::move(arguments)) - }); - auto calls = Value(m_context, result).toJSONString(); - m_delegate->callNativeModules(*this, std::move(calls), true); - } catch (...) { - std::throw_with_nested(std::runtime_error("Error calling function: " + moduleId + ":" + methodId)); - } + // This weird pattern is because Value is not default constructible. + // The lambda is inlined, so there's no overhead. + + auto result = [&] { + try { + return m_callFunctionReturnFlushedQueueJS->callAsFunction({ + Value(m_context, String::createExpectingAscii(moduleId)), + Value(m_context, String::createExpectingAscii(methodId)), + Value::fromDynamic(m_context, std::move(arguments)) + }); + } catch (...) { + std::throw_with_nested( + std::runtime_error("Error calling function: " + moduleId + ":" + methodId)); + } + }(); + + callNativeModules(std::move(result)); } void JSCExecutor::invokeCallback(const double callbackId, const folly::dynamic& arguments) { - try { - auto result = m_invokeCallbackAndReturnFlushedQueueJS->callAsFunction({ - JSValueMakeNumber(m_context, callbackId), - Value::fromDynamic(m_context, std::move(arguments)) - }); - auto calls = Value(m_context, result).toJSONString(); - m_delegate->callNativeModules(*this, std::move(calls), true); - } catch (...) { - std::throw_with_nested(std::runtime_error(folly::to("Error invoking callback.", callbackId))); - } + auto result = [&] { + try { + return m_invokeCallbackAndReturnFlushedQueueJS->callAsFunction({ + JSValueMakeNumber(m_context, callbackId), + Value::fromDynamic(m_context, std::move(arguments)) + }); + } catch (...) { + std::throw_with_nested( + std::runtime_error(folly::to("Error invoking callback.", callbackId))); + } + }(); + + callNativeModules(std::move(result)); } void JSCExecutor::setGlobalVariable(std::string propName, std::unique_ptr jsonValue) { diff --git a/ReactCommon/cxxreact/JSCExecutor.h b/ReactCommon/cxxreact/JSCExecutor.h index 455fa5b9d40560..c36e3adc3b159b 100644 --- a/ReactCommon/cxxreact/JSCExecutor.h +++ b/ReactCommon/cxxreact/JSCExecutor.h @@ -117,6 +117,7 @@ class JSCExecutor : public JSExecutor { void initOnJSVMThread() throw(JSException); void terminateOnJSVMThread(); void bindBridge() throw(JSException); + void callNativeModules(Value&&); void flush(); void flushQueueImmediate(std::string queueJSON); void loadModule(uint32_t moduleId);