diff options
Diffstat (limited to 'Objective-C')
-rw-r--r-- | Objective-C/libobjcl.h | 4 | ||||
-rw-r--r-- | Objective-C/libobjcl.m | 42 |
2 files changed, 39 insertions, 7 deletions
diff --git a/Objective-C/libobjcl.h b/Objective-C/libobjcl.h index 4a7137e..cca5d12 100644 --- a/Objective-C/libobjcl.h +++ b/Objective-C/libobjcl.h @@ -70,6 +70,7 @@ objcl_shutdown_runtime (void); id objcl_invoke_with_types (int argc, + Class superclass_for_send_super, char *return_typespec, char *arg_typespecs[], void *return_value, @@ -105,7 +106,8 @@ objcl_selector_name (SEL selector); IMP objcl_get_method_implementation (id object, - SEL selector); + SEL selector, + Class superclass_for_send_super); BOOL objcl_object_is_class (id obj); diff --git a/Objective-C/libobjcl.m b/Objective-C/libobjcl.m index b380b6e..97422c2 100644 --- a/Objective-C/libobjcl.m +++ b/Objective-C/libobjcl.m @@ -114,6 +114,7 @@ objcl_shutdown_runtime (void) #ifdef USE_LIBFFI id objcl_invoke_with_types (int argc, + Class superclass_for_send_super, char *return_typespec, char *arg_typespecs[], void *return_value, @@ -140,7 +141,8 @@ objcl_invoke_with_types (int argc, NS_DURING { TRACE (@"get-method"); - method = objcl_get_method_implementation (receiver, method_selector); + method = objcl_get_method_implementation (receiver, method_selector, + superclass_for_send_super); TRACE (@"method == NULL"); if (method == NULL) [[NSException exceptionWithName: @"MLKNoApplicableMethod" @@ -284,22 +286,50 @@ objcl_selector_name (SEL selector) IMP objcl_get_method_implementation (id object, - SEL selector) + SEL selector, + Class superclass_for_send_super) { + /* If superclass_for_send_super == nil, this is just plain old method + implementation hunting. If it isn't, though, we're trying to do a + super call, which can get a bit hairy quickly. */ TRACE (@"method-impl %p %p", object, selector); #ifdef __NEXT_RUNTIME__ + Class target_class; + if (objcl_object_is_class (object)) - return method_getImplementation (class_getClassMethod (object, selector)); + { + if (superclass_for_send_super == nil) + target_class = object; + else + target_class = superclass_for_send_super; + + return method_getImplementation (class_getClassMethod (target_class, + selector)); + } else { + if (superclass_for_send_super == nil) + target_class = [object class]; + else + target_class = superclass_for_send_super; + #ifdef __OBJC2__ - return class_getMethodImplementation ([object class], selector); + return class_getMethodImplementation (target_class, selector); #else - return method_getImplementation (class_getInstanceMethod ([object class], selector)); + return method_getImplementation (class_getInstanceMethod (target_class, + selector)); #endif } #else - return objc_msg_lookup (object, selector); + if (superclass_for_send_super == nil) + return objc_msg_lookup (object, selector); + else + { + Super super_struct; + super_struct.self = object; + super_struct.class = superclass_for_send_super; + return objc_msg_lookup_super (&super_struct, selector); + } #endif } |