From e4bb9f52e577cfc4d1f043e1f56e997f08657f67 Mon Sep 17 00:00:00 2001 From: Alexander Blom Date: Thu, 12 May 2016 14:32:42 -0700 Subject: [PATCH] Move all hooks over to new helper Reviewed By: astreet Differential Revision: D3292927 fbshipit-source-id: baafa6ded3872391ae1319b2855b2616ec79c2ad --- ReactCommon/bridge/JSCExecutor.cpp | 219 ++++++++--------------------- ReactCommon/bridge/JSCExecutor.h | 58 ++------ 2 files changed, 70 insertions(+), 207 deletions(-) diff --git a/ReactCommon/bridge/JSCExecutor.cpp b/ReactCommon/bridge/JSCExecutor.cpp index 1108f0bf6..2419348db 100644 --- a/ReactCommon/bridge/JSCExecutor.cpp +++ b/ReactCommon/bridge/JSCExecutor.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "Bridge.h" @@ -80,8 +81,6 @@ inline JSObjectCallAsFunctionCallback exceptionWrapMethod() { } -static std::unordered_map s_globalContextRefToJSCExecutor; - static JSValueRef nativeInjectHMRUpdate( JSContextRef ctx, JSObjectRef function, @@ -143,7 +142,7 @@ JSCExecutor::JSCExecutor( m_messageQueueThread->runOnQueue([this, script, globalObjAsJSON] () { initOnJSVMThread(); - installGlobalFunction(m_context, "postMessage", nativePostMessage); + installNativeHook<&JSCExecutor::nativePostMessage>("postMessage"); for (auto& it : globalObjAsJSON) { setGlobalVariable(it.first, it.second); @@ -189,13 +188,13 @@ void JSCExecutor::initOnJSVMThread() { // Add a pointer to ourselves so we can retrieve it later in our hooks JSObjectSetPrivate(JSContextGetGlobalObject(m_context), this); - s_globalContextRefToJSCExecutor[m_context] = this; - installGlobalFunction(m_context, "nativeFlushQueueImmediate", nativeFlushQueueImmediate); - installGlobalFunction(m_context, "nativeStartWorker", nativeStartWorker); - installGlobalFunction(m_context, "nativePostMessageToWorker", nativePostMessageToWorker); - installGlobalFunction(m_context, "nativeTerminateWorker", nativeTerminateWorker); + installNativeHook<&JSCExecutor::nativeFlushQueueImmediate>("nativeFlushQueueImmediate"); + installNativeHook<&JSCExecutor::nativeFlushQueueImmediate>("nativeFlushQueueImmediate"); + installNativeHook<&JSCExecutor::nativeStartWorker>("nativeStartWorker"); + installNativeHook<&JSCExecutor::nativePostMessageToWorker>("nativePostMessageToWorker"); + installNativeHook<&JSCExecutor::nativeTerminateWorker>("nativeTerminateWorker"); installGlobalFunction(m_context, "nativeInjectHMRUpdate", nativeInjectHMRUpdate); - installGlobalFunction(m_context, "nativeCallSyncHook", nativeCallSyncHook); + installNativeHook<&JSCExecutor::nativeCallSyncHook>("nativeCallSyncHook"); installGlobalFunction(m_context, "nativeLoggingHook", JSNativeHooks::loggingHook); installGlobalFunction(m_context, "nativePerformanceNow", JSNativeHooks::nowHook); @@ -230,7 +229,6 @@ void JSCExecutor::terminateOnJSVMThread() { terminateOwnedWebWorker(workerId); } - s_globalContextRefToJSCExecutor.erase(m_context); JSGlobalContextRelease(m_context); m_context = nullptr; } @@ -254,7 +252,7 @@ void JSCExecutor::loadApplicationScript( void JSCExecutor::setJSModulesUnbundle(std::unique_ptr unbundle) { if (!m_unbundle) { - installGlobalFunction(m_context, "nativeRequire", nativeRequire); + installNativeHook<&JSCExecutor::nativeRequire>("nativeRequire"); } m_unbundle = std::move(unbundle); } @@ -388,7 +386,7 @@ int JSCExecutor::addWebWorker( return workerId; } -void JSCExecutor::postMessageToOwnedWebWorker(int workerId, JSValueRef message, JSValueRef *exn) { +void JSCExecutor::postMessageToOwnedWebWorker(int workerId, JSValueRef message) { auto worker = m_ownedWorkers.at(workerId).executor; std::string msgString = Value(m_context, message).toJSONString(); @@ -468,227 +466,120 @@ void JSCExecutor::installNativeHook(const char* name) { } JSValueRef JSCExecutor::nativePostMessage( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception) { + const JSValueRef arguments[]) { if (argumentCount != 1) { - *exception = makeJSCException(ctx, "postMessage got wrong number of arguments"); - return JSValueMakeUndefined(ctx); + throw std::invalid_argument("Got wrong number of args"); } JSValueRef msg = arguments[0]; - JSCExecutor *webWorker = s_globalContextRefToJSCExecutor.at(JSContextGetGlobalContext(ctx)); + postMessageToOwner(msg); - webWorker->postMessageToOwner(msg); - - return JSValueMakeUndefined(ctx); -} - -static JSValueRef makeInvalidModuleIdJSCException( - JSContextRef ctx, - const JSValueRef id, - JSValueRef *exception) { - std::string message = "Received invalid module ID: "; - message += String::adopt(JSValueToStringCopy(ctx, id, exception)).str(); - return makeJSCException(ctx, message.c_str()); + return JSValueMakeUndefined(m_context); } JSValueRef JSCExecutor::nativeRequire( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception) { + const JSValueRef arguments[]) { if (argumentCount != 1) { - *exception = makeJSCException(ctx, "Got wrong number of args"); - return JSValueMakeUndefined(ctx); + throw std::invalid_argument("Got wrong number of args"); } - JSCExecutor *executor; - try { - executor = s_globalContextRefToJSCExecutor.at(JSContextGetGlobalContext(ctx)); - } catch (std::out_of_range& e) { - *exception = makeJSCException(ctx, "Global JS context didn't map to a valid executor"); - return JSValueMakeUndefined(ctx); - } - - double moduleId = JSValueToNumber(ctx, arguments[0], exception); + double moduleId = Value(m_context, arguments[0]).asNumber(); if (moduleId <= (double) std::numeric_limits::max() && moduleId >= 0.0) { try { - executor->loadModule(moduleId); + loadModule(moduleId); } catch (JSModulesUnbundle::ModuleNotFound&) { - *exception = makeInvalidModuleIdJSCException(ctx, arguments[0], exception); + throw std::invalid_argument(folly::to("Received invalid module ID: ", moduleId)); } } else { - *exception = makeInvalidModuleIdJSCException(ctx, arguments[0], exception); + throw std::invalid_argument(folly::to("Received invalid module ID: ", moduleId)); } - return JSValueMakeUndefined(ctx); -} - -static JSValueRef createErrorString(JSContextRef ctx, const char *msg) { - return JSValueMakeString(ctx, String(msg)); + return JSValueMakeUndefined(m_context); } JSValueRef JSCExecutor::nativeFlushQueueImmediate( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception) { + const JSValueRef arguments[]) { if (argumentCount != 1) { - *exception = createErrorString(ctx, "Got wrong number of args"); - return JSValueMakeUndefined(ctx); + throw std::invalid_argument("Got wrong number of args"); } - JSCExecutor *executor; - try { - executor = s_globalContextRefToJSCExecutor.at(JSContextGetGlobalContext(ctx)); - } catch (std::out_of_range& e) { - *exception = createErrorString(ctx, "Global JS context didn't map to a valid executor"); - return JSValueMakeUndefined(ctx); - } - - std::string resStr = Value(ctx, arguments[0]).toJSONString(); - - executor->flushQueueImmediate(resStr); - - return JSValueMakeUndefined(ctx); + std::string resStr = Value(m_context, arguments[0]).toJSONString(); + flushQueueImmediate(resStr); + return JSValueMakeUndefined(m_context); } JSValueRef JSCExecutor::nativeStartWorker( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception) { + const JSValueRef arguments[]) { if (argumentCount != 3) { - *exception = createErrorString(ctx, "Got wrong number of args"); - return JSValueMakeUndefined(ctx); + throw std::invalid_argument("Got wrong number of args"); } - std::string scriptFile = Value(ctx, arguments[0]).toString().str(); + std::string scriptFile = Value(m_context, arguments[0]).toString().str(); JSValueRef worker = arguments[1]; JSValueRef globalObj = arguments[2]; - JSCExecutor *executor; - try { - executor = s_globalContextRefToJSCExecutor.at(JSContextGetGlobalContext(ctx)); - } catch (std::out_of_range& e) { - *exception = createErrorString(ctx, "Global JS context didn't map to a valid executor"); - return JSValueMakeUndefined(ctx); - } + int workerId = addWebWorker(scriptFile, worker, globalObj); - int workerId = executor->addWebWorker(scriptFile, worker, globalObj); - - return JSValueMakeNumber(ctx, workerId); + return JSValueMakeNumber(m_context, workerId); } JSValueRef JSCExecutor::nativePostMessageToWorker( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception) { + const JSValueRef arguments[]) { if (argumentCount != 2) { - *exception = createErrorString(ctx, "Got wrong number of args"); - return JSValueMakeUndefined(ctx); + throw std::invalid_argument("Got wrong number of args"); } - double workerDouble = JSValueToNumber(ctx, arguments[0], exception); + double workerDouble = Value(m_context, arguments[0]).asNumber(); if (workerDouble != workerDouble) { - *exception = createErrorString(ctx, "Got invalid worker id"); - return JSValueMakeUndefined(ctx); + throw std::invalid_argument("Got invalid worker id"); } - JSCExecutor *executor; - try { - executor = s_globalContextRefToJSCExecutor.at(JSContextGetGlobalContext(ctx)); - } catch (std::out_of_range& e) { - *exception = createErrorString(ctx, "Global JS context didn't map to a valid executor"); - return JSValueMakeUndefined(ctx); - } + postMessageToOwnedWebWorker((int) workerDouble, arguments[1]); - executor->postMessageToOwnedWebWorker((int) workerDouble, arguments[1], exception); - - return JSValueMakeUndefined(ctx); + return JSValueMakeUndefined(m_context); } JSValueRef JSCExecutor::nativeTerminateWorker( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception) { + const JSValueRef arguments[]) { if (argumentCount != 1) { - *exception = createErrorString(ctx, "Got wrong number of args"); - return JSValueMakeUndefined(ctx); + throw std::invalid_argument("Got wrong number of args"); } - double workerDouble = JSValueToNumber(ctx, arguments[0], exception); + double workerDouble = Value(m_context, arguments[0]).asNumber(); if (workerDouble != workerDouble) { - *exception = createErrorString(ctx, "Got invalid worker id"); - return JSValueMakeUndefined(ctx); + std::invalid_argument("Got invalid worker id"); } - JSCExecutor *executor; - try { - executor = s_globalContextRefToJSCExecutor.at(JSContextGetGlobalContext(ctx)); - } catch (std::out_of_range& e) { - *exception = createErrorString(ctx, "Global JS context didn't map to a valid executor"); - return JSValueMakeUndefined(ctx); - } + terminateOwnedWebWorker((int) workerDouble); - executor->terminateOwnedWebWorker((int) workerDouble); - - return JSValueMakeUndefined(ctx); + return JSValueMakeUndefined(m_context); } JSValueRef JSCExecutor::nativeCallSyncHook( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception) { + const JSValueRef arguments[]) { if (argumentCount != 3) { - *exception = createErrorString(ctx, "Got wrong number of args for callSyncHook"); - return JSValueMakeUndefined(ctx); + throw std::invalid_argument("Got wrong number of args"); } - unsigned int moduleId = Value(ctx, arguments[0]).asUnsignedInteger(); - unsigned int methodId = Value(ctx, arguments[1]).asUnsignedInteger(); - std::string argsJson = Value(ctx, arguments[2]).toJSONString(); + unsigned int moduleId = Value(m_context, arguments[0]).asUnsignedInteger(); + unsigned int methodId = Value(m_context, arguments[1]).asUnsignedInteger(); + std::string argsJson = Value(m_context, arguments[2]).toJSONString(); - JSCExecutor *executor; - try { - executor = s_globalContextRefToJSCExecutor.at(JSContextGetGlobalContext(ctx)); - } catch (std::out_of_range& e) { - *exception = createErrorString(ctx, "Global JS context didn't map to a valid executor"); - return JSValueMakeUndefined(ctx); - } - - try { - MethodCallResult result = executor->m_bridge->callSerializableNativeHook( - moduleId, - methodId, - argsJson); - if (result.isUndefined) { - return JSValueMakeUndefined(ctx); - } - return Value::fromJSON(ctx, String(folly::toJson(result.result).c_str())); - } catch (...) { - *exception = translatePendingCppExceptionToJSError(ctx, "nativeCallSyncHook"); - return JSValueMakeUndefined(ctx); + MethodCallResult result = m_bridge->callSerializableNativeHook( + moduleId, + methodId, + argsJson); + if (result.isUndefined) { + return JSValueMakeUndefined(m_context); } + return Value::fromJSON(m_context, String(folly::toJson(result.result).c_str())); } static JSValueRef nativeInjectHMRUpdate( diff --git a/ReactCommon/bridge/JSCExecutor.h b/ReactCommon/bridge/JSCExecutor.h index 255c8096a..3b6c14f6c 100644 --- a/ReactCommon/bridge/JSCExecutor.h +++ b/ReactCommon/bridge/JSCExecutor.h @@ -108,7 +108,7 @@ private: void loadModule(uint32_t moduleId); int addWebWorker(const std::string& script, JSValueRef workerRef, JSValueRef globalObjRef); - void postMessageToOwnedWebWorker(int worker, JSValueRef message, JSValueRef *exn); + void postMessageToOwnedWebWorker(int worker, JSValueRef message); void postMessageToOwner(JSValueRef result); void receiveMessageFromOwnedWebWorker(int workerId, const std::string& message); void receiveMessageFromOwner(const std::string &msgString); @@ -118,55 +118,27 @@ private: template< JSValueRef (JSCExecutor::*method)(size_t, const JSValueRef[])> void installNativeHook(const char* name); - static JSValueRef nativeStartWorker( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, + JSValueRef nativeStartWorker( size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception); - static JSValueRef nativePostMessageToWorker( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, + const JSValueRef arguments[]); + JSValueRef nativePostMessageToWorker( size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception); - static JSValueRef nativeTerminateWorker( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, + const JSValueRef arguments[]); + JSValueRef nativeTerminateWorker( size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception); - static JSValueRef nativePostMessage( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, + const JSValueRef arguments[]); + JSValueRef nativePostMessage( size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception); - static JSValueRef nativeRequire( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, + const JSValueRef arguments[]); + JSValueRef nativeRequire( size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception); - static JSValueRef nativeFlushQueueImmediate( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, + const JSValueRef arguments[]); + JSValueRef nativeFlushQueueImmediate( size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception); - static JSValueRef nativeCallSyncHook( - JSContextRef ctx, - JSObjectRef function, - JSObjectRef thisObject, + const JSValueRef arguments[]); + JSValueRef nativeCallSyncHook( size_t argumentCount, - const JSValueRef arguments[], - JSValueRef *exception); + const JSValueRef arguments[]); }; } }