From 03a0e4ee2ba144f121f6185d953df642ef103777 Mon Sep 17 00:00:00 2001 From: Tadeu Zagallo Date: Tue, 15 Dec 2015 05:32:24 -0800 Subject: [PATCH] Use JSC block API Summary: public Clean up the `RCTContextExecutor` a little bit by converting the exposed hooks to use the ObjC API. Reviewed By: nicklockwood Differential Revision: D2757363 fb-gh-sync-id: c6f5f53c5c1adb78af1cdb449268b6b3cc9740e8 --- React/Executors/RCTContextExecutor.m | 121 +++++++-------------------- 1 file changed, 31 insertions(+), 90 deletions(-) diff --git a/React/Executors/RCTContextExecutor.m b/React/Executors/RCTContextExecutor.m index b0fa84134..0d2d181de 100644 --- a/React/Executors/RCTContextExecutor.m +++ b/React/Executors/RCTContextExecutor.m @@ -102,38 +102,6 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init) RCT_EXPORT_MODULE() -/** - * The one tiny pure native hook that we implement is a native logging hook. - * You could even argue that this is not necessary - we could plumb logging - * calls through a batched bridge, but having the pure native hook allows - * logging to successfully come through even in the event that a batched bridge - * crashes. - */ - -static JSValueRef RCTNativeLoggingHook(JSContextRef context, __unused JSObjectRef object, __unused JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) -{ - if (argumentCount > 0) { - NSString *message = RCTJSValueToNSString(context, arguments[0], exception); - - RCTLogLevel level = RCTLogLevelInfo; - if (argumentCount > 1) { - level = MAX(level, JSValueToNumber(context, arguments[1], exception)); - } - - _RCTLogJavaScriptInternal(level, message); - } - - return JSValueMakeUndefined(context); -} - -// Do-very-little native hook for testing. -static JSValueRef RCTNoop(JSContextRef context, __unused JSObjectRef object, __unused JSObjectRef thisObject, __unused size_t argumentCount, __unused const JSValueRef arguments[], __unused JSValueRef *exception) -{ - static int counter = 0; - counter++; - return JSValueMakeUndefined(context); -} - static NSString *RCTJSValueToNSString(JSContextRef context, JSValueRef value, JSValueRef *exception) { JSStringRef JSString = JSValueToStringCopy(context, value, exception); @@ -165,43 +133,6 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError) #if RCT_DEV -static JSValueRef RCTNativeTraceBeginSection(JSContextRef context, __unused JSObjectRef object, __unused JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) -{ - static int profileCounter = 1; - NSString *profileName; - double tag = 0; - - if (argumentCount > 0) { - if (JSValueIsNumber(context, arguments[0])) { - tag = JSValueToNumber(context, arguments[0], NULL); - } else { - profileName = RCTJSValueToNSString(context, arguments[0], exception); - } - } else { - profileName = [NSString stringWithFormat:@"Profile %d", profileCounter++]; - } - - if (argumentCount > 1 && JSValueIsString(context, arguments[1])) { - profileName = RCTJSValueToNSString(context, arguments[1], exception); - } - - if (profileName) { - RCT_PROFILE_BEGIN_EVENT(tag, profileName, nil); - } - - return JSValueMakeUndefined(context); -} - -static JSValueRef RCTNativeTraceEndSection(JSContextRef context, __unused JSObjectRef object, __unused JSObjectRef thisObject, __unused size_t argumentCount, __unused const JSValueRef arguments[], JSValueRef *exception) -{ - if (argumentCount > 0) { - double tag = JSValueToNumber(context, arguments[0], exception); - RCT_PROFILE_END_EVENT((uint64_t)tag, @"console", nil); - } - - return JSValueMakeUndefined(context); -} - static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context) { if (RCTJSCProfilerIsSupported()) { @@ -298,16 +229,27 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context) if (!strongSelf.isValid) { return; } + if (!strongSelf->_context) { JSContext *context = [JSContext new]; strongSelf->_context = [[RCTJavaScriptContext alloc] initWithJSContext:context]; } - [strongSelf _addNativeHook:RCTNativeLoggingHook withName:"nativeLoggingHook"]; - [strongSelf _addNativeHook:RCTNoop withName:"noop"]; __weak RCTBridge *weakBridge = strongSelf->_bridge; + JSContext *context = strongSelf->_context.context; - strongSelf->_context.context[@"nativeRequireModuleConfig"] = ^NSString *(NSString *moduleName) { + context[@"noop"] = ^{}; + + context[@"nativeLoggingHook"] = ^(NSString *message, NSNumber *logLevel) { + RCTLogLevel level = RCTLogLevelInfo; + if (logLevel) { + level = MAX(level, logLevel.integerValue); + } + + _RCTLogJavaScriptInternal(level, message); + }; + + context[@"nativeRequireModuleConfig"] = ^NSString *(NSString *moduleName) { if (!weakSelf.valid) { return nil; } @@ -318,39 +260,47 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context) return nil; }; - strongSelf->_context.context[@"nativeFlushQueueImmediate"] = ^(NSArray *calls){ + context[@"nativeFlushQueueImmediate"] = ^(NSArray *calls){ if (!weakSelf.valid || !calls) { return; } [weakBridge handleBuffer:calls batchEnded:NO]; }; - strongSelf->_context.context[@"RCTPerformanceNow"] = ^{ + context[@"RCTPerformanceNow"] = ^{ return CACurrentMediaTime() * 1000 * 1000; }; #if RCT_DEV if (RCTProfileIsProfiling()) { - strongSelf->_context.context[@"__RCTProfileIsProfiling"] = @YES; + context[@"__RCTProfileIsProfiling"] = @YES; } CFMutableDictionaryRef cookieMap = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); - strongSelf->_context.context[@"nativeTraceBeginAsyncSection"] = ^(uint64_t tag, NSString *name, NSUInteger cookie) { + context[@"nativeTraceBeginAsyncSection"] = ^(uint64_t tag, NSString *name, NSUInteger cookie) { NSUInteger newCookie = RCTProfileBeginAsyncEvent(tag, name, nil); CFDictionarySetValue(cookieMap, (const void *)cookie, (const void *)newCookie); - return; }; - strongSelf->_context.context[@"nativeTraceEndAsyncSection"] = ^(uint64_t tag, NSString *name, NSUInteger cookie) { + context[@"nativeTraceEndAsyncSection"] = ^(uint64_t tag, NSString *name, NSUInteger cookie) { NSUInteger newCookie = (NSUInteger)CFDictionaryGetValue(cookieMap, (const void *)cookie); RCTProfileEndAsyncEvent(tag, @"js,async", newCookie, name, nil); CFDictionaryRemoveValue(cookieMap, (const void *)cookie); - return; }; - [strongSelf _addNativeHook:RCTNativeTraceBeginSection withName:"nativeTraceBeginSection"]; - [strongSelf _addNativeHook:RCTNativeTraceEndSection withName:"nativeTraceEndSection"]; + context[@"nativeTraceBeginSection"] = ^(NSNumber *tag, NSString *profileName){ + static int profileCounter = 1; + if (!profileName) { + profileName = [NSString stringWithFormat:@"Profile %d", profileCounter++]; + } + + RCT_PROFILE_BEGIN_EVENT(tag.longLongValue, profileName, nil); + }; + + context[@"nativeTraceEndSection"] = ^(NSNumber *tag) { + RCT_PROFILE_END_EVENT(tag.longLongValue, @"console", nil); + }; RCTInstallJSCProfiler(_bridge, strongSelf->_context.ctx); @@ -374,15 +324,6 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context) }]; } -- (void)_addNativeHook:(JSObjectCallAsFunctionCallback)hook withName:(const char *)name -{ - JSObjectRef globalObject = JSContextGetGlobalObject(_context.ctx); - - JSStringRef JSName = JSStringCreateWithUTF8CString(name); - JSObjectSetProperty(_context.ctx, globalObject, JSName, JSObjectMakeFunctionWithCallback(_context.ctx, JSName, hook), kJSPropertyAttributeNone, NULL); - JSStringRelease(JSName); -} - - (void)invalidate { if (!self.isValid) {