Add locking around calls from JSCExecuter

Reviewed By: javache

Differential Revision: D5488452

fbshipit-source-id: bda18e7948574117b8ce95894782e0e6e9c321de
This commit is contained in:
Kathy Gray
2017-08-08 04:46:23 -07:00
committed by Facebook Github Bot
parent 8d757e5ad7
commit 66a788fd99
3 changed files with 83 additions and 14 deletions

View File

@@ -287,6 +287,7 @@ void JSCExecutor::loadApplicationScript(std::unique_ptr<const JSBigString> scrip
// TODO t15069155: reduce the number of overrides here
#ifdef WITH_FBJSCEXTENSIONS
if (auto fileStr = dynamic_cast<const JSBigFileString *>(script.get())) {
JSContextLock lock(m_context);
JSLoadSourceStatus jsStatus;
auto bcSourceCode = JSCreateSourceCodeFromFile(fileStr->fd(), jsSourceURL, nullptr, &jsStatus);
@@ -295,7 +296,6 @@ void JSCExecutor::loadApplicationScript(std::unique_ptr<const JSBigString> scrip
if (!bcSourceCode) {
throw std::runtime_error("Unexpected error opening compiled bundle");
}
evaluateSourceCode(m_context, bcSourceCode, jsSourceURL);
flush();
@@ -332,6 +332,7 @@ void JSCExecutor::loadApplicationScript(std::unique_ptr<const JSBigString> scrip
#endif
{
String jsScript;
JSContextLock lock(m_context);
{
SystraceSection s_("JSCExecutor::loadApplicationScript-createExpectingAscii");
ReactMarker::logMarker(ReactMarker::JS_BUNDLE_STRING_CONVERT_START);
@@ -433,10 +434,10 @@ void JSCExecutor::flush() {
void JSCExecutor::callFunction(const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) {
SystraceSection s("JSCExecutor::callFunction");
// This weird pattern is because Value is not default constructible.
// The lambda is inlined, so there's no overhead.
auto result = [&] {
JSContextLock lock(m_context);
try {
if (!m_callFunctionReturnResultAndFlushedQueueJS) {
bindBridge();
@@ -451,13 +452,13 @@ void JSCExecutor::callFunction(const std::string& moduleId, const std::string& m
std::runtime_error("Error calling " + moduleId + "." + methodId));
}
}();
callNativeModules(std::move(result));
}
void JSCExecutor::invokeCallback(const double callbackId, const folly::dynamic& arguments) {
SystraceSection s("JSCExecutor::invokeCallback");
auto result = [&] {
JSContextLock lock(m_context);
try {
if (!m_invokeCallbackAndReturnFlushedQueueJS) {
bindBridge();
@@ -471,29 +472,29 @@ void JSCExecutor::invokeCallback(const double callbackId, const folly::dynamic&
std::runtime_error(folly::to<std::string>("Error invoking callback ", callbackId)));
}
}();
callNativeModules(std::move(result));
}
Value JSCExecutor::callFunctionSyncWithValue(
const std::string& module, const std::string& method, Value args) {
SystraceSection s("JSCExecutor::callFunction");
if (!m_callFunctionReturnResultAndFlushedQueueJS) {
bindBridge();
}
Object result = m_callFunctionReturnResultAndFlushedQueueJS->callAsFunction({
Value(m_context, String::createExpectingAscii(m_context, module)),
Value(m_context, String::createExpectingAscii(m_context, method)),
std::move(args),
}).asObject();
Object result = [&] {
JSContextLock lock(m_context);
if (!m_callFunctionReturnResultAndFlushedQueueJS) {
bindBridge();
}
return m_callFunctionReturnResultAndFlushedQueueJS->callAsFunction({
Value(m_context, String::createExpectingAscii(m_context, module)),
Value(m_context, String::createExpectingAscii(m_context, 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);
}