@@ -38,16 +38,14 @@ #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "macros.h" -#if (defined(OF_APPLE_RUNTIME) && __OBJC2__) || defined(OF_GNU_RUNTIME) +#if defined(OF_APPLE_RUNTIME) && __OBJC2__ # import #elif defined(OF_OBJFW_RUNTIME) -# import -#elif defined(OF_OLD_GNU_RUNTIME) -# import +# import "runtime.h" #endif #ifdef _WIN32 # include #endif @@ -79,14 +77,10 @@ #define PRE_MEM_ALIGN ((sizeof(struct pre_mem) + \ (__BIGGEST_ALIGNMENT__ - 1)) & ~(__BIGGEST_ALIGNMENT__ - 1)) #define PRE_MEM(mem) ((struct pre_mem*)(void*)((char*)mem - PRE_MEM_ALIGN)) -#ifdef OF_OLD_GNU_RUNTIME -extern void __objc_update_dispatch_table_for_class(Class); -#endif - static struct { Class isa; } alloc_failed_exception; static Class autoreleasePool = Nil; @@ -94,19 +88,16 @@ static SEL cxx_destruct = NULL; size_t of_pagesize; size_t of_num_cpus; -#ifdef NEED_OBJC_SYNC_INIT +#ifdef OF_OBJFW_RUNTIME extern BOOL objc_sync_init(); -#endif - -#ifdef NEED_OBJC_PROPERTIES_INIT extern BOOL objc_properties_init(); #endif -#if (defined(OF_APPLE_RUNTIME) && __OBJC2__) || defined(OF_GNU_RUNTIME) +#if !defined(OF_APPLE_RUNTIME) || defined(__OBJC2__) static void uncaught_exception_handler(id exception) { fprintf(stderr, "\nUnhandled exception:\n%s\n", [[exception description] UTF8String]); @@ -127,14 +118,10 @@ { enumeration_mutation_handler(object); } #endif -#if defined(HAVE_OBJC_ENUMERATIONMUTATION) && defined(OF_OLD_GNU_RUNTIME) -extern void objc_setEnumerationMutationHandler(void(*handler)(id)); -#endif - id of_alloc_object(Class class, size_t extraSize, size_t extraAlignment, void **extra) { OFObject *instance; @@ -184,65 +171,33 @@ { return [[object description] cStringWithEncoding: OF_STRING_ENCODING_NATIVE]; } -#ifdef OF_OLD_GNU_RUNTIME -static BOOL -protocol_conformsToProtocol(Protocol *a, Protocol *b) -{ - /* - * This function is an ugly workaround for a bug that only happens with - * Clang 2.9 together with the libobjc from GCC 4.6. - * Since the instance variables of Protocol are @private, we have to - * cast them to a struct here in order to access them. - */ - struct objc_protocol { - Class isa; - const char *protocol_name; - struct objc_protocol_list *protocol_list; - } *pa = (struct objc_protocol*)a, *pb = (struct objc_protocol*)b; - struct objc_protocol_list *pl; - size_t i; - - if (!strcmp(pa->protocol_name, pb->protocol_name)) - return YES; - - for (pl = pa->protocol_list; pl != NULL; pl = pl->next) - for (i = 0; i < pl->count; i++) - if (protocol_conformsToProtocol(pl->list[i], b)) - return YES; - - return NO; -} -#endif - /* References for static linking */ void _references_to_categories_of_OFObject(void) { _OFObject_Serialization_reference = 1; } @implementation OFObject + (void)load { -#ifdef NEED_OBJC_SYNC_INIT +#ifdef OF_OBJFW_RUNTIME if (!objc_sync_init()) { fputs("Runtime error: objc_sync_init() failed!\n", stderr); abort(); } -#endif -#ifdef NEED_OBJC_PROPERTIES_INIT if (!objc_properties_init()) { fputs("Runtime error: objc_properties_init() failed!\n", stderr); abort(); } #endif -#if (defined(OF_APPLE_RUNTIME) && __OBJC2__) || defined(OF_GNU_RUNTIME) +#if !defined(OF_APPLE_RUNTIME) || defined(__OBJC2__) objc_setUncaughtExceptionHandler(uncaught_exception_handler); #endif #ifdef HAVE_OBJC_ENUMERATIONMUTATION objc_setEnumerationMutationHandler(enumeration_mutation_handler); @@ -314,52 +269,27 @@ return class_getSuperclass(self); } + (BOOL)instancesRespondToSelector: (SEL)selector { -#ifdef OF_OLD_GNU_RUNTIME - return class_get_instance_method(self, selector) != METHOD_NULL; -#else return class_respondsToSelector(self, selector); -#endif } + (BOOL)conformsToProtocol: (Protocol*)protocol { -#ifdef OF_OLD_GNU_RUNTIME - Class c; - struct objc_protocol_list *pl; - size_t i; - - for (c = self; c != Nil; c = class_get_super_class(c)) - for (pl = c->protocols; pl != NULL; pl = pl->next) - for (i = 0; i < pl->count; i++) - if (protocol_conformsToProtocol(pl->list[i], - protocol)) - return YES; - - return NO; -#else Class c; for (c = self; c != Nil; c = class_getSuperclass(c)) if (class_conformsToProtocol(c, protocol)) return YES; return NO; -#endif } + (IMP)instanceMethodForSelector: (SEL)selector { -#if defined(OF_OBJFW_RUNTIME) - return objc_get_instance_method(self, selector); -#elif defined(OF_OLD_GNU_RUNTIME) - return method_get_imp(class_get_instance_method(self, selector)); -#else return class_getMethodImplementation(self, selector); -#endif } + (const char*)typeEncodingForInstanceSelector: (SEL)selector { #if defined(OF_OBJFW_RUNTIME) @@ -368,19 +298,10 @@ if ((ret = objc_get_type_encoding(self, selector)) == NULL) @throw [OFNotImplementedException exceptionWithClass: self selector: selector]; return ret; -#elif defined(OF_OLD_GNU_RUNTIME) - Method_t m; - - if ((m = class_get_instance_method(self, selector)) == NULL || - m->method_types == NULL) - @throw [OFNotImplementedException exceptionWithClass: self - selector: selector]; - - return m->method_types; #else Method m; const char *ret; if ((m = class_getInstanceMethod(self, selector)) == NULL || @@ -427,121 +348,30 @@ + (IMP)replaceInstanceMethod: (SEL)selector withImplementation: (IMP)implementation typeEncoding: (const char*)typeEncoding { -#if defined(OF_APPLE_RUNTIME) || defined(OF_GNU_RUNTIME) return class_replaceMethod(self, selector, implementation, typeEncoding); -#elif defined(OF_OLD_GNU_RUNTIME) - MethodList_t methodList; - - for (methodList = ((Class)self)->methods; methodList != NULL; - methodList = methodList->method_next) { - int i; - - for (i = 0; i < methodList->method_count; i++) { - if (sel_eq(methodList->method_list[i].method_name, - selector)) { - IMP oldImp; - oldImp = methodList->method_list[i].method_imp; - - methodList->method_list[i].method_imp = - implementation; - - __objc_update_dispatch_table_for_class(self); - - return oldImp; - } - } - } - - if ((methodList = malloc(sizeof(*methodList))) == NULL) - @throw [OFOutOfMemoryException - exceptionWithClass: self - requestedSize: sizeof(*methodList)]; - - methodList->method_next = ((Class)self)->methods; - methodList->method_count = 1; - - methodList->method_list[0].method_name = selector; - methodList->method_list[0].method_types = typeEncoding; - methodList->method_list[0].method_imp = implementation; - - ((Class)self)->methods = methodList; - - __objc_update_dispatch_table_for_class(self); - - return (IMP)nil; -#else - @throw [OFNotImplementedException exceptionWithClass: self - selector: _cmd]; -#endif } + (IMP)replaceClassMethod: (SEL)selector withImplementation: (IMP)implementation typeEncoding: (const char*)typeEncoding { -#if defined(OF_APPLE_RUNTIME) || defined(OF_GNU_RUNTIME) return class_replaceMethod(((OFObject*)self)->isa, selector, implementation, typeEncoding); -#elif defined(OF_OLD_GNU_RUNTIME) - MethodList_t methodList; - - for (methodList = ((Class)self->class_pointer)->methods; - methodList != NULL; methodList = methodList->method_next) { - int i; - - for (i = 0; i < methodList->method_count; i++) { - if (sel_eq(methodList->method_list[i].method_name, - selector)) { - IMP oldImp; - oldImp = methodList->method_list[i].method_imp; - - methodList->method_list[i].method_imp = - implementation; - - __objc_update_dispatch_table_for_class( - (Class)self->class_pointer); - - return oldImp; - } - } - } - - if ((methodList = malloc(sizeof(*methodList))) == NULL) - @throw [OFOutOfMemoryException - exceptionWithClass: self - requestedSize: sizeof(*methodList)]; - - methodList->method_next = ((Class)self->class_pointer)->methods; - methodList->method_count = 1; - - methodList->method_list[0].method_name = selector; - methodList->method_list[0].method_types = typeEncoding; - methodList->method_list[0].method_imp = implementation; - - ((Class)self->class_pointer)->methods = methodList; - - __objc_update_dispatch_table_for_class((Class)self->class_pointer); - - return (IMP)nil; -#else - @throw [OFNotImplementedException exceptionWithClass: self - selector: _cmd]; -#endif } + (void)inheritMethodsFromClass: (Class)class { Class superclass = [self superclass]; if ([self isSubclassOfClass: class]) return; -#if defined(OF_APPLE_RUNTIME) || defined(OF_GNU_RUNTIME) +#if defined(OF_APPLE_RUNTIME) Method *methodList; unsigned i, count; methodList = class_copyMethodList(((OFObject*)class)->isa, &count); @try { @@ -578,19 +408,19 @@ withMethodFromClass: class]; } } @finally { free(methodList); } -#elif defined(OF_OLD_GNU_RUNTIME) - MethodList_t methodList; +#elif defined(OF_OBJFW_RUNTIME) + struct objc_method_list *methodlist; - for (methodList = class->class_pointer->methods; - methodList != NULL; methodList = methodList->method_next) { + for (methodlist = class->isa->methodlist; + methodlist != NULL; methodlist = methodlist->next) { int i; - for (i = 0; i < methodList->method_count; i++) { - SEL selector = methodList->method_list[i].method_name; + for (i = 0; i < methodlist->count; i++) { + SEL selector = (SEL)&methodlist->methods[i].sel; /* * Don't replace methods implemented in receiving class. */ if ([self methodForSelector: selector] != @@ -600,16 +430,16 @@ [self replaceClassMethod: selector withMethodFromClass: class]; } } - for (methodList = class->methods; methodList != NULL; - methodList = methodList->method_next) { + for (methodlist = class->methodlist; methodlist != NULL; + methodlist = methodlist->next) { int i; - for (i = 0; i < methodList->method_count; i++) { - SEL selector = methodList->method_list[i].method_name; + for (i = 0; i < methodlist->count; i++) { + SEL selector = (SEL)&methodlist->methods[i].sel; /* * Don't replace methods implemented in receiving class. */ if ([self instanceMethodForSelector: selector] != @@ -618,13 +448,10 @@ [self replaceInstanceMethod: selector withMethodFromClass: class]; } } -#else - @throw [OFNotImplementedException exceptionWithClass: self - selector: _cmd]; #endif [self inheritMethodsFromClass: [class superclass]]; } @@ -676,32 +503,21 @@ return (isa == class); } - (BOOL)respondsToSelector: (SEL)selector { -#ifdef OF_OLD_GNU_RUNTIME - if (object_is_instance(self)) - return class_get_instance_method(isa, selector) != METHOD_NULL; - else - return class_get_class_method(isa, selector) != METHOD_NULL; -#else return class_respondsToSelector(isa, selector); -#endif } - (BOOL)conformsToProtocol: (Protocol*)protocol { return [isa conformsToProtocol: protocol]; } - (IMP)methodForSelector: (SEL)selector { -#if defined(OF_OBJFW_RUNTIME) || defined(OF_OLD_GNU_RUNTIME) - return objc_msg_lookup(self, selector); -#else return class_getMethodImplementation(isa, selector); -#endif } - (id)performSelector: (SEL)selector { id (*imp)(id, SEL) = (id(*)(id, SEL))[self methodForSelector: selector]; @@ -736,19 +552,10 @@ if ((ret = objc_get_type_encoding(isa, selector)) == NULL) @throw [OFNotImplementedException exceptionWithClass: isa selector: selector]; return ret; -#elif defined(OF_OLD_GNU_RUNTIME) - Method_t m; - - if ((m = class_get_instance_method(isa, selector)) == NULL || - m->method_types == NULL) - @throw [OFNotImplementedException exceptionWithClass: isa - selector: selector]; - - return m->method_types; #else Method m; const char *ret; if ((m = class_getInstanceMethod(isa, selector)) == NULL || @@ -943,11 +750,11 @@ - autorelease { /* * Cache OFAutoreleasePool since class lookups are expensive with the - * GNU runtime. + * GNU ABI. */ if (autoreleasePool == Nil) autoreleasePool = [OFAutoreleasePool class]; [autoreleasePool addObject: self];