diff --git a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js index ec12a99e6..29d64152e 100644 --- a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js +++ b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js @@ -119,6 +119,11 @@ function setUpWebSockets() { GLOBAL.WebSocket = require('WebSocket'); } +function setupProfile() { + console.profile = console.profile || GLOBAL.consoleProfile || function () {}; + console.profileEnd = console.profileEnd || GLOBAL.consoleProfileEnd || function () {}; +} + setUpRedBoxErrorHandler(); setUpTimers(); setUpAlert(); @@ -127,3 +132,4 @@ setUpXHR(); setUpRedBoxConsoleErrorHandler(); setUpGeolocation(); setUpWebSockets(); +setupProfile(); diff --git a/React/Executors/RCTContextExecutor.m b/React/Executors/RCTContextExecutor.m index 412ffd256..ab5efe5a6 100644 --- a/React/Executors/RCTContextExecutor.m +++ b/React/Executors/RCTContextExecutor.m @@ -112,6 +112,48 @@ static JSValueRef RCTNoop(JSContextRef context, JSObjectRef object, JSObjectRef return JSValueMakeUndefined(context); } +#if RCT_DEV + +static NSMutableArray *profiles; + +static JSValueRef RCTConsoleProfile(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + profiles = [[NSMutableArray alloc] init]; + }); + + static int profileCounter = 1; + NSString *profileName; + NSNumber *profileID = _RCTProfileBeginEvent(); + + if (argumentCount > 0) { + profileName = RCTJSValueToNSString(context, arguments[0]); + } else { + profileName = [NSString stringWithFormat:@"Profile %d", profileCounter++]; + } + + [profiles addObjectsFromArray:@[profileName, profileID]]; + + RCTLog(@"Profile '%@' finished.", profileName); + return JSValueMakeUndefined(context); +} + +static JSValueRef RCTConsoleProfileEnd(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) +{ + NSNumber *profileID = [profiles lastObject]; + [profiles removeLastObject]; + NSString *profileName = [profiles lastObject]; + [profiles removeLastObject]; + + _RCTProfileEndEvent(profileID, profileName, @"console", nil); + + RCTLog(@"Profile '%@' started.", profileName); + return JSValueMakeUndefined(context); +} + +#endif + static NSString *RCTJSValueToNSString(JSContextRef context, JSValueRef value) { JSStringRef JSString = JSValueToStringCopy(context, value, NULL); @@ -198,6 +240,12 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError) strongSelf->_context = [[RCTJavaScriptContext alloc] initWithJSContext:ctx]; [strongSelf _addNativeHook:RCTNativeLoggingHook withName:"nativeLoggingHook"]; [strongSelf _addNativeHook:RCTNoop withName:"noop"]; + +#if RCT_DEV + [strongSelf _addNativeHook:RCTConsoleProfile withName:"consoleProfile"]; + [strongSelf _addNativeHook:RCTConsoleProfileEnd withName:"consoleProfileEnd"]; +#endif + }]; }