/** |
|
* This function parses the exported methods inside RCTBridgeModules and |
|
* generates an array of arrays of RCTModuleMethod objects, keyed |
|
* by module index. |
|
*/ |
|
static RCTSparseArray *RCTExportedMethodsByModuleID(void) |
|
{ |
|
static RCTSparseArray *methodsByModuleID; |
|
static dispatch_once_t onceToken; |
|
dispatch_once(&onceToken, ^{ |
|
|
|
Dl_info info; |
|
dladdr(&RCTExportedMethodsByModuleID, &info); |
|
|
|
#ifdef __LP64__ |
|
typedef uint64_t RCTExportValue; |
|
typedef struct section_64 RCTExportSection; |
|
#define RCTGetSectByNameFromHeader getsectbynamefromheader_64 |
|
#else |
|
typedef uint32_t RCTExportValue; |
|
typedef struct section RCTExportSection; |
|
#define RCTGetSectByNameFromHeader getsectbynamefromheader |
|
#endif |
|
|
|
const RCTExportValue mach_header = (RCTExportValue)info.dli_fbase; |
|
const RCTExportSection *section = RCTGetSectByNameFromHeader((void *)mach_header, "__DATA", "RCTExport"); |
|
|
|
if (section == NULL) { |
|
return; |
|
} |
|
|
|
NSArray *classes = RCTBridgeModuleClassesByModuleID(); |
|
NSMutableDictionary *methodsByModuleClassName = [NSMutableDictionary dictionaryWithCapacity:[classes count]]; |
|
|
|
for (RCTExportValue addr = section->offset; |
|
addr < section->offset + section->size; |
|
addr += sizeof(const char **) * 2) { |
|
|
|
// Get data entry |
|
const char **entries = (const char **)(mach_header + addr); |
|
|
|
// Create method |
|
RCTModuleMethod *moduleMethod = |
|
[[RCTModuleMethod alloc] initWithMethodName:@(entries[0]) |
|
JSMethodName:strlen(entries[1]) ? @(entries[1]) : nil]; |
|
|
|
// Cache method |
|
NSArray *methods = methodsByModuleClassName[moduleMethod.moduleClassName]; |
|
methodsByModuleClassName[moduleMethod.moduleClassName] = |
|
methods ? [methods arrayByAddingObject:moduleMethod] : @[moduleMethod]; |
|
} |
|
|
|
methodsByModuleID = [[RCTSparseArray alloc] initWithCapacity:[classes count]]; |
|
[classes enumerateObjectsUsingBlock:^(Class moduleClass, NSUInteger moduleID, BOOL *stop) { |
|
methodsByModuleID[moduleID] = methodsByModuleClassName[NSStringFromClass(moduleClass)]; |
|
}]; |
|
}); |
|
|
|
return methodsByModuleID; |
|
} |