Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -2,10 +2,11 @@ SUBDIRS = src ${TESTS} DISTCLEAN = aclocal.m4 \ autom4te.cache \ buildsys.mk \ + config.h \ config.log \ config.status \ extra.mk include buildsys.mk Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -208,28 +208,58 @@ } #else - performv: (SEL)selector : (marg_list)args { -#if !__OBJC2__ - Method method; - unsigned size; - - if ((method = class_getInstanceMethod(isa, selector)) != NULL) - size = method_getSizeOfArguments(method); - else - size = 0; - - if (!size) - return [self forward: selector - : args]; - - return objc_msgSendv(self, selector, size, args); + Method m; + char *encoding, rettype; + size_t depth, argsize; + + if ((m = class_getInstanceMethod(isa, selector)) == NULL || + (encoding = (char*)method_getTypeEncoding(m)) == NULL) + @throw [OFInvalidArgumentException newWithClass: [self class] + andSelector: _cmd]; + + rettype = *encoding; + + /* Skip the return type */ + switch (*encoding) { + case '{': + for (depth = 0; *encoding; encoding++) { + if (OF_UNLIKELY(*encoding == '{')) + depth++; + else if (OF_UNLIKELY(*encoding == '}') && + OF_LIKELY(!--depth)) + break; + } + break; + case '(': + for (depth = 0; *encoding; encoding++) { + if (OF_UNLIKELY(*encoding == '(')) + depth++; + else if (OF_UNLIKELY(*encoding == ')') && + OF_LIKELY(!--depth)) + break; + } + break; + } + encoding++; + + for (argsize = 0; *encoding >= '0' && *encoding <= '9'; encoding++) + argsize = argsize * 10 + (*encoding - '0'); + + /* We don't support returning structs or unions yet */ + if (rettype == '{' || rettype == '(') + @throw [OFNotImplementedException newWithClass: [self class] + andSelector: _cmd]; + +#if __OBJC2__ + @throw [OFNotImplementedException newWithClass: [self class] + andSelector: _cmd]; + return self; #else -#warning ObjC2 removed objc_msgSendv and there is -#warning no own implementation for it yet! - return nil; + return objc_msgSendv(self, selector, argsize, args); #endif } #endif - (BOOL)isEqual: (id)obj