Create JSCWrapper in C++ bridge
Reviewed By: bnham Differential Revision: D4082204 fbshipit-source-id: 03bff2ac53e6df931063fcd6ba6ad28dc5ae9562
This commit is contained in:
Родитель
c8a5b42b45
Коммит
0c03b788d7
|
@ -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
|
Загрузка…
Ссылка в новой задаче