react-native/React/Executors/RCTJSCExecutor.h
Nikhilesh Sigatapu c67225818d Add a way to access the underlying JavaScriptCore context
Summary:
**Motivation**

I'm working on a project that uses React Native and needs to add direct synchronous bindings to native stuff through the JavaScriptCore C API. This is because it's performance-sensitive and would benefit from the quickest JS->C path. It does this using cross-platform C++ code that works on both iOS and Android. Most of the infrastructure for getting access to the JSC context is already in React Native actually, just had to add a few more things.

(lexs you mentioned to tag you in this pull request)

**Test plan**

Modify the JavaScriptCore context through the `JSContextRef` returned (eg. add an object at global scope) and verify that it exists in JavaScript.
Closes https://github.com/facebook/react-native/pull/10399

Differential Revision: D4080945

Pulled By: lexs

fbshipit-source-id: 6659b7a01e09fd84475adde183c1d3aca2d4cf09
2016-10-26 03:43:44 -07:00

117 lines
4.3 KiB
Objective-C

/**
* Copyright (c) 2015-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.
*/
#import <JavaScriptCore/JavaScriptCore.h>
#import "RCTJavaScriptExecutor.h"
typedef void (^RCTJavaScriptValueCallback)(JSValue *result, NSError *error);
/**
* Default name for the JS thread
*/
RCT_EXTERN NSString *const RCTJSCThreadName;
/**
* This notification fires on the JS thread immediately after a `JSContext`
* is fully initialized, but before the JS bundle has been loaded. The object
* of this notification is the `JSContext`. Native modules should listen for
* notification only if they need to install custom functionality into the
* context. Note that this notification won't fire when debugging in Chrome.
*/
RCT_EXTERN NSString *const RCTJavaScriptContextCreatedNotification;
/**
* A key to a reference to a JSContext class, held in the the current thread's
* dictionary. The reference would point to the JSContext class in the JS VM
* used in React (or ComponenetScript). It is recommended not to access it
* through the thread's dictionary, but rather to use the `FBJSCurrentContext()`
* accessor, which will return the current JSContext in the currently used VM.
*/
RCT_EXTERN NSString *const RCTFBJSContextClassKey;
/**
* A key to a reference to a JSValue class, held in the the current thread's
* dictionary. The reference would point to the JSValue class in the JS VM
* used in React (or ComponenetScript). It is recommended not to access it
* through the thread's dictionary, but rather to use the `FBJSValue()` accessor.
*/
RCT_EXTERN NSString *const RCTFBJSValueClassKey;
/**
* @experimental
* May be used to pre-create the JSContext to make RCTJSCExecutor creation less costly.
* Avoid using this; it's experimental and is not likely to be supported long-term.
*/
@interface RCTJSContextProvider : NSObject
- (instancetype)initWithUseCustomJSCLibrary:(BOOL)useCustomJSCLibrary;
/**
* Marks whether the provider uses the custom implementation of JSC and not the system one.
*/
@property (nonatomic, readonly, assign) BOOL useCustomJSCLibrary;
@end
/**
* Uses a JavaScriptCore context as the execution engine.
*/
@interface RCTJSCExecutor : NSObject <RCTJavaScriptExecutor>
/**
* Returns whether executor uses custom JSC library.
* This value is used to initialize RCTJSCWrapper.
* @default is NO.
*/
@property (nonatomic, readonly, assign) BOOL useCustomJSCLibrary;
/**
* Specify a name for the JSContext used, which will be visible in debugging tools
* @default is "RCTJSContext"
*/
@property (nonatomic, copy) NSString *contextName;
/**
* Inits a new executor instance with given flag that's used
* to initialize RCTJSCWrapper.
*/
- (instancetype)initWithUseCustomJSCLibrary:(BOOL)useCustomJSCLibrary;
/**
* @experimental
* Pass a RCTJSContextProvider object to use an NSThread/JSContext pair that have already been created.
* The returned executor has already executed the supplied application script synchronously.
* The underlying JSContext will be returned in the JSContext pointer if it is non-NULL and there was no error.
* If an error occurs, this method will return nil and specify the error in the error pointer if it is non-NULL.
*/
+ (instancetype)initializedExecutorWithContextProvider:(RCTJSContextProvider *)JSContextProvider
applicationScript:(NSData *)applicationScript
sourceURL:(NSURL *)sourceURL
JSContext:(JSContext **)JSContext
error:(NSError **)error;
/**
* Invokes the given module/method directly. The completion block will be called with the
* JSValue returned by the JS context.
*
* Currently this does not flush the JS-to-native message queue.
*/
- (void)callFunctionOnModule:(NSString *)module
method:(NSString *)method
arguments:(NSArray *)args
jsValueCallback:(RCTJavaScriptValueCallback)onComplete;
/**
* Get the JavaScriptCore context associated with this executor instance.
*/
- (JSContext *)jsContext;
@end