Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -405,11 +405,12 @@ * All methods from the superclasses of the specified class will also be added. * * If the specified class is a superclass of the receiving class, nothing is * done. * - * The specified class may not use instance variables and has to use accessors. + * The methods which will be added from the specified class are not allowed to + * use super or access instance variables, instead they have to use accessors. * * \param class The class from which the instance methods should be inherited */ + (void)inheritMethodsFromClass: (Class)class; Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -455,10 +455,42 @@ withTypeEncoding: (const char*)typeEncoding implementation: (IMP)implementation { #if defined(OF_APPLE_RUNTIME) || defined(OF_GNU_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 + newWithClass: 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; + + /* Update the dtable */ + sarray_at_put_safe(((Class)self)->dtable, + (sidx)selector->sel_id, implementation); + + return YES; #else @throw [OFNotImplementedException newWithClass: self selector: _cmd]; #endif } @@ -468,10 +500,42 @@ implementation: (IMP)implementation { #if defined(OF_APPLE_RUNTIME) || defined(OF_GNU_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 + newWithClass: 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; + + /* Update the dtable */ + sarray_at_put_safe(((Class)self->class_pointer)->dtable, + (sidx)selector->sel_id, implementation); + + return YES; #else @throw [OFNotImplementedException newWithClass: self selector: _cmd]; #endif }