Start to use the Obj-C JSContext instead of the C API

Summary: The Obj-C API is usually easier to work with, and also makes it very easy to use the C API when necessary (performance, for example). This diff just switches the designated initializer of RCTContextExecutor to take a JSContext instead of JSGlobalContextRef, but the old initializer still works if needed.

I was doing some memory leak investigation and it is easier with ARC so I wanted to incrementally move the executor to Obj-C.
Closes https://github.com/facebook/react-native/pull/2159

Reviewed By: svcscm

Differential Revision: D2554890

Pulled By: tadeuzagallo

fb-gh-sync-id: 75b96d04cddff68fa3daf5d0fafdffad21dae307
This commit is contained in:
James Ide 2015-10-19 03:49:43 -07:00 committed by facebook-github-bot-7
parent 716f7e8ef2
commit 45d2c691a3
2 changed files with 31 additions and 15 deletions

View File

@ -19,10 +19,16 @@
@interface RCTContextExecutor : NSObject <RCTJavaScriptExecutor> @interface RCTContextExecutor : NSObject <RCTJavaScriptExecutor>
/** /**
* Configures the executor to run JavaScript on a custom performer. * Configures the executor to run JavaScript on a specific thread with a given JS context.
* You probably don't want to use this; use -init instead. * You probably don't want to use this; use -init instead.
*/ */
- (instancetype)initWithJavaScriptThread:(NSThread *)javaScriptThread - (instancetype)initWithJavaScriptThread:(NSThread *)javaScriptThread
globalContextRef:(JSGlobalContextRef)context NS_DESIGNATED_INITIALIZER; context:(JSContext *)context NS_DESIGNATED_INITIALIZER;
/**
* Like -[initWithJavaScriptThread:context:] but uses JSGlobalContextRef from JavaScriptCore's C API.
*/
- (instancetype)initWithJavaScriptThread:(NSThread *)javaScriptThread
globalContextRef:(JSGlobalContextRef)contextRef;
@end @end

View File

@ -42,9 +42,10 @@ static NSString * const RCTJSCProfilerEnabledDefaultsKey = @"RCTJSCProfilerEnabl
@interface RCTJavaScriptContext : NSObject <RCTInvalidating> @interface RCTJavaScriptContext : NSObject <RCTInvalidating>
@property (nonatomic, strong, readonly) JSContext *context;
@property (nonatomic, assign, readonly) JSGlobalContextRef ctx; @property (nonatomic, assign, readonly) JSGlobalContextRef ctx;
- (instancetype)initWithJSContext:(JSGlobalContextRef)context NS_DESIGNATED_INITIALIZER; - (instancetype)initWithJSContext:(JSContext *)context NS_DESIGNATED_INITIALIZER;
@end @end
@ -53,10 +54,10 @@ static NSString * const RCTJSCProfilerEnabledDefaultsKey = @"RCTJSCProfilerEnabl
RCTJavaScriptContext *_self; RCTJavaScriptContext *_self;
} }
- (instancetype)initWithJSContext:(JSGlobalContextRef)context - (instancetype)initWithJSContext:(JSContext *)context
{ {
if ((self = [super init])) { if ((self = [super init])) {
_ctx = context; _context = context;
_self = self; _self = self;
} }
return self; return self;
@ -64,16 +65,20 @@ static NSString * const RCTJSCProfilerEnabledDefaultsKey = @"RCTJSCProfilerEnabl
RCT_NOT_IMPLEMENTED(-(instancetype)init) RCT_NOT_IMPLEMENTED(-(instancetype)init)
- (JSGlobalContextRef)ctx
{
return _context.JSGlobalContextRef;
}
- (BOOL)isValid - (BOOL)isValid
{ {
return _ctx != NULL; return _context != nil;
} }
- (void)invalidate - (void)invalidate
{ {
if (self.isValid) { if (self.isValid) {
JSGlobalContextRelease(_ctx); _context = nil;
_ctx = NULL;
_self = nil; _self = nil;
} }
} }
@ -282,11 +287,11 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
javaScriptThread.threadPriority = [NSThread mainThread].threadPriority; javaScriptThread.threadPriority = [NSThread mainThread].threadPriority;
[javaScriptThread start]; [javaScriptThread start];
return [self initWithJavaScriptThread:javaScriptThread globalContextRef:NULL]; return [self initWithJavaScriptThread:javaScriptThread context:nil];
} }
- (instancetype)initWithJavaScriptThread:(NSThread *)javaScriptThread - (instancetype)initWithJavaScriptThread:(NSThread *)javaScriptThread
globalContextRef:(JSGlobalContextRef)context context:(JSContext *)context
{ {
RCTAssert(javaScriptThread != nil, RCTAssert(javaScriptThread != nil,
@"Can't initialize RCTContextExecutor without a javaScriptThread"); @"Can't initialize RCTContextExecutor without a javaScriptThread");
@ -301,10 +306,8 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
return; return;
} }
// Assumes that no other JS tasks are scheduled before. // Assumes that no other JS tasks are scheduled before.
JSGlobalContextRef ctx;
if (context) { if (context) {
ctx = JSGlobalContextRetain(context); strongSelf->_context = [[RCTJavaScriptContext alloc] initWithJSContext:context];
strongSelf->_context = [[RCTJavaScriptContext alloc] initWithJSContext:ctx];
} }
}]; }];
} }
@ -312,6 +315,13 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
return self; return self;
} }
- (instancetype)initWithJavaScriptThread:(NSThread *)javaScriptThread
globalContextRef:(JSGlobalContextRef)contextRef
{
JSContext *context = contextRef ? [JSContext contextWithJSGlobalContextRef:contextRef] : nil;
return [self initWithJavaScriptThread:javaScriptThread context:context];
}
- (void)setUp - (void)setUp
{ {
__weak RCTContextExecutor *weakSelf = self; __weak RCTContextExecutor *weakSelf = self;
@ -321,8 +331,8 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
return; return;
} }
if (!strongSelf->_context) { if (!strongSelf->_context) {
JSGlobalContextRef ctx = JSGlobalContextCreate(NULL); JSContext *context = [[JSContext alloc] init];
strongSelf->_context = [[RCTJavaScriptContext alloc] initWithJSContext:ctx]; strongSelf->_context = [[RCTJavaScriptContext alloc] initWithJSContext:context];
} }
[strongSelf _addNativeHook:RCTNativeLoggingHook withName:"nativeLoggingHook"]; [strongSelf _addNativeHook:RCTNativeLoggingHook withName:"nativeLoggingHook"];
[strongSelf _addNativeHook:RCTNoop withName:"noop"]; [strongSelf _addNativeHook:RCTNoop withName:"noop"];