@@ -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 "runtime.h" -#elif defined(OF_OLD_GNU_RUNTIME) -# import #endif #ifdef _WIN32 # include #endif @@ -76,14 +74,10 @@ #define PRE_IVAR_ALIGN ((sizeof(struct pre_ivar) + \ (__BIGGEST_ALIGNMENT__ - 1)) & ~(__BIGGEST_ALIGNMENT__ - 1)) #define PRE_IVAR ((struct pre_ivar*)(void*)((char*)self - PRE_IVAR_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; @@ -98,11 +92,11 @@ #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) && __OBJC2__) static void uncaught_exception_handler(id exception) { fprintf(stderr, "\nUnhandled exception:\n%s\n", [[exception description] UTF8String]); @@ -123,51 +117,17 @@ { enumeration_mutation_handler(object); } #endif -#if defined(HAVE_OBJC_ENUMERATIONMUTATION) && defined(OF_OLD_GNU_RUNTIME) -extern void objc_setEnumerationMutationHandler(void(*handler)(id)); -#endif - const char* _NSPrintForDebugger(id object) { 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; } @@ -188,11 +148,11 @@ stderr); abort(); } #endif -#if (defined(OF_APPLE_RUNTIME) && __OBJC2__) || defined(OF_GNU_RUNTIME) +#if (defined(OF_APPLE_RUNTIME) && __OBJC2__) objc_setUncaughtExceptionHandler(uncaught_exception_handler); #endif #ifdef HAVE_OBJC_ENUMERATIONMUTATION objc_setEnumerationMutationHandler(enumeration_mutation_handler); @@ -300,49 +260,28 @@ 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 } @@ -354,19 +293,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 || @@ -390,44 +320,10 @@ if (newImp == (IMP)0 || !class_respondsToSelector(self->isa, selector)) @throw [OFInvalidArgumentException exceptionWithClass: self selector: _cmd]; return objc_replace_class_method(self, selector, newImp); -#elif defined(OF_OLD_GNU_RUNTIME) - Method_t method; - MethodList_t iter; - - method = class_get_class_method(self->class_pointer, selector); - - if (newImp == (IMP)0 || method == METHOD_NULL) - @throw [OFInvalidArgumentException exceptionWithClass: self - selector: _cmd]; - - for (iter = ((Class)self->class_pointer)->methods; iter != NULL; - iter = iter->method_next) { - int i; - - for (i = 0; i < iter->method_count; i++) - if (sel_eq(iter->method_list[i].method_name, - selector)) { - IMP oldImp; - - oldImp = iter->method_list[i].method_imp; - iter->method_list[i].method_imp = newImp; - - __objc_update_dispatch_table_for_class( - (Class)self->class_pointer); - - return oldImp; - } - } - - assert([self addClassMethod: selector - withTypeEncoding: method->method_types - implementation: newImp]); - - return (IMP)0; #else Method method; if (newImp == (IMP)0 || (method = class_getClassMethod(self, selector)) == NULL) @@ -465,43 +361,10 @@ if (newImp == (IMP)0 || !class_respondsToSelector(self, selector)) @throw [OFInvalidArgumentException exceptionWithClass: self selector: _cmd]; return objc_replace_instance_method(self, selector, newImp); -#elif defined(OF_OLD_GNU_RUNTIME) - Method_t method; - MethodList_t iter; - - method = class_get_instance_method(self, selector); - - if (newImp == (IMP)0 || method == METHOD_NULL) - @throw [OFInvalidArgumentException exceptionWithClass: self - selector: _cmd]; - - for (iter = ((Class)self)->methods; iter != NULL; - iter = iter->method_next) { - int i; - - for (i = 0; i < iter->method_count; i++) - if (sel_eq(iter->method_list[i].method_name, - selector)) { - IMP oldImp; - - oldImp = iter->method_list[i].method_imp; - iter->method_list[i].method_imp = newImp; - - __objc_update_dispatch_table_for_class(self); - - return oldImp; - } - } - - assert([self addInstanceMethod: selector - withTypeEncoding: method->method_types - implementation: newImp]); - - return (IMP)0; #else Method method; if (newImp == (IMP)0 || (method = class_getInstanceMethod(self, selector)) == NULL) @@ -530,88 +393,22 @@ + (BOOL)addInstanceMethod: (SEL)selector withTypeEncoding: (const char*)typeEncoding implementation: (IMP)implementation { -#if defined(OF_APPLE_RUNTIME) || defined(OF_GNU_RUNTIME) +#if defined(OF_APPLE_RUNTIME) return class_addMethod(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)) - return NO; - } - - 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 YES; -#else - @throw [OFNotImplementedException exceptionWithClass: self - selector: _cmd]; #endif } + (BOOL)addClassMethod: (SEL)selector withTypeEncoding: (const char*)typeEncoding implementation: (IMP)implementation { -#if defined(OF_APPLE_RUNTIME) || defined(OF_GNU_RUNTIME) +#if defined(OF_APPLE_RUNTIME) return class_addMethod(((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)) - return NO; - } - - 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 YES; -#else - @throw [OFNotImplementedException exceptionWithClass: self - selector: _cmd]; #endif } + (void)inheritMethodsFromClass: (Class)class { @@ -618,11 +415,11 @@ 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 { @@ -682,76 +479,12 @@ } } } @finally { free(methodList); } -#elif defined(OF_OLD_GNU_RUNTIME) - MethodList_t methodList; - - for (methodList = class->class_pointer->methods; - methodList != NULL; methodList = methodList->method_next) { - int i; - - for (i = 0; i < methodList->method_count; i++) { - SEL selector = methodList->method_list[i].method_name; - IMP implementation; - - /* - * Don't replace methods implemented in receiving class. - */ - if ([self methodForSelector: selector] != - [superclass methodForSelector: selector]) - continue; - - implementation = [class methodForSelector: selector]; - - if ([self respondsToSelector: selector]) - [self setImplementation: implementation - forClassMethod: selector]; - else { - const char *typeEncoding = - methodList->method_list[i].method_types; - [self addClassMethod: selector - withTypeEncoding: typeEncoding - implementation: implementation]; - } - } - } - - for (methodList = class->methods; methodList != NULL; - methodList = methodList->method_next) { - int i; - - for (i = 0; i < methodList->method_count; i++) { - SEL selector = methodList->method_list[i].method_name; - IMP implementation; - - /* - * Don't replace methods implemented in receiving class. - */ - if ([self instanceMethodForSelector: selector] != - [superclass instanceMethodForSelector: selector]) - continue; - - implementation = - [class instanceMethodForSelector: selector]; - - if ([self instancesRespondToSelector: selector]) - [self setImplementation: implementation - forInstanceMethod: selector]; - else { - const char *typeEncoding = - methodList->method_list[i].method_types; - [self addInstanceMethod: selector - withTypeEncoding: typeEncoding - implementation: implementation]; - } - } - } #else - @throw [OFNotImplementedException exceptionWithClass: self - selector: _cmd]; + /* FIXME */ #endif [self inheritMethodsFromClass: [class superclass]]; } @@ -787,28 +520,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) +#if defined(OF_OBJFW_RUNTIME) return objc_msg_lookup(self, selector); #else return class_getMethodImplementation(isa, selector); #endif } @@ -847,19 +573,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 ||