mirror of
https://github.com/darlinghq/darling-objc4.git
synced 2024-10-07 01:23:27 +00:00
Fix Building For i386/Non-OBJC2
This commit is contained in:
parent
09e9e2f56c
commit
5a22f74c04
@ -46,6 +46,14 @@ extern "C" {
|
||||
#include <os/variant_private.h>
|
||||
}
|
||||
|
||||
#ifdef DARLING
|
||||
#if __OBJC2__
|
||||
#define DARLING_GET_SUPER_CLASS getSuperclass()
|
||||
#else
|
||||
#define DARLING_GET_SUPER_CLASS superclass
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@interface NSInvocation
|
||||
- (SEL)selector;
|
||||
@end
|
||||
@ -572,7 +580,11 @@ objc_loadWeakRetained(id *location)
|
||||
// callout with the lock held.
|
||||
if (cls->isInitialized() || _thisThreadIsInitializingClass(cls)) {
|
||||
BOOL (*tryRetain)(id, SEL) = (BOOL(*)(id, SEL))
|
||||
#if defined(DARLING) && defined(__i386__)
|
||||
class_getMethodImplementation(cls, @selector(retainWeakReference));
|
||||
#else
|
||||
lookUpImpOrForwardTryCache(obj, @selector(retainWeakReference), cls);
|
||||
#endif
|
||||
if ((IMP)tryRetain == _objc_msgForward) {
|
||||
result = nil;
|
||||
}
|
||||
@ -2013,7 +2025,7 @@ objc_opt_isKindOfClass(id obj, Class otherClass)
|
||||
if (slowpath(!obj)) return NO;
|
||||
Class cls = obj->getIsa();
|
||||
if (fastpath(!cls->hasCustomCore())) {
|
||||
for (Class tcls = cls; tcls; tcls = tcls->getSuperclass()) {
|
||||
for (Class tcls = cls; tcls; tcls = tcls->DARLING_GET_SUPER_CLASS) {
|
||||
if (tcls == otherClass) return YES;
|
||||
}
|
||||
return NO;
|
||||
@ -2266,11 +2278,11 @@ NONLAZY_CLASS_LOAD
|
||||
}
|
||||
|
||||
+ (Class)superclass {
|
||||
return self->getSuperclass();
|
||||
return self->DARLING_GET_SUPER_CLASS;
|
||||
}
|
||||
|
||||
- (Class)superclass {
|
||||
return [self class]->getSuperclass();
|
||||
return [self class]->DARLING_GET_SUPER_CLASS;
|
||||
}
|
||||
|
||||
+ (BOOL)isMemberOfClass:(Class)cls {
|
||||
@ -2282,28 +2294,28 @@ NONLAZY_CLASS_LOAD
|
||||
}
|
||||
|
||||
+ (BOOL)isKindOfClass:(Class)cls {
|
||||
for (Class tcls = self->ISA(); tcls; tcls = tcls->getSuperclass()) {
|
||||
for (Class tcls = self->ISA(); tcls; tcls = tcls->DARLING_GET_SUPER_CLASS) {
|
||||
if (tcls == cls) return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isKindOfClass:(Class)cls {
|
||||
for (Class tcls = [self class]; tcls; tcls = tcls->getSuperclass()) {
|
||||
for (Class tcls = [self class]; tcls; tcls = tcls->DARLING_GET_SUPER_CLASS) {
|
||||
if (tcls == cls) return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL)isSubclassOfClass:(Class)cls {
|
||||
for (Class tcls = self; tcls; tcls = tcls->getSuperclass()) {
|
||||
for (Class tcls = self; tcls; tcls = tcls->DARLING_GET_SUPER_CLASS) {
|
||||
if (tcls == cls) return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL)isAncestorOfObject:(NSObject *)obj {
|
||||
for (Class tcls = [obj class]; tcls; tcls = tcls->getSuperclass()) {
|
||||
for (Class tcls = [obj class]; tcls; tcls = tcls->DARLING_GET_SUPER_CLASS) {
|
||||
if (tcls == self) return YES;
|
||||
}
|
||||
return NO;
|
||||
@ -2323,7 +2335,7 @@ NONLAZY_CLASS_LOAD
|
||||
|
||||
+ (BOOL)conformsToProtocol:(Protocol *)protocol {
|
||||
if (!protocol) return NO;
|
||||
for (Class tcls = self; tcls; tcls = tcls->getSuperclass()) {
|
||||
for (Class tcls = self; tcls; tcls = tcls->DARLING_GET_SUPER_CLASS) {
|
||||
if (class_conformsToProtocol(tcls, protocol)) return YES;
|
||||
}
|
||||
return NO;
|
||||
@ -2331,7 +2343,7 @@ NONLAZY_CLASS_LOAD
|
||||
|
||||
- (BOOL)conformsToProtocol:(Protocol *)protocol {
|
||||
if (!protocol) return NO;
|
||||
for (Class tcls = [self class]; tcls; tcls = tcls->getSuperclass()) {
|
||||
for (Class tcls = [self class]; tcls; tcls = tcls->DARLING_GET_SUPER_CLASS) {
|
||||
if (class_conformsToProtocol(tcls, protocol)) return YES;
|
||||
}
|
||||
return NO;
|
||||
|
@ -336,7 +336,11 @@ static void _class_resolveClassMethod(id inst, SEL sel, Class cls)
|
||||
ASSERT(cls->isMetaClass());
|
||||
SEL resolve_sel = @selector(resolveClassMethod:);
|
||||
|
||||
#if defined(DARLING) && defined(__i386__)
|
||||
if (!lookUpImpOrNil(inst, resolve_sel, cls)) {
|
||||
#else
|
||||
if (!lookUpImpOrNilTryCache(inst, resolve_sel, cls)) {
|
||||
#endif
|
||||
// Resolver not implemented.
|
||||
return;
|
||||
}
|
||||
@ -346,7 +350,11 @@ static void _class_resolveClassMethod(id inst, SEL sel, Class cls)
|
||||
|
||||
// Cache the result (good or bad) so the resolver doesn't fire next time.
|
||||
// +resolveClassMethod adds to self->ISA() a.k.a. cls
|
||||
#if defined(DARLING) && defined(__i386__)
|
||||
IMP imp = lookUpImpOrNil(inst, sel, cls);
|
||||
#else
|
||||
IMP imp = lookUpImpOrNilTryCache(inst, sel, cls);
|
||||
#endif
|
||||
if (resolved && PrintResolving) {
|
||||
if (imp) {
|
||||
_objc_inform("RESOLVE: method %c[%s %s] "
|
||||
@ -376,7 +384,11 @@ static void _class_resolveInstanceMethod(id inst, SEL sel, Class cls)
|
||||
{
|
||||
SEL resolve_sel = @selector(resolveInstanceMethod:);
|
||||
|
||||
#if defined(DARLING) && defined(__i386__)
|
||||
if (! lookUpImpOrNil(cls, resolve_sel, cls->ISA())) {
|
||||
#else
|
||||
if (! lookUpImpOrNilTryCache(cls, resolve_sel, cls->ISA())) {
|
||||
#endif
|
||||
// Resolver not implemented.
|
||||
return;
|
||||
}
|
||||
@ -386,7 +398,11 @@ static void _class_resolveInstanceMethod(id inst, SEL sel, Class cls)
|
||||
|
||||
// Cache the result (good or bad) so the resolver doesn't fire next time.
|
||||
// +resolveInstanceMethod adds to self a.k.a. cls
|
||||
#if defined(DARLING) && defined(__i386__)
|
||||
IMP imp = lookUpImpOrNil(inst, sel, cls);
|
||||
#else
|
||||
IMP imp = lookUpImpOrNilTryCache(inst, sel, cls);
|
||||
#endif
|
||||
|
||||
if (resolved && PrintResolving) {
|
||||
if (imp) {
|
||||
@ -424,7 +440,11 @@ _class_resolveMethod(id inst, SEL sel, Class cls)
|
||||
// try [nonMetaClass resolveClassMethod:sel]
|
||||
// and [cls resolveInstanceMethod:sel]
|
||||
_class_resolveClassMethod(inst, sel, cls);
|
||||
#if defined(DARLING) && defined(__i386__)
|
||||
if (!lookUpImpOrNil(inst, sel, cls)) {
|
||||
#else
|
||||
if (!lookUpImpOrNilTryCache(inst, sel, cls)) {
|
||||
#endif
|
||||
_class_resolveInstanceMethod(inst, sel, cls);
|
||||
}
|
||||
}
|
||||
@ -475,7 +495,11 @@ IMP lookUpImpOrForward(id inst, SEL sel, Class cls, int behavior)
|
||||
methodListLock.assertUnlocked();
|
||||
|
||||
// Optimistic cache lookup
|
||||
#ifdef DARLING
|
||||
if ((behavior & LOOKUP_NOCACHE) == 0) {
|
||||
#else
|
||||
if (behavior & LOOKUP_CACHE) {
|
||||
#endif
|
||||
methodPC = _cache_getImp(cls, sel);
|
||||
if (methodPC) goto out_nolock;
|
||||
}
|
||||
@ -2442,7 +2466,11 @@ void *objc_destructInstance(id obj)
|
||||
}
|
||||
|
||||
if (isa->instancesHaveAssociatedObjects()) {
|
||||
#ifdef DARLING
|
||||
_object_remove_assocations(obj,false);
|
||||
#else
|
||||
_object_remove_assocations(obj);
|
||||
#endif
|
||||
}
|
||||
|
||||
objc_clear_deallocating(obj);
|
||||
|
@ -163,6 +163,14 @@
|
||||
#include <os/linker_set.h>
|
||||
#endif
|
||||
|
||||
#ifdef DARLING
|
||||
#if __OBJC2__
|
||||
#define DARLING_GET_SUPER_CLASS getSuperclass()
|
||||
#else
|
||||
#define DARLING_GET_SUPER_CLASS superclass
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* Information about multi-thread support:
|
||||
*
|
||||
@ -200,7 +208,11 @@ Class object_setClass(id obj, Class cls)
|
||||
if (!cls->isFuture() && !cls->isInitialized()) {
|
||||
// use lookUpImpOrNilTryCache to indirectly provoke +initialize
|
||||
// to avoid duplicating the code to actually send +initialize
|
||||
#if defined(DARLING) && defined(__i386__)
|
||||
lookUpImpOrNil(nil, @selector(initialize), cls, LOOKUP_INITIALIZE);
|
||||
#else
|
||||
lookUpImpOrNilTryCache(nil, @selector(initialize), cls, LOOKUP_INITIALIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
return obj->changeIsa(cls);
|
||||
@ -284,7 +296,7 @@ _class_lookUpIvar(Class cls, Ivar ivar, ptrdiff_t& ivarOffset,
|
||||
// Preflight the hasAutomaticIvars check
|
||||
// because _class_getClassForIvar() may need to take locks.
|
||||
bool hasAutomaticIvars = NO;
|
||||
for (Class c = cls; c; c = c->getSuperclass()) {
|
||||
for (Class c = cls; c; c = c->DARLING_GET_SUPER_CLASS) {
|
||||
if (c->hasAutomaticIvars()) {
|
||||
hasAutomaticIvars = YES;
|
||||
break;
|
||||
@ -443,7 +455,7 @@ static void object_cxxDestructFromClass(id obj, Class cls)
|
||||
|
||||
// Call cls's dtor first, then superclasses's dtors.
|
||||
|
||||
for ( ; cls; cls = cls->getSuperclass()) {
|
||||
for ( ; cls; cls = cls->DARLING_GET_SUPER_CLASS) {
|
||||
if (!cls->hasCxxDtor()) return;
|
||||
dtor = (void(*)(id))
|
||||
lookupMethodInClassAndLoadCache(cls, SEL_cxx_destruct);
|
||||
@ -493,7 +505,7 @@ object_cxxConstructFromClass(id obj, Class cls, int flags)
|
||||
id (*ctor)(id);
|
||||
Class supercls;
|
||||
|
||||
supercls = cls->getSuperclass();
|
||||
supercls = cls->DARLING_GET_SUPER_CLASS;
|
||||
|
||||
// Call superclasses' ctors first, if any.
|
||||
if (supercls && supercls->hasCxxCtor()) {
|
||||
@ -512,7 +524,7 @@ object_cxxConstructFromClass(id obj, Class cls, int flags)
|
||||
}
|
||||
if (fastpath((*ctor)(obj))) return obj; // ctor called and succeeded - ok
|
||||
|
||||
supercls = cls->getSuperclass(); // this reload avoids a spill on the stack
|
||||
supercls = cls->DARLING_GET_SUPER_CLASS; // this reload avoids a spill on the stack
|
||||
|
||||
// This class's ctor was called and failed.
|
||||
// Call superclasses's dtors to clean up.
|
||||
@ -532,7 +544,7 @@ object_cxxConstructFromClass(id obj, Class cls, int flags)
|
||||
**********************************************************************/
|
||||
void fixupCopiedIvars(id newObject, id oldObject)
|
||||
{
|
||||
for (Class cls = oldObject->ISA(); cls; cls = cls->getSuperclass()) {
|
||||
for (Class cls = oldObject->ISA(); cls; cls = cls->DARLING_GET_SUPER_CLASS) {
|
||||
if (cls->hasAutomaticIvars()) {
|
||||
// Use alignedInstanceStart() because unaligned bytes at the start
|
||||
// of this class's ivars are not represented in the layout bitmap.
|
||||
@ -643,7 +655,11 @@ class_respondsToSelector_inst(id inst, SEL sel, Class cls)
|
||||
{
|
||||
// Avoids +initialize because it historically did so.
|
||||
// We're not returning a callable IMP anyway.
|
||||
#if defined(DARLING) && defined(__i386__)
|
||||
return sel && cls && lookUpImpOrNil(inst, sel, cls, LOOKUP_RESOLVER);
|
||||
#else
|
||||
return sel && cls && lookUpImpOrNilTryCache(inst, sel, cls, LOOKUP_RESOLVER);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -673,7 +689,11 @@ IMP class_getMethodImplementation(Class cls, SEL sel)
|
||||
|
||||
lockdebug_assert_no_locks_locked_except({ &loadMethodLock });
|
||||
|
||||
#if defined(DARLING) && defined(__i386__)
|
||||
imp = lookUpImpOrNil(nil, sel, cls, LOOKUP_INITIALIZE | LOOKUP_RESOLVER);
|
||||
#else
|
||||
imp = lookUpImpOrNilTryCache(nil, sel, cls, LOOKUP_INITIALIZE | LOOKUP_RESOLVER);
|
||||
#endif
|
||||
|
||||
// Translate forwarding function to C-callable external version
|
||||
if (!imp) {
|
||||
@ -780,7 +800,7 @@ Class _calloc_class(size_t size)
|
||||
Class class_getSuperclass(Class cls)
|
||||
{
|
||||
if (!cls) return nil;
|
||||
return cls->getSuperclass();
|
||||
return cls->DARLING_GET_SUPER_CLASS;
|
||||
}
|
||||
|
||||
BOOL class_isMetaClass(Class cls)
|
||||
|
@ -97,6 +97,15 @@
|
||||
#include "objc-initialize.h"
|
||||
#include "DenseMapExtras.h"
|
||||
|
||||
#ifdef DARLING
|
||||
#if __OBJC2__
|
||||
#define DARLING_GET_SUPER_CLASS getSuperclass()
|
||||
#else
|
||||
#define DARLING_GET_SUPER_CLASS superclass
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* classInitLock protects CLS_INITIALIZED and CLS_INITIALIZING, and
|
||||
* is signalled when any class is done initializing.
|
||||
* Threads that are waiting for a class to finish initializing wait on this. */
|
||||
@ -396,10 +405,15 @@ static bool classHasTrivialInitialize(Class cls)
|
||||
{
|
||||
if (cls->isRootClass() || cls->isRootMetaclass()) return true;
|
||||
|
||||
Class rootCls = cls->ISA()->ISA()->getSuperclass();
|
||||
Class rootCls = cls->ISA()->ISA()->DARLING_GET_SUPER_CLASS;
|
||||
|
||||
#if defined(DARLING) && defined(__i386__)
|
||||
IMP rootImp = lookUpImpOrNil(rootCls, @selector(initialize), rootCls->ISA());
|
||||
IMP imp = lookUpImpOrNil(cls, @selector(initialize), cls->ISA());
|
||||
#else
|
||||
IMP rootImp = lookUpImpOrNilTryCache(rootCls, @selector(initialize), rootCls->ISA());
|
||||
IMP imp = lookUpImpOrNilTryCache(cls, @selector(initialize), cls->ISA());
|
||||
#endif
|
||||
return (imp == nil || imp == (IMP)&objc_noop_imp || imp == rootImp);
|
||||
}
|
||||
|
||||
@ -500,7 +514,7 @@ void initializeNonMetaClass(Class cls)
|
||||
|
||||
// Make sure super is done initializing BEFORE beginning to initialize cls.
|
||||
// See note about deadlock above.
|
||||
supercls = cls->getSuperclass();
|
||||
supercls = cls->DARLING_GET_SUPER_CLASS;
|
||||
if (supercls && !supercls->isInitialized()) {
|
||||
initializeNonMetaClass(supercls);
|
||||
}
|
||||
|
@ -609,6 +609,14 @@ extern IMP lookUpImpOrForward(id obj, SEL, Class cls, int behavior);
|
||||
extern IMP lookUpImpOrForwardTryCache(id obj, SEL, Class cls, int behavior = 0);
|
||||
extern IMP lookUpImpOrNilTryCache(id obj, SEL, Class cls, int behavior = 0);
|
||||
|
||||
#ifdef DARLING
|
||||
static inline IMP
|
||||
lookUpImpOrNil(id obj, SEL sel, Class cls, int behavior = 0)
|
||||
{
|
||||
return lookUpImpOrForward(obj, sel, cls, behavior | LOOKUP_NIL);
|
||||
}
|
||||
#endif
|
||||
|
||||
extern IMP lookupMethodInClassAndLoadCache(Class cls, SEL sel);
|
||||
|
||||
struct IMPAndSEL {
|
||||
|
@ -407,9 +407,16 @@ weak_register_no_lock(weak_table_t *weak_table, id referent_id,
|
||||
// Use lookUpImpOrForward so we can avoid the assert in
|
||||
// class_getInstanceMethod, since we intentionally make this
|
||||
// callout with the lock held.
|
||||
#if defined(DARLING) && defined(__i386__)
|
||||
BOOL (*allowsWeakReference)(objc_object *, SEL) =
|
||||
(BOOL(*)(objc_object *, SEL))
|
||||
object_getMethodImplementation((id)referent,
|
||||
@selector(allowsWeakReference));
|
||||
#else
|
||||
auto allowsWeakReference = (BOOL(*)(objc_object *, SEL))
|
||||
lookUpImpOrForwardTryCache((id)referent, @selector(allowsWeakReference),
|
||||
referent->getIsa());
|
||||
#endif
|
||||
if ((IMP)allowsWeakReference == _objc_msgForward) {
|
||||
return nil;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user