Add JSContextRef param to String constructor

Reviewed By: bnham

Differential Revision: D4197300

fbshipit-source-id: 306ffc85e3ced24047b68499f7cdf5e2d31fc052
This commit is contained in:
Pieter De Baets 2016-11-18 06:25:29 -08:00 committed by Facebook Github Bot
parent b1c91606ff
commit 20514e3482
13 changed files with 75 additions and 78 deletions

View File

@ -133,7 +133,7 @@ react_library(
soname = 'libreactnativefb.$(ext)', soname = 'libreactnativefb.$(ext)',
header_namespace = 'cxxreact', header_namespace = 'cxxreact',
force_static = True, force_static = True,
srcs = glob(['*.cpp']), srcs = glob(['*.cpp'], excludes=['SampleCxxModule.cpp']),
headers = glob(['*.h'], excludes=CXXREACT_PUBLIC_HEADERS), headers = glob(['*.h'], excludes=CXXREACT_PUBLIC_HEADERS),
xcode_public_headers_symlinks = True, xcode_public_headers_symlinks = True,
exported_headers = CXXREACT_PUBLIC_HEADERS, exported_headers = CXXREACT_PUBLIC_HEADERS,

View File

@ -209,8 +209,8 @@ void JSCExecutor::destroy() {
} }
void JSCExecutor::setContextName(const std::string& name) { void JSCExecutor::setContextName(const std::string& name) {
String jsName = String(name.c_str()); String jsName = String(m_context, name.c_str());
JSGlobalContextSetName(m_context, static_cast<JSStringRef>(jsName)); JSGlobalContextSetName(m_context, jsName);
} }
void JSCExecutor::initOnJSVMThread() throw(JSException) { void JSCExecutor::initOnJSVMThread() throw(JSException) {
@ -313,7 +313,7 @@ void JSCExecutor::loadApplicationScript(
(flags & UNPACKED_JS_SOURCE) || (flags & UNPACKED_BYTECODE), (flags & UNPACKED_JS_SOURCE) || (flags & UNPACKED_BYTECODE),
"Optimized bundle with no unpacked source or bytecode"); "Optimized bundle with no unpacked source or bytecode");
String jsSourceURL(sourceURL.c_str()); String jsSourceURL(m_context, sourceURL.c_str());
JSSourceCodeRef sourceCode = nullptr; JSSourceCodeRef sourceCode = nullptr;
SCOPE_EXIT { SCOPE_EXIT {
if (sourceCode) { if (sourceCode) {
@ -338,9 +338,11 @@ void JSCExecutor::loadApplicationScript(
return loadApplicationScript(std::move(jsScriptBigString), sourceURL); return loadApplicationScript(std::move(jsScriptBigString), sourceURL);
} }
#if defined(WITH_FB_JSC_TUNING) && defined(__ANDROID__)
if (flags & UNPACKED_BC_CACHE) { if (flags & UNPACKED_BC_CACHE) {
configureJSCBCCache(m_context, bundlePath); configureJSCBCCache(m_context, bundlePath);
} }
#endif
sourceCode = JSCreateSourceCode( sourceCode = JSCreateSourceCode(
jsScriptBigString->fd(), jsScriptBigString->fd(),
@ -403,14 +405,14 @@ void JSCExecutor::loadApplicationScript(std::unique_ptr<const JSBigString> scrip
ReactMarker::logMarker("RUN_JS_BUNDLE_START"); ReactMarker::logMarker("RUN_JS_BUNDLE_START");
ReactMarker::logMarker("loadApplicationScript_startStringConvert"); ReactMarker::logMarker("loadApplicationScript_startStringConvert");
String jsScript = jsStringFromBigString(*script); String jsScript = jsStringFromBigString(m_context, *script);
ReactMarker::logMarker("loadApplicationScript_endStringConvert"); ReactMarker::logMarker("loadApplicationScript_endStringConvert");
#ifdef WITH_FBSYSTRACE #ifdef WITH_FBSYSTRACE
fbsystrace_end_section(TRACE_TAG_REACT_CXX_BRIDGE); fbsystrace_end_section(TRACE_TAG_REACT_CXX_BRIDGE);
#endif #endif
String jsSourceURL(sourceURL.c_str()); String jsSourceURL(m_context, sourceURL.c_str());
evaluateScript(m_context, jsScript, jsSourceURL); evaluateScript(m_context, jsScript, jsSourceURL);
// TODO(luk): t13903306 Remove this check once we make native modules working for java2js // 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 = [&] { auto result = [&] {
try { try {
return m_callFunctionReturnFlushedQueueJS->callAsFunction({ return m_callFunctionReturnFlushedQueueJS->callAsFunction({
Value(m_context, String::createExpectingAscii(moduleId)), Value(m_context, String::createExpectingAscii(m_context, moduleId)),
Value(m_context, String::createExpectingAscii(methodId)), Value(m_context, String::createExpectingAscii(m_context, methodId)),
Value::fromDynamic(m_context, std::move(arguments)) Value::fromDynamic(m_context, std::move(arguments))
}); });
} catch (...) { } catch (...) {
@ -508,8 +510,8 @@ Value JSCExecutor::callFunctionSyncWithValue(
SystraceSection s("JSCExecutor::callFunction"); SystraceSection s("JSCExecutor::callFunction");
Object result = m_callFunctionReturnResultAndFlushedQueueJS->callAsFunction({ Object result = m_callFunctionReturnResultAndFlushedQueueJS->callAsFunction({
Value(m_context, String::createExpectingAscii(module)), Value(m_context, String::createExpectingAscii(m_context, module)),
Value(m_context, String::createExpectingAscii(method)), Value(m_context, String::createExpectingAscii(m_context, method)),
std::move(args), std::move(args),
}).asObject(); }).asObject();
@ -528,7 +530,7 @@ void JSCExecutor::setGlobalVariable(std::string propName, std::unique_ptr<const
SystraceSection s("JSCExecutor.setGlobalVariable", SystraceSection s("JSCExecutor.setGlobalVariable",
"propName", propName); "propName", propName);
auto valueToInject = Value::fromJSON(m_context, jsStringFromBigString(*jsonValue)); auto valueToInject = Value::fromJSON(m_context, jsStringFromBigString(m_context, *jsonValue));
Object::getGlobalObject(m_context).setProperty(propName.c_str(), valueToInject); Object::getGlobalObject(m_context).setProperty(propName.c_str(), valueToInject);
} catch (...) { } catch (...) {
std::throw_with_nested(std::runtime_error("Error setting global variable: " + propName)); std::throw_with_nested(std::runtime_error("Error setting global variable: " + propName));
@ -549,21 +551,19 @@ bool JSCExecutor::supportsProfiling() {
void JSCExecutor::startProfiler(const std::string &titleString) { void JSCExecutor::startProfiler(const std::string &titleString) {
#ifdef WITH_JSC_EXTRA_TRACING #ifdef WITH_JSC_EXTRA_TRACING
JSStringRef title = JSStringCreateWithUTF8CString(titleString.c_str()); String title(m_context, titleString.c_str());
#if WITH_REACT_INTERNAL_SETTINGS #if WITH_REACT_INTERNAL_SETTINGS
JSStartProfiling(m_context, title, false); JSStartProfiling(m_context, title, false);
#else #else
JSStartProfiling(m_context, title); JSStartProfiling(m_context, title);
#endif #endif
JSStringRelease(title);
#endif #endif
} }
void JSCExecutor::stopProfiler(const std::string &titleString, const std::string& filename) { void JSCExecutor::stopProfiler(const std::string &titleString, const std::string& filename) {
#ifdef WITH_JSC_EXTRA_TRACING #ifdef WITH_JSC_EXTRA_TRACING
JSStringRef title = JSStringCreateWithUTF8CString(titleString.c_str()); String title(m_context, titleString.c_str());
facebook::react::stopAndOutputProfilingFile(m_context, title, filename.c_str()); facebook::react::stopAndOutputProfilingFile(m_context, title, filename.c_str());
JSStringRelease(title);
#endif #endif
} }
@ -592,8 +592,8 @@ void JSCExecutor::flushQueueImmediate(Value&& queue) {
void JSCExecutor::loadModule(uint32_t moduleId) { void JSCExecutor::loadModule(uint32_t moduleId) {
auto module = m_unbundle->getModule(moduleId); auto module = m_unbundle->getModule(moduleId);
auto sourceUrl = String::createExpectingAscii(module.name); auto sourceUrl = String::createExpectingAscii(m_context, module.name);
auto source = String::createExpectingAscii(module.code); auto source = String::createExpectingAscii(m_context, module.code);
evaluateScript(m_context, source, sourceUrl); evaluateScript(m_context, source, sourceUrl);
} }
@ -700,7 +700,7 @@ void JSCExecutor::terminateOwnedWebWorker(int workerId) {
} }
Object JSCExecutor::createMessageObject(const std::string& msgJson) { 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); Object messageObject = Object::create(m_context);
messageObject.setProperty("data", rebornJSMsg); messageObject.setProperty("data", rebornJSMsg);
return messageObject; return messageObject;
@ -714,7 +714,7 @@ void JSCExecutor::installNativeHook(const char* name) {
JSValueRef JSCExecutor::getNativeModule(JSObjectRef object, JSStringRef propertyName) { JSValueRef JSCExecutor::getNativeModule(JSObjectRef object, JSStringRef propertyName) {
if (JSStringIsEqualToUTF8CString(propertyName, "name")) { 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); return m_nativeModules.getModule(m_context, propertyName);

View File

@ -29,13 +29,12 @@ static JSValueRef nativeProfilerStart(
return Value::makeUndefined(ctx); 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 #if WITH_REACT_INTERNAL_SETTINGS
JSStartProfiling(ctx, title, false); JSStartProfiling(ctx, title, false);
#else #else
JSStartProfiling(ctx, title); JSStartProfiling(ctx, title);
#endif #endif
JSStringRelease(title);
return Value::makeUndefined(ctx); return Value::makeUndefined(ctx);
} }
@ -57,15 +56,15 @@ static JSValueRef nativeProfilerEnd(
std::string writeLocation("/sdcard/"); std::string writeLocation("/sdcard/");
if (argumentCount > 1) { if (argumentCount > 1) {
JSStringRef fileName = JSValueToStringCopy(ctx, arguments[1], exception); auto fileName = String::adopt(
writeLocation += facebook::react::String::ref(fileName).str(); ctx, JSValueToStringCopy(ctx, arguments[1], exception));
JSStringRelease(fileName); writeLocation += fileName.str();
} else { } else {
writeLocation += "profile.json"; 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()); JSEndProfilingAndRender(ctx, title, writeLocation.c_str());
JSStringRelease(title);
return Value::makeUndefined(ctx); return Value::makeUndefined(ctx);
} }

View File

@ -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 #if WITH_REACT_INTERNAL_SETTINGS
JSStartProfiling(ctx, title, true); JSStartProfiling(ctx, title, true);
#else #else
JSStartProfiling(ctx, title); JSStartProfiling(ctx, title);
#endif #endif
JSStringRelease(title);
return Value::makeUndefined(ctx); 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); JSEndProfiling(ctx, title);
JSStringRelease(title);
return Value::makeUndefined(ctx); return Value::makeUndefined(ctx);
} }

View File

@ -28,10 +28,9 @@ static JSValueRef nativeCaptureHeap(
return Value::makeUndefined(ctx); return Value::makeUndefined(ctx);
} }
JSStringRef outputFilename = JSValueToStringCopy(ctx, arguments[0], exception); auto outputFilename = String::adopt(
std::string finalFilename = facebook::react::String::ref(outputFilename).str(); ctx, JSValueToStringCopy(ctx, arguments[0], exception));
JSCaptureHeap(ctx, finalFilename.c_str(), exception); JSCaptureHeap(ctx, outputFilename.str().c_str(), exception);
JSStringRelease(outputFilename);
return Value::makeUndefined(ctx); return Value::makeUndefined(ctx);
} }

View File

@ -11,7 +11,7 @@ JSCNativeModules::JSCNativeModules(std::shared_ptr<ModuleRegistry> moduleRegistr
m_moduleRegistry(std::move(moduleRegistry)) {} m_moduleRegistry(std::move(moduleRegistry)) {}
JSValueRef JSCNativeModules::getModule(JSContextRef context, JSStringRef jsName) { 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); const auto it = m_objects.find(moduleName);
if (it != m_objects.end()) { if (it != m_objects.end()) {

View File

@ -5,11 +5,11 @@
namespace facebook { namespace facebook {
namespace react { namespace react {
String jsStringFromBigString(const JSBigString& bigstr) { String jsStringFromBigString(JSContextRef ctx, const JSBigString& bigstr) {
if (bigstr.isAscii()) { if (bigstr.isAscii()) {
return String::createExpectingAscii(bigstr.c_str(), bigstr.size()); return String::createExpectingAscii(ctx, bigstr.c_str(), bigstr.size());
} else { } else {
return String(bigstr.c_str()); return String(ctx, bigstr.c_str());
} }
} }

View File

@ -9,7 +9,7 @@
namespace facebook { namespace facebook {
namespace react { namespace react {
String jsStringFromBigString(const JSBigString& bigstr); String jsStringFromBigString(JSContextRef ctx, const JSBigString& bigstr);
} }
} }

View File

@ -92,7 +92,7 @@ void JSCWebWorker::initJSVMAndLoadScript() {
// TODO(9604438): Protect against script does not exist // TODO(9604438): Protect against script does not exist
std::unique_ptr<const JSBigString> script = WebWorkerUtil::loadScriptFromAssets(scriptName_); std::unique_ptr<const JSBigString> 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); installGlobalFunction(context_, "postMessage", nativePostMessage);
} }
@ -127,7 +127,7 @@ JSValueRef JSCWebWorker::nativePostMessage(
/*static*/ /*static*/
Object JSCWebWorker::createMessageObject(JSContextRef context, const std::string& msgJson) { 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); Object messageObject = Object::create(context);
messageObject.setProperty("data", rebornJSMsg); messageObject.setProperty("data", rebornJSMsg);
return messageObject; return messageObject;

View File

@ -12,7 +12,6 @@
#include <stdexcept> #include <stdexcept>
using namespace facebook;
using namespace facebook::react; using namespace facebook::react;
#ifdef ANDROID #ifdef ANDROID
@ -21,15 +20,14 @@ static void prepare() {
ALooper_prepare(0); ALooper_prepare(0);
} }
#else #else
static void prepare() { static void prepare() {}
}
#endif #endif
TEST(Value, Undefined) { TEST(Value, Undefined) {
prepare(); prepare();
JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr); JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr);
auto v = Value::makeUndefined(ctx); 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()); EXPECT_EQ("undefined", s.str());
JSGlobalContextRelease(ctx); JSGlobalContextRelease(ctx);
} }
@ -37,7 +35,7 @@ TEST(Value, Undefined) {
TEST(Value, FromJSON) { TEST(Value, FromJSON) {
prepare(); prepare();
JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr); JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr);
react::String s("{\"a\": 4}"); String s(ctx, "{\"a\": 4}");
Value v(Value::fromJSON(ctx, s)); Value v(Value::fromJSON(ctx, s));
EXPECT_TRUE(JSValueIsObject(ctx, v)); EXPECT_TRUE(JSValueIsObject(ctx, v));
JSGlobalContextRelease(ctx); JSGlobalContextRelease(ctx);
@ -46,7 +44,7 @@ TEST(Value, FromJSON) {
TEST(Value, ToJSONString) { TEST(Value, ToJSONString) {
prepare(); prepare();
JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr); JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr);
react::String s("{\"a\": 4}"); String s(ctx, "{\"a\": 4}");
Value v(Value::fromJSON(ctx, s)); Value v(Value::fromJSON(ctx, s));
folly::dynamic dyn = folly::parseJson(v.toJSONString()); folly::dynamic dyn = folly::parseJson(v.toJSONString());
ASSERT_NE(nullptr, dyn); ASSERT_NE(nullptr, dyn);

View File

@ -55,14 +55,14 @@ JSObjectRef makeFunction(
JSContextRef ctx, JSContextRef ctx,
const char* name, const char* name,
JSFunction function) { JSFunction function) {
return makeFunction(ctx, String(name), std::move(function)); return makeFunction(ctx, String(ctx, name), std::move(function));
} }
void installGlobalFunction( void installGlobalFunction(
JSGlobalContextRef ctx, JSGlobalContextRef ctx,
const char* name, const char* name,
JSFunction function) { JSFunction function) {
auto jsName = String(name); auto jsName = String(ctx, name);
auto functionObj = makeFunction(ctx, jsName, std::move(function)); auto functionObj = makeFunction(ctx, jsName, std::move(function));
Object::getGlobalObject(ctx).setProperty(jsName, Value(ctx, functionObj)); Object::getGlobalObject(ctx).setProperty(jsName, Value(ctx, functionObj));
} }
@ -71,7 +71,7 @@ JSObjectRef makeFunction(
JSGlobalContextRef ctx, JSGlobalContextRef ctx,
const char* name, const char* name,
JSObjectCallAsFunctionCallback callback) { JSObjectCallAsFunctionCallback callback) {
auto jsName = String(name); auto jsName = String(ctx, name);
return JSObjectMakeFunctionWithCallback(ctx, jsName, callback); return JSObjectMakeFunctionWithCallback(ctx, jsName, callback);
} }
@ -79,7 +79,7 @@ void installGlobalFunction(
JSGlobalContextRef ctx, JSGlobalContextRef ctx,
const char* name, const char* name,
JSObjectCallAsFunctionCallback callback) { JSObjectCallAsFunctionCallback callback) {
String jsName(name); String jsName(ctx, name);
JSObjectRef functionObj = JSObjectMakeFunctionWithCallback( JSObjectRef functionObj = JSObjectMakeFunctionWithCallback(
ctx, jsName, callback); ctx, jsName, callback);
Object::getGlobalObject(ctx).setProperty(jsName, Value(ctx, functionObj)); 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 // The null/empty-ness of source tells us if the JS came from a
// file/resource, or was a constructed statement. The location // file/resource, or was a constructed statement. The location
// info will include that source, if any. // 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(); Object exObject = exception.asObject();
auto line = exObject.getProperty("line"); auto line = exObject.getProperty("line");
if (line != nullptr && line.isNumber()) { if (line != nullptr && line.isNumber()) {

View File

@ -46,7 +46,7 @@ std::string Value::toJSONString(unsigned indent) const {
std::string exceptionText = Value(m_context, exn).toString().str(); std::string exceptionText = Value(m_context, exn).toString().str();
throwJSExecutionException("Exception creating JSON string: %s", exceptionText.c_str()); throwJSExecutionException("Exception creating JSON string: %s", exceptionText.c_str());
} }
return String::adopt(stringToAdopt).str(); return String::adopt(m_context, stringToAdopt).str();
} }
/* static */ /* static */
@ -77,7 +77,7 @@ JSValueRef Value::fromDynamic(JSContextRef ctx, const folly::dynamic& value) {
return jsVal; return jsVal;
#else #else
auto json = folly::toJson(value); auto json = folly::toJson(value);
return fromJSON(ctx, String(json.c_str())); return fromJSON(ctx, String(ctx, json.c_str()));
#endif #endif
} }
@ -97,7 +97,7 @@ JSValueRef Value::fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj)
return JSValueMakeNumber(ctx, obj.asDouble()); return JSValueMakeNumber(ctx, obj.asDouble());
case folly::dynamic::Type::STRING: 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: { case folly::dynamic::Type::ARRAY: {
// Collect JSValue for every element in the array // Collect JSValue for every element in the array
@ -118,7 +118,7 @@ JSValueRef Value::fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj)
JSObjectSetProperty( JSObjectSetProperty(
ctx, ctx,
jsObj, jsObj,
String(it->first.asString().c_str()), String(ctx, it->first.asString().c_str()),
fromDynamicInner(ctx, it->second), fromDynamicInner(ctx, it->second),
kJSPropertyAttributeNone, kJSPropertyAttributeNone,
nullptr); nullptr);
@ -147,7 +147,7 @@ Object Value::asObject() {
Value Value::makeError(JSContextRef ctx, const char *error) Value Value::makeError(JSContextRef ctx, const char *error)
{ {
JSValueRef exn; JSValueRef exn;
JSValueRef args[] = { Value(ctx, String(error)) }; JSValueRef args[] = { Value(ctx, String(ctx, error)) };
JSObjectRef errorObj = JSObjectMakeError(ctx, 1, args, &exn); JSObjectRef errorObj = JSObjectMakeError(ctx, 1, args, &exn);
if (!errorObj) { if (!errorObj) {
std::string exceptionText = Value(ctx, exn).toString().str(); 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 { 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 { 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 { void Object::setProperty(const char *propName, const Value& value) const {
setProperty(String(propName), value); setProperty(String(m_context, propName), value);
} }
std::vector<String> Object::getPropertyNames() const { std::vector<String> Object::getPropertyNames() const {
@ -239,7 +239,8 @@ std::vector<String> Object::getPropertyNames() const {
std::vector<String> names; std::vector<String> names;
names.reserve(count); names.reserve(count);
for (size_t i = 0; i < count; i++) { 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); JSPropertyNameArrayRelease(namesRef);
return names; return names;
@ -250,7 +251,8 @@ std::unordered_map<std::string, std::string> Object::toJSONMap() const {
auto namesRef = JSObjectCopyPropertyNames(m_context, m_obj); auto namesRef = JSObjectCopyPropertyNames(m_context, m_obj);
size_t count = JSPropertyNameArrayGetCount(namesRef); size_t count = JSPropertyNameArrayGetCount(namesRef);
for (size_t i = 0; i < count; i++) { 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()); map.emplace(key.str(), getProperty(key).toJSONString());
} }
JSPropertyNameArrayRelease(namesRef); JSPropertyNameArrayRelease(namesRef);

View File

@ -47,18 +47,18 @@ private:
class String : public noncopyable { class String : public noncopyable {
public: public:
explicit String(const char* utf8) : explicit String(JSContextRef context, const char* utf8) :
m_string(JSStringCreateWithUTF8CString(utf8)) m_context(context), m_string(JSStringCreateWithUTF8CString(utf8))
{} {}
String(String&& other) : String(String&& other) :
m_string(other.m_string) m_context(other.m_context), m_string(other.m_string)
{ {
other.m_string = nullptr; other.m_string = nullptr;
} }
String(const String& other) : String(const String& other) :
m_string(other.m_string) m_context(other.m_context), m_string(other.m_string)
{ {
if (m_string) { if (m_string) {
JSStringRetain(m_string); JSStringRetain(m_string);
@ -111,35 +111,36 @@ public:
} }
// This assumes ascii is nul-terminated. // 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 #if WITH_FBJSCEXTENSIONS
return String(JSStringCreateWithUTF8CStringExpectAscii(ascii, len), true); return String(context, JSStringCreateWithUTF8CStringExpectAscii(ascii, len), true);
#else #else
return String(JSStringCreateWithUTF8CString(ascii), true); return String(context, JSStringCreateWithUTF8CString(ascii), true);
#endif #endif
} }
static String createExpectingAscii(std::string const &ascii) { static String createExpectingAscii(JSContextRef context, std::string const &ascii) {
return createExpectingAscii(ascii.c_str(), ascii.size()); return createExpectingAscii(context, ascii.c_str(), ascii.size());
} }
static String ref(JSStringRef string) { static String ref(JSContextRef context, JSStringRef string) {
return String(string, false); return String(context, string, false);
} }
static String adopt(JSStringRef string) { static String adopt(JSContextRef context, JSStringRef string) {
return String(string, true); return String(context, string, true);
} }
private: private:
explicit String(JSStringRef string, bool adopt) : explicit String(JSContextRef context, JSStringRef string, bool adopt) :
m_string(string) m_context(context), m_string(string)
{ {
if (!adopt && string) { if (!adopt && string) {
JSStringRetain(string); JSStringRetain(string);
} }
} }
JSContextRef m_context;
JSStringRef m_string; JSStringRef m_string;
}; };
@ -295,7 +296,7 @@ public:
} }
String toString() noexcept { 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); static Value makeError(JSContextRef ctx, const char *error);