Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -10,11 +10,11 @@ AC_PROG_INSTALL AC_PROG_EGREP CPP="$OBJCPP" CPPFLAGS="$CPPFLAGS $OBJCPPFLAGS" -OBJCFLAGS="$OBJCFLAGS -Wall -fexceptions" +OBJCFLAGS="$OBJCFLAGS -Wall -fexceptions -fobjc-exceptions" OBJCFLAGS="$OBJCFLAGS -fconstant-string-class=OFConstantString" AX_CHECK_COMPILER_FLAGS(-pipe, [OBJCFLAGS="$OBJCFLAGS -pipe"]) AX_CHECK_COMPILER_FLAGS(-fno-common, [OBJCFLAGS="$OBJCFLAGS -fno-common"]) AX_CHECK_COMPILER_FLAGS(-fno-constant-cfstrings, [ @@ -85,20 +85,29 @@ AC_CHECK_HEADERS([objfw-rt.h objc/objc.h]) test x"$ac_cv_header_objfw_rt_h" = x"yes" && objc_runtime="ObjFW-RT" AS_IF([test x"$ac_cv_header_objc_objc_h" = x"yes"], [ - dnl TODO: This is ugly. Let's think of a better check. - AC_EGREP_CPP(gnu, [ + AC_EGREP_CPP(yes, [ #import - #ifdef __objc_INCLUDE_GNU - gnu + #ifdef __GNU_LIBOBJC__ + yes #endif ], [ test x"$objc_runtime" = "x" && objc_runtime="GNU" ], [ - objc_runtime="Apple" + dnl TODO: This is ugly. Let's think of a better check. + AC_EGREP_CPP(yes, [ + #import + #ifdef __objc_INCLUDE_GNU + yes + #endif + ], [ + test x"$objc_runtime" = "x" && objc_runtime="old GNU" + ], [ + objc_runtime="Apple" + ]) ]) ]) AC_MSG_CHECKING(which Objective C runtime we use) case $objc_runtime in @@ -117,10 +126,15 @@ GNU) AC_DEFINE(OF_GNU_RUNTIME, 1, [Whether we use the GNU ObjC runtime]) LIBS="$LIBS -lobjc" ;; + "old GNU") + AC_DEFINE(OF_OLD_GNU_RUNTIME, 1, + [Whether we use the old GNU ObjC runtime]) + LIBS="$LIBS -lobjc" + ;; *) AC_MSG_RESULT(none) AC_MSG_ERROR(No ObjC runtime found! Please install ObjFW-RT!) ;; esac Index: src/OFBlock.m ================================================================== --- src/OFBlock.m +++ src/OFBlock.m @@ -26,11 +26,12 @@ @protocol RetainRelease - retain; - (void)release; @end -#if defined(OF_GNU_RUNTIME) || defined(OF_OBJFW_RUNTIME) +#if defined(OF_OBJFW_RUNTIME) || defined(OF_GNU_RUNTIME) || \ + defined(OF_OLD_GNU_RUNTIME) struct objc_abi_class { struct objc_abi_metaclass *metaclass; const char *superclass, *name; unsigned long version, info, instance_size; void *ivars, *methodlist, *dtable, *subclass_list, *sibling_class; Index: src/OFExceptions.m ================================================================== --- src/OFExceptions.m +++ src/OFExceptions.m @@ -14,16 +14,15 @@ #define _GNU_SOURCE #include #include #include -#ifdef OF_APPLE_RUNTIME +#if defined(OF_APPLE_RUNTIME) || defined(OF_GNU_RUNTIME) # import -# import #endif -#ifdef OF_GNU_RUNTIME +#ifdef OF_OLD_GNU_RUNTIME # import # define sel_getName(x) sel_get_name(x) #endif #import "OFExceptions.h" Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -23,16 +23,15 @@ #import "OFExceptions.h" #import "macros.h" #if defined(OF_OBJFW_RUNTIME) # import -#elif defined(OF_APPLE_RUNTIME) -# import -# import -#elif defined(OF_GNU_RUNTIME) +#elif defined(OF_OLD_GNU_RUNTIME) # import # import +#else +# import #endif #ifdef _WIN32 # include #endif @@ -44,11 +43,11 @@ #else # import "threading.h" #endif /* A few macros to reduce #ifdefs */ -#ifdef OF_GNU_RUNTIME +#ifdef OF_OLD_GNU_RUNTIME # define class_getInstanceSize class_get_instance_size # define class_getName class_get_class_name # define class_getSuperclass class_get_super_class #endif @@ -110,11 +109,11 @@ stderr); abort(); } #endif -#ifdef OF_APPLE_RUNTIME +#if defined(OF_APPLE_RUNTIME) || defined(OF_GNU_RUNTIME) objc_setEnumerationMutationHandler(enumeration_mutation_handler); #endif #ifndef _WIN32 if ((of_pagesize = sysconf(_SC_PAGESIZE)) < 1) @@ -184,20 +183,20 @@ return class_getSuperclass(self); } + (BOOL)instancesRespondToSelector: (SEL)selector { -#ifdef OF_GNU_RUNTIME +#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_GNU_RUNTIME +#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)) @@ -220,42 +219,42 @@ + (IMP)instanceMethodForSelector: (SEL)selector { #if defined(OF_OBJFW_RUNTIME) return objc_get_instance_method(self, selector); -#elif defined(OF_APPLE_RUNTIME) - return class_getMethodImplementation(self, selector); -#else +#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_APPLE_RUNTIME) - Method m; +#if defined(OF_OBJFW_RUNTIME) const char *ret; - if ((m = class_getInstanceMethod(self, selector)) == NULL || - (ret = method_getTypeEncoding(m)) == NULL) + if ((ret = objc_get_type_encoding(self, selector)) == NULL) @throw [OFNotImplementedException newWithClass: self selector: selector]; return ret; -#elif defined(OF_GNU_RUNTIME) +#elif defined(OF_OLD_GNU_RUNTIME) Method_t m; if ((m = class_get_instance_method(self, selector)) == NULL || m->method_types == NULL) @throw [OFNotImplementedException newWithClass: self selector: selector]; return m->method_types; -#elif defined(OF_OBJFW_RUNTIME) +#else + Method m; const char *ret; - if ((ret = objc_get_type_encoding(self, selector)) == NULL) + if ((m = class_getInstanceMethod(self, selector)) == NULL || + (ret = method_getTypeEncoding(m)) == NULL) @throw [OFNotImplementedException newWithClass: self selector: selector]; return ret; #endif @@ -273,21 +272,11 @@ if (newimp == (IMP)0 || !class_respondsToSelector(self->isa, selector)) @throw [OFInvalidArgumentException newWithClass: self selector: _cmd]; return objc_replace_class_method(self, selector, newimp); -#elif defined(OF_APPLE_RUNTIME) - Method method; - - if (newimp == (IMP)0 || - (method = class_getClassMethod(self, selector)) == NULL) - @throw [OFInvalidArgumentException newWithClass: self - selector: _cmd]; - - return class_replaceMethod(self->isa, selector, newimp, - method_getTypeEncoding(method)); -#else +#elif defined(OF_OLD_GNU_RUNTIME) Method_t method; IMP oldimp; /* The class method is the instance method of the meta class */ if ((method = class_get_instance_method(self->class_pointer, @@ -306,10 +295,24 @@ (sidx)method->method_name->sel_id)) sarray_at_put_safe(((Class)self->class_pointer)->dtable, (sidx)method->method_name->sel_id, method->method_imp); return oldimp; +#else + Method method; + + if (newimp == (IMP)0 || + (method = class_getClassMethod(self, selector)) == NULL) + @throw [OFInvalidArgumentException newWithClass: self + selector: _cmd]; + + /* + * Cast needed because it's isa in the Apple runtime, but class_pointer + * in the GNU runtime. + */ + return class_replaceMethod(((OFObject*)self)->isa, selector, newimp, + method_getTypeEncoding(method)); #endif } + (IMP)replaceClassMethod: (SEL)selector withMethodFromClass: (Class)class; @@ -333,21 +336,11 @@ if (newimp == (IMP)0 || !class_respondsToSelector(self, selector)) @throw [OFInvalidArgumentException newWithClass: self selector: _cmd]; return objc_replace_instance_method(self, selector, newimp); -#elif defined(OF_APPLE_RUNTIME) - Method method; - - if (newimp == (IMP)0 || - (method = class_getInstanceMethod(self, selector)) == NULL) - @throw [OFInvalidArgumentException newWithClass: self - selector: _cmd]; - - return class_replaceMethod(self, selector, newimp, - method_getTypeEncoding(method)); -#else +#elif defined(OF_OLD_GNU_RUNTIME) Method_t method = class_get_instance_method(self, selector); IMP oldimp; if (method == NULL) @throw [OFInvalidArgumentException newWithClass: self @@ -364,10 +357,20 @@ (sidx)method->method_name->sel_id)) sarray_at_put_safe(((Class)self)->dtable, (sidx)method->method_name->sel_id, method->method_imp); return oldimp; +#else + Method method; + + if (newimp == (IMP)0 || + (method = class_getInstanceMethod(self, selector)) == NULL) + @throw [OFInvalidArgumentException newWithClass: self + selector: _cmd]; + + return class_replaceMethod(self, selector, newimp, + method_getTypeEncoding(method)); #endif } + (IMP)replaceInstanceMethod: (SEL)selector withMethodFromClass: (Class)class; @@ -410,11 +413,11 @@ return NO; } - (BOOL)respondsToSelector: (SEL)selector { -#ifdef OF_GNU_RUNTIME +#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 @@ -427,42 +430,42 @@ return [isa conformsToProtocol: protocol]; } - (IMP)methodForSelector: (SEL)selector { -#ifdef OF_APPLE_RUNTIME - return class_getMethodImplementation(isa, selector); +#if defined(OF_OBJFW_RUNTIME) || defined(OF_OLD_GNU_RUNTIME) + return objc_msg_lookup(self, selector); #else - return objc_msg_lookup(self, selector); + return class_getMethodImplementation(isa, selector); #endif } - (const char*)typeEncodingForSelector: (SEL)selector { -#if defined(OF_APPLE_RUNTIME) - Method m; +#if defined(OF_OBJFW_RUNTIME) const char *ret; - if ((m = class_getInstanceMethod(isa, selector)) == NULL || - (ret = method_getTypeEncoding(m)) == NULL) + if ((ret = objc_get_type_encoding(isa, selector)) == NULL) @throw [OFNotImplementedException newWithClass: isa selector: selector]; return ret; -#elif defined(OF_GNU_RUNTIME) +#elif defined(OF_OLD_GNU_RUNTIME) Method_t m; if ((m = class_get_instance_method(isa, selector)) == NULL || m->method_types == NULL) @throw [OFNotImplementedException newWithClass: isa selector: selector]; return m->method_types; -#elif defined(OF_OBJFW_RUNTIME) +#else + Method m; const char *ret; - if ((ret = objc_get_type_encoding(isa, selector)) == NULL) + if ((m = class_getInstanceMethod(isa, selector)) == NULL || + (ret = method_getTypeEncoding(m)) == NULL) @throw [OFNotImplementedException newWithClass: isa selector: selector]; return ret; #endif Index: src/objfw-defs.h.in ================================================================== --- src/objfw-defs.h.in +++ src/objfw-defs.h.in @@ -14,8 +14,9 @@ #undef OF_HAVE_PTHREADS #undef OF_HAVE_PTHREAD_SPINLOCKS #undef OF_HAVE_SCHED_YIELD #undef OF_HAVE_SYS_SELECT_H #undef OF_OBJFW_RUNTIME +#undef OF_OLD_GNU_RUNTIME #undef OF_PLUGINS #undef OF_THREADS #undef SIZE_MAX Index: tests/OFBlockTests.m ================================================================== --- tests/OFBlockTests.m +++ tests/OFBlockTests.m @@ -16,14 +16,14 @@ #import "OFAutoreleasePool.h" #import "OFExceptions.h" #if defined(OF_OBJFW_RUNTIME) # include -#elif defined(OF_GNU_RUNTIME) +#elif defined(OF_OLD_GNU_RUNTIME) # include #endif -#if defined(OF_GNU_RUNTIME) || defined(OF_OBJFW_RUNTIME) +#if defined(OF_OLD_GNU_RUNTIME) || defined(OF_OBJFW_RUNTIME) # define objc_getClass objc_get_class #endif #import "TestsAppDelegate.h"