Create JSCWrapper in C++ bridge

Reviewed By: bnham

Differential Revision: D4082204

fbshipit-source-id: 03bff2ac53e6df931063fcd6ba6ad28dc5ae9562
This commit is contained in:
Pieter De Baets 2016-11-21 04:30:04 -08:00 коммит произвёл Facebook Github Bot
Родитель c8a5b42b45
Коммит 0c03b788d7
2 изменённых файлов: 272 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,141 @@
/**
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "JSCWrapper.h"
#if defined(__APPLE__)
#include <glog/logging.h>
#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(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(configureJSCForIOS)
bool JSSamplingProfilerEnabled() {
return false;
}
namespace facebook {
namespace react {
static const JSCWrapper* s_customWrapper = nullptr;
static JSCWrapper s_systemWrapper = {
.JSGlobalContextCreateInGroup = JSGlobalContextCreateInGroup,
.JSGlobalContextRelease = JSGlobalContextRelease,
.JSGlobalContextSetName = JSGlobalContextSetName,
.JSContextGetGlobalContext = JSContextGetGlobalContext,
.JSContextGetGlobalObject = JSContextGetGlobalObject,
.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,
.JSClassRelease = JSClassRelease,
.JSObjectCallAsConstructor = JSObjectCallAsConstructor,
.JSObjectCallAsFunction = JSObjectCallAsFunction,
.JSObjectGetPrivate = JSObjectGetPrivate,
.JSObjectGetProperty = JSObjectGetProperty,
.JSObjectGetPropertyAtIndex = JSObjectGetPropertyAtIndex,
.JSObjectIsConstructor = JSObjectIsConstructor,
.JSObjectIsFunction = JSObjectIsFunction,
.JSObjectMake = JSObjectMake,
.JSObjectMakeArray = JSObjectMakeArray,
.JSObjectMakeError = JSObjectMakeError,
.JSObjectMakeFunctionWithCallback = JSObjectMakeFunctionWithCallback,
.JSObjectSetPrivate = JSObjectSetPrivate,
.JSObjectSetProperty = JSObjectSetProperty,
.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,
.JSSamplingProfilerEnabled = JSSamplingProfilerEnabled,
.JSPokeSamplingProfiler =
(decltype(&JSPokeSamplingProfiler))Unimplemented_JSPokeSamplingProfiler,
.JSStartSamplingProfilingOnMainJSCThread =
(decltype(&JSStartSamplingProfilingOnMainJSCThread))Unimplemented_JSStartSamplingProfilingOnMainJSCThread,
.configureJSCForIOS = (decltype(&configureJSCForIOS))Unimplemented_configureJSCForIOS,
.JSBytecodeFileFormatVersion = -1,
.JSContext = nullptr,
.JSValue = nullptr,
};
void setCustomJSCWrapper(const JSCWrapper* wrapper) {
CHECK(s_customWrapper == nullptr) << "Can't set custom JSC wrapper multiple times";
s_customWrapper = wrapper;
}
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.JSContext = objc_getClass("JSContext");
s_systemWrapper.JSValue = objc_getClass("JSValue");
});
return &s_systemWrapper;
}
const JSCWrapper* customJSCWrapper() {
CHECK(s_customWrapper != nullptr) << "Accessing custom JSC wrapper before it's set";
return s_customWrapper;
}
} }
#endif

Просмотреть файл

@ -0,0 +1,131 @@
/**
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#include <JavaScriptCore/JavaScript.h>
#if WITH_FBJSCEXTENSIONS
#include <jsc_stringref.h>
#endif
#if defined(__APPLE__)
#import <objc/objc.h>
#import <JavaScriptCore/JSStringRefCF.h>
// This is used to substitute an alternate JSC implementation for
// testing. These calls must all be ABI compatible with the standard JSC.
extern void configureJSCForIOS();
extern JSValueRef JSEvaluateBytecodeBundle(JSContextRef, JSObjectRef, int, JSStringRef, JSValueRef*);
extern bool JSSamplingProfilerEnabled();
extern void JSStartSamplingProfilingOnMainJSCThread(JSGlobalContextRef);
extern JSValueRef JSPokeSamplingProfiler(JSContextRef);
namespace facebook {
namespace react {
#define JSC_WRAPPER_METHOD(m) const 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);
// 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(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(JSObjectMakeError);
JSC_WRAPPER_METHOD(JSObjectMakeFunctionWithCallback);
JSC_WRAPPER_METHOD(JSObjectSetPrivate);
JSC_WRAPPER_METHOD(JSObjectSetProperty);
// 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);
// Sampling profiler
JSC_WRAPPER_METHOD(JSSamplingProfilerEnabled);
JSC_WRAPPER_METHOD(JSPokeSamplingProfiler);
JSC_WRAPPER_METHOD(JSStartSamplingProfilingOnMainJSCThread);
JSC_WRAPPER_METHOD(configureJSCForIOS);
// Objective-C API
Class JSContext;
Class JSValue;
const int32_t JSBytecodeFileFormatVersion;
};
template <typename T>
bool isCustomJSCPtr(T *x) {
return (uintptr_t)x & 0x1;
}
void setCustomJSCWrapper(const JSCWrapper* wrapper);
// This will return a single value for the whole life of the process.
const JSCWrapper *systemJSCWrapper();
const JSCWrapper *customJSCWrapper();
} }
#endif