@@ -22,13 +22,15 @@ #import "runtime.h" #import "runtime-private.h" #import "macros.h" IMP (*objc_forward_handler)(id, SEL) = NULL; +IMP (*objc_forward_handler_stret)(id, SEL) = NULL; -IMP -objc_not_found_handler(id obj, SEL sel) +static IMP +common_not_found_handler(id obj, SEL sel, IMP (*lookup)(id, SEL), + IMP (*forward_handler)(id, SEL)) { bool is_class = object_getClass(obj)->info & OBJC_CLASS_INFO_METACLASS; if (!(object_getClass(obj)->info & OBJC_CLASS_INFO_INITIALIZED)) { Class cls = (is_class ? (Class)obj : object_getClass(obj)); @@ -35,11 +37,11 @@ objc_initialize_class(cls); if (!(cls->info & OBJC_CLASS_INFO_SETUP)) { if (is_class) - return objc_msg_lookup(nil, sel); + return lookup(nil, sel); else OBJC_ERROR("Could not dispatch message for " "incomplete class %s!", cls->name); } @@ -47,19 +49,33 @@ * We don't need to handle the case that super was called. * The reason for this is that a call to super is not possible * before a message to the class has been sent and it thus has * been initialized together with its superclasses. */ - return objc_msg_lookup(obj, sel); + return lookup(obj, sel); } - if (objc_forward_handler != NULL) - return objc_forward_handler(obj, sel); + if (forward_handler != NULL) + return forward_handler(obj, sel); OBJC_ERROR("Selector %c[%s] is not implemented for class %s!", (is_class ? '+' : '-'), sel_getName(sel), object_getClassName(obj)); } + +IMP +objc_not_found_handler(id obj, SEL sel) +{ + return common_not_found_handler(obj, sel, objc_msg_lookup, + objc_forward_handler); +} + +IMP +objc_not_found_handler_stret(id obj, SEL sel) +{ + return common_not_found_handler(obj, sel, objc_msg_lookup_stret, + objc_forward_handler_stret); +} bool class_respondsToSelector(Class cls, SEL sel) { if (cls == Nil) @@ -73,12 +89,12 @@ nil_method(id self, SEL _cmd) { return nil; } -IMP -objc_msg_lookup(id obj, SEL sel) +static OF_INLINE IMP +common_lookup(id obj, SEL sel, IMP (*not_found_handler)(id, SEL)) { IMP imp; if (obj == nil) return (IMP)nil_method; @@ -85,26 +101,51 @@ imp = objc_sparsearray_get(object_getClass(obj)->dtable, (uint32_t)sel->uid); if (imp == NULL) - return objc_not_found_handler(obj, sel); + return not_found_handler(obj, sel); return imp; } IMP -objc_msg_lookup_super(struct objc_super *super, SEL sel) +objc_msg_lookup(id obj, SEL sel) +{ + return common_lookup(obj, sel, objc_not_found_handler); +} + +IMP +objc_msg_lookup_stret(id obj, SEL sel) +{ + return common_lookup(obj, sel, objc_not_found_handler_stret); +} + +static OF_INLINE IMP +common_lookup_super(struct objc_super *super, SEL sel, + IMP (*not_found_handler)(id, SEL)) { IMP imp; if (super->self == nil) return (IMP)nil_method; imp = objc_sparsearray_get(super->cls->dtable, (uint32_t)sel->uid); if (imp == NULL) - return objc_not_found_handler(super->self, sel); + return not_found_handler(super->self, sel); return imp; } + +IMP +objc_msg_lookup_super(struct objc_super *super, SEL sel) +{ + return common_lookup_super(super, sel, objc_not_found_handler); +} + +IMP +objc_msg_lookup_super_stret(struct objc_super *super, SEL sel) +{ + return common_lookup_super(super, sel, objc_not_found_handler_stret); +} #endif