diff --git a/React/Base/RCTBatchedBridge.m b/React/Base/RCTBatchedBridge.m index 84ca447d9..2721f1537 100644 --- a/React/Base/RCTBatchedBridge.m +++ b/React/Base/RCTBatchedBridge.m @@ -1100,4 +1100,20 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR return _wasBatchActive; } +#pragma mark - JavaScriptCore + +- (JSGlobalContextRef)jsContextRef +{ + return [self.jsContext JSGlobalContextRef]; +} + +- (JSContext *)jsContext +{ + if ([_javaScriptExecutor isKindOfClass:[RCTJSCExecutor class]]) { + return [(RCTJSCExecutor *)_javaScriptExecutor jsContext]; + } else { + return nil; + } +} + @end diff --git a/React/Base/RCTBridge+JavaScriptCore.h b/React/Base/RCTBridge+JavaScriptCore.h new file mode 100644 index 000000000..00a1501cf --- /dev/null +++ b/React/Base/RCTBridge+JavaScriptCore.h @@ -0,0 +1,26 @@ +/** + * 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 + +#import + +@interface RCTBridge (JavaScriptCore) + +/** + * The JSContext used by the bridge. + */ +@property (nonatomic, readonly, strong) JSContext *jsContext; + +/** + * The raw JSGlobalContextRef used by the bridge. + */ +@property (nonatomic, readonly, assign) JSGlobalContextRef jsContextRef; + +@end diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h index a2c86ba98..51b2ec0cb 100644 --- a/React/Base/RCTBridge.h +++ b/React/Base/RCTBridge.h @@ -15,7 +15,6 @@ #import #import -@class JSContext; @class JSValue; @class RCTBridge; @class RCTEventDispatcher; @@ -185,11 +184,6 @@ RCT_EXTERN NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass); */ @property (nonatomic, readonly, getter=isValid) BOOL valid; -/** - * The JSContext used by the bridge. - */ -@property (nonatomic, readonly, weak) JSContext *jsContext; - /** * Link to the Performance Logger that logs React Native perf events. */ diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index a00fdd71f..e86df784b 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -12,6 +12,7 @@ #import +#import "RCTBridge+JavaScriptCore.h" #import "RCTConvert.h" #import "RCTEventDispatcher.h" #import "RCTLog.h" @@ -378,5 +379,18 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) return [self.batchedBridge callFunctionOnModule:module method:method arguments:arguments error:error]; } +@end + +@implementation RCTBridge (JavaScriptCore) + +- (JSContext *)jsContext +{ + return [self.batchedBridge jsContext]; +} + +- (JSGlobalContextRef)jsContextRef +{ + return [self.batchedBridge jsContextRef]; +} @end diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 931228be9..3605b1ca6 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -138,7 +138,12 @@ struct RCTInstanceCallback : public InstanceCallback { - (JSContext *)jsContext { - return contextForGlobalContextRef((JSGlobalContextRef) self->_reactInstance->getJavaScriptContext()); + return contextForGlobalContextRef([self jsContextRef]); +} + +- (JSGlobalContextRef)jsContextRef +{ + return (JSGlobalContextRef)self->_reactInstance->getJavaScriptContext(); } - (instancetype)initWithParentBridge:(RCTBridge *)bridge diff --git a/React/DevSupport/RCTSamplingProfilerPackagerMethod.h b/React/DevSupport/RCTSamplingProfilerPackagerMethod.h index b293d6eae..386c21d0f 100644 --- a/React/DevSupport/RCTSamplingProfilerPackagerMethod.h +++ b/React/DevSupport/RCTSamplingProfilerPackagerMethod.h @@ -7,12 +7,13 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import #import +@class RCTBridge; + #if RCT_DEV // Only supported in dev mode -@interface RCTSamplingProfilerPackagerMethod : NSObject +@interface RCTSamplingProfilerPackagerMethod : NSObject - (instancetype)initWithBridge:(RCTBridge *)bridge; diff --git a/React/DevSupport/RCTSamplingProfilerPackagerMethod.mm b/React/DevSupport/RCTSamplingProfilerPackagerMethod.mm index 13906681f..c7adaf27e 100644 --- a/React/DevSupport/RCTSamplingProfilerPackagerMethod.mm +++ b/React/DevSupport/RCTSamplingProfilerPackagerMethod.mm @@ -11,6 +11,7 @@ #import +#import #import #import "RCTLog.h" @@ -31,8 +32,7 @@ - (void)handleRequest:(__unused id)params withResponder:(RCTPackagerClientResponder *)responder { - JSContext *context = _bridge.jsContext; - JSGlobalContextRef globalContext = context.JSGlobalContextRef; + JSGlobalContextRef globalContext = [_bridge jsContextRef]; if (!JSC_JSSamplingProfilerEnabled(globalContext)) { [responder respondWithError:@"The JSSamplingProfiler is disabled. See 'iOS specific setup' section here https://fburl.com/u4lw7xeq for some help"]; return; @@ -43,6 +43,7 @@ if (JSC_JSValueGetType(globalContext, jsResult) == kJSTypeNull) { [responder respondWithResult:@"started"]; } else { + JSContext *context = [_bridge jsContext]; NSString *results = [[JSC_JSValue(globalContext) valueWithJSValueRef:jsResult inContext:context] toObject]; [responder respondWithResult:results]; } diff --git a/React/Executors/RCTJSCExecutor.mm b/React/Executors/RCTJSCExecutor.mm index 75be11f54..b74c79c80 100644 --- a/React/Executors/RCTJSCExecutor.mm +++ b/React/Executors/RCTJSCExecutor.mm @@ -282,11 +282,9 @@ static NSThread *newJavaScriptThread(void) - (RCTJavaScriptContext *)context { - RCTAssertThread(_javaScriptThread, @"Must be called on JS thread."); if (!self.isValid) { return nil; } - RCTAssert(_context != nil, @"Fetching context while valid, but before it is created"); return _context; } diff --git a/React/Modules/RCTDevSettings.mm b/React/Modules/RCTDevSettings.mm index 241838b0d..3e63ea1ab 100644 --- a/React/Modules/RCTDevSettings.mm +++ b/React/Modules/RCTDevSettings.mm @@ -16,6 +16,7 @@ #import #import "JSCSamplingProfiler.h" +#import "RCTBridge+JavaScriptCore.h" #import "RCTBridge+Private.h" #import "RCTBridgeModule.h" #import "RCTEventDispatcher.h" @@ -188,7 +189,7 @@ RCT_EXPORT_MODULE() - (BOOL)isJSCSamplingProfilerAvailable { - return JSC_JSSamplingProfilerEnabled(_bridge.jsContext.JSGlobalContextRef); + return JSC_JSSamplingProfilerEnabled(_bridge.jsContextRef); } RCT_EXPORT_METHOD(reload) diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index 0a03aac53..7854faf31 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -165,6 +165,10 @@ 369123E11DDC75850095B341 /* JSCSamplingProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 369123E01DDC75850095B341 /* JSCSamplingProfiler.m */; }; 391E86A41C623EC800009732 /* RCTTouchEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 391E86A21C623EC800009732 /* RCTTouchEvent.m */; }; 3D05745A1DE5FFF500184BB4 /* RCTJavaScriptLoader.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC70D2E81DE489E4002E6351 /* RCTJavaScriptLoader.mm */; }; + 3D0976C11E97399A00B9C6DD /* RCTBridge+JavaScriptCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0976C01E97399A00B9C6DD /* RCTBridge+JavaScriptCore.h */; }; + 3D0976C21E9739A100B9C6DD /* RCTBridge+JavaScriptCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0976C01E97399A00B9C6DD /* RCTBridge+JavaScriptCore.h */; }; + 3D0976C31E9739AE00B9C6DD /* RCTBridge+JavaScriptCore.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D0976C01E97399A00B9C6DD /* RCTBridge+JavaScriptCore.h */; }; + 3D0976C41E9739B400B9C6DD /* RCTBridge+JavaScriptCore.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D0976C01E97399A00B9C6DD /* RCTBridge+JavaScriptCore.h */; }; 3D1E68DB1CABD13900DD7465 /* RCTDisplayLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D1E68D91CABD13900DD7465 /* RCTDisplayLink.m */; }; 3D302F1C1DF8264000D6DDAE /* JSBundleType.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D3CD8F51DE5FB2300167DC4 /* JSBundleType.h */; }; 3D302F1E1DF8265A00D6DDAE /* JavaScriptCore.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7A27DC1DE32541002E3F95 /* JavaScriptCore.h */; }; @@ -804,6 +808,7 @@ dstPath = include/React; dstSubfolderSpec = 16; files = ( + 3D0976C31E9739AE00B9C6DD /* RCTBridge+JavaScriptCore.h in Copy Headers */, 3D6B76D51E83DD3A008FA614 /* RCTDevSettings.h in Copy Headers */, 3D6B76D61E83DD3A008FA614 /* RCTConvert+Transform.h in Copy Headers */, A12E9E211E5DEAFB0029001B /* RCTPackagerClient.h in Copy Headers */, @@ -965,6 +970,7 @@ dstPath = include/React; dstSubfolderSpec = 16; files = ( + 3D0976C41E9739B400B9C6DD /* RCTBridge+JavaScriptCore.h in Copy Headers */, A12E9E1F1E5DEAEF0029001B /* RCTPackagerClient.h in Copy Headers */, A12E9E201E5DEAEF0029001B /* RCTPackagerClientResponder.h in Copy Headers */, 3D80D91F1DF6FA890028D040 /* RCTImageLoader.h in Copy Headers */, @@ -1281,6 +1287,7 @@ 369123E01DDC75850095B341 /* JSCSamplingProfiler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSCSamplingProfiler.m; sourceTree = ""; }; 391E86A21C623EC800009732 /* RCTTouchEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTouchEvent.m; sourceTree = ""; }; 391E86A31C623EC800009732 /* RCTTouchEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTouchEvent.h; sourceTree = ""; }; + 3D0976C01E97399A00B9C6DD /* RCTBridge+JavaScriptCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTBridge+JavaScriptCore.h"; sourceTree = ""; }; 3D1E68D81CABD13900DD7465 /* RCTDisplayLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDisplayLink.h; sourceTree = ""; }; 3D1E68D91CABD13900DD7465 /* RCTDisplayLink.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDisplayLink.m; sourceTree = ""; }; 3D1FA07A1DE4F2EA00E03CC6 /* RCTNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTNetworking.h; sourceTree = ""; }; @@ -1724,13 +1731,12 @@ 83CBBA491A601E3B00E9B192 /* Base */ = { isa = PBXGroup; children = ( - 139324FC1E70B069009FD7E0 /* RCTJSCErrorHandling.h */, - 139324FD1E70B069009FD7E0 /* RCTJSCErrorHandling.mm */, 83CBBA4A1A601E3B00E9B192 /* RCTAssert.h */, 83CBBA4B1A601E3B00E9B192 /* RCTAssert.m */, 14C2CA771B3ACB0400E6CBB2 /* RCTBatchedBridge.m */, 83CBBA5E1A601EAA00E9B192 /* RCTBridge.h */, 83CBBA5F1A601EAA00E9B192 /* RCTBridge.m */, + 3D0976C01E97399A00B9C6DD /* RCTBridge+JavaScriptCore.h */, 14A43DB81C1F849600794BC8 /* RCTBridge+Private.h */, 1482F9E61B55B927000ADFF3 /* RCTBridgeDelegate.h */, 13AFBCA11C07287B00BBAEAA /* RCTBridgeMethod.h */, @@ -1755,6 +1761,8 @@ 83CBBA631A601ECA00E9B192 /* RCTJavaScriptExecutor.h */, 14200DA81AC179B3008EE6BA /* RCTJavaScriptLoader.h */, AC70D2E81DE489E4002E6351 /* RCTJavaScriptLoader.mm */, + 139324FC1E70B069009FD7E0 /* RCTJSCErrorHandling.h */, + 139324FD1E70B069009FD7E0 /* RCTJSCErrorHandling.mm */, 008341F51D1DB34400876D9A /* RCTJSStackFrame.h */, 008341F41D1DB34400876D9A /* RCTJSStackFrame.m */, 13A1F71C1A75392D00D3D453 /* RCTKeyCommands.h */, @@ -1876,6 +1884,7 @@ 3D302F3B1DF828F800D6DDAE /* RCTJavaScriptExecutor.h in Headers */, 3D302F3C1DF828F800D6DDAE /* RCTJavaScriptLoader.h in Headers */, 3D302F3D1DF828F800D6DDAE /* RCTJSStackFrame.h in Headers */, + 3D0976C21E9739A100B9C6DD /* RCTBridge+JavaScriptCore.h in Headers */, 3D302F3E1DF828F800D6DDAE /* RCTKeyCommands.h in Headers */, 3D302F3F1DF828F800D6DDAE /* RCTLog.h in Headers */, 3D302F401DF828F800D6DDAE /* RCTModuleData.h in Headers */, @@ -2087,6 +2096,7 @@ 3D80DA451DF820620028D040 /* RCTWebSocketObserverProtocol.h in Headers */, 3D80DA481DF820620028D040 /* RCTJSCExecutor.h in Headers */, 3D80DA491DF820620028D040 /* JSCSamplingProfiler.h in Headers */, + 3D0976C11E97399A00B9C6DD /* RCTBridge+JavaScriptCore.h in Headers */, 3D80DA4A1DF820620028D040 /* RCTAccessibilityManager.h in Headers */, 3D80DA4B1DF820620028D040 /* RCTAlertManager.h in Headers */, 3D80DA4C1DF820620028D040 /* RCTAppState.h in Headers */, diff --git a/React/ReactCxx.xcodeproj/project.pbxproj b/React/ReactCxx.xcodeproj/project.pbxproj index 7dd721d64..29476f0e9 100644 --- a/React/ReactCxx.xcodeproj/project.pbxproj +++ b/React/ReactCxx.xcodeproj/project.pbxproj @@ -356,6 +356,10 @@ 369123E11DDC75850095B341 /* JSCSamplingProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 369123E01DDC75850095B341 /* JSCSamplingProfiler.m */; }; 391E86A41C623EC800009732 /* RCTTouchEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 391E86A21C623EC800009732 /* RCTTouchEvent.m */; }; 3D05745A1DE5FFF500184BB4 /* RCTJavaScriptLoader.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC70D2E81DE489E4002E6351 /* RCTJavaScriptLoader.mm */; }; + 3D0976D51E9739ED00B9C6DD /* RCTBridge+JavaScriptCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0976D41E9739ED00B9C6DD /* RCTBridge+JavaScriptCore.h */; }; + 3D0976D61E9739F000B9C6DD /* RCTBridge+JavaScriptCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0976D41E9739ED00B9C6DD /* RCTBridge+JavaScriptCore.h */; }; + 3D0976D71E9739FB00B9C6DD /* RCTBridge+JavaScriptCore.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D0976D41E9739ED00B9C6DD /* RCTBridge+JavaScriptCore.h */; }; + 3D0976D81E973A0200B9C6DD /* RCTBridge+JavaScriptCore.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D0976D41E9739ED00B9C6DD /* RCTBridge+JavaScriptCore.h */; }; 3D1E68DB1CABD13900DD7465 /* RCTDisplayLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D1E68D91CABD13900DD7465 /* RCTDisplayLink.m */; }; 3D302F1E1DF8265A00D6DDAE /* JavaScriptCore.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7A27DC1DE32541002E3F95 /* JavaScriptCore.h */; }; 3D302F1F1DF8265A00D6DDAE /* JSCWrapper.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7A27DE1DE32541002E3F95 /* JSCWrapper.h */; }; @@ -1062,6 +1066,7 @@ dstPath = include/React; dstSubfolderSpec = 16; files = ( + 3D0976D71E9739FB00B9C6DD /* RCTBridge+JavaScriptCore.h in Copy Headers */, 3DA981E91E5B0F7F004F2374 /* JSCSamplingProfiler.h in Copy Headers */, 3DA981EA1E5B0F7F004F2374 /* RCTAccessibilityManager.h in Copy Headers */, 3DA981EB1E5B0F7F004F2374 /* RCTAlertManager.h in Copy Headers */, @@ -1254,6 +1259,7 @@ dstPath = include/React; dstSubfolderSpec = 16; files = ( + 3D0976D81E973A0200B9C6DD /* RCTBridge+JavaScriptCore.h in Copy Headers */, 3D80D91F1DF6FA890028D040 /* RCTImageLoader.h in Copy Headers */, 3D80D9201DF6FA890028D040 /* RCTImageStoreManager.h in Copy Headers */, 3D80D9211DF6FA890028D040 /* RCTResizeMode.h in Copy Headers */, @@ -1679,6 +1685,7 @@ 369123E01DDC75850095B341 /* JSCSamplingProfiler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSCSamplingProfiler.m; sourceTree = ""; }; 391E86A21C623EC800009732 /* RCTTouchEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTouchEvent.m; sourceTree = ""; }; 391E86A31C623EC800009732 /* RCTTouchEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTouchEvent.h; sourceTree = ""; }; + 3D0976D41E9739ED00B9C6DD /* RCTBridge+JavaScriptCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTBridge+JavaScriptCore.h"; sourceTree = ""; }; 3D1E68D81CABD13900DD7465 /* RCTDisplayLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDisplayLink.h; sourceTree = ""; }; 3D1E68D91CABD13900DD7465 /* RCTDisplayLink.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDisplayLink.m; sourceTree = ""; }; 3D1FA07A1DE4F2EA00E03CC6 /* RCTNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTNetworking.h; sourceTree = ""; }; @@ -2315,12 +2322,11 @@ 83CBBA491A601E3B00E9B192 /* Base */ = { isa = PBXGroup; children = ( - 135A9BF91E7B0EAE00587AEB /* RCTJSCErrorHandling.h */, - 135A9BFA1E7B0EAE00587AEB /* RCTJSCErrorHandling.mm */, 83CBBA4A1A601E3B00E9B192 /* RCTAssert.h */, 83CBBA4B1A601E3B00E9B192 /* RCTAssert.m */, 83CBBA5E1A601EAA00E9B192 /* RCTBridge.h */, 83CBBA5F1A601EAA00E9B192 /* RCTBridge.m */, + 3D0976D41E9739ED00B9C6DD /* RCTBridge+JavaScriptCore.h */, 14A43DB81C1F849600794BC8 /* RCTBridge+Private.h */, 1482F9E61B55B927000ADFF3 /* RCTBridgeDelegate.h */, 13AFBCA11C07287B00BBAEAA /* RCTBridgeMethod.h */, @@ -2345,6 +2351,8 @@ 83CBBA631A601ECA00E9B192 /* RCTJavaScriptExecutor.h */, 14200DA81AC179B3008EE6BA /* RCTJavaScriptLoader.h */, AC70D2E81DE489E4002E6351 /* RCTJavaScriptLoader.mm */, + 135A9BF91E7B0EAE00587AEB /* RCTJSCErrorHandling.h */, + 135A9BFA1E7B0EAE00587AEB /* RCTJSCErrorHandling.mm */, 008341F51D1DB34400876D9A /* RCTJSStackFrame.h */, 008341F41D1DB34400876D9A /* RCTJSStackFrame.m */, 13A1F71C1A75392D00D3D453 /* RCTKeyCommands.h */, @@ -2542,6 +2550,7 @@ 3D302F621DF828F800D6DDAE /* RCTSourceCode.h in Headers */, 3D302F631DF828F800D6DDAE /* RCTStatusBarManager.h in Headers */, 3D302F641DF828F800D6DDAE /* RCTTiming.h in Headers */, + 3D0976D61E9739F000B9C6DD /* RCTBridge+JavaScriptCore.h in Headers */, 3D302F651DF828F800D6DDAE /* RCTUIManager.h in Headers */, 3D302F661DF828F800D6DDAE /* RCTFPSGraph.h in Headers */, 3D302F681DF828F800D6DDAE /* RCTMacros.h in Headers */, @@ -2824,6 +2833,7 @@ 3D80DA721DF820620028D040 /* RCTModalHostViewManager.h in Headers */, 13134C9C1E296B2A00B9F3CB /* RCTCxxModule.h in Headers */, 3D80DA731DF820620028D040 /* RCTNavigator.h in Headers */, + 3D0976D51E9739ED00B9C6DD /* RCTBridge+JavaScriptCore.h in Headers */, 3D80DA741DF820620028D040 /* RCTNavigatorManager.h in Headers */, 3D80DA751DF820620028D040 /* RCTNavItem.h in Headers */, 3D80DA761DF820620028D040 /* RCTNavItemManager.h in Headers */,