diff --git a/Libraries/Utilities/MessageQueue.js b/Libraries/Utilities/MessageQueue.js index 8a56aa714..cac48a8e5 100644 --- a/Libraries/Utilities/MessageQueue.js +++ b/Libraries/Utilities/MessageQueue.js @@ -305,10 +305,12 @@ var MessageQueueMixin = { return guardReturn(this._callFunction, [moduleID, methodID, params], null, this); }, - _callFunction: function(moduleID, methodID, params) { - var moduleName = this._localModuleIDToModuleName[moduleID]; + _callFunction: function(moduleName, methodName, params) { + if (isFinite(moduleName)) { + moduleName = this._localModuleIDToModuleName[moduleName]; + methodName = this._localModuleNameToMethodIDToName[moduleName][methodName]; + } - var methodName = this._localModuleNameToMethodIDToName[moduleName][methodID]; if (DEBUG_SPY_MODE) { console.log( 'N->JS: ' + moduleName + '.' + methodName + diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h index 5c5cfe49b..35183437d 100644 --- a/React/Base/RCTBridge.h +++ b/React/Base/RCTBridge.h @@ -75,22 +75,15 @@ RCT_EXTERN NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass); /** * This method is used to call functions in the JavaScript application context. * It is primarily intended for use by modules that require two-way communication - * with the JavaScript code. Method should be registered using the - * RCT_IMPORT_METHOD macro below. Attempting to call a method that has not been - * registered will result in an error. Safe to call from any thread. + * with the JavaScript code. Safe to call from any thread. */ - (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args; /** - * This macro is used to register a JS method to be called via the enqueueJSCall - * bridge method. You should place this macro inside any file that uses the - * imported method. If a method has already been registered by another class, it - * is not necessary to register it again, but it is good practice. Registering - * the same method more than once will not result in an error. + * DEPRECATED: Do not use. */ #define RCT_IMPORT_METHOD(module, method) \ -__attribute__((used, section("__DATA,RCTImport"))) \ -static const char *__rct_import_##module##_##method##__ = #module"."#method; + _Pragma("message(\"This macro is no longer required\")") /** * URL of the script that was loaded into the bridge. diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index 818af496b..f8e9eeab7 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -13,10 +13,6 @@ #import #import -#import -#import - -#import "RCTAssert.h" #import "RCTContextExecutor.h" #import "RCTConvert.h" #import "RCTEventDispatcher.h" @@ -54,16 +50,6 @@ typedef NS_ENUM(NSUInteger, RCTJavaScriptFunctionKind) { RCTJavaScriptFunctionKindAsync, }; -#ifdef __LP64__ -typedef struct mach_header_64 *RCTHeaderValue; -typedef struct section_64 RCTHeaderSection; -#define RCTGetSectByNameFromHeader getsectbynamefromheader_64 -#else -typedef struct mach_header *RCTHeaderValue; -typedef struct section RCTHeaderSection; -#define RCTGetSectByNameFromHeader getsectbynamefromheader -#endif - #define RCTAssertJSThread() \ RCTAssert(![NSStringFromClass([_javaScriptExecutor class]) isEqualToString:@"RCTContextExecutor"] || \ [[[NSThread currentThread] name] isEqualToString:@"com.facebook.React.JavaScript"], \ @@ -114,40 +100,6 @@ NSString *RCTBridgeModuleNameForClass(Class cls) return name; } -/** - * This function scans all classes available at runtime and returns an array - * of all JSMethods registered. - */ -static NSArray *RCTJSMethods(void) -{ - static NSArray *JSMethods; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSMutableSet *uniqueMethods = [NSMutableSet set]; - - Dl_info info; - dladdr(&RCTJSMethods, &info); - - const RCTHeaderValue mach_header = (RCTHeaderValue)info.dli_fbase; - unsigned long size = 0; - const uint8_t *sectionData = getsectiondata(mach_header, "__DATA", "RCTImport", &size); - if (sectionData) { - for (const uint8_t *addr = sectionData; - addr < sectionData + size; - addr += sizeof(const char **)) { - - // Get data entry - NSString *entry = @(*(const char **)addr); - [uniqueMethods addObject:entry]; - } - } - - JSMethods = [uniqueMethods allObjects]; - }); - - return JSMethods; -} - // TODO: Can we just replace RCTMakeError with this function instead? static NSDictionary *RCTJSErrorFromNSError(NSError *error) { @@ -596,80 +548,6 @@ static NSDictionary *RCTRemoteModulesConfig(NSDictionary *modulesByName) return moduleConfig; } -/** - * As above, but for local modules/methods, which represent JS classes - * and methods that will be called by the native code via the bridge. - * Structure is essentially the same as for remote modules: - * - * "ModuleName1": { - * "moduleID": 0, - * "methods": { - * "methodName1": { - * "methodID": 0, - * "type": "local" - * }, - * "methodName2": { - * "methodID": 1, - * "type": "local" - * }, - * etc... - * } - * }, - * etc... - */ -static NSMutableDictionary *RCTLocalModuleIDs; -static NSMutableDictionary *RCTLocalMethodIDs; -static NSMutableArray *RCTLocalModuleNames; -static NSMutableArray *RCTLocalMethodNames; -static NSDictionary *RCTLocalModulesConfig() -{ - static NSMutableDictionary *localModules; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - - RCTLocalModuleIDs = [[NSMutableDictionary alloc] init]; - RCTLocalMethodIDs = [[NSMutableDictionary alloc] init]; - RCTLocalModuleNames = [[NSMutableArray alloc] init]; - RCTLocalMethodNames = [[NSMutableArray alloc] init]; - - localModules = [[NSMutableDictionary alloc] init]; - for (NSString *moduleDotMethod in RCTJSMethods()) { - - NSArray *parts = [moduleDotMethod componentsSeparatedByString:@"."]; - RCTAssert(parts.count == 2, @"'%@' is not a valid JS method definition - expected 'Module.method' format.", moduleDotMethod); - - // Add module if it doesn't already exist - NSString *moduleName = parts[0]; - NSDictionary *module = localModules[moduleName]; - if (!module) { - module = @{ - @"moduleID": @(localModules.count), - @"methods": [[NSMutableDictionary alloc] init] - }; - localModules[moduleName] = module; - [RCTLocalModuleNames addObject:moduleName]; - } - - // Add method if it doesn't already exist - NSString *methodName = parts[1]; - NSMutableDictionary *methods = module[@"methods"]; - if (!methods[methodName]) { - methods[methodName] = @{ - @"methodID": @(methods.count), - @"type": @"local" - }; - [RCTLocalMethodNames addObject:methodName]; - } - - // Add module and method lookup - RCTLocalModuleIDs[moduleDotMethod] = module[@"moduleID"]; - RCTLocalMethodIDs[moduleDotMethod] = methods[methodName][@"methodID"]; - } - }); - - return localModules; -} - @interface RCTFrameUpdate (Private) - (instancetype)initWithDisplayLink:(CADisplayLink *)displayLink; @@ -734,12 +612,6 @@ static id _latestJSExecutor; RCTAssertMainThread(); if ((self = [super init])) { - - /** - * Pre register modules - */ - RCTLocalModulesConfig(); - _bundleURL = bundleURL; _moduleProvider = block; _launchOptions = [launchOptions copy]; @@ -1052,7 +924,6 @@ RCT_INNER_BRIDGE_ONLY(_invokeAndProcessModule:(__unused NSString *)module // Inject module data into JS context NSString *configJSON = RCTJSONStringify(@{ @"remoteModuleConfig": RCTRemoteModulesConfig(_modulesByName), - @"localModulesConfig": RCTLocalModulesConfig() }, NULL); dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [_javaScriptExecutor injectJSONText:configJSON @@ -1211,13 +1082,6 @@ RCT_INNER_BRIDGE_ONLY(_invokeAndProcessModule:(__unused NSString *)module }]; } -/** - * - TODO (#5906496): When we build a `MessageQueue.m`, handling all the requests could - * cause both a queue of "responses". We would flush them here. However, we - * currently just expect each objc block to handle its own response sending - * using a `RCTResponseSenderBlock`. - */ - #pragma mark - RCTBridge methods /** @@ -1225,16 +1089,11 @@ RCT_INNER_BRIDGE_ONLY(_invokeAndProcessModule:(__unused NSString *)module */ - (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args { - NSNumber *moduleID = RCTLocalModuleIDs[moduleDotMethod]; - RCTAssert(moduleID != nil, @"Module '%@' not registered.", - [[moduleDotMethod componentsSeparatedByString:@"."] firstObject]); - - NSNumber *methodID = RCTLocalMethodIDs[moduleDotMethod]; - RCTAssert(methodID != nil, @"Method '%@' not registered.", moduleDotMethod); + NSArray *ids = [moduleDotMethod componentsSeparatedByString:@"."]; [self _invokeAndProcessModule:@"BatchedBridge" method:@"callFunctionReturnFlushedQueue" - arguments:@[moduleID ?: @0, methodID ?: @0, args ?: @[]] + arguments:@[ids[0], ids[1], args ?: @[]] context:RCTGetExecutorID(_javaScriptExecutor)]; } @@ -1245,18 +1104,10 @@ RCT_INNER_BRIDGE_ONLY(_invokeAndProcessModule:(__unused NSString *)module { RCTAssertJSThread(); - NSString *moduleDotMethod = @"JSTimersExecution.callTimers"; - NSNumber *moduleID = RCTLocalModuleIDs[moduleDotMethod]; - RCTAssert(moduleID != nil, @"Module '%@' not registered.", - [[moduleDotMethod componentsSeparatedByString:@"."] firstObject]); - - NSNumber *methodID = RCTLocalMethodIDs[moduleDotMethod]; - RCTAssert(methodID != nil, @"Method '%@' not registered.", moduleDotMethod); - dispatch_block_t block = ^{ [self _actuallyInvokeAndProcessModule:@"BatchedBridge" method:@"callFunctionReturnFlushedQueue" - arguments:@[moduleID, methodID, @[@[timer]]] + arguments:@[@"JSTimersExecution", @"callTimers", @[@[timer]]] context:RCTGetExecutorID(_javaScriptExecutor)]; }; diff --git a/React/Base/RCTEventDispatcher.m b/React/Base/RCTEventDispatcher.m index 8a553c7a2..ac0d1097b 100644 --- a/React/Base/RCTEventDispatcher.m +++ b/React/Base/RCTEventDispatcher.m @@ -89,10 +89,6 @@ RCT_EXPORT_MODULE() return self; } -RCT_IMPORT_METHOD(RCTNativeAppEventEmitter, emit); -RCT_IMPORT_METHOD(RCTDeviceEventEmitter, emit); -RCT_IMPORT_METHOD(RCTEventEmitter, receiveEvent); - - (void)sendAppEventWithName:(NSString *)name body:(id)body { [_bridge enqueueJSCall:@"RCTNativeAppEventEmitter.emit" diff --git a/React/Base/RCTRootView.m b/React/Base/RCTRootView.m index 16bee5475..094e88840 100644 --- a/React/Base/RCTRootView.m +++ b/React/Base/RCTRootView.m @@ -119,9 +119,6 @@ RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder) return YES; } -RCT_IMPORT_METHOD(AppRegistry, runApplication) -RCT_IMPORT_METHOD(ReactNative, unmountComponentAtNodeAndRemoveContainer) - - (void)setLoadingView:(UIView *)loadingView { _loadingView = loadingView; diff --git a/React/Base/RCTTouchHandler.m b/React/Base/RCTTouchHandler.m index 759f1078d..c7c19ed9b 100644 --- a/React/Base/RCTTouchHandler.m +++ b/React/Base/RCTTouchHandler.m @@ -149,8 +149,6 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) { reactTouch[@"timestamp"] = @(nativeTouch.timestamp * 1000); // in ms, for JS } -RCT_IMPORT_METHOD(RCTEventEmitter, receiveTouches); - /** * Constructs information about touch events to send across the serialized * boundary. This data should be compliant with W3C `Touch` objects. This data diff --git a/React/Executors/RCTContextExecutor.m b/React/Executors/RCTContextExecutor.m index 270bc4a93..54736613e 100644 --- a/React/Executors/RCTContextExecutor.m +++ b/React/Executors/RCTContextExecutor.m @@ -365,7 +365,7 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError) JSValueRef moduleJSRef = JSObjectCallAsFunction(contextJSRef, (JSObjectRef)requireJSRef, NULL, 1, (const JSValueRef *)&moduleNameJSRef, &errorJSRef); JSStringRelease(moduleNameJSStringRef); - if (moduleJSRef != NULL && errorJSRef == NULL) { + if (moduleJSRef != NULL && errorJSRef == NULL && !JSValueIsUndefined(contextJSRef, moduleJSRef)) { // get method JSStringRef methodNameJSStringRef = JSStringCreateWithCFString((__bridge CFStringRef)method); diff --git a/React/Modules/RCTTiming.m b/React/Modules/RCTTiming.m index 06cb8b3e9..d6387d1d6 100644 --- a/React/Modules/RCTTiming.m +++ b/React/Modules/RCTTiming.m @@ -74,8 +74,6 @@ RCT_EXPORT_MODULE() -RCT_IMPORT_METHOD(JSTimersExecution, callTimers) - - (instancetype)init { if ((self = [super init])) {