mirror of
https://github.com/darlinghq/darling-corefoundation.git
synced 2024-10-07 09:13:26 +00:00
1c6ea502b7
This reverts commit 3cf877c00d
.
The issue with this commit is that it adds stubs for some methods
which are actually implemeneted in categories in Foundation. The good
parts of this commit will be later committed once those are removed.
346 lines
7.2 KiB
Objective-C
346 lines
7.2 KiB
Objective-C
//
|
|
// NSObject.m
|
|
// CoreFoundation
|
|
//
|
|
// Copyright (c) 2014 Apportable. All rights reserved.
|
|
//
|
|
|
|
#import <Foundation/NSObject.h>
|
|
#import <Foundation/NSString.h>
|
|
#import <Foundation/NSMethodSignature.h>
|
|
#import <Foundation/NSInvocation.h>
|
|
#import <Foundation/NSException.h>
|
|
#import "CFString.h"
|
|
#import "NSZombie.h"
|
|
#import <objc/runtime.h>
|
|
#import <objc/message.h>
|
|
#include <stdio.h>
|
|
#include <malloc/malloc.h>
|
|
|
|
//#import <libv/libv.h>
|
|
#define _GETENV(a,b) 0
|
|
|
|
#define SYMBOL_HERE_IN_3(sym, vers, n) \
|
|
OBJC_EXPORT const char here_ ##n __asm__("$ld$add$os" #vers "$" #sym); const char here_ ##n = 0
|
|
#define SYMBOL_HERE_IN_2(sym, vers, n) \
|
|
SYMBOL_HERE_IN_3(sym, vers, n)
|
|
#define SYMBOL_HERE_IN(sym, vers) \
|
|
SYMBOL_HERE_IN_2(sym, vers, __COUNTER__)
|
|
|
|
#if __OBJC2__
|
|
# define NSOBJECT_HERE_IN(vers) \
|
|
SYMBOL_HERE_IN(_OBJC_CLASS_$_NSObject, vers); \
|
|
SYMBOL_HERE_IN(_OBJC_METACLASS_$_NSObject, vers); \
|
|
SYMBOL_HERE_IN(_OBJC_IVAR_$_NSObject.isa, vers)
|
|
#else
|
|
# define NSOBJECT_HERE_IN(vers) \
|
|
SYMBOL_HERE_IN(.objc_class_name_NSObject, vers)
|
|
#endif
|
|
|
|
#if TARGET_OS_IOS
|
|
|
|
NSOBJECT_HERE_IN(2.0);
|
|
NSOBJECT_HERE_IN(2.1);
|
|
NSOBJECT_HERE_IN(2.2);
|
|
NSOBJECT_HERE_IN(3.0);
|
|
NSOBJECT_HERE_IN(3.1);
|
|
NSOBJECT_HERE_IN(3.2);
|
|
NSOBJECT_HERE_IN(4.0);
|
|
NSOBJECT_HERE_IN(4.1);
|
|
NSOBJECT_HERE_IN(4.2);
|
|
NSOBJECT_HERE_IN(4.3);
|
|
NSOBJECT_HERE_IN(5.0);
|
|
NSOBJECT_HERE_IN(5.1);
|
|
|
|
#elif TARGET_OS_MAC
|
|
|
|
NSOBJECT_HERE_IN(10.0);
|
|
NSOBJECT_HERE_IN(10.1);
|
|
NSOBJECT_HERE_IN(10.2);
|
|
NSOBJECT_HERE_IN(10.3);
|
|
NSOBJECT_HERE_IN(10.4);
|
|
NSOBJECT_HERE_IN(10.5);
|
|
NSOBJECT_HERE_IN(10.6);
|
|
NSOBJECT_HERE_IN(10.7);
|
|
|
|
#endif
|
|
|
|
void __CFZombifyNSObject(void) {
|
|
Class cls = objc_lookUpClass("NSObject");
|
|
Method dealloc_zombie = class_getInstanceMethod(cls, @selector(__dealloc_zombie));
|
|
Method dealloc = class_getInstanceMethod(cls, @selector(dealloc));
|
|
method_exchangeImplementations(dealloc_zombie, dealloc);
|
|
}
|
|
|
|
static void NSUnrecognizedForwarding() { __asm__("int3"); }
|
|
|
|
@implementation NSObject (NSObject)
|
|
|
|
+ (void)doesNotRecognizeSelector:(SEL)sel
|
|
{
|
|
if (_GETENV(BOOL, "NSUnrecognizedForwardingDisabled"))
|
|
{
|
|
RELEASE_LOG("+[%s %s]: unrecognized selector sent to instance %p; set a breakpoint on NSUnrecognizedForwarding to debug", class_getName(self), sel_getName(sel), self);
|
|
NSUnrecognizedForwarding();
|
|
}
|
|
else
|
|
{
|
|
// DONT EVEN THINK ABOUT REMOVING/HACKING AROUND THIS!
|
|
// EVER!
|
|
// ...
|
|
// yes, I mean YOU!
|
|
[NSException raise:NSInvalidArgumentException format:@"+[%s %s]: unrecognized selector sent to instance %p", class_getName(self), sel_getName(sel), self];
|
|
}
|
|
}
|
|
|
|
- (void)doesNotRecognizeSelector:(SEL)sel
|
|
{
|
|
if (_GETENV(BOOL, "NSUnrecognizedForwardingDisabled"))
|
|
{
|
|
RELEASE_LOG("+[%s %s]: unrecognized selector sent to instance %p; set a breakpoint on NSUnrecognizedForwarding to debug", object_getClassName(self), sel_getName(sel), self);
|
|
NSUnrecognizedForwarding();
|
|
}
|
|
else
|
|
{
|
|
// DONT EVEN THINK ABOUT REMOVING/HACKING AROUND THIS!
|
|
// EVER!
|
|
// ...
|
|
// yes, I mean YOU!
|
|
[NSException raise:NSInvalidArgumentException format:@"-[%s %s]: unrecognized selector sent to instance %p", object_getClassName(self), sel_getName(sel), self];
|
|
}
|
|
}
|
|
|
|
+ (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)sel
|
|
{
|
|
if (sel == NULL)
|
|
{
|
|
return nil;
|
|
}
|
|
|
|
Method m = class_getInstanceMethod(self, sel);
|
|
|
|
if (m == NULL)
|
|
{
|
|
return nil;
|
|
}
|
|
|
|
return [NSMethodSignature signatureWithObjCTypes:method_getTypeEncoding(m)];
|
|
}
|
|
|
|
+ (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
|
|
{
|
|
if (sel == NULL)
|
|
{
|
|
return nil;
|
|
}
|
|
|
|
Method m = class_getClassMethod(self, sel);
|
|
|
|
if (m == NULL)
|
|
{
|
|
return nil;
|
|
}
|
|
|
|
return [NSMethodSignature signatureWithObjCTypes:method_getTypeEncoding(m)];
|
|
}
|
|
|
|
|
|
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
|
|
{
|
|
if (sel == NULL)
|
|
{
|
|
return nil;
|
|
}
|
|
|
|
Method m = class_getInstanceMethod(object_getClass(self), sel);
|
|
|
|
if (m == NULL)
|
|
{
|
|
return nil;
|
|
}
|
|
|
|
return [NSMethodSignature signatureWithObjCTypes:method_getTypeEncoding(m)];
|
|
}
|
|
|
|
+ (NSString *)description
|
|
{
|
|
CFStringRef description = CFStringCreateWithCString(kCFAllocatorDefault, class_getName(self), kCFStringEncodingUTF8);
|
|
return [(NSString *)description autorelease];
|
|
}
|
|
|
|
- (NSString *)description
|
|
{
|
|
CFStringRef description = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("<%s: %p>"), object_getClassName(self), self);
|
|
return [(NSString *)description autorelease];
|
|
}
|
|
|
|
+ (BOOL)implementsSelector:(SEL)selector
|
|
{
|
|
if (selector == NULL)
|
|
{
|
|
[NSException raise:NSInvalidArgumentException format:@"selector cannot be NULL"];
|
|
return NO;
|
|
}
|
|
|
|
return class_getMethodImplementation(object_getClass(self), selector) != (IMP)&_objc_msgForward;
|
|
}
|
|
|
|
- (BOOL)implementsSelector:(SEL)selector
|
|
{
|
|
if (selector == NULL)
|
|
{
|
|
[NSException raise:NSInvalidArgumentException format:@"selector cannot be NULL"];
|
|
return NO;
|
|
}
|
|
|
|
// sneaky! this calls [self class]!!
|
|
return class_getMethodImplementation([self class], selector) != (IMP)&_objc_msgForward;
|
|
}
|
|
|
|
+ (BOOL)instancesImplementSelector:(SEL)selector
|
|
{
|
|
if (selector == NULL)
|
|
{
|
|
[NSException raise:NSInvalidArgumentException format:@"selector cannot be NULL"];
|
|
return NO;
|
|
}
|
|
|
|
return class_getMethodImplementation(self, selector) != (IMP)&_objc_msgForward;
|
|
}
|
|
|
|
+ (void)forwardInvocation:(NSInvocation *)inv
|
|
{
|
|
[inv setTarget:self];
|
|
[inv invoke];
|
|
}
|
|
|
|
- (void)forwardInvocation:(NSInvocation *)inv
|
|
{
|
|
[inv setTarget:self];
|
|
[inv invoke];
|
|
}
|
|
|
|
- (void)__dealloc_zombie
|
|
{
|
|
const char *className = object_getClassName(self);
|
|
char *zombieClassName = NULL;
|
|
do {
|
|
if (asprintf(&zombieClassName, "%s%s", ZOMBIE_PREFIX, className) == -1)
|
|
{
|
|
break;
|
|
}
|
|
|
|
Class zombieClass = objc_getClass(zombieClassName);
|
|
|
|
if (zombieClass == Nil)
|
|
{
|
|
zombieClass = objc_duplicateClass(objc_getClass(ZOMBIE_PREFIX), zombieClassName, 0);
|
|
}
|
|
|
|
if (zombieClass == Nil)
|
|
{
|
|
break;
|
|
}
|
|
|
|
objc_destructInstance(self);
|
|
|
|
object_setClass(self, zombieClass);
|
|
|
|
} while (0);
|
|
|
|
if (zombieClassName != NULL)
|
|
{
|
|
free(zombieClassName);
|
|
}
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation NSObject (NSCoderMethods)
|
|
|
|
- (BOOL)_allowsDirectEncoding
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
+ (NSInteger)version
|
|
{
|
|
return class_getVersion(self);
|
|
}
|
|
|
|
+ (void)setVersion:(NSInteger)aVersion
|
|
{
|
|
class_setVersion(self, aVersion);
|
|
}
|
|
|
|
- (Class)classForCoder
|
|
{
|
|
return [self class];
|
|
}
|
|
|
|
- (id)replacementObjectForCoder:(NSCoder *)aCoder
|
|
{
|
|
return self;
|
|
}
|
|
|
|
- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder
|
|
{
|
|
return self;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation NSObject (__NSIsKinds)
|
|
|
|
- (BOOL)isNSValue__
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
- (BOOL)isNSTimeZone__
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
- (BOOL)isNSString__
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
- (BOOL)isNSSet__
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
- (BOOL)isNSOrderedSet__
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
- (BOOL)isNSNumber__
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
- (BOOL)isNSDictionary__
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
- (BOOL)isNSDate__
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
- (BOOL)isNSData__
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
- (BOOL)isNSArray__
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
@end
|