Remove jschelpers and privatedata

Summary: JSI doesn't use any of this.

Reviewed By: RSNara

Differential Revision: D10229167

fbshipit-source-id: 9eaa288a1d62bafb3ff0626f9f8430e699fdad4a
This commit is contained in:
Marc Horowitz 2018-10-18 00:47:05 -07:00 committed by Facebook Github Bot
parent c49d3653ef
commit 00381920c6
18 changed files with 0 additions and 2070 deletions

View File

@ -147,6 +147,5 @@ rn_xplat_cxx_library(
react_native_xplat_target("microprofiler:microprofiler"),
"xplat//folly:optional",
"xplat//third-party/glog:glog",
react_native_xplat_target("privatedata:privatedata"),
],
)

View File

@ -1,27 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := jschelpers
LOCAL_SRC_FILES := \
JSCHelpers.cpp \
Unicode.cpp \
Value.cpp \
LOCAL_C_INCLUDES := $(LOCAL_PATH)/..
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
LOCAL_CFLAGS := \
-DLOG_TAG=\"ReactNative\"
LOCAL_CFLAGS += -fexceptions -frtti
LOCAL_SHARED_LIBRARIES := libfolly_json libjsc libglog
include $(BUILD_STATIC_LIBRARY)
$(call import-module,folly)
$(call import-module,jsc)
$(call import-module,glog)
$(call import-module,privatedata)

View File

@ -1,73 +0,0 @@
load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "ANDROID_JSC_INTERNAL_DEPS", "APPLE", "APPLE_JSC_INTERNAL_DEPS", "react_native_xplat_target", "rn_xplat_cxx_library")
EXPORTED_HEADERS = [
"JavaScriptCore.h",
"JSCHelpers.h",
"JSCWrapper.h",
"noncopyable.h",
"Unicode.h",
"Value.h",
]
rn_xplat_cxx_library(
name = "jscinternalhelpers",
srcs = glob(
["*.cpp"],
exclude = ["systemJSCWrapper.cpp"],
),
headers = glob(
["*.h"],
exclude = EXPORTED_HEADERS,
),
header_namespace = "",
exported_headers = dict([
(
"jschelpers/%s" % header,
header,
)
for header in EXPORTED_HEADERS
]),
compiler_flags = [
"-Wall",
"-fexceptions",
"-frtti",
"-fvisibility=hidden",
"-std=c++1y",
],
fbandroid_deps = ANDROID_JSC_INTERNAL_DEPS,
fbobjc_deps = APPLE_JSC_INTERNAL_DEPS,
force_static = True,
platforms = (ANDROID, APPLE),
visibility = [
"PUBLIC",
],
deps = [
"xplat//folly:molly",
"xplat//third-party/glog:glog",
react_native_xplat_target("privatedata:privatedata"),
],
exported_deps = [
react_native_xplat_target("privatedata:privatedata"),
],
)
rn_xplat_cxx_library(
name = "jschelpers",
srcs = [],
compiler_flags = [
"-Wall",
"-fexceptions",
"-fvisibility=hidden",
"-std=c++1y",
],
fbobjc_frameworks = [
"$SDKROOT/System/Library/Frameworks/JavaScriptCore.framework",
],
fbobjc_srcs = ["systemJSCWrapper.cpp"],
force_static = True,
platforms = (ANDROID, APPLE),
visibility = [
"PUBLIC",
],
deps = [":jscinternalhelpers"],
)

View File

@ -1,299 +0,0 @@
// Copyright (c) Facebook, Inc. and its affiliates.
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "JSCHelpers.h"
#ifdef WITH_FBSYSTRACE
#include <fbsystrace.h>
#endif
#include <glog/logging.h>
#if WITH_FBJSCEXTENSIONS
#include <pthread.h>
#endif
#include "JavaScriptCore.h"
#include "Value.h"
#include <privatedata/PrivateDataBase.h>
#if WITH_FBJSCEXTENSIONS
#undef ASSERT
#undef WTF_EXPORT_PRIVATE
#include <JavaScriptCore/config.h>
#include <wtf/WTFThreadData.h>
#undef TRUE
#undef FALSE
#endif
namespace facebook {
namespace react {
namespace {
class JSFunctionPrivateData : public PrivateDataBase {
public:
explicit JSFunctionPrivateData(JSFunction&& function) : jsFunction_{std::move(function)} {}
JSFunction& getJSFunction() {
return jsFunction_;
}
private:
JSFunction jsFunction_;
};
JSValueRef functionCaller(
JSContextRef ctx,
JSObjectRef function,
JSObjectRef thisObject,
size_t argumentCount,
const JSValueRef arguments[],
JSValueRef* exception) {
const bool isCustomJSC = isCustomJSCPtr(ctx);
auto* privateData = PrivateDataBase::cast<JSFunctionPrivateData>(
JSC_JSObjectGetPrivate(isCustomJSC, function));
return (privateData->getJSFunction())(ctx, thisObject, argumentCount, arguments);
}
JSClassRef createFuncClass(JSContextRef ctx) {
JSClassDefinition definition = kJSClassDefinitionEmpty;
definition.attributes |= kJSClassAttributeNoAutomaticPrototype;
// Need to duplicate the two different finalizer blocks, since there's no way
// for it to capture this static information.
const bool isCustomJSC = isCustomJSCPtr(ctx);
if (isCustomJSC) {
definition.finalize = [](JSObjectRef object) {
auto* privateData = PrivateDataBase::cast<JSFunctionPrivateData>(
JSC_JSObjectGetPrivate(true, object));
delete privateData;
};
} else {
definition.finalize = [](JSObjectRef object) {
auto* privateData = PrivateDataBase::cast<JSFunctionPrivateData>(
JSC_JSObjectGetPrivate(false, object));
delete privateData;
};
}
definition.callAsFunction = exceptionWrapMethod<&functionCaller>();
return JSC_JSClassCreate(isCustomJSC, &definition);
}
JSObjectRef makeFunction(
JSContextRef ctx,
JSStringRef name,
JSFunction function) {
static JSClassRef kClassDef = NULL, kCustomJSCClassDef = NULL;
JSClassRef *classRef = isCustomJSCPtr(ctx) ? &kCustomJSCClassDef : &kClassDef;
if (!*classRef) {
*classRef = createFuncClass(ctx);
}
// dealloc in kClassDef.finalize
JSFunctionPrivateData *functionDataPtr = new JSFunctionPrivateData(std::move(function));
auto functionObject = Object(ctx, JSC_JSObjectMake(ctx, *classRef, functionDataPtr));
functionObject.setProperty("name", Value(ctx, name));
return functionObject;
}
}
void JSException::buildMessage(JSContextRef ctx, JSValueRef exn, JSStringRef sourceURL, const char* errorMsg) {
std::ostringstream msgBuilder;
if (errorMsg && strlen(errorMsg) > 0) {
msgBuilder << errorMsg << ": ";
}
Object exnObject = Value(ctx, exn).asObject();
Value exnMessage = exnObject.getProperty("message");
msgBuilder << (exnMessage.isString() ? exnMessage : (Value)exnObject).toString().str();
// 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 = sourceURL != nullptr ? String::ref(ctx, sourceURL).str() : "";
auto line = exnObject.getProperty("line");
if (line != nullptr && line.isNumber()) {
if (locationInfo.empty() && line.asInteger() != 1) {
// If there is a non-trivial line number, but there was no
// location info, we include a placeholder, and the line
// number.
locationInfo = folly::to<std::string>("<unknown file>:", line.asInteger());
} else if (!locationInfo.empty()) {
// If there is location info, we always include the line
// number, regardless of its value.
locationInfo += folly::to<std::string>(":", line.asInteger());
}
}
if (!locationInfo.empty()) {
msgBuilder << " (" << locationInfo << ")";
}
auto exceptionText = msgBuilder.str();
LOG(ERROR) << "Got JS Exception: " << exceptionText;
msg_ = std::move(exceptionText);
Value jsStack = exnObject.getProperty("stack");
if (jsStack.isString()) {
auto stackText = jsStack.toString().str();
LOG(ERROR) << "Got JS Stack: " << stackText;
stack_ = std::move(stackText);
}
}
namespace ExceptionHandling {
PlatformErrorExtractor platformErrorExtractor;
}
JSObjectRef makeFunction(
JSContextRef ctx,
const char* name,
JSFunction function) {
return makeFunction(ctx, String(ctx, name), std::move(function));
}
void installGlobalFunction(
JSGlobalContextRef ctx,
const char* name,
JSFunction function) {
auto jsName = String(ctx, name);
auto functionObj = makeFunction(ctx, jsName, std::move(function));
Object::getGlobalObject(ctx).setProperty(jsName, Value(ctx, functionObj));
}
JSObjectRef makeFunction(
JSGlobalContextRef ctx,
const char* name,
JSObjectCallAsFunctionCallback callback) {
auto jsName = String(ctx, name);
return JSC_JSObjectMakeFunctionWithCallback(ctx, jsName, callback);
}
void installGlobalFunction(
JSGlobalContextRef ctx,
const char* name,
JSObjectCallAsFunctionCallback callback) {
String jsName(ctx, name);
JSObjectRef functionObj = JSC_JSObjectMakeFunctionWithCallback(
ctx, jsName, callback);
Object::getGlobalObject(ctx).setProperty(jsName, Value(ctx, functionObj));
}
void installGlobalProxy(
JSGlobalContextRef ctx,
const char* name,
JSObjectGetPropertyCallback callback) {
JSClassDefinition proxyClassDefintion = kJSClassDefinitionEmpty;
proxyClassDefintion.attributes |= kJSClassAttributeNoAutomaticPrototype;
proxyClassDefintion.getProperty = callback;
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));
}
void removeGlobal(JSGlobalContextRef ctx, const char* name) {
Object::getGlobalObject(ctx).setProperty(name, Value::makeUndefined(ctx));
}
JSValueRef evaluateScript(JSContextRef context, JSStringRef script, JSStringRef sourceURL) {
JSValueRef exn, result;
result = JSC_JSEvaluateScript(context, script, NULL, sourceURL, 0, &exn);
if (result == nullptr) {
throw JSException(context, exn, sourceURL);
}
return result;
}
#if WITH_FBJSCEXTENSIONS
JSValueRef evaluateSourceCode(JSContextRef context, JSSourceCodeRef source, JSStringRef sourceURL) {
JSValueRef exn, result;
result = JSEvaluateSourceCode(context, source, NULL, &exn);
if (result == nullptr) {
throw JSException(context, exn, sourceURL);
}
return result;
}
#endif
JSContextLock::JSContextLock(JSGlobalContextRef ctx) noexcept
#if WITH_FBJSCEXTENSIONS
: ctx_(ctx),
globalLock_(PTHREAD_MUTEX_INITIALIZER)
{
WTFThreadData& threadData = wtfThreadData();
// Code below is responsible for acquiring locks. It should execute
// atomically, thus none of the functions invoked from now on are allowed to
// throw an exception
try {
if (!threadData.isDebuggerThread()) {
CHECK(0 == pthread_mutex_lock(&globalLock_));
}
JSLock(ctx_);
} catch (...) {
abort();
}
}
#else
{}
#endif
JSContextLock::~JSContextLock() noexcept {
#if WITH_FBJSCEXTENSIONS
WTFThreadData& threadData = wtfThreadData();
JSUnlock(ctx_);
if (!threadData.isDebuggerThread()) {
CHECK(0 == pthread_mutex_unlock(&globalLock_));
}
#endif
}
JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, const char *exceptionLocation) {
try {
throw;
} catch (const std::bad_alloc& ex) {
throw; // We probably shouldn't try to handle this in JS
} catch (const std::exception& ex) {
if (ExceptionHandling::platformErrorExtractor) {
auto extractedEror = ExceptionHandling::platformErrorExtractor(ex, exceptionLocation);
if (extractedEror.message.length() > 0) {
return Value::makeError(ctx, extractedEror.message.c_str(), extractedEror.stack.c_str());
}
}
auto msg = folly::to<std::string>("C++ exception in '", exceptionLocation, "'\n\n", ex.what());
return Value::makeError(ctx, msg.c_str());
} catch (const char* ex) {
auto msg = folly::to<std::string>("C++ exception (thrown as a char*) in '", exceptionLocation, "'\n\n", ex);
return Value::makeError(ctx, msg.c_str());
} catch (...) {
auto msg = folly::to<std::string>("Unknown C++ exception in '", exceptionLocation, "'");
return Value::makeError(ctx, msg.c_str());
}
}
JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, JSObjectRef jsFunctionCause) {
try {
auto functionName = Object(ctx, jsFunctionCause).getProperty("name").toString().str();
return translatePendingCppExceptionToJSError(ctx, functionName.c_str());
} catch (...) {
return Value::makeError(ctx, "Failed to translate native exception");
}
}
} }

View File

@ -1,149 +0,0 @@
// Copyright (c) Facebook, Inc. and its affiliates.
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#pragma once
#include <algorithm>
#include <functional>
#include <stdexcept>
#include <jschelpers/JavaScriptCore.h>
#include <jschelpers/Value.h>
#ifndef RN_EXPORT
#define RN_EXPORT __attribute__((visibility("default")))
#endif
namespace facebook {
namespace react {
class RN_EXPORT JSException : public std::exception {
public:
explicit JSException(const char* msg)
: msg_(msg) {}
explicit JSException(JSContextRef ctx, JSValueRef exn, const char* msg) {
buildMessage(ctx, exn, nullptr, msg);
}
explicit JSException(JSContextRef ctx, JSValueRef exn, JSStringRef sourceURL) {
buildMessage(ctx, exn, sourceURL, nullptr);
}
const std::string& getStack() const {
return stack_;
}
virtual const char* what() const noexcept override {
return msg_.c_str();
}
private:
std::string msg_;
std::string stack_;
void buildMessage(JSContextRef ctx, JSValueRef exn, JSStringRef sourceURL, const char* errorMsg);
};
namespace ExceptionHandling {
struct ExtractedEror {
std::string message;
// Stacktrace formatted like JS stack
// method@filename[:line[:column]]
std::string stack;
};
typedef ExtractedEror(*PlatformErrorExtractor)(const std::exception &ex, const char *context);
extern PlatformErrorExtractor platformErrorExtractor;
}
using JSFunction = std::function<JSValueRef(JSContextRef, JSObjectRef, size_t, const JSValueRef[])>;
JSObjectRef makeFunction(
JSContextRef ctx,
const char* name,
JSFunction function);
RN_EXPORT void installGlobalFunction(
JSGlobalContextRef ctx,
const char* name,
JSFunction function);
JSObjectRef makeFunction(
JSGlobalContextRef ctx,
const char* name,
JSObjectCallAsFunctionCallback callback);
RN_EXPORT void installGlobalFunction(
JSGlobalContextRef ctx,
const char* name,
JSObjectCallAsFunctionCallback callback);
void installGlobalProxy(
JSGlobalContextRef ctx,
const char* name,
JSObjectGetPropertyCallback callback);
void removeGlobal(JSGlobalContextRef ctx, const char* name);
JSValueRef evaluateScript(
JSContextRef ctx,
JSStringRef script,
JSStringRef sourceURL);
#if WITH_FBJSCEXTENSIONS
JSValueRef evaluateSourceCode(
JSContextRef ctx,
JSSourceCodeRef source,
JSStringRef sourceURL);
#endif
/**
* A lock for protecting accesses to the JSGlobalContext
* This will be a no-op for most compilations, where #if WITH_FBJSCEXTENSIONS is false,
* but avoids deadlocks in execution environments with advanced locking requirements,
* particularly with uses of the pthread mutex lock
**/
class JSContextLock {
public:
JSContextLock(JSGlobalContextRef ctx) noexcept;
~JSContextLock() noexcept;
private:
#if WITH_FBJSCEXTENSIONS
JSGlobalContextRef ctx_;
pthread_mutex_t globalLock_;
#endif
};
JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, const char *exceptionLocation);
JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, JSObjectRef jsFunctionCause);
template<JSValueRef (method)(JSContextRef ctx,
JSObjectRef function,
JSObjectRef thisObject,
size_t argumentCount,
const JSValueRef arguments[],
JSValueRef *exception)>
inline JSObjectCallAsFunctionCallback exceptionWrapMethod() {
struct funcWrapper {
static JSValueRef call(
JSContextRef ctx,
JSObjectRef function,
JSObjectRef thisObject,
size_t argumentCount,
const JSValueRef arguments[],
JSValueRef *exception) {
try {
return (*method)(ctx, function, thisObject, argumentCount, arguments, exception);
} catch (...) {
*exception = translatePendingCppExceptionToJSError(ctx, function);
return JSC_JSValueMakeUndefined(ctx);
}
}
};
return &funcWrapper::call;
}
} }

View File

@ -1,45 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "JSCWrapper.h"
#if defined(__APPLE__)
// TODO: use glog in OSS too
#if __has_include(<glog/logging.h>)
#define USE_GLOG 1
#include <glog/logging.h>
#else
#define USE_GLOG 0
#endif
namespace facebook {
namespace react {
static const JSCWrapper* s_customWrapper = nullptr;
bool isCustomJSCWrapperSet() {
return s_customWrapper != nullptr;
}
const JSCWrapper* customJSCWrapper() {
#if USE_GLOG
CHECK(s_customWrapper != nullptr) << "Accessing custom JSC wrapper before it's set";
#endif
return s_customWrapper;
}
void setCustomJSCWrapper(const JSCWrapper* wrapper) {
#if USE_GLOG
CHECK(s_customWrapper == nullptr) << "Can't set custom JSC wrapper multiple times";
#endif
s_customWrapper = wrapper;
}
} }
#endif

View File

@ -1,189 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <functional>
#include <string>
#include <JavaScriptCore/JavaScript.h>
#if defined(JSCINTERNAL) || (!defined(__APPLE__))
#define JSC_IMPORT extern "C"
#else
#define JSC_IMPORT extern
#endif
#ifndef RN_EXPORT
#define RN_EXPORT __attribute__((visibility("default")))
#endif
namespace facebook {
namespace react {
class IInspector;
}
}
JSC_IMPORT void JSGlobalContextEnableDebugger(
JSGlobalContextRef ctx,
facebook::react::IInspector &globalInspector,
const char *title,
const std::function<bool()> &checkIsInspectedRemote);
JSC_IMPORT void JSGlobalContextDisableDebugger(
JSGlobalContextRef ctx,
facebook::react::IInspector &globalInspector);
// This is used to substitute an alternate JSC implementation for
// testing. These calls must all be ABI compatible with the standard JSC.
JSC_IMPORT JSValueRef JSEvaluateBytecodeBundle(JSContextRef, JSObjectRef, int, JSStringRef, JSValueRef*);
JSC_IMPORT bool JSSamplingProfilerEnabled();
JSC_IMPORT void JSStartSamplingProfilingOnMainJSCThread(JSGlobalContextRef);
JSC_IMPORT JSValueRef JSPokeSamplingProfiler(JSContextRef);
#ifdef __cplusplus
extern "C" {
#endif
JSC_IMPORT void configureJSCForIOS(std::string); // TODO: replace with folly::dynamic once supported
JSC_IMPORT void FBJSContextStartGCTimers(JSContextRef);
#ifdef __cplusplus
}
#endif
#if defined(__APPLE__)
#include <objc/objc.h>
#include <JavaScriptCore/JSStringRefCF.h>
#include <string>
/**
* JSNoBytecodeFileFormatVersion
*
* Version number indicating that bytecode is not supported by this runtime.
*/
RN_EXPORT extern const int32_t JSNoBytecodeFileFormatVersion;
namespace facebook {
namespace react {
#define JSC_WRAPPER_METHOD(m) decltype(&m) m
struct JSCWrapper {
// JSGlobalContext
JSC_WRAPPER_METHOD(JSGlobalContextCreateInGroup);
JSC_WRAPPER_METHOD(JSGlobalContextRelease);
JSC_WRAPPER_METHOD(JSGlobalContextSetName);
// JSContext
JSC_WRAPPER_METHOD(JSContextGetGlobalContext);
JSC_WRAPPER_METHOD(JSContextGetGlobalObject);
JSC_WRAPPER_METHOD(FBJSContextStartGCTimers);
// JSEvaluate
JSC_WRAPPER_METHOD(JSEvaluateScript);
JSC_WRAPPER_METHOD(JSEvaluateBytecodeBundle);
// JSString
JSC_WRAPPER_METHOD(JSStringCreateWithUTF8CString);
JSC_WRAPPER_METHOD(JSStringCreateWithCFString);
#if WITH_FBJSCEXTENSIONS
JSC_WRAPPER_METHOD(JSStringCreateWithUTF8CStringExpectAscii);
#endif
JSC_WRAPPER_METHOD(JSStringCopyCFString);
JSC_WRAPPER_METHOD(JSStringGetCharactersPtr);
JSC_WRAPPER_METHOD(JSStringGetLength);
JSC_WRAPPER_METHOD(JSStringGetMaximumUTF8CStringSize);
JSC_WRAPPER_METHOD(JSStringIsEqualToUTF8CString);
JSC_WRAPPER_METHOD(JSStringRelease);
JSC_WRAPPER_METHOD(JSStringRetain);
// JSClass
JSC_WRAPPER_METHOD(JSClassCreate);
JSC_WRAPPER_METHOD(JSClassRetain);
JSC_WRAPPER_METHOD(JSClassRelease);
// JSObject
JSC_WRAPPER_METHOD(JSObjectCallAsConstructor);
JSC_WRAPPER_METHOD(JSObjectCallAsFunction);
JSC_WRAPPER_METHOD(JSObjectGetPrivate);
JSC_WRAPPER_METHOD(JSObjectGetProperty);
JSC_WRAPPER_METHOD(JSObjectGetPropertyAtIndex);
JSC_WRAPPER_METHOD(JSObjectIsConstructor);
JSC_WRAPPER_METHOD(JSObjectIsFunction);
JSC_WRAPPER_METHOD(JSObjectMake);
JSC_WRAPPER_METHOD(JSObjectMakeArray);
JSC_WRAPPER_METHOD(JSObjectMakeDate);
JSC_WRAPPER_METHOD(JSObjectMakeError);
JSC_WRAPPER_METHOD(JSObjectMakeFunctionWithCallback);
JSC_WRAPPER_METHOD(JSObjectSetPrivate);
JSC_WRAPPER_METHOD(JSObjectSetProperty);
JSC_WRAPPER_METHOD(JSObjectSetPropertyAtIndex);
// JSPropertyNameArray
JSC_WRAPPER_METHOD(JSObjectCopyPropertyNames);
JSC_WRAPPER_METHOD(JSPropertyNameArrayGetCount);
JSC_WRAPPER_METHOD(JSPropertyNameArrayGetNameAtIndex);
JSC_WRAPPER_METHOD(JSPropertyNameArrayRelease);
// JSValue
JSC_WRAPPER_METHOD(JSValueCreateJSONString);
JSC_WRAPPER_METHOD(JSValueGetType);
JSC_WRAPPER_METHOD(JSValueMakeFromJSONString);
JSC_WRAPPER_METHOD(JSValueMakeBoolean);
JSC_WRAPPER_METHOD(JSValueMakeNull);
JSC_WRAPPER_METHOD(JSValueMakeNumber);
JSC_WRAPPER_METHOD(JSValueMakeString);
JSC_WRAPPER_METHOD(JSValueMakeUndefined);
JSC_WRAPPER_METHOD(JSValueProtect);
JSC_WRAPPER_METHOD(JSValueToBoolean);
JSC_WRAPPER_METHOD(JSValueToNumber);
JSC_WRAPPER_METHOD(JSValueToObject);
JSC_WRAPPER_METHOD(JSValueToStringCopy);
JSC_WRAPPER_METHOD(JSValueUnprotect);
JSC_WRAPPER_METHOD(JSValueIsNull);
// Sampling profiler
JSC_WRAPPER_METHOD(JSSamplingProfilerEnabled);
JSC_WRAPPER_METHOD(JSPokeSamplingProfiler);
JSC_WRAPPER_METHOD(JSStartSamplingProfilingOnMainJSCThread);
JSC_WRAPPER_METHOD(JSGlobalContextEnableDebugger);
JSC_WRAPPER_METHOD(JSGlobalContextDisableDebugger);
JSC_WRAPPER_METHOD(configureJSCForIOS);
// Objective-C API
Class JSContext;
Class JSValue;
int32_t JSBytecodeFileFormatVersion;
};
template <typename T>
bool isCustomJSCPtr(T *x) {
return (uintptr_t)x & 0x1;
}
RN_EXPORT bool isCustomJSCWrapperSet();
RN_EXPORT void setCustomJSCWrapper(const JSCWrapper* wrapper);
// This will return a single value for the whole life of the process.
RN_EXPORT const JSCWrapper *systemJSCWrapper();
RN_EXPORT const JSCWrapper *customJSCWrapper();
} }
#else
namespace facebook {
namespace react {
template <typename T>
bool isCustomJSCPtr(T *x) {
// Always use system JSC pointers
return false;
}
} }
#endif

View File

@ -1,212 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <jschelpers/JSCWrapper.h>
#if defined(__APPLE__)
// Use for methods that are taking JSContextRef as a first param
#define __jsc_wrapper(method, ctx, ...) \
(facebook::react::isCustomJSCPtr(ctx) ? \
facebook::react::customJSCWrapper() : \
facebook::react::systemJSCWrapper() \
)->method(ctx, ## __VA_ARGS__)
// Use for methods that don't take a JSContextRef as a first param. The wrapped version
// of this method will require context as an additional param, but it will be dropped
// before calling into the JSC method.
#define __jsc_drop_ctx_wrapper(method, ctx, ...) \
(facebook::react::isCustomJSCPtr(ctx) ? \
facebook::react::customJSCWrapper() : \
facebook::react::systemJSCWrapper() \
)->method(__VA_ARGS__)
// Use for methods were access to a JSContextRef is impractical. The first bool param
// will be dropped before the JSC method is invoked.
#define __jsc_ensure_bool(field) \
static_assert(std::is_same<typename std::decay<decltype(field)>::type, bool>::value, "useCustomJSC must be bool");
#define __jsc_bool_wrapper(method, useCustomJSC, ...) \
([]{ __jsc_ensure_bool(useCustomJSC) }, useCustomJSC ? \
facebook::react::customJSCWrapper() : \
facebook::react::systemJSCWrapper() \
)->method(__VA_ARGS__)
// Used for wrapping properties
#define __jsc_prop_wrapper(prop, ctx) \
(facebook::react::isCustomJSCPtr(ctx) ? \
facebook::react::customJSCWrapper() : \
facebook::react::systemJSCWrapper() \
)->prop
// Poison all regular versions of the JSC API in shared code. This prevents accidental
// mixed usage of regular and custom JSC methods.
// See https://gcc.gnu.org/onlinedocs/gcc-3.3/cpp/Pragmas.html for details
#define jsc_pragma(x) _Pragma(#x)
#ifndef NO_JSC_POISON
#define jsc_poison(methods) jsc_pragma(GCC poison methods)
#else
#define jsc_poison(methods)
#endif
#else
#define __jsc_wrapper(method, ctx, ...) method(ctx, ## __VA_ARGS__)
#define __jsc_drop_ctx_wrapper(method, ctx, ...) ((void)ctx, method(__VA_ARGS__))
#define __jsc_bool_wrapper(method, useCustomJSC, ...) \
((void)useCustomJSC, method(__VA_ARGS__))
#define __jsc_prop_wrapper(prop, ctx) prop
#define jsc_pragma(x)
#define jsc_poison(methods)
#endif
// JSGlobalContext
#define JSC_JSGlobalContextCreateInGroup(...) __jsc_bool_wrapper(JSGlobalContextCreateInGroup, __VA_ARGS__)
#define JSC_JSGlobalContextRelease(...) __jsc_wrapper(JSGlobalContextRelease, __VA_ARGS__)
#define JSC_JSGlobalContextSetName(...) __jsc_wrapper(JSGlobalContextSetName, __VA_ARGS__)
jsc_poison(JSContextGroupCreate JSContextGroupRelease JSContextGroupRetain
JSGlobalContextCreate JSGlobalContextCreateInGroup JSGlobalContextCopyName
JSGlobalContextRelease JSGlobalContextRetain JSGlobalContextSetName)
// JSContext
#define JSC_JSContextGetGlobalContext(...) __jsc_wrapper(JSContextGetGlobalContext, __VA_ARGS__)
#define JSC_JSContextGetGlobalObject(...) __jsc_wrapper(JSContextGetGlobalObject, __VA_ARGS__)
#define JSC_FBJSContextStartGCTimers(...) __jsc_wrapper(FBJSContextStartGCTimers, __VA_ARGS__)
jsc_poison(JSContextGetGlobalContext JSContextGetGlobalObject JSContextGetGroup FBJSContextStartGCTimers)
// JSEvaluate
#define JSC_JSEvaluateScript(...) __jsc_wrapper(JSEvaluateScript, __VA_ARGS__)
#define JSC_JSEvaluateBytecodeBundle(...) __jsc_wrapper(JSEvaluateBytecodeBundle, __VA_ARGS__)
jsc_poison(JSCheckScriptSyntax JSEvaluateScript JSEvaluateBytecodeBundle JSGarbageCollect)
// JSString
#define JSC_JSStringCreateWithCFString(...) __jsc_drop_ctx_wrapper(JSStringCreateWithCFString, __VA_ARGS__)
#define JSC_JSStringCreateWithUTF8CString(...) __jsc_drop_ctx_wrapper(JSStringCreateWithUTF8CString, __VA_ARGS__)
#define JSC_JSStringCreateWithUTF8CStringExpectAscii(...) __jsc_drop_ctx_wrapper(JSStringCreateWithUTF8CStringExpectAscii, __VA_ARGS__)
#define JSC_JSStringCopyCFString(...) __jsc_drop_ctx_wrapper(JSStringCopyCFString, __VA_ARGS__)
#define JSC_JSStringGetCharactersPtr(...) __jsc_drop_ctx_wrapper(JSStringGetCharactersPtr, __VA_ARGS__)
#define JSC_JSStringGetLength(...) __jsc_drop_ctx_wrapper(JSStringGetLength, __VA_ARGS__)
#define JSC_JSStringGetMaximumUTF8CStringSize(...) __jsc_drop_ctx_wrapper(JSStringGetMaximumUTF8CStringSize, __VA_ARGS__)
#define JSC_JSStringIsEqualToUTF8CString(...) __jsc_drop_ctx_wrapper(JSStringIsEqualToUTF8CString, __VA_ARGS__)
#define JSC_JSStringRelease(...) __jsc_drop_ctx_wrapper(JSStringRelease, __VA_ARGS__)
#define JSC_JSStringRetain(...) __jsc_drop_ctx_wrapper(JSStringRetain, __VA_ARGS__)
jsc_poison(JSStringCopyCFString JSStringCreateWithCharacters JSStringCreateWithCFString
JSStringCreateWithUTF8CString JSStringCreateWithUTF8CStringExpectAscii
JSStringGetCharactersPtr JSStringGetLength JSStringGetMaximumUTF8CStringSize
JSStringGetUTF8CString JSStringIsEqual JSStringIsEqualToUTF8CString
JSStringRelease JSStringRetain)
// JSValueRef
#define JSC_JSValueCreateJSONString(...) __jsc_wrapper(JSValueCreateJSONString, __VA_ARGS__)
#define JSC_JSValueGetType(...) __jsc_wrapper(JSValueGetType, __VA_ARGS__)
#define JSC_JSValueMakeFromJSONString(...) __jsc_wrapper(JSValueMakeFromJSONString, __VA_ARGS__)
#define JSC_JSValueMakeBoolean(...) __jsc_wrapper(JSValueMakeBoolean, __VA_ARGS__)
#define JSC_JSValueMakeNull(...) __jsc_wrapper(JSValueMakeNull, __VA_ARGS__)
#define JSC_JSValueMakeNumber(...) __jsc_wrapper(JSValueMakeNumber, __VA_ARGS__)
#define JSC_JSValueMakeString(...) __jsc_wrapper(JSValueMakeString, __VA_ARGS__)
#define JSC_JSValueMakeUndefined(...) __jsc_wrapper(JSValueMakeUndefined, __VA_ARGS__)
#define JSC_JSValueProtect(...) __jsc_wrapper(JSValueProtect, __VA_ARGS__)
#define JSC_JSValueToBoolean(...) __jsc_wrapper(JSValueToBoolean, __VA_ARGS__)
#define JSC_JSValueToNumber(...) __jsc_wrapper(JSValueToNumber, __VA_ARGS__)
#define JSC_JSValueToObject(...) __jsc_wrapper(JSValueToObject, __VA_ARGS__)
#define JSC_JSValueToStringCopy(...) __jsc_wrapper(JSValueToStringCopy, __VA_ARGS__)
#define JSC_JSValueUnprotect(...) __jsc_wrapper(JSValueUnprotect, __VA_ARGS__)
#define JSC_JSValueIsNull(...) __jsc_wrapper(JSValueIsNull, __VA_ARGS__)
jsc_poison(JSValueCreateJSONString JSValueGetType JSValueGetTypedArrayType JSValueIsArray
JSValueIsBoolean JSValueIsDate JSValueIsEqual JSValueIsInstanceOfConstructor
JSValueIsNull JSValueIsNumber JSValueIsObject JSValueIsObjectOfClass
JSValueIsStrictEqual JSValueIsString JSValueIsString JSValueIsUndefined
JSValueMakeBoolean JSValueMakeFromJSONString JSValueMakeNull JSValueMakeNumber
JSValueMakeString JSValueMakeUndefined JSValueProtect JSValueToBoolean
JSValueToNumber JSValueToObject JSValueToStringCopy JSValueUnprotect)
// JSClass
#define JSC_JSClassCreate(...) __jsc_bool_wrapper(JSClassCreate, __VA_ARGS__)
#define JSC_JSClassRetain(...) __jsc_bool_wrapper(JSClassRetain, __VA_ARGS__)
#define JSC_JSClassRelease(...) __jsc_bool_wrapper(JSClassRelease, __VA_ARGS__)
jsc_poison(JSClassCreate JSClassRelease JSClassRetain)
// JSObject
#define JSC_JSObjectCallAsConstructor(...) __jsc_wrapper(JSObjectCallAsConstructor, __VA_ARGS__)
#define JSC_JSObjectCallAsFunction(...) __jsc_wrapper(JSObjectCallAsFunction, __VA_ARGS__)
#define JSC_JSObjectGetPrivate(...) __jsc_bool_wrapper(JSObjectGetPrivate, __VA_ARGS__)
#define JSC_JSObjectGetProperty(...) __jsc_wrapper(JSObjectGetProperty, __VA_ARGS__)
#define JSC_JSObjectGetPropertyAtIndex(...) __jsc_wrapper(JSObjectGetPropertyAtIndex, __VA_ARGS__)
#define JSC_JSObjectIsConstructor(...) __jsc_wrapper(JSObjectIsConstructor, __VA_ARGS__)
#define JSC_JSObjectIsFunction(...) __jsc_wrapper(JSObjectIsFunction, __VA_ARGS__)
#define JSC_JSObjectMake(...) __jsc_wrapper(JSObjectMake, __VA_ARGS__)
#define JSC_JSObjectMakeArray(...) __jsc_wrapper(JSObjectMakeArray, __VA_ARGS__)
#define JSC_JSObjectMakeDate(...) __jsc_wrapper(JSObjectMakeDate, __VA_ARGS__)
#define JSC_JSObjectMakeError(...) __jsc_wrapper(JSObjectMakeError, __VA_ARGS__)
#define JSC_JSObjectMakeFunctionWithCallback(...) __jsc_wrapper(JSObjectMakeFunctionWithCallback, __VA_ARGS__)
#define JSC_JSObjectSetPrivate(...) __jsc_bool_wrapper(JSObjectSetPrivate, __VA_ARGS__)
#define JSC_JSObjectSetProperty(...) __jsc_wrapper(JSObjectSetProperty, __VA_ARGS__)
#define JSC_JSObjectSetPropertyAtIndex(...) __jsc_wrapper(JSObjectSetPropertyAtIndex, __VA_ARGS__)
jsc_poison(JSObjectCallAsConstructor JSObjectCallAsFunction JSObjectDeleteProperty
JSObjectGetPrivate JSObjectGetProperty JSObjectGetPropertyAtIndex
JSObjectGetPrototype JSObjectHasProperty JSObjectIsConstructor
JSObjectIsFunction JSObjectMake JSObjectMakeArray JSObjectMakeConstructor
JSObjectMakeDate JSObjectMakeError JSObjectMakeFunction
JSObjectMakeFunctionWithCallback JSObjectMakeRegExp JSObjectSetPrivate
JSObjectSetPrototype JSObjectSetProperty JSObjectSetPropertyAtIndex)
// JSPropertyNameArray
#define JSC_JSObjectCopyPropertyNames(...) __jsc_wrapper(JSObjectCopyPropertyNames, __VA_ARGS__)
#define JSC_JSPropertyNameArrayGetCount(...) __jsc_drop_ctx_wrapper(JSPropertyNameArrayGetCount, __VA_ARGS__)
#define JSC_JSPropertyNameArrayGetNameAtIndex(...) __jsc_drop_ctx_wrapper(JSPropertyNameArrayGetNameAtIndex, __VA_ARGS__)
#define JSC_JSPropertyNameArrayRelease(...) __jsc_drop_ctx_wrapper(JSPropertyNameArrayRelease, __VA_ARGS__)
jsc_poison(JSObjectCopyPropertyNames JSPropertyNameAccumulatorAddName
JSPropertyNameArrayGetCount JSPropertyNameArrayGetNameAtIndex
JSPropertyNameArrayRelease JSPropertyNameArrayRetain)
// JSTypedArray
jsc_poison(JSObjectMakeArrayBufferWithBytesNoCopy JSObjectMakeTypedArray
JSObjectMakeTypedArrayWithArrayBuffer
JSObjectMakeTypedArrayWithArrayBufferAndOffset
JSObjectMakeTypedArrayWithBytesNoCopy JSObjectGetTypedArrayByteLength
JSObjectGetTypedArrayByteOffset JSObjectGetTypedArrayBytesPtr
JSObjectGetTypedArrayBuffer JSObjectGetTypedArrayLength
JSObjectGetArrayBufferBytesPtr JSObjectGetArrayBufferByteLength)
// Sampling profiler
#define JSC_JSSamplingProfilerEnabled(...) __jsc_drop_ctx_wrapper(JSSamplingProfilerEnabled, __VA_ARGS__)
#define JSC_JSPokeSamplingProfiler(...) __jsc_wrapper(JSPokeSamplingProfiler, __VA_ARGS__)
#define JSC_JSStartSamplingProfilingOnMainJSCThread(...) __jsc_wrapper(JSStartSamplingProfilingOnMainJSCThread, __VA_ARGS__)
jsc_poison(JSSamplingProfilerEnabled JSPokeSamplingProfiler
JSStartSamplingProfilingOnMainJSCThread)
#define JSC_JSGlobalContextEnableDebugger(...) __jsc_wrapper(JSGlobalContextEnableDebugger, __VA_ARGS__)
// no need to poison JSGlobalContextEnableDebugger because it's not defined for System JSC / standard SDK header
// jsc_poison(JSGlobalContextEnableDebugger)
#define JSC_JSGlobalContextDisableDebugger(...) __jsc_wrapper(JSGlobalContextDisableDebugger, __VA_ARGS__)
// no need to poison JSGlobalContextDisableDebugger because it's not defined for System JSC / standard SDK header
// jsc_poison(JSGlobalContextDisableDebugger)
#define JSC_configureJSCForIOS(...) __jsc_bool_wrapper(configureJSCForIOS, __VA_ARGS__)
jsc_poison(configureJSCForIOS)
// Objective-C API
#define JSC_JSContext(ctx) __jsc_prop_wrapper(JSContext, ctx)
#define JSC_JSValue(ctx) __jsc_prop_wrapper(JSValue, ctx)
#undef jsc_poison
#undef jsc_pragma

View File

@ -1,91 +0,0 @@
// Copyright (c) Facebook, Inc. and its affiliates.
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "Unicode.h"
namespace facebook {
namespace react {
namespace unicode {
namespace {
// TODO(12827176): Don't duplicate this code here and fbjni.
const uint16_t kUtf8OneByteBoundary = 0x80;
const uint16_t kUtf8TwoBytesBoundary = 0x800;
const uint16_t kUtf16HighSubLowBoundary = 0xD800;
const uint16_t kUtf16HighSubHighBoundary = 0xDC00;
const uint16_t kUtf16LowSubHighBoundary = 0xE000;
// Calculate how many bytes are needed to convert an UTF16 string into UTF8
// UTF16 string
size_t utf16toUTF8Length(const uint16_t* utf16String, size_t utf16StringLen) {
if (!utf16String || utf16StringLen == 0) {
return 0;
}
uint32_t utf8StringLen = 0;
auto utf16StringEnd = utf16String + utf16StringLen;
auto idx16 = utf16String;
while (idx16 < utf16StringEnd) {
auto ch = *idx16++;
if (ch < kUtf8OneByteBoundary) {
utf8StringLen++;
} else if (ch < kUtf8TwoBytesBoundary) {
utf8StringLen += 2;
} else if (
(ch >= kUtf16HighSubLowBoundary) && (ch < kUtf16HighSubHighBoundary) &&
(idx16 < utf16StringEnd) &&
(*idx16 >= kUtf16HighSubHighBoundary) && (*idx16 < kUtf16LowSubHighBoundary)) {
utf8StringLen += 4;
idx16++;
} else {
utf8StringLen += 3;
}
}
return utf8StringLen;
}
} // namespace
std::string utf16toUTF8(const uint16_t* utf16String, size_t utf16StringLen) noexcept {
if (!utf16String || utf16StringLen <= 0) {
return "";
}
std::string utf8String(utf16toUTF8Length(utf16String, utf16StringLen), '\0');
auto idx8 = utf8String.begin();
auto idx16 = utf16String;
auto utf16StringEnd = utf16String + utf16StringLen;
while (idx16 < utf16StringEnd) {
auto ch = *idx16++;
if (ch < kUtf8OneByteBoundary) {
*idx8++ = (ch & 0x7F);
} else if (ch < kUtf8TwoBytesBoundary) {
*idx8++ = 0b11000000 | (ch >> 6);
*idx8++ = 0b10000000 | (ch & 0x3F);
} else if (
(ch >= kUtf16HighSubLowBoundary) && (ch < kUtf16HighSubHighBoundary) &&
(idx16 < utf16StringEnd) &&
(*idx16 >= kUtf16HighSubHighBoundary) && (*idx16 < kUtf16LowSubHighBoundary)) {
auto ch2 = *idx16++;
uint8_t trunc_byte = (((ch >> 6) & 0x0F) + 1);
*idx8++ = 0b11110000 | (trunc_byte >> 2);
*idx8++ = 0b10000000 | ((trunc_byte & 0x03) << 4) | ((ch >> 2) & 0x0F);
*idx8++ = 0b10000000 | ((ch & 0x03) << 4) | ((ch2 >> 6) & 0x0F);
*idx8++ = 0b10000000 | (ch2 & 0x3F);
} else {
*idx8++ = 0b11100000 | (ch >> 12);
*idx8++ = 0b10000000 | ((ch >> 6) & 0x3F);
*idx8++ = 0b10000000 | (ch & 0x3F);
}
}
return utf8String;
}
} // namespace unicode
} // namespace react
} // namespace facebook

View File

@ -1,17 +0,0 @@
// Copyright (c) Facebook, Inc. and its affiliates.
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#pragma once
#include <string>
#include <cstdint>
namespace facebook {
namespace react {
namespace unicode {
__attribute__((visibility("default"))) std::string utf16toUTF8(const uint16_t* utf16, size_t length) noexcept;
}
}
}

View File

@ -1,325 +0,0 @@
// Copyright (c) Facebook, Inc. and its affiliates.
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "Value.h"
#include <folly/json.h>
#include <folly/Conv.h>
#include "JSCHelpers.h"
#include "JavaScriptCore.h"
// See the comment under Value::fromDynamic()
#if !defined(__APPLE__) && defined(WITH_FB_JSC_TUNING)
#define USE_FAST_FOLLY_DYNAMIC_CONVERSION 1
#else
#define USE_FAST_FOLLY_DYNAMIC_CONVERSION 0
#endif
namespace facebook {
namespace react {
/* static */
Object Object::makeDate(JSContextRef ctx, Object::TimeType time) {
using std::chrono::duration_cast;
using std::chrono::milliseconds;
JSValueRef arguments[1];
arguments[0] = JSC_JSValueMakeNumber(
ctx,
duration_cast<milliseconds>(time.time_since_epoch()).count());
JSValueRef exn;
auto result = JSC_JSObjectMakeDate(ctx, 1, arguments, &exn);
if (!result) {
throw JSException(ctx, exn, "Failed to create Date");
}
return Object(ctx, result);
}
Object Object::makeArray(JSContextRef ctx, JSValueRef* elements, unsigned length) {
JSValueRef exn;
auto arr = JSC_JSObjectMakeArray(ctx, length, elements, &exn);
if (!arr) {
throw JSException(ctx, exn, "Failed to create an Array");
}
return Object(ctx, arr);
}
Value::Value(JSContextRef context, JSValueRef value)
: m_context(context), m_value(value) {}
Value::Value(JSContextRef context, JSStringRef str)
: m_context(context), m_value(JSC_JSValueMakeString(context, str)) {}
JSContextRef Value::context() const {
return m_context;
}
/* static */
std::string Value::toJSONString(unsigned indent) const {
JSValueRef exn;
auto stringToAdopt = JSC_JSValueCreateJSONString(m_context, m_value, indent, &exn);
if (!stringToAdopt) {
throw JSException(m_context, exn, "Exception creating JSON string");
}
return String::adopt(m_context, stringToAdopt).str();
}
/* static */
Value Value::fromJSON(const String& json) {
JSContextRef ctx = json.context();
auto result = JSC_JSValueMakeFromJSONString(ctx, json);
if (!result) {
throw JSException(folly::to<std::string>(
"Failed to create Value from JSON: ", json.str()).c_str());
}
return Value(ctx, result);
}
Value Value::fromDynamic(JSContextRef ctx, const folly::dynamic& value) {
// JavaScriptCore's iOS APIs have their own version of this direct conversion.
// In addition, using this requires exposing some of JSC's private APIs,
// so it's limited to non-apple platforms and to builds that use the custom JSC.
// Otherwise, we use the old way of converting through JSON.
#if USE_FAST_FOLLY_DYNAMIC_CONVERSION
// Defer GC during the creation of the JSValue, as we don't want
// intermediate objects to be collected.
// We could use JSValueProtect(), but it will make the process much slower.
JSDeferredGCRef deferGC = JSDeferGarbageCollection(ctx);
// Set a global lock for the whole process,
// instead of re-acquiring the lock for each operation.
JSLock(ctx);
JSValueRef jsVal = Value::fromDynamicInner(ctx, value);
JSUnlock(ctx);
JSResumeGarbageCollection(ctx, deferGC);
return Value(ctx, jsVal);
#else
auto json = folly::toJson(value);
return fromJSON(String(ctx, json.c_str()));
#endif
}
JSValueRef Value::fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj) {
switch (obj.type()) {
// For primitive types (and strings), just create and return an equivalent JSValue
case folly::dynamic::Type::NULLT:
return JSC_JSValueMakeNull(ctx);
case folly::dynamic::Type::BOOL:
return JSC_JSValueMakeBoolean(ctx, obj.getBool());
case folly::dynamic::Type::DOUBLE:
return JSC_JSValueMakeNumber(ctx, obj.getDouble());
case folly::dynamic::Type::INT64:
return JSC_JSValueMakeNumber(ctx, obj.asDouble());
case folly::dynamic::Type::STRING:
return JSC_JSValueMakeString(ctx, String(ctx, obj.getString().c_str()));
case folly::dynamic::Type::ARRAY: {
// Collect JSValue for every element in the array
JSValueRef vals[obj.size()];
for (size_t i = 0; i < obj.size(); ++i) {
vals[i] = fromDynamicInner(ctx, obj[i]);
}
// Create a JSArray with the values
JSValueRef arr = JSC_JSObjectMakeArray(ctx, obj.size(), vals, nullptr);
return arr;
}
case folly::dynamic::Type::OBJECT: {
// Create an empty object
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) {
JSC_JSObjectSetProperty(
ctx,
jsObj,
String(ctx, it->first.asString().c_str()),
fromDynamicInner(ctx, it->second),
kJSPropertyAttributeNone,
nullptr);
}
return jsObj;
}
default:
// Assert not reached
LOG(FATAL) << "Trying to convert a folly object of unsupported type.";
return JSC_JSValueMakeNull(ctx);
}
}
Object Value::asObject() const {
JSValueRef exn;
JSObjectRef jsObj = JSC_JSValueToObject(context(), m_value, &exn);
if (!jsObj) {
throw JSException(m_context, exn, "Failed to convert to object");
}
return Object(context(), jsObj);
}
String Value::toString() const {
JSValueRef exn;
JSStringRef jsStr = JSC_JSValueToStringCopy(context(), m_value, &exn);
if (!jsStr) {
throw JSException(m_context, exn, "Failed to convert to string");
}
return String::adopt(context(), jsStr);
}
Value Value::makeError(JSContextRef ctx, const char *error, const char *stack)
{
auto errorMsg = Value(ctx, String(ctx, error));
JSValueRef args[] = {errorMsg};
if (stack) {
// Using this instead of JSObjectMakeError to actually get a stack property.
// MakeError only sets it stack when returning from the invoked function, so we
// can't extend it here.
auto errorConstructor = Object::getGlobalObject(ctx).getProperty("Error").asObject();
auto jsError = errorConstructor.callAsConstructor({errorMsg});
auto fullStack = std::string(stack) + jsError.getProperty("stack").toString().str();
jsError.setProperty("stack", String(ctx, fullStack.c_str()));
return jsError;
} else {
JSValueRef exn;
JSObjectRef errorObj = JSC_JSObjectMakeError(ctx, 1, args, &exn);
if (!errorObj) {
throw JSException(ctx, exn, "Exception making error");
}
return Value(ctx, errorObj);
}
}
void Value::throwTypeException(const std::string &expectedType) const {
std::string wat("TypeError: Expected ");
wat += expectedType;
wat += ", instead got '";
wat += toString().str();
wat += "'";
throw JSException(wat.c_str());
}
Object::operator Value() const {
return Value(m_context, m_obj);
}
Value Object::callAsFunction(std::initializer_list<JSValueRef> args) const {
return callAsFunction(nullptr, args.size(), args.begin());
}
Value Object::callAsFunction(const Object& thisObj, std::initializer_list<JSValueRef> args) const {
return callAsFunction((JSObjectRef)thisObj, args.size(), args.begin());
}
Value Object::callAsFunction(int nArgs, const JSValueRef args[]) const {
return callAsFunction(nullptr, nArgs, args);
}
Value Object::callAsFunction(const Object& thisObj, int nArgs, const JSValueRef args[]) const {
return callAsFunction(static_cast<JSObjectRef>(thisObj), nArgs, args);
}
Value Object::callAsFunction(JSObjectRef thisObj, int nArgs, const JSValueRef args[]) const {
JSValueRef exn;
JSValueRef result = JSC_JSObjectCallAsFunction(m_context, m_obj, thisObj, nArgs, args, &exn);
if (!result) {
throw JSException(m_context, exn, "Exception calling object as function");
}
return Value(m_context, result);
}
Object Object::callAsConstructor(std::initializer_list<JSValueRef> args) const {
JSValueRef exn;
JSObjectRef result = JSC_JSObjectCallAsConstructor(m_context, m_obj, args.size(), args.begin(), &exn);
if (!result) {
throw JSException(m_context, exn, "Exception calling object as constructor");
}
return Object(m_context, result);
}
Value Object::getProperty(const String& propName) const {
JSValueRef exn;
JSValueRef property = JSC_JSObjectGetProperty(m_context, m_obj, propName, &exn);
if (!property) {
throw JSException(m_context, exn, folly::to<std::string>(
"Failed to get property '", propName.str(), "'").c_str());
}
return Value(m_context, property);
}
Value Object::getPropertyAtIndex(unsigned int index) const {
JSValueRef exn;
JSValueRef property = JSC_JSObjectGetPropertyAtIndex(m_context, m_obj, index, &exn);
if (!property) {
throw JSException(m_context, exn, folly::to<std::string>(
"Failed to get property at index ", index).c_str());
}
return Value(m_context, property);
}
Value Object::getProperty(const char *propName) const {
return getProperty(String(m_context, propName));
}
void Object::setProperty(const String& propName, const Value& value) {
JSValueRef exn = nullptr;
JSC_JSObjectSetProperty(m_context, m_obj, propName, value, kJSPropertyAttributeNone, &exn);
if (exn) {
throw JSException(m_context, exn, folly::to<std::string>(
"Failed to set property '", propName.str(), "'").c_str());
}
}
void Object::setPropertyAtIndex(unsigned int index, const Value& value) {
JSValueRef exn = nullptr;
JSC_JSObjectSetPropertyAtIndex(m_context, m_obj, index, value, &exn);
if (exn) {
throw JSException(m_context, exn, folly::to<std::string>(
"Failed to set property at index ", index).c_str());
}
}
void Object::setProperty(const char *propName, const Value& value) {
setProperty(String(m_context, propName), value);
}
std::vector<String> Object::getPropertyNames() const {
auto namesRef = JSC_JSObjectCopyPropertyNames(m_context, m_obj);
size_t count = JSC_JSPropertyNameArrayGetCount(m_context, namesRef);
std::vector<String> names;
names.reserve(count);
for (size_t i = 0; i < count; i++) {
names.emplace_back(String::ref(m_context,
JSC_JSPropertyNameArrayGetNameAtIndex(m_context, namesRef, i)));
}
JSC_JSPropertyNameArrayRelease(m_context, namesRef);
return names;
}
std::unordered_map<std::string, std::string> Object::toJSONMap() const {
std::unordered_map<std::string, std::string> map;
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,
JSC_JSPropertyNameArrayGetNameAtIndex(m_context, namesRef, i));
map.emplace(key.str(), getProperty(key).toJSONString());
}
JSC_JSPropertyNameArrayRelease(m_context, namesRef);
return map;
}
/* static */
Object Object::create(JSContextRef ctx) {
JSObjectRef newObj = JSC_JSObjectMake(
ctx,
NULL, // create instance of default object class
NULL); // no private data
return Object(ctx, newObj);
}
} }

View File

@ -1,373 +0,0 @@
// Copyright (c) Facebook, Inc. and its affiliates.
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#pragma once
#include <chrono>
#include <memory>
#include <sstream>
#include <unordered_map>
#include <vector>
#include <folly/dynamic.h>
#include <jschelpers/JavaScriptCore.h>
#include <jschelpers/Unicode.h>
#include <jschelpers/noncopyable.h>
#include <privatedata/PrivateDataBase.h>
#ifndef RN_EXPORT
#define RN_EXPORT __attribute__((visibility("default")))
#endif
namespace facebook {
namespace react {
class Value;
// C++ object wrapper for JSStringRef
class String : public noncopyable {
public:
explicit String(): m_context(nullptr), m_string(nullptr) {} // dummy empty constructor
explicit String(JSContextRef context, const char* utf8)
: m_context(context), m_string(JSC_JSStringCreateWithUTF8CString(context, utf8)) {}
String(String&& other) :
m_context(other.m_context), m_string(other.m_string)
{
other.m_string = nullptr;
}
String(const String& other) :
m_context(other.m_context), m_string(other.m_string)
{
if (m_string) {
JSC_JSStringRetain(m_context, m_string);
}
}
~String() {
if (m_string) {
JSC_JSStringRelease(m_context, m_string);
}
}
String& operator=(String&& other) {
if (m_string) {
JSC_JSStringRelease(m_context, m_string);
}
m_context = other.m_context;
m_string = other.m_string;
other.m_string = nullptr;
return *this;
}
operator JSStringRef() const {
return m_string;
}
JSContextRef context() const {
return m_context;
}
// Length in characters
size_t length() const {
return m_string ? JSC_JSStringGetLength(m_context, m_string) : 0;
}
// Length in bytes of a nul-terminated utf8 encoded value
size_t utf8Size() const {
return m_string ? JSC_JSStringGetMaximumUTF8CStringSize(m_context, m_string) : 0;
}
/*
* JavaScriptCore is built with strict utf16 -> utf8 conversion.
* This means if JSC's built-in conversion function encounters a JavaScript
* string which contains half of a 32-bit UTF-16 symbol, it produces an error
* rather than returning a string.
*
* Instead of relying on this, we use our own utf16 -> utf8 conversion function
* which is more lenient and always returns a string. When an invalid UTF-16
* string is provided, it'll likely manifest as a rendering glitch in the app for
* the invalid symbol.
*
* For details on JavaScript's unicode support see:
* https://mathiasbynens.be/notes/javascript-unicode
*/
std::string str() const {
if (!m_string) {
return "";
}
const JSChar* utf16 = JSC_JSStringGetCharactersPtr(m_context, m_string);
size_t stringLength = JSC_JSStringGetLength(m_context, m_string);
return unicode::utf16toUTF8(utf16, stringLength);
}
// Assumes that utf8 is nul-terminated
bool equals(const char* utf8) {
return m_string ? JSC_JSStringIsEqualToUTF8CString(m_context, m_string, utf8) : false;
}
// This assumes ascii is nul-terminated.
static String createExpectingAscii(JSContextRef context, const char* ascii, size_t len) {
#if WITH_FBJSCEXTENSIONS
return String(context, JSC_JSStringCreateWithUTF8CStringExpectAscii(context, ascii, len), true);
#else
return String(context, JSC_JSStringCreateWithUTF8CString(context, ascii), true);
#endif
}
static String createExpectingAscii(JSContextRef context, std::string const &ascii) {
return createExpectingAscii(context, ascii.c_str(), ascii.size());
}
// Creates a String wrapper and increases the refcount of the JSStringRef
static String ref(JSContextRef context, JSStringRef string) {
return String(context, string, false);
}
// Creates a String wrapper that takes over ownership of the string. The
// JSStringRef passed in must previously have been created or retained.
static String adopt(JSContextRef context, JSStringRef string) {
return String(context, string, true);
}
private:
explicit String(JSContextRef context, JSStringRef string, bool adopt) :
m_context(context), m_string(string)
{
if (!adopt && string) {
JSC_JSStringRetain(context, string);
}
}
JSContextRef m_context;
JSStringRef m_string;
};
// C++ object wrapper for JSObjectRef. The underlying JSObjectRef can be
// optionally protected. You must protect the object if it is ever
// heap-allocated, since otherwise you may end up with an invalid reference.
class Object : public noncopyable {
public:
using TimeType = std::chrono::time_point<std::chrono::system_clock>;
Object(JSContextRef context, JSObjectRef obj) :
m_context(context),
m_obj(obj)
{}
Object(Object&& other) :
m_context(other.m_context),
m_obj(other.m_obj),
m_isProtected(other.m_isProtected) {
other.m_obj = nullptr;
other.m_isProtected = false;
}
~Object() {
if (m_isProtected && m_obj) {
JSC_JSValueUnprotect(m_context, m_obj);
}
}
Object& operator=(Object&& other) {
std::swap(m_context, other.m_context);
std::swap(m_obj, other.m_obj);
std::swap(m_isProtected, other.m_isProtected);
return *this;
}
operator JSObjectRef() const {
return m_obj;
}
operator Value() const;
bool isFunction() const {
return JSC_JSObjectIsFunction(m_context, m_obj);
}
Value callAsFunction(std::initializer_list<JSValueRef> args) const;
Value callAsFunction(const Object& thisObj, std::initializer_list<JSValueRef> args) const;
Value callAsFunction(int nArgs, const JSValueRef args[]) const;
Value callAsFunction(const Object& thisObj, int nArgs, const JSValueRef args[]) const;
Object callAsConstructor(std::initializer_list<JSValueRef> args) const;
Value getProperty(const String& propName) const;
Value getProperty(const char *propName) const;
Value getPropertyAtIndex(unsigned int index) const;
void setProperty(const String& propName, const Value& value);
void setProperty(const char *propName, const Value& value);
void setPropertyAtIndex(unsigned int index, const Value& value);
std::vector<String> getPropertyNames() const;
std::unordered_map<std::string, std::string> toJSONMap() const;
void makeProtected() {
if (!m_isProtected && m_obj) {
JSC_JSValueProtect(m_context, m_obj);
m_isProtected = true;
}
}
RN_EXPORT static Object makeArray(JSContextRef ctx, JSValueRef* elements, unsigned length);
RN_EXPORT static Object makeDate(JSContextRef ctx, TimeType time);
template<typename ReturnType>
ReturnType* getPrivate() const {
const bool isCustomJSC = isCustomJSCPtr(m_context);
return PrivateDataBase::cast<ReturnType>(JSC_JSObjectGetPrivate(isCustomJSC, m_obj));
}
void setPrivate(PrivateDataBase* data) const {
const bool isCustomJSC = isCustomJSCPtr(m_context);
JSC_JSObjectSetPrivate(isCustomJSC, m_obj, data);
}
JSContextRef context() const {
return m_context;
}
static Object getGlobalObject(JSContextRef ctx) {
auto globalObj = JSC_JSContextGetGlobalObject(ctx);
return Object(ctx, globalObj);
}
/**
* Creates an instance of the default object class.
*/
static Object create(JSContextRef ctx);
private:
JSContextRef m_context;
JSObjectRef m_obj;
bool m_isProtected = false;
Value callAsFunction(JSObjectRef thisObj, int nArgs, const JSValueRef args[]) const;
};
// C++ object wrapper for JSValueRef. The underlying JSValueRef is not
// protected, so this class should always be used as a stack-allocated
// variable.
class Value : public noncopyable {
public:
RN_EXPORT Value(JSContextRef context, JSValueRef value);
RN_EXPORT Value(JSContextRef context, JSStringRef value);
RN_EXPORT Value(const Value &o) : Value(o.m_context, o.m_value) {}
RN_EXPORT Value(const String &o) : Value(o.context(), o) {}
Value& operator=(Value&& other) {
m_context = other.m_context;
m_value = other.m_value;
other.m_value = NULL;
return *this;
};
operator JSValueRef() const {
return m_value;
}
JSType getType() const {
return JSC_JSValueGetType(m_context, m_value);
}
bool isBoolean() const {
return getType() == kJSTypeBoolean;
}
bool asBoolean() const {
return JSC_JSValueToBoolean(context(), m_value);
}
bool isNumber() const {
return getType() == kJSTypeNumber;
}
bool isNull() const {
return getType() == kJSTypeNull;
}
bool isUndefined() const {
return getType() == kJSTypeUndefined;
}
double asNumber() const {
if (isNumber()) {
return JSC_JSValueToNumber(context(), m_value, nullptr);
} else {
return 0.0f;
}
}
double getNumberOrThrow() const {
if (!isNumber()) {
throwTypeException("Number");
}
return JSC_JSValueToNumber(context(), m_value, nullptr);
}
int32_t asInteger() const {
return static_cast<int32_t>(asNumber());
}
uint32_t asUnsignedInteger() const {
return static_cast<uint32_t>(asNumber());
}
bool isObject() const {
return getType() == kJSTypeObject;
}
RN_EXPORT Object asObject() const;
bool isString() const {
return getType() == kJSTypeString;
}
RN_EXPORT String toString() const;
// Create an error, optionally adding an additional number of lines to the stack.
// Stack must be empty or newline terminated.
RN_EXPORT static Value makeError(JSContextRef ctx, const char *error, const char *stack = nullptr);
static Value makeNumber(JSContextRef ctx, double value) {
return Value(ctx, JSC_JSValueMakeNumber(ctx, value));
}
static Value makeUndefined(JSContextRef ctx) {
return Value(ctx, JSC_JSValueMakeUndefined(ctx));
}
static Value makeNull(JSContextRef ctx) {
return Value(ctx, JSC_JSValueMakeNull(ctx));
}
static Value makeBoolean(JSContextRef ctx, bool value) {
return Value(ctx, JSC_JSValueMakeBoolean(ctx, value));
}
static Value makeString(JSContextRef ctx, const char* utf8) {
return Value(ctx, String(ctx, utf8));
}
RN_EXPORT std::string toJSONString(unsigned indent = 0) const;
RN_EXPORT static Value fromJSON(const String& json);
RN_EXPORT static Value fromDynamic(JSContextRef ctx, const folly::dynamic& value);
RN_EXPORT JSContextRef context() const;
private:
JSContextRef m_context;
JSValueRef m_value;
void throwTypeException(const std::string &expectedType) const;
static JSValueRef fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj);
};
} }

View File

@ -1,15 +0,0 @@
// Copyright (c) Facebook, Inc. and its affiliates.
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#pragma once
namespace facebook {
namespace react {
struct noncopyable {
noncopyable(const noncopyable&) = delete;
noncopyable& operator=(const noncopyable&) = delete;
protected:
noncopyable() = default;
};
}}

View File

@ -1,154 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <jschelpers/JSCWrapper.h>
#if defined(__APPLE__)
#include <mutex>
#include <objc/runtime.h>
// Crash the app (with a descriptive stack trace) if a function that is not supported by
// the system JSC is called.
#define UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(FUNC_NAME) \
static void Unimplemented_##FUNC_NAME(__unused void* args...) { \
assert(false); \
}
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(JSEvaluateBytecodeBundle)
#if WITH_FBJSCEXTENSIONS
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(JSStringCreateWithUTF8CStringExpectAscii)
#endif
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(JSPokeSamplingProfiler)
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(JSStartSamplingProfilingOnMainJSCThread)
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(JSGlobalContextEnableDebugger)
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(JSGlobalContextDisableDebugger)
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(configureJSCForIOS)
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(FBJSContextStartGCTimers)
bool JSSamplingProfilerEnabled() {
return false;
}
const int32_t JSNoBytecodeFileFormatVersion = -1;
namespace facebook {
namespace react {
static JSCWrapper s_systemWrapper = {};
const JSCWrapper* systemJSCWrapper() {
// Note that this is not used on Android. All methods are statically linked instead.
// Some fields are lazily initialized
static std::once_flag flag;
std::call_once(flag, []() {
s_systemWrapper = {
.JSGlobalContextCreateInGroup = JSGlobalContextCreateInGroup,
.JSGlobalContextRelease = JSGlobalContextRelease,
.JSGlobalContextSetName = JSGlobalContextSetName,
.JSContextGetGlobalContext = JSContextGetGlobalContext,
.JSContextGetGlobalObject = JSContextGetGlobalObject,
.FBJSContextStartGCTimers =
(decltype(&FBJSContextStartGCTimers))
Unimplemented_FBJSContextStartGCTimers,
.JSEvaluateScript = JSEvaluateScript,
.JSEvaluateBytecodeBundle =
(decltype(&JSEvaluateBytecodeBundle))
Unimplemented_JSEvaluateBytecodeBundle,
.JSStringCreateWithUTF8CString = JSStringCreateWithUTF8CString,
.JSStringCreateWithCFString = JSStringCreateWithCFString,
#if WITH_FBJSCEXTENSIONS
.JSStringCreateWithUTF8CStringExpectAscii =
(decltype(&JSStringCreateWithUTF8CStringExpectAscii))
Unimplemented_JSStringCreateWithUTF8CStringExpectAscii,
#endif
.JSStringCopyCFString = JSStringCopyCFString,
.JSStringGetCharactersPtr = JSStringGetCharactersPtr,
.JSStringGetLength = JSStringGetLength,
.JSStringGetMaximumUTF8CStringSize = JSStringGetMaximumUTF8CStringSize,
.JSStringIsEqualToUTF8CString = JSStringIsEqualToUTF8CString,
.JSStringRelease = JSStringRelease,
.JSStringRetain = JSStringRetain,
.JSClassCreate = JSClassCreate,
.JSClassRetain = JSClassRetain,
.JSClassRelease = JSClassRelease,
.JSObjectCallAsConstructor = JSObjectCallAsConstructor,
.JSObjectCallAsFunction = JSObjectCallAsFunction,
.JSObjectGetPrivate = JSObjectGetPrivate,
.JSObjectGetProperty = JSObjectGetProperty,
.JSObjectGetPropertyAtIndex = JSObjectGetPropertyAtIndex,
.JSObjectIsConstructor = JSObjectIsConstructor,
.JSObjectIsFunction = JSObjectIsFunction,
.JSObjectMake = JSObjectMake,
.JSObjectMakeArray = JSObjectMakeArray,
.JSObjectMakeDate = JSObjectMakeDate,
.JSObjectMakeError = JSObjectMakeError,
.JSObjectMakeFunctionWithCallback = JSObjectMakeFunctionWithCallback,
.JSObjectSetPrivate = JSObjectSetPrivate,
.JSObjectSetProperty = JSObjectSetProperty,
.JSObjectSetPropertyAtIndex = JSObjectSetPropertyAtIndex,
.JSObjectCopyPropertyNames = JSObjectCopyPropertyNames,
.JSPropertyNameArrayGetCount = JSPropertyNameArrayGetCount,
.JSPropertyNameArrayGetNameAtIndex = JSPropertyNameArrayGetNameAtIndex,
.JSPropertyNameArrayRelease = JSPropertyNameArrayRelease,
.JSValueCreateJSONString = JSValueCreateJSONString,
.JSValueGetType = JSValueGetType,
.JSValueMakeFromJSONString = JSValueMakeFromJSONString,
.JSValueMakeBoolean = JSValueMakeBoolean,
.JSValueMakeNull = JSValueMakeNull,
.JSValueMakeNumber = JSValueMakeNumber,
.JSValueMakeString = JSValueMakeString,
.JSValueMakeUndefined = JSValueMakeUndefined,
.JSValueProtect = JSValueProtect,
.JSValueToBoolean = JSValueToBoolean,
.JSValueToNumber = JSValueToNumber,
.JSValueToObject = JSValueToObject,
.JSValueToStringCopy = JSValueToStringCopy,
.JSValueUnprotect = JSValueUnprotect,
.JSValueIsNull = JSValueIsNull,
.JSSamplingProfilerEnabled = JSSamplingProfilerEnabled,
.JSPokeSamplingProfiler =
(decltype(&JSPokeSamplingProfiler))
Unimplemented_JSPokeSamplingProfiler,
.JSStartSamplingProfilingOnMainJSCThread =
(decltype(&JSStartSamplingProfilingOnMainJSCThread))
Unimplemented_JSStartSamplingProfilingOnMainJSCThread,
.JSGlobalContextEnableDebugger =
(decltype(&JSGlobalContextEnableDebugger))
Unimplemented_JSGlobalContextEnableDebugger,
.JSGlobalContextDisableDebugger =
(decltype(&JSGlobalContextDisableDebugger))
Unimplemented_JSGlobalContextDisableDebugger,
.configureJSCForIOS =
(decltype(&configureJSCForIOS))Unimplemented_configureJSCForIOS,
.JSContext = objc_getClass("JSContext"),
.JSValue = objc_getClass("JSValue"),
.JSBytecodeFileFormatVersion = JSNoBytecodeFileFormatVersion,
};
});
return &s_systemWrapper;
}
} }
#endif

View File

@ -1,18 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := privatedata
LOCAL_SRC_FILES := \
PrivateDataBase.cpp \
LOCAL_C_INCLUDES := $(LOCAL_PATH)/..
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
LOCAL_CFLAGS := \
-DLOG_TAG=\"ReactNative\"
LOCAL_CFLAGS += -fexceptions -frtti
include $(BUILD_SHARED_LIBRARY)

View File

@ -1,24 +0,0 @@
load("@fbsource//tools/build_defs:glob_defs.bzl", "subdir_glob")
load("//tools/build_defs/oss:rn_defs.bzl", "rn_xplat_cxx_library")
rn_xplat_cxx_library(
name = "privatedata",
srcs = glob(["**/*.cpp"]),
header_namespace = "",
exported_headers = subdir_glob(
[
("", "**/*.h"),
],
prefix = "privatedata",
),
compiler_flags = [
"-Wall",
"-fexceptions",
"-frtti",
"-fvisibility=hidden",
"-std=c++1y",
],
visibility = [
"PUBLIC",
],
)

View File

@ -1,13 +0,0 @@
// Copyright (c) Facebook, Inc. and its affiliates.
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "PrivateDataBase.h"
namespace facebook {
namespace react {
PrivateDataBase::~PrivateDataBase() {}
} }

View File

@ -1,45 +0,0 @@
// Copyright (c) Facebook, Inc. and its affiliates.
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#pragma once
#include <cassert>
#include <cstdlib>
#include <type_traits>
#ifndef RN_EXPORT
#define RN_EXPORT __attribute__((visibility("default")))
#endif
namespace facebook {
namespace react {
// Base class for private data used to implement hybrid JS-native objects. A common root class,
// rtti and dynamic_cast allow us to do some runtime type checking that makes it possible
// for multiple hybrid object implementations to co-exist.
class RN_EXPORT PrivateDataBase {
public:
virtual ~PrivateDataBase();
// Casts given void* to PrivateDataBase and performs dynamic_cast to desired type. Returns null on
// failure.
template <typename T>
static typename std::enable_if<std::is_base_of<PrivateDataBase, T>::value, T>::type* tryCast(void* ptr) {
return dynamic_cast<T*>(reinterpret_cast<PrivateDataBase*>(ptr));
}
// Like tryCast, but aborts on failure.
template <typename T>
static typename std::enable_if<std::is_base_of<PrivateDataBase, T>::value, T>::type* cast(void* ptr) {
auto result = tryCast<T>(ptr);
if (!result) {
assert(false && "could not cast to desired type");
abort();
}
return result;
}
};
} }