Przeglądaj źródła

FLEXRuntimeClient additions

- Move initializeWebKitLegacy to FLEXRuntimeClient
- Add -copySafeClassList and -copyProtocolList
Tanner Bennett 6 lat temu
rodzic
commit
87ea2bb147

+ 11 - 0
Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeClient.h

@@ -19,6 +19,17 @@
 /// been loaded since this method was first called.
 - (void)reloadLibrariesList;
 
+/// You must call this method on the main thread
+/// before you attempt to call \c copySafeClassList.
++ (void)initializeWebKitLegacy;
+
+/// Do not call unless you absolutely need all classes. This will cause
+/// every class in the runtime to initialize itself, which is not common.
+/// Before you call this method, call \c initializeWebKitLegacy on the main thread.
+- (NSArray<Class> *)copySafeClassList;
+
+- (NSArray<Protocol *> *)copyProtocolList;
+
 /// An array of strings representing the currently loaded libraries.
 @property (nonatomic, readonly) NSArray<NSString *> *imageDisplayNames;
 

+ 33 - 0
Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeClient.m

@@ -11,6 +11,7 @@
 #import "FLEXMethod.h"
 #import "NSArray+Functional.h"
 #import "FLEXRuntimeSafety.h"
+#include <dlfcn.h>
 
 #define Equals(a, b)    ([a compare:b options:NSCaseInsensitiveSearch] == NSOrderedSame)
 #define Contains(a, b)  ([a rangeOfString:b options:NSCaseInsensitiveSearch].location != NSNotFound)
@@ -187,6 +188,38 @@ static inline NSString * TBWildcardMap(NSString *token, NSString *candidate, TBW
 
 #pragma mark - Public
 
++ (void)initializeWebKitLegacy {
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        void *handle = dlopen(
+            "/System/Library/PrivateFrameworks/WebKitLegacy.framework/WebKitLegacy",
+            RTLD_LAZY
+        );
+        void (*WebKitInitialize)() = dlsym(handle, "WebKitInitialize");
+        if (WebKitInitialize) {
+            NSAssert(NSThread.isMainThread,
+                @"WebKitInitialize can only be called on the main thread"
+            );
+            WebKitInitialize();
+        }
+    });
+}
+
+- (NSArray<Class> *)copySafeClassList {
+    unsigned int count = 0;
+    Class *classes = objc_copyClassList(&count);
+    return [NSArray flex_forEachUpTo:count map:^id(NSUInteger i) {
+        Class cls = classes[i];
+        return FLEXClassIsSafe(cls) ? cls : nil;
+    }];
+}
+
+- (NSArray<Protocol *> *)copyProtocolList {
+    unsigned int count = 0;
+    Protocol *__unsafe_unretained *protocols = objc_copyProtocolList(&count);
+    return [NSArray arrayWithObjects:protocols count:count];
+}
+
 - (NSMutableArray<NSString *> *)bundleNamesForToken:(FLEXSearchToken *)token {
     if (self.imagePaths.count) {
         TBWildcardOptions options = token.options;

+ 2 - 1
Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeController.h

@@ -8,7 +8,7 @@
 
 #import "FLEXRuntimeKeyPath.h"
 
-/// Wraps FLEXRuntimeClient and provides caching mechanisms
+/// Wraps FLEXRuntimeClient and provides extra caching mechanisms
 @interface FLEXRuntimeController : NSObject
 
 /// @return An array of strings if the key path only evaluates
@@ -30,6 +30,7 @@
 
 + (NSString *)imagePathWithShortName:(NSString *)suffix;
 
+/// Gives back short names. For example, "Foundation.framework"
 + (NSArray<NSString*> *)allBundleNames;
 
 @end

+ 2 - 19
Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeKeyPath.m

@@ -7,7 +7,7 @@
 //
 
 #import "FLEXRuntimeKeyPath.h"
-#include <dlfcn.h>
+#import "FLEXRuntimeClient.h"
 
 @interface FLEXRuntimeKeyPath () {
     NSString *flex_description;
@@ -49,29 +49,12 @@
     keyPath->flex_description = keyPathString;
     
     if (bundle.isAny && cls.isAny && method.isAny) {
-        [self initializeWebKitLegacy];
+        [FLEXRuntimeClient initializeWebKitLegacy];
     }
 
     return keyPath;
 }
 
-+ (void)initializeWebKitLegacy {
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        void *handle = dlopen(
-            "/System/Library/PrivateFrameworks/WebKitLegacy.framework/WebKitLegacy",
-            RTLD_LAZY
-        );
-        void (*WebKitInitialize)() = dlsym(handle, "WebKitInitialize");
-        if (WebKitInitialize) {
-            NSAssert(NSThread.isMainThread,
-                @"WebKitInitialize can only be called on the main thread"
-            );
-            WebKitInitialize();
-        }
-    });
-}
-
 - (NSString *)description {
     return flex_description;
 }