From 3f50a887d93268411e68c79fd8ae9328615bf8fd Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Tue, 22 Nov 2016 06:05:38 -0800 Subject: [PATCH] Move JSC API usage in ReactCommon to our wrapper methods Reviewed By: bnham Differential Revision: D4197374 fbshipit-source-id: 107a129cff35dddfe06104b607441ad412f83d90 --- ReactCommon/cxxreact/JSCExecutor.cpp | 13 +++-- ReactCommon/cxxreact/JSCLegacyProfiler.cpp | 4 +- ReactCommon/cxxreact/JSCSamplingProfiler.cpp | 4 +- ReactCommon/cxxreact/JSCTracing.cpp | 10 ++-- ReactCommon/cxxreact/JSCWebWorker.cpp | 7 ++- ReactCommon/cxxreact/tests/value.cpp | 24 ++++---- ReactCommon/jschelpers/JSCHelpers.cpp | 50 ++++++++++------ ReactCommon/jschelpers/JSCHelpers.h | 2 +- ReactCommon/jschelpers/Value.cpp | 60 ++++++++++---------- ReactCommon/jschelpers/Value.h | 48 ++++++++-------- 10 files changed, 122 insertions(+), 100 deletions(-) diff --git a/ReactCommon/cxxreact/JSCExecutor.cpp b/ReactCommon/cxxreact/JSCExecutor.cpp index 0c7b08d06..564ab65c1 100644 --- a/ReactCommon/cxxreact/JSCExecutor.cpp +++ b/ReactCommon/cxxreact/JSCExecutor.cpp @@ -210,12 +210,13 @@ void JSCExecutor::destroy() { void JSCExecutor::setContextName(const std::string& name) { String jsName = String(m_context, name.c_str()); - JSGlobalContextSetName(m_context, jsName); + JSC_JSGlobalContextSetName(m_context, jsName); } void JSCExecutor::initOnJSVMThread() throw(JSException) { SystraceSection s("JSCExecutor.initOnJSVMThread"); + const bool useCustomJSC = false; #if defined(WITH_FB_JSC_TUNING) && defined(__ANDROID__) configureJSCForAndroid(m_jscConfig); #endif @@ -224,13 +225,13 @@ void JSCExecutor::initOnJSVMThread() throw(JSException) { JSClassRef globalClass = nullptr; { SystraceSection s("JSClassCreate"); - globalClass = JSClassCreate(&kJSClassDefinitionEmpty); + globalClass = JSC_JSClassCreate(useCustomJSC, &kJSClassDefinitionEmpty); } { SystraceSection s("JSGlobalContextCreateInGroup"); - m_context = JSGlobalContextCreateInGroup(nullptr, globalClass); + m_context = JSC_JSGlobalContextCreateInGroup(useCustomJSC, nullptr, globalClass); } - JSClassRelease(globalClass); + JSC_JSClassRelease(useCustomJSC, globalClass); // Add a pointer to ourselves so we can retrieve it later in our hooks Object::getGlobalObject(m_context).setPrivate(this); @@ -297,7 +298,7 @@ void JSCExecutor::terminateOnJSVMThread() { Inspector::instance().unregisterGlobalContext(m_context); #endif - JSGlobalContextRelease(m_context); + JSC_JSGlobalContextRelease(m_context); m_context = nullptr; } @@ -713,7 +714,7 @@ void JSCExecutor::installNativeHook(const char* name) { } JSValueRef JSCExecutor::getNativeModule(JSObjectRef object, JSStringRef propertyName) { - if (JSStringIsEqualToUTF8CString(propertyName, "name")) { + if (JSC_JSStringIsEqualToUTF8CString(m_context, propertyName, "name")) { return Value(m_context, String(m_context, "NativeModules")); } diff --git a/ReactCommon/cxxreact/JSCLegacyProfiler.cpp b/ReactCommon/cxxreact/JSCLegacyProfiler.cpp index d3381b2d7..32bdea863 100644 --- a/ReactCommon/cxxreact/JSCLegacyProfiler.cpp +++ b/ReactCommon/cxxreact/JSCLegacyProfiler.cpp @@ -57,13 +57,13 @@ static JSValueRef nativeProfilerEnd( std::string writeLocation("/sdcard/"); if (argumentCount > 1) { auto fileName = String::adopt( - ctx, JSValueToStringCopy(ctx, arguments[1], exception)); + ctx, JSC_JSValueToStringCopy(ctx, arguments[1], exception)); writeLocation += fileName.str(); } else { writeLocation += "profile.json"; } auto title = String::adopt( - ctx, JSValueToStringCopy(ctx, arguments[0], exception)); + ctx, JSC_JSValueToStringCopy(ctx, arguments[0], exception)); JSEndProfilingAndRender(ctx, title, writeLocation.c_str()); return Value::makeUndefined(ctx); } diff --git a/ReactCommon/cxxreact/JSCSamplingProfiler.cpp b/ReactCommon/cxxreact/JSCSamplingProfiler.cpp index eeab17693..f9944fb28 100644 --- a/ReactCommon/cxxreact/JSCSamplingProfiler.cpp +++ b/ReactCommon/cxxreact/JSCSamplingProfiler.cpp @@ -20,12 +20,12 @@ static JSValueRef pokeSamplingProfiler( size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { - return JSPokeSamplingProfiler(ctx); + return JSC_JSPokeSamplingProfiler(ctx); } } void initSamplingProfilerOnMainJSCThread(JSGlobalContextRef ctx) { - JSStartSamplingProfilingOnMainJSCThread(ctx); + JSC_JSStartSamplingProfilingOnMainJSCThread(ctx); installGlobalFunction(ctx, "pokeSamplingProfiler", pokeSamplingProfiler); } diff --git a/ReactCommon/cxxreact/JSCTracing.cpp b/ReactCommon/cxxreact/JSCTracing.cpp index ea7323c48..f629ebd44 100644 --- a/ReactCommon/cxxreact/JSCTracing.cpp +++ b/ReactCommon/cxxreact/JSCTracing.cpp @@ -20,7 +20,7 @@ static int64_t int64FromJSValue( JSValueRef value, JSValueRef* exception) { (void)exception; - int64_t num = (int64_t) JSValueToNumber(ctx, value, NULL); + int64_t num = (int64_t)JSC_JSValueToNumber(ctx, value, NULL); return num; } @@ -30,19 +30,19 @@ static size_t copyTruncatedAsciiChars( JSContextRef ctx, JSValueRef value, size_t maxLen) { - JSStringRef jsString = JSValueToStringCopy(ctx, value, NULL); - size_t stringLen = JSStringGetLength(jsString); + JSStringRef jsString = JSC_JSValueToStringCopy(ctx, value, NULL); + size_t stringLen = JSC_JSStringGetLength(ctx, jsString); // Unlike the Java version, we truncate from the end of the string, // rather than the beginning. size_t toWrite = min(stringLen, min(bufLen, maxLen)); const char *startBuf = buf; - const JSChar* chars = JSStringGetCharactersPtr(jsString); + const JSChar* chars = JSC_JSStringGetCharactersPtr(ctx, jsString); while (toWrite-- > 0) { *(buf++) = (char)*(chars++); } - JSStringRelease(jsString); + JSC_JSStringRelease(ctx, jsString); // Return the number of bytes written return buf - startBuf; diff --git a/ReactCommon/cxxreact/JSCWebWorker.cpp b/ReactCommon/cxxreact/JSCWebWorker.cpp index cb976b6ab..49a1dc88d 100644 --- a/ReactCommon/cxxreact/JSCWebWorker.cpp +++ b/ReactCommon/cxxreact/JSCWebWorker.cpp @@ -68,7 +68,7 @@ void JSCWebWorker::terminate() { void JSCWebWorker::terminateOnWorkerThread() { s_globalContextRefToJSCWebWorker.erase(context_); - JSGlobalContextRelease(context_); + JSC_JSGlobalContextRelease(context_); context_ = nullptr; workerMessageQueueThread_->quitSynchronous(); } @@ -81,7 +81,8 @@ void JSCWebWorker::initJSVMAndLoadScript() { CHECK(!isTerminated()) << "Worker was already finished!"; CHECK(!context_) << "Worker JS VM was already created!"; - context_ = JSGlobalContextCreateInGroup( + context_ = JSC_JSGlobalContextCreateInGroup( + false, // no support required for custom JSC NULL, // use default JS 'global' object NULL // create new group (i.e. new VM) ); @@ -113,7 +114,7 @@ JSValueRef JSCWebWorker::nativePostMessage( return Value::makeUndefined(ctx); } JSValueRef msg = arguments[0]; - JSCWebWorker *webWorker = s_globalContextRefToJSCWebWorker.at(JSContextGetGlobalContext(ctx)); + JSCWebWorker *webWorker = s_globalContextRefToJSCWebWorker.at(JSC_JSContextGetGlobalContext(ctx)); if (!webWorker->isTerminated()) { webWorker->postMessageToOwner(msg); diff --git a/ReactCommon/cxxreact/tests/value.cpp b/ReactCommon/cxxreact/tests/value.cpp index be2ee7bf6..4965b2345 100644 --- a/ReactCommon/cxxreact/tests/value.cpp +++ b/ReactCommon/cxxreact/tests/value.cpp @@ -25,25 +25,25 @@ static void prepare() {} TEST(Value, Undefined) { prepare(); - JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr); + JSGlobalContextRef ctx = JSC_JSGlobalContextCreateInGroup(false, nullptr, nullptr); auto v = Value::makeUndefined(ctx); - auto s = String::adopt(ctx, JSValueToStringCopy(ctx, v, nullptr)); + auto s = String::adopt(ctx, JSC_JSValueToStringCopy(ctx, v, nullptr)); EXPECT_EQ("undefined", s.str()); - JSGlobalContextRelease(ctx); + JSC_JSGlobalContextRelease(ctx); } TEST(Value, FromJSON) { prepare(); - JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr); + JSGlobalContextRef ctx = JSC_JSGlobalContextCreateInGroup(false, nullptr, nullptr); String s(ctx, "{\"a\": 4}"); Value v(Value::fromJSON(ctx, s)); - EXPECT_TRUE(JSValueIsObject(ctx, v)); - JSGlobalContextRelease(ctx); + EXPECT_TRUE(v.isObject()); + JSC_JSGlobalContextRelease(ctx); } TEST(Value, ToJSONString) { prepare(); - JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr); + JSGlobalContextRef ctx = JSC_JSGlobalContextCreateInGroup(false, nullptr, nullptr); String s(ctx, "{\"a\": 4}"); Value v(Value::fromJSON(ctx, s)); folly::dynamic dyn = folly::parseJson(v.toJSONString()); @@ -55,14 +55,14 @@ TEST(Value, ToJSONString) { EXPECT_EQ(4, val.getInt()); EXPECT_EQ(4.0f, val.asDouble()); - JSGlobalContextRelease(ctx); + JSC_JSGlobalContextRelease(ctx); } #ifdef WITH_FBJSCEXTENSION // Just test that handling invalid data doesn't crash. TEST(Value, FromBadUtf8) { prepare(); - JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr); + JSGlobalContextRef ctx = JSC_JSGlobalContextCreateInGroup(false, nullptr, nullptr); // 110xxxxx 10xxxxxx auto dyn = folly::dynamic("\xC0"); Value::fromDynamic(ctx, dyn); @@ -89,17 +89,17 @@ TEST(Value, FromBadUtf8) { dyn = "\xF0\x80\x80\x00"; Value::fromDynamic(ctx, dyn); Value(ctx, Value::fromDynamic(ctx, dyn)).toJSONString(); - JSGlobalContextRelease(ctx); + JSC_JSGlobalContextRelease(ctx); } // Just test that handling invalid data doesn't crash. TEST(Value, BadUtf16) { prepare(); - JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr); + JSGlobalContextRef ctx = JSC_JSGlobalContextCreateInGroup(false, nullptr, nullptr); UChar buf[] = { 0xDD00, 0xDD00, 0xDD00, 0x1111 }; JSStringRef ref = OpaqueJSString::create(buf, 4).leakRef(); Value v(ctx, ref); v.toJSONString(0); - JSGlobalContextRelease(ctx); + JSC_JSGlobalContextRelease(ctx); } #endif diff --git a/ReactCommon/jschelpers/JSCHelpers.cpp b/ReactCommon/jschelpers/JSCHelpers.cpp index cd860ad10..f99d76076 100644 --- a/ReactCommon/jschelpers/JSCHelpers.cpp +++ b/ReactCommon/jschelpers/JSCHelpers.cpp @@ -1,5 +1,5 @@ // Copyright 2004-present Facebook. All Rights Reserved. - + #include "JSCHelpers.h" #ifdef WITH_FBSYSTRACE @@ -24,27 +24,44 @@ JSValueRef functionCaller( size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { - auto* f = static_cast(JSObjectGetPrivate(function)); + const bool isCustomJSC = isCustomJSCPtr(ctx); + auto* f = static_cast(JSC_JSObjectGetPrivate(isCustomJSC, function)); return (*f)(ctx, thisObject, argumentCount, arguments); } -JSClassRef createFuncClass() { +JSClassRef createFuncClass(JSContextRef ctx) { auto definition = kJSClassDefinitionEmpty; - definition.finalize = [](JSObjectRef object) { - auto* function = static_cast(JSObjectGetPrivate(object)); - delete function; - }; + // Need to duplicate the two different finalizer blocks, since there's no way + // for it to capture this static information. + if (isCustomJSCPtr(ctx)) { + definition.finalize = [](JSObjectRef object) { + auto* function = static_cast(JSC_JSObjectGetPrivate(true, object)); + delete function; + }; + } else { + definition.finalize = [](JSObjectRef object) { + auto* function = static_cast(JSC_JSObjectGetPrivate(false, object)); + delete function; + }; + } definition.callAsFunction = exceptionWrapMethod<&functionCaller>(); - return JSClassCreate(&definition); + return JSC_JSClassCreate(ctx, &definition); } JSObjectRef makeFunction( JSContextRef ctx, JSStringRef name, JSFunction function) { - static auto kClassDef = createFuncClass(); - auto functionObject = Object(ctx, JSObjectMake(ctx, kClassDef, new JSFunction(std::move(function)))); + static JSClassRef kClassDef = NULL, kCustomJSCClassDef = NULL; + JSClassRef *classRef = isCustomJSCPtr(ctx) ? &kCustomJSCClassDef : &kClassDef; + if (!*classRef) { + *classRef = createFuncClass(ctx); + } + + // dealloc in kClassDef.finalize + JSFunction *functionPtr = new JSFunction(std::move(function)); + auto functionObject = Object(ctx, JSC_JSObjectMake(ctx, *classRef, functionPtr)); functionObject.setProperty("name", Value(ctx, name)); return functionObject; } @@ -72,7 +89,7 @@ JSObjectRef makeFunction( const char* name, JSObjectCallAsFunctionCallback callback) { auto jsName = String(ctx, name); - return JSObjectMakeFunctionWithCallback(ctx, jsName, callback); + return JSC_JSObjectMakeFunctionWithCallback(ctx, jsName, callback); } void installGlobalFunction( @@ -80,7 +97,7 @@ void installGlobalFunction( const char* name, JSObjectCallAsFunctionCallback callback) { String jsName(ctx, name); - JSObjectRef functionObj = JSObjectMakeFunctionWithCallback( + JSObjectRef functionObj = JSC_JSObjectMakeFunctionWithCallback( ctx, jsName, callback); Object::getGlobalObject(ctx).setProperty(jsName, Value(ctx, functionObj)); } @@ -93,9 +110,10 @@ void installGlobalProxy( proxyClassDefintion.className = "_FBProxyClass"; proxyClassDefintion.getProperty = callback; - JSClassRef proxyClass = JSClassCreate(&proxyClassDefintion); - JSObjectRef proxyObj = JSObjectMake(ctx, proxyClass, nullptr); - JSClassRelease(proxyClass); + const bool isCustomJSC = isCustomJSCPtr(ctx); + JSClassRef proxyClass = JSC_JSClassCreate(isCustomJSC, &proxyClassDefintion); + JSObjectRef proxyObj = JSC_JSObjectMake(ctx, proxyClass, nullptr); + JSC_JSClassRelease(isCustomJSC, proxyClass); Object::getGlobalObject(ctx).setProperty(name, Value(ctx, proxyObj)); } @@ -109,7 +127,7 @@ JSValueRef evaluateScript(JSContextRef context, JSStringRef script, JSStringRef fbsystrace::FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "evaluateScript"); #endif JSValueRef exn, result; - result = JSEvaluateScript(context, script, NULL, source, 0, &exn); + result = JSC_JSEvaluateScript(context, script, NULL, source, 0, &exn); if (result == nullptr) { formatAndThrowJSException(context, exn, source); } diff --git a/ReactCommon/jschelpers/JSCHelpers.h b/ReactCommon/jschelpers/JSCHelpers.h index 7e5c3dfe5..c30a562af 100644 --- a/ReactCommon/jschelpers/JSCHelpers.h +++ b/ReactCommon/jschelpers/JSCHelpers.h @@ -98,7 +98,7 @@ inline JSObjectCallAsFunctionCallback exceptionWrapMethod() { return (*method)(ctx, function, thisObject, argumentCount, arguments, exception); } catch (...) { *exception = translatePendingCppExceptionToJSError(ctx, function); - return JSValueMakeUndefined(ctx); + return JSC_JSValueMakeUndefined(ctx); } } }; diff --git a/ReactCommon/jschelpers/Value.cpp b/ReactCommon/jschelpers/Value.cpp index 820881c77..c872749d8 100644 --- a/ReactCommon/jschelpers/Value.cpp +++ b/ReactCommon/jschelpers/Value.cpp @@ -25,7 +25,7 @@ Value::Value(JSContextRef context, JSValueRef value) : Value::Value(JSContextRef context, JSStringRef str) : m_context(context), - m_value(JSValueMakeString(context, str)) + m_value(JSC_JSValueMakeString(context, str)) { } @@ -42,7 +42,7 @@ JSContextRef Value::context() const { std::string Value::toJSONString(unsigned indent) const { JSValueRef exn; - auto stringToAdopt = JSValueCreateJSONString(m_context, m_value, indent, &exn); + auto stringToAdopt = JSC_JSValueCreateJSONString(m_context, m_value, indent, &exn); if (stringToAdopt == nullptr) { std::string exceptionText = Value(m_context, exn).toString().str(); throwJSExecutionException("Exception creating JSON string: %s", exceptionText.c_str()); @@ -52,7 +52,7 @@ std::string Value::toJSONString(unsigned indent) const { /* static */ Value Value::fromJSON(JSContextRef ctx, const String& json) { - auto result = JSValueMakeFromJSONString(ctx, json); + auto result = JSC_JSValueMakeFromJSONString(ctx, json); if (!result) { throwJSExecutionException("Failed to create String from JSON: %s", json.str().c_str()); } @@ -86,19 +86,19 @@ JSValueRef Value::fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj) switch (obj.type()) { // For premitive types (and strings), just create and return an equivalent JSValue case folly::dynamic::Type::NULLT: - return JSValueMakeNull(ctx); + return JSC_JSValueMakeNull(ctx); case folly::dynamic::Type::BOOL: - return JSValueMakeBoolean(ctx, obj.getBool()); + return JSC_JSValueMakeBoolean(ctx, obj.getBool()); case folly::dynamic::Type::DOUBLE: - return JSValueMakeNumber(ctx, obj.getDouble()); + return JSC_JSValueMakeNumber(ctx, obj.getDouble()); case folly::dynamic::Type::INT64: - return JSValueMakeNumber(ctx, obj.asDouble()); + return JSC_JSValueMakeNumber(ctx, obj.asDouble()); case folly::dynamic::Type::STRING: - return JSValueMakeString(ctx, String(ctx, obj.getString().c_str())); + return JSC_JSValueMakeString(ctx, String(ctx, obj.getString().c_str())); case folly::dynamic::Type::ARRAY: { // Collect JSValue for every element in the array @@ -107,16 +107,16 @@ JSValueRef Value::fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj) vals[i] = fromDynamicInner(ctx, obj[i]); } // Create a JSArray with the values - JSValueRef arr = JSObjectMakeArray(ctx, obj.size(), vals, nullptr); + JSValueRef arr = JSC_JSObjectMakeArray(ctx, obj.size(), vals, nullptr); return arr; } case folly::dynamic::Type::OBJECT: { // Create an empty object - JSObjectRef jsObj = JSObjectMake(ctx, nullptr, nullptr); + JSObjectRef jsObj = JSC_JSObjectMake(ctx, nullptr, nullptr); // Create a JSValue for each of the object's children and set them in the object for (auto it = obj.items().begin(); it != obj.items().end(); ++it) { - JSObjectSetProperty( + JSC_JSObjectSetProperty( ctx, jsObj, String(ctx, it->first.asString().c_str()), @@ -129,13 +129,13 @@ JSValueRef Value::fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj) default: // Assert not reached LOG(FATAL) << "Trying to convert a folly object of unsupported type."; - return JSValueMakeNull(ctx); + return JSC_JSValueMakeNull(ctx); } } Object Value::asObject() { JSValueRef exn; - JSObjectRef jsObj = JSValueToObject(context(), m_value, &exn); + JSObjectRef jsObj = JSC_JSValueToObject(context(), m_value, &exn); if (!jsObj) { std::string exceptionText = Value(m_context, exn).toString().str(); throwJSExecutionException("Failed to convert to object: %s", exceptionText.c_str()); @@ -149,7 +149,7 @@ Value Value::makeError(JSContextRef ctx, const char *error) { JSValueRef exn; JSValueRef args[] = { Value(ctx, String(ctx, error)) }; - JSObjectRef errorObj = JSObjectMakeError(ctx, 1, args, &exn); + JSObjectRef errorObj = JSC_JSObjectMakeError(ctx, 1, args, &exn); if (!errorObj) { std::string exceptionText = Value(ctx, exn).toString().str(); throwJSExecutionException("Exception calling object as function: %s", exceptionText.c_str()); @@ -179,7 +179,7 @@ Value Object::callAsFunction(const Object& thisObj, int nArgs, const JSValueRef Value Object::callAsFunction(JSObjectRef thisObj, int nArgs, const JSValueRef args[]) const { JSValueRef exn; - JSValueRef result = JSObjectCallAsFunction(m_context, m_obj, thisObj, nArgs, args, &exn); + JSValueRef result = JSC_JSObjectCallAsFunction(m_context, m_obj, thisObj, nArgs, args, &exn); if (!result) { std::string exceptionText = Value(m_context, exn).toString().str(); throwJSExecutionException("Exception calling object as function: %s", exceptionText.c_str()); @@ -189,7 +189,7 @@ Value Object::callAsFunction(JSObjectRef thisObj, int nArgs, const JSValueRef ar Object Object::callAsConstructor(std::initializer_list args) const { JSValueRef exn; - JSObjectRef result = JSObjectCallAsConstructor(m_context, m_obj, args.size(), args.begin(), &exn); + JSObjectRef result = JSC_JSObjectCallAsConstructor(m_context, m_obj, args.size(), args.begin(), &exn); if (!result) { std::string exceptionText = Value(m_context, exn).toString().str(); throwJSExecutionException("Exception calling object as constructor: %s", exceptionText.c_str()); @@ -199,7 +199,7 @@ Object Object::callAsConstructor(std::initializer_list args) const { Value Object::getProperty(const String& propName) const { JSValueRef exn; - JSValueRef property = JSObjectGetProperty(m_context, m_obj, propName, &exn); + JSValueRef property = JSC_JSObjectGetProperty(m_context, m_obj, propName, &exn); if (!property) { std::string exceptionText = Value(m_context, exn).toString().str(); throwJSExecutionException("Failed to get property: %s", exceptionText.c_str()); @@ -209,7 +209,7 @@ Value Object::getProperty(const String& propName) const { Value Object::getPropertyAtIndex(unsigned index) const { JSValueRef exn; - JSValueRef property = JSObjectGetPropertyAtIndex(m_context, m_obj, index, &exn); + JSValueRef property = JSC_JSObjectGetPropertyAtIndex(m_context, m_obj, index, &exn); if (!property) { std::string exceptionText = Value(m_context, exn).toString().str(); throwJSExecutionException("Failed to get property at index %u: %s", index, exceptionText.c_str()); @@ -223,7 +223,7 @@ Value Object::getProperty(const char *propName) const { void Object::setProperty(const String& propName, const Value& value) const { JSValueRef exn = NULL; - JSObjectSetProperty(m_context, m_obj, propName, value, kJSPropertyAttributeNone, &exn); + JSC_JSObjectSetProperty(m_context, m_obj, propName, value, kJSPropertyAttributeNone, &exn); if (exn) { std::string exceptionText = Value(m_context, exn).toString().str(); throwJSExecutionException("Failed to set property: %s", exceptionText.c_str()); @@ -235,34 +235,34 @@ void Object::setProperty(const char *propName, const Value& value) const { } std::vector Object::getPropertyNames() const { - auto namesRef = JSObjectCopyPropertyNames(m_context, m_obj); - size_t count = JSPropertyNameArrayGetCount(namesRef); + auto namesRef = JSC_JSObjectCopyPropertyNames(m_context, m_obj); + size_t count = JSC_JSPropertyNameArrayGetCount(m_context, namesRef); std::vector names; names.reserve(count); for (size_t i = 0; i < count; i++) { - names.emplace_back( - String::ref(m_context, JSPropertyNameArrayGetNameAtIndex(namesRef, i))); + names.emplace_back(String::ref(m_context, + JSC_JSPropertyNameArrayGetNameAtIndex(m_context, namesRef, i))); } - JSPropertyNameArrayRelease(namesRef); + JSC_JSPropertyNameArrayRelease(m_context, namesRef); return names; } std::unordered_map Object::toJSONMap() const { std::unordered_map map; - auto namesRef = JSObjectCopyPropertyNames(m_context, m_obj); - size_t count = JSPropertyNameArrayGetCount(namesRef); + auto namesRef = JSC_JSObjectCopyPropertyNames(m_context, m_obj); + size_t count = JSC_JSPropertyNameArrayGetCount(m_context, namesRef); for (size_t i = 0; i < count; i++) { - auto key = String::ref(m_context, - JSPropertyNameArrayGetNameAtIndex(namesRef, i)); + auto key = String::ref(m_context, + JSC_JSPropertyNameArrayGetNameAtIndex(m_context, namesRef, i)); map.emplace(key.str(), getProperty(key).toJSONString()); } - JSPropertyNameArrayRelease(namesRef); + JSC_JSPropertyNameArrayRelease(m_context, namesRef); return map; } /* static */ Object Object::create(JSContextRef ctx) { - JSObjectRef newObj = JSObjectMake( + JSObjectRef newObj = JSC_JSObjectMake( ctx, NULL, // create instance of default object class NULL); // no private data diff --git a/ReactCommon/jschelpers/Value.h b/ReactCommon/jschelpers/Value.h index af035e78a..2a890d37e 100644 --- a/ReactCommon/jschelpers/Value.h +++ b/ReactCommon/jschelpers/Value.h @@ -40,7 +40,7 @@ private: class String : public noncopyable { public: explicit String(JSContextRef context, const char* utf8) : - m_context(context), m_string(JSStringCreateWithUTF8CString(utf8)) + m_context(context), m_string(JSC_JSStringCreateWithUTF8CString(context, utf8)) {} String(String&& other) : @@ -53,13 +53,13 @@ public: m_context(other.m_context), m_string(other.m_string) { if (m_string) { - JSStringRetain(m_string); + JSC_JSStringRetain(m_context, m_string); } } ~String() { if (m_string) { - JSStringRelease(m_string); + JSC_JSStringRelease(m_context, m_string); } } @@ -69,12 +69,12 @@ public: // Length in characters size_t length() const { - return JSStringGetLength(m_string); + return JSC_JSStringGetLength(m_context, m_string); } // Length in bytes of a null-terminated utf8 encoded value size_t utf8Size() const { - return JSStringGetMaximumUTF8CStringSize(m_string); + return JSC_JSStringGetMaximumUTF8CStringSize(m_context, m_string); } /* @@ -92,22 +92,22 @@ public: * https://mathiasbynens.be/notes/javascript-unicode */ std::string str() const { - const JSChar* utf16 = JSStringGetCharactersPtr(m_string); - int stringLength = JSStringGetLength(m_string); + const JSChar* utf16 = JSC_JSStringGetCharactersPtr(m_context, m_string); + int stringLength = JSC_JSStringGetLength(m_context, m_string); return unicode::utf16toUTF8(utf16, stringLength); } // Assumes that utf8 is null terminated bool equals(const char* utf8) { - return JSStringIsEqualToUTF8CString(m_string, utf8); + return JSC_JSStringIsEqualToUTF8CString(m_context, m_string, utf8); } // This assumes ascii is nul-terminated. static String createExpectingAscii(JSContextRef context, const char* ascii, size_t len) { #if WITH_FBJSCEXTENSIONS - return String(context, JSStringCreateWithUTF8CStringExpectAscii(ascii, len), true); + return String(context, JSC_JSStringCreateWithUTF8CStringExpectAscii(context, ascii, len), true); #else - return String(context, JSStringCreateWithUTF8CString(ascii), true); + return String(context, JSC_JSStringCreateWithUTF8CString(context, ascii), true); #endif } @@ -128,7 +128,7 @@ private: m_context(context), m_string(string) { if (!adopt && string) { - JSStringRetain(string); + JSC_JSStringRetain(context, string); } } @@ -153,7 +153,7 @@ public: ~Object() { if (m_isProtected && m_obj) { - JSValueUnprotect(m_context, m_obj); + JSC_JSValueUnprotect(m_context, m_obj); } } @@ -171,7 +171,7 @@ public: operator Value() const; bool isFunction() const { - return JSObjectIsFunction(m_context, m_obj); + return JSC_JSObjectIsFunction(m_context, m_obj); } Value callAsFunction(std::initializer_list args) const; @@ -191,18 +191,20 @@ public: void makeProtected() { if (!m_isProtected && m_obj) { - JSValueProtect(m_context, m_obj); + JSC_JSValueProtect(m_context, m_obj); m_isProtected = true; } } template ReturnType* getPrivate() const { - return static_cast(JSObjectGetPrivate(m_obj)); + const bool isCustomJSC = isCustomJSCPtr(m_context); + return static_cast(JSC_JSObjectGetPrivate(isCustomJSC, m_obj)); } void setPrivate(void* data) const { - JSObjectSetPrivate(m_obj, data); + const bool isCustomJSC = isCustomJSCPtr(m_context); + JSC_JSObjectSetPrivate(isCustomJSC, m_obj, data); } JSContextRef context() const { @@ -210,7 +212,7 @@ public: } static Object getGlobalObject(JSContextRef ctx) { - auto globalObj = JSContextGetGlobalObject(ctx); + auto globalObj = JSC_JSContextGetGlobalObject(ctx); return Object(ctx, globalObj); } @@ -238,7 +240,7 @@ public: } JSType getType() const { - return JSValueGetType(m_context, m_value); + return JSC_JSValueGetType(m_context, m_value); } bool isBoolean() const { @@ -246,7 +248,7 @@ public: } bool asBoolean() const { - return JSValueToBoolean(context(), m_value); + return JSC_JSValueToBoolean(context(), m_value); } bool isNumber() const { @@ -263,7 +265,7 @@ public: double asNumber() const { if (isNumber()) { - return JSValueToNumber(context(), m_value, nullptr); + return JSC_JSValueToNumber(context(), m_value, nullptr); } else { return 0.0f; } @@ -288,17 +290,17 @@ public: } String toString() noexcept { - return String::adopt(context(), JSValueToStringCopy(context(), m_value, nullptr)); + return String::adopt(context(), JSC_JSValueToStringCopy(context(), m_value, nullptr)); } static Value makeError(JSContextRef ctx, const char *error); static Value makeNumber(JSContextRef ctx, double value) { - return Value(ctx, JSValueMakeNumber(ctx, value)); + return Value(ctx, JSC_JSValueMakeNumber(ctx, value)); } static Value makeUndefined(JSContextRef ctx) { - return Value(ctx, JSValueMakeUndefined(ctx)); + return Value(ctx, JSC_JSValueMakeUndefined(ctx)); } std::string toJSONString(unsigned indent = 0) const;