diff --git a/ReactCommon/cxxreact/BUCK b/ReactCommon/cxxreact/BUCK index efcf46c40..f2df12617 100644 --- a/ReactCommon/cxxreact/BUCK +++ b/ReactCommon/cxxreact/BUCK @@ -133,7 +133,7 @@ react_library( soname = 'libreactnativefb.$(ext)', header_namespace = 'cxxreact', force_static = True, - srcs = glob(['*.cpp']), + srcs = glob(['*.cpp'], excludes=['SampleCxxModule.cpp']), headers = glob(['*.h'], excludes=CXXREACT_PUBLIC_HEADERS), xcode_public_headers_symlinks = True, exported_headers = CXXREACT_PUBLIC_HEADERS, diff --git a/ReactCommon/cxxreact/JSCExecutor.cpp b/ReactCommon/cxxreact/JSCExecutor.cpp index acfeaa79e..f3a557b8b 100644 --- a/ReactCommon/cxxreact/JSCExecutor.cpp +++ b/ReactCommon/cxxreact/JSCExecutor.cpp @@ -209,8 +209,8 @@ void JSCExecutor::destroy() { } void JSCExecutor::setContextName(const std::string& name) { - String jsName = String(name.c_str()); - JSGlobalContextSetName(m_context, static_cast(jsName)); + String jsName = String(m_context, name.c_str()); + JSGlobalContextSetName(m_context, jsName); } void JSCExecutor::initOnJSVMThread() throw(JSException) { @@ -313,7 +313,7 @@ void JSCExecutor::loadApplicationScript( (flags & UNPACKED_JS_SOURCE) || (flags & UNPACKED_BYTECODE), "Optimized bundle with no unpacked source or bytecode"); - String jsSourceURL(sourceURL.c_str()); + String jsSourceURL(m_context, sourceURL.c_str()); JSSourceCodeRef sourceCode = nullptr; SCOPE_EXIT { if (sourceCode) { @@ -338,9 +338,11 @@ void JSCExecutor::loadApplicationScript( return loadApplicationScript(std::move(jsScriptBigString), sourceURL); } + #if defined(WITH_FB_JSC_TUNING) && defined(__ANDROID__) if (flags & UNPACKED_BC_CACHE) { configureJSCBCCache(m_context, bundlePath); } + #endif sourceCode = JSCreateSourceCode( jsScriptBigString->fd(), @@ -403,14 +405,14 @@ void JSCExecutor::loadApplicationScript(std::unique_ptr scrip ReactMarker::logMarker("RUN_JS_BUNDLE_START"); ReactMarker::logMarker("loadApplicationScript_startStringConvert"); - String jsScript = jsStringFromBigString(*script); + String jsScript = jsStringFromBigString(m_context, *script); ReactMarker::logMarker("loadApplicationScript_endStringConvert"); #ifdef WITH_FBSYSTRACE fbsystrace_end_section(TRACE_TAG_REACT_CXX_BRIDGE); #endif - String jsSourceURL(sourceURL.c_str()); + String jsSourceURL(m_context, sourceURL.c_str()); evaluateScript(m_context, jsScript, jsSourceURL); // TODO(luk): t13903306 Remove this check once we make native modules working for java2js @@ -473,8 +475,8 @@ void JSCExecutor::callFunction(const std::string& moduleId, const std::string& m auto result = [&] { try { return m_callFunctionReturnFlushedQueueJS->callAsFunction({ - Value(m_context, String::createExpectingAscii(moduleId)), - Value(m_context, String::createExpectingAscii(methodId)), + Value(m_context, String::createExpectingAscii(m_context, moduleId)), + Value(m_context, String::createExpectingAscii(m_context, methodId)), Value::fromDynamic(m_context, std::move(arguments)) }); } catch (...) { @@ -508,8 +510,8 @@ Value JSCExecutor::callFunctionSyncWithValue( SystraceSection s("JSCExecutor::callFunction"); Object result = m_callFunctionReturnResultAndFlushedQueueJS->callAsFunction({ - Value(m_context, String::createExpectingAscii(module)), - Value(m_context, String::createExpectingAscii(method)), + Value(m_context, String::createExpectingAscii(m_context, module)), + Value(m_context, String::createExpectingAscii(m_context, method)), std::move(args), }).asObject(); @@ -528,7 +530,7 @@ void JSCExecutor::setGlobalVariable(std::string propName, std::unique_ptrgetModule(moduleId); - auto sourceUrl = String::createExpectingAscii(module.name); - auto source = String::createExpectingAscii(module.code); + auto sourceUrl = String::createExpectingAscii(m_context, module.name); + auto source = String::createExpectingAscii(m_context, module.code); evaluateScript(m_context, source, sourceUrl); } @@ -700,7 +700,7 @@ void JSCExecutor::terminateOwnedWebWorker(int workerId) { } Object JSCExecutor::createMessageObject(const std::string& msgJson) { - Value rebornJSMsg = Value::fromJSON(m_context, String(msgJson.c_str())); + Value rebornJSMsg = Value::fromJSON(m_context, String(m_context, msgJson.c_str())); Object messageObject = Object::create(m_context); messageObject.setProperty("data", rebornJSMsg); return messageObject; @@ -714,7 +714,7 @@ void JSCExecutor::installNativeHook(const char* name) { JSValueRef JSCExecutor::getNativeModule(JSObjectRef object, JSStringRef propertyName) { if (JSStringIsEqualToUTF8CString(propertyName, "name")) { - return Value(m_context, String("NativeModules")); + return Value(m_context, String(m_context, "NativeModules")); } return m_nativeModules.getModule(m_context, propertyName); diff --git a/ReactCommon/cxxreact/JSCLegacyProfiler.cpp b/ReactCommon/cxxreact/JSCLegacyProfiler.cpp index 41a376b2d..2c811127b 100644 --- a/ReactCommon/cxxreact/JSCLegacyProfiler.cpp +++ b/ReactCommon/cxxreact/JSCLegacyProfiler.cpp @@ -29,13 +29,12 @@ static JSValueRef nativeProfilerStart( return Value::makeUndefined(ctx); } - JSStringRef title = JSValueToStringCopy(ctx, arguments[0], exception); + auto title = String::adopt(ctx, JSValueToStringCopy(ctx, arguments[0], exception)); #if WITH_REACT_INTERNAL_SETTINGS JSStartProfiling(ctx, title, false); #else JSStartProfiling(ctx, title); #endif - JSStringRelease(title); return Value::makeUndefined(ctx); } @@ -57,15 +56,15 @@ static JSValueRef nativeProfilerEnd( std::string writeLocation("/sdcard/"); if (argumentCount > 1) { - JSStringRef fileName = JSValueToStringCopy(ctx, arguments[1], exception); - writeLocation += facebook::react::String::ref(fileName).str(); - JSStringRelease(fileName); + auto fileName = String::adopt( + ctx, JSValueToStringCopy(ctx, arguments[1], exception)); + writeLocation += fileName.str(); } else { writeLocation += "profile.json"; } - JSStringRef title = JSValueToStringCopy(ctx, arguments[0], exception); + auto title = String::adopt( + ctx, JSValueToStringCopy(ctx, arguments[0], exception)); JSEndProfilingAndRender(ctx, title, writeLocation.c_str()); - JSStringRelease(title); return Value::makeUndefined(ctx); } diff --git a/ReactCommon/cxxreact/JSCLegacyTracing.cpp b/ReactCommon/cxxreact/JSCLegacyTracing.cpp index 07419999a..7e684e510 100644 --- a/ReactCommon/cxxreact/JSCLegacyTracing.cpp +++ b/ReactCommon/cxxreact/JSCLegacyTracing.cpp @@ -32,13 +32,12 @@ static JSValueRef nativeTraceBeginLegacy( } } - JSStringRef title = JSStringCreateWithUTF8CString(ENABLED_FBSYSTRACE_PROFILE_NAME); + String title(ctx, ENABLED_FBSYSTRACE_PROFILE_NAME); #if WITH_REACT_INTERNAL_SETTINGS JSStartProfiling(ctx, title, true); #else JSStartProfiling(ctx, title); #endif - JSStringRelease(title); return Value::makeUndefined(ctx); } @@ -57,9 +56,8 @@ static JSValueRef nativeTraceEndLegacy( } } - JSStringRef title = JSStringCreateWithUTF8CString(ENABLED_FBSYSTRACE_PROFILE_NAME); + String title(ctx, ENABLED_FBSYSTRACE_PROFILE_NAME); JSEndProfiling(ctx, title); - JSStringRelease(title); return Value::makeUndefined(ctx); } diff --git a/ReactCommon/cxxreact/JSCMemory.cpp b/ReactCommon/cxxreact/JSCMemory.cpp index ec8799d98..b639eae63 100644 --- a/ReactCommon/cxxreact/JSCMemory.cpp +++ b/ReactCommon/cxxreact/JSCMemory.cpp @@ -28,10 +28,9 @@ static JSValueRef nativeCaptureHeap( return Value::makeUndefined(ctx); } - JSStringRef outputFilename = JSValueToStringCopy(ctx, arguments[0], exception); - std::string finalFilename = facebook::react::String::ref(outputFilename).str(); - JSCaptureHeap(ctx, finalFilename.c_str(), exception); - JSStringRelease(outputFilename); + auto outputFilename = String::adopt( + ctx, JSValueToStringCopy(ctx, arguments[0], exception)); + JSCaptureHeap(ctx, outputFilename.str().c_str(), exception); return Value::makeUndefined(ctx); } diff --git a/ReactCommon/cxxreact/JSCNativeModules.cpp b/ReactCommon/cxxreact/JSCNativeModules.cpp index 564a80a98..b1036ba37 100644 --- a/ReactCommon/cxxreact/JSCNativeModules.cpp +++ b/ReactCommon/cxxreact/JSCNativeModules.cpp @@ -11,7 +11,7 @@ JSCNativeModules::JSCNativeModules(std::shared_ptr moduleRegistr m_moduleRegistry(std::move(moduleRegistry)) {} JSValueRef JSCNativeModules::getModule(JSContextRef context, JSStringRef jsName) { - std::string moduleName = String::ref(jsName).str(); + std::string moduleName = String::ref(context, jsName).str(); const auto it = m_objects.find(moduleName); if (it != m_objects.end()) { diff --git a/ReactCommon/cxxreact/JSCUtils.cpp b/ReactCommon/cxxreact/JSCUtils.cpp index 214d8641b..6a3239bb3 100644 --- a/ReactCommon/cxxreact/JSCUtils.cpp +++ b/ReactCommon/cxxreact/JSCUtils.cpp @@ -5,11 +5,11 @@ namespace facebook { namespace react { -String jsStringFromBigString(const JSBigString& bigstr) { +String jsStringFromBigString(JSContextRef ctx, const JSBigString& bigstr) { if (bigstr.isAscii()) { - return String::createExpectingAscii(bigstr.c_str(), bigstr.size()); + return String::createExpectingAscii(ctx, bigstr.c_str(), bigstr.size()); } else { - return String(bigstr.c_str()); + return String(ctx, bigstr.c_str()); } } diff --git a/ReactCommon/cxxreact/JSCUtils.h b/ReactCommon/cxxreact/JSCUtils.h index 20acc40dd..e85b5564f 100644 --- a/ReactCommon/cxxreact/JSCUtils.h +++ b/ReactCommon/cxxreact/JSCUtils.h @@ -9,7 +9,7 @@ namespace facebook { namespace react { -String jsStringFromBigString(const JSBigString& bigstr); +String jsStringFromBigString(JSContextRef ctx, const JSBigString& bigstr); } } diff --git a/ReactCommon/cxxreact/JSCWebWorker.cpp b/ReactCommon/cxxreact/JSCWebWorker.cpp index 360cebb83..e8bfa55cd 100644 --- a/ReactCommon/cxxreact/JSCWebWorker.cpp +++ b/ReactCommon/cxxreact/JSCWebWorker.cpp @@ -92,7 +92,7 @@ void JSCWebWorker::initJSVMAndLoadScript() { // TODO(9604438): Protect against script does not exist std::unique_ptr script = WebWorkerUtil::loadScriptFromAssets(scriptName_); - evaluateScript(context_, jsStringFromBigString(*script), String(scriptName_.c_str())); + evaluateScript(context_, jsStringFromBigString(context_, *script), String(context_, scriptName_.c_str())); installGlobalFunction(context_, "postMessage", nativePostMessage); } @@ -127,7 +127,7 @@ JSValueRef JSCWebWorker::nativePostMessage( /*static*/ Object JSCWebWorker::createMessageObject(JSContextRef context, const std::string& msgJson) { - Value rebornJSMsg = Value::fromJSON(context, String(msgJson.c_str())); + Value rebornJSMsg = Value::fromJSON(context, String(context, msgJson.c_str())); Object messageObject = Object::create(context); messageObject.setProperty("data", rebornJSMsg); return messageObject; diff --git a/ReactCommon/cxxreact/tests/value.cpp b/ReactCommon/cxxreact/tests/value.cpp index 8eac6d9bd..be2ee7bf6 100644 --- a/ReactCommon/cxxreact/tests/value.cpp +++ b/ReactCommon/cxxreact/tests/value.cpp @@ -12,7 +12,6 @@ #include -using namespace facebook; using namespace facebook::react; #ifdef ANDROID @@ -21,15 +20,14 @@ static void prepare() { ALooper_prepare(0); } #else -static void prepare() { -} +static void prepare() {} #endif TEST(Value, Undefined) { prepare(); JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr); auto v = Value::makeUndefined(ctx); - auto s = String::adopt(JSValueToStringCopy(ctx, v, nullptr)); + auto s = String::adopt(ctx, JSValueToStringCopy(ctx, v, nullptr)); EXPECT_EQ("undefined", s.str()); JSGlobalContextRelease(ctx); } @@ -37,7 +35,7 @@ TEST(Value, Undefined) { TEST(Value, FromJSON) { prepare(); JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr); - react::String s("{\"a\": 4}"); + String s(ctx, "{\"a\": 4}"); Value v(Value::fromJSON(ctx, s)); EXPECT_TRUE(JSValueIsObject(ctx, v)); JSGlobalContextRelease(ctx); @@ -46,7 +44,7 @@ TEST(Value, FromJSON) { TEST(Value, ToJSONString) { prepare(); JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr); - react::String s("{\"a\": 4}"); + String s(ctx, "{\"a\": 4}"); Value v(Value::fromJSON(ctx, s)); folly::dynamic dyn = folly::parseJson(v.toJSONString()); ASSERT_NE(nullptr, dyn); diff --git a/ReactCommon/jschelpers/JSCHelpers.cpp b/ReactCommon/jschelpers/JSCHelpers.cpp index edf298f21..1b2d9f6c4 100644 --- a/ReactCommon/jschelpers/JSCHelpers.cpp +++ b/ReactCommon/jschelpers/JSCHelpers.cpp @@ -55,14 +55,14 @@ JSObjectRef makeFunction( JSContextRef ctx, const char* name, JSFunction function) { - return makeFunction(ctx, String(name), std::move(function)); + return makeFunction(ctx, String(ctx, name), std::move(function)); } void installGlobalFunction( JSGlobalContextRef ctx, const char* name, JSFunction function) { - auto jsName = String(name); + auto jsName = String(ctx, name); auto functionObj = makeFunction(ctx, jsName, std::move(function)); Object::getGlobalObject(ctx).setProperty(jsName, Value(ctx, functionObj)); } @@ -71,7 +71,7 @@ JSObjectRef makeFunction( JSGlobalContextRef ctx, const char* name, JSObjectCallAsFunctionCallback callback) { - auto jsName = String(name); + auto jsName = String(ctx, name); return JSObjectMakeFunctionWithCallback(ctx, jsName, callback); } @@ -79,9 +79,9 @@ void installGlobalFunction( JSGlobalContextRef ctx, const char* name, JSObjectCallAsFunctionCallback callback) { - String jsName(name); + String jsName(ctx, name); JSObjectRef functionObj = JSObjectMakeFunctionWithCallback( - ctx, jsName, callback); + ctx, jsName, callback); Object::getGlobalObject(ctx).setProperty(jsName, Value(ctx, functionObj)); } @@ -134,7 +134,7 @@ void formatAndThrowJSException(JSContextRef context, JSValueRef exn, JSStringRef // The null/empty-ness of source tells us if the JS came from a // file/resource, or was a constructed statement. The location // info will include that source, if any. - std::string locationInfo = source != nullptr ? String::ref(source).str() : ""; + std::string locationInfo = source != nullptr ? String::ref(context, source).str() : ""; Object exObject = exception.asObject(); auto line = exObject.getProperty("line"); if (line != nullptr && line.isNumber()) { diff --git a/ReactCommon/jschelpers/Value.cpp b/ReactCommon/jschelpers/Value.cpp index 73f2ce69f..2bb0b61f2 100644 --- a/ReactCommon/jschelpers/Value.cpp +++ b/ReactCommon/jschelpers/Value.cpp @@ -46,7 +46,7 @@ std::string Value::toJSONString(unsigned indent) const { std::string exceptionText = Value(m_context, exn).toString().str(); throwJSExecutionException("Exception creating JSON string: %s", exceptionText.c_str()); } - return String::adopt(stringToAdopt).str(); + return String::adopt(m_context, stringToAdopt).str(); } /* static */ @@ -77,7 +77,7 @@ JSValueRef Value::fromDynamic(JSContextRef ctx, const folly::dynamic& value) { return jsVal; #else auto json = folly::toJson(value); - return fromJSON(ctx, String(json.c_str())); + return fromJSON(ctx, String(ctx, json.c_str())); #endif } @@ -97,7 +97,7 @@ JSValueRef Value::fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj) return JSValueMakeNumber(ctx, obj.asDouble()); case folly::dynamic::Type::STRING: - return JSValueMakeString(ctx, String(obj.getString().c_str())); + return JSValueMakeString(ctx, String(ctx, obj.getString().c_str())); case folly::dynamic::Type::ARRAY: { // Collect JSValue for every element in the array @@ -118,7 +118,7 @@ JSValueRef Value::fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj) JSObjectSetProperty( ctx, jsObj, - String(it->first.asString().c_str()), + String(ctx, it->first.asString().c_str()), fromDynamicInner(ctx, it->second), kJSPropertyAttributeNone, nullptr); @@ -147,7 +147,7 @@ Object Value::asObject() { Value Value::makeError(JSContextRef ctx, const char *error) { JSValueRef exn; - JSValueRef args[] = { Value(ctx, String(error)) }; + JSValueRef args[] = { Value(ctx, String(ctx, error)) }; JSObjectRef errorObj = JSObjectMakeError(ctx, 1, args, &exn); if (!errorObj) { std::string exceptionText = Value(ctx, exn).toString().str(); @@ -217,7 +217,7 @@ Value Object::getPropertyAtIndex(unsigned index) const { } Value Object::getProperty(const char *propName) const { - return getProperty(String(propName)); + return getProperty(String(m_context, propName)); } void Object::setProperty(const String& propName, const Value& value) const { @@ -230,7 +230,7 @@ void Object::setProperty(const String& propName, const Value& value) const { } void Object::setProperty(const char *propName, const Value& value) const { - setProperty(String(propName), value); + setProperty(String(m_context, propName), value); } std::vector Object::getPropertyNames() const { @@ -239,7 +239,8 @@ std::vector Object::getPropertyNames() const { std::vector names; names.reserve(count); for (size_t i = 0; i < count; i++) { - names.emplace_back(String::ref(JSPropertyNameArrayGetNameAtIndex(namesRef, i))); + names.emplace_back( + String::ref(m_context, JSPropertyNameArrayGetNameAtIndex(namesRef, i))); } JSPropertyNameArrayRelease(namesRef); return names; @@ -250,7 +251,8 @@ std::unordered_map Object::toJSONMap() const { auto namesRef = JSObjectCopyPropertyNames(m_context, m_obj); size_t count = JSPropertyNameArrayGetCount(namesRef); for (size_t i = 0; i < count; i++) { - auto key = String::ref(JSPropertyNameArrayGetNameAtIndex(namesRef, i)); + auto key = String::ref(m_context, + JSPropertyNameArrayGetNameAtIndex(namesRef, i)); map.emplace(key.str(), getProperty(key).toJSONString()); } JSPropertyNameArrayRelease(namesRef); diff --git a/ReactCommon/jschelpers/Value.h b/ReactCommon/jschelpers/Value.h index 31b9736ce..ff96cfd06 100644 --- a/ReactCommon/jschelpers/Value.h +++ b/ReactCommon/jschelpers/Value.h @@ -47,18 +47,18 @@ private: class String : public noncopyable { public: - explicit String(const char* utf8) : - m_string(JSStringCreateWithUTF8CString(utf8)) + explicit String(JSContextRef context, const char* utf8) : + m_context(context), m_string(JSStringCreateWithUTF8CString(utf8)) {} String(String&& other) : - m_string(other.m_string) + m_context(other.m_context), m_string(other.m_string) { other.m_string = nullptr; } String(const String& other) : - m_string(other.m_string) + m_context(other.m_context), m_string(other.m_string) { if (m_string) { JSStringRetain(m_string); @@ -111,35 +111,36 @@ public: } // This assumes ascii is nul-terminated. - static String createExpectingAscii(const char* ascii, size_t len) { + static String createExpectingAscii(JSContextRef context, const char* ascii, size_t len) { #if WITH_FBJSCEXTENSIONS - return String(JSStringCreateWithUTF8CStringExpectAscii(ascii, len), true); + return String(context, JSStringCreateWithUTF8CStringExpectAscii(ascii, len), true); #else - return String(JSStringCreateWithUTF8CString(ascii), true); + return String(context, JSStringCreateWithUTF8CString(ascii), true); #endif } - static String createExpectingAscii(std::string const &ascii) { - return createExpectingAscii(ascii.c_str(), ascii.size()); + static String createExpectingAscii(JSContextRef context, std::string const &ascii) { + return createExpectingAscii(context, ascii.c_str(), ascii.size()); } - static String ref(JSStringRef string) { - return String(string, false); + static String ref(JSContextRef context, JSStringRef string) { + return String(context, string, false); } - static String adopt(JSStringRef string) { - return String(string, true); + static String adopt(JSContextRef context, JSStringRef string) { + return String(context, string, true); } private: - explicit String(JSStringRef string, bool adopt) : - m_string(string) + explicit String(JSContextRef context, JSStringRef string, bool adopt) : + m_context(context), m_string(string) { if (!adopt && string) { JSStringRetain(string); } } + JSContextRef m_context; JSStringRef m_string; }; @@ -295,7 +296,7 @@ public: } String toString() noexcept { - return String::adopt(JSValueToStringCopy(context(), m_value, nullptr)); + return String::adopt(context(), JSValueToStringCopy(context(), m_value, nullptr)); } static Value makeError(JSContextRef ctx, const char *error);