1// TEST_CONFIG 2 3#include "test.h" 4#include "testroot.i" 5#include <objc/runtime.h> 6#include <objc/message.h> 7 8static int state = 0; 9 10@interface Super : TestRoot @end 11@implementation Super 12+(void)classMethod { state = 1; } 13-(void)instanceMethod { state = 4; } 14+(void)classMethodSuperOnly { state = 3; } 15-(void)instanceMethodSuperOnly { state = 6; } 16@end 17 18@interface Sub : Super @end 19@implementation Sub 20+(void)classMethod { state = 2; } 21-(void)instanceMethod { state = 5; } 22@end 23 24typedef void (*imp_t)(id, SEL); 25 26int main() 27{ 28 Class Super_cls, Sub_cls; 29 Class buf[10]; 30 Method m; 31 SEL sel; 32 IMP imp; 33 34 // don't use [Super class] to check laziness handing 35 Super_cls = objc_getClass("Super"); 36 Sub_cls = objc_getClass("Sub"); 37 38 sel = sel_registerName("classMethod"); 39 m = class_getClassMethod(Super_cls, sel); 40 testassert(m); 41 testassert(sel == method_getName(m)); 42 imp = method_getImplementation(m); 43 testassert(imp == class_getMethodImplementation(object_getClass(Super_cls), sel)); 44 testassert(imp == object_getMethodImplementation(Super_cls, sel)); 45 state = 0; 46 (*(imp_t)imp)(Super_cls, sel); 47 testassert(state == 1); 48 49 sel = sel_registerName("classMethod"); 50 m = class_getClassMethod(Sub_cls, sel); 51 testassert(m); 52 testassert(sel == method_getName(m)); 53 imp = method_getImplementation(m); 54 testassert(imp == class_getMethodImplementation(object_getClass(Sub_cls), sel)); 55 testassert(imp == object_getMethodImplementation(Sub_cls, sel)); 56 state = 0; 57 (*(imp_t)imp)(Sub_cls, sel); 58 testassert(state == 2); 59 60 sel = sel_registerName("classMethodSuperOnly"); 61 m = class_getClassMethod(Sub_cls, sel); 62 testassert(m); 63 testassert(sel == method_getName(m)); 64 imp = method_getImplementation(m); 65 testassert(imp == class_getMethodImplementation(object_getClass(Sub_cls), sel)); 66 testassert(imp == object_getMethodImplementation(Sub_cls, sel)); 67 state = 0; 68 (*(imp_t)imp)(Sub_cls, sel); 69 testassert(state == 3); 70 71 sel = sel_registerName("instanceMethod"); 72 m = class_getInstanceMethod(Super_cls, sel); 73 testassert(m); 74 testassert(sel == method_getName(m)); 75 imp = method_getImplementation(m); 76 testassert(imp == class_getMethodImplementation(Super_cls, sel)); 77 buf[0] = Super_cls; 78 testassert(imp == object_getMethodImplementation(objc_unretainedObject(buf), sel)); 79 state = 0; 80 (*(imp_t)imp)(objc_unretainedObject(buf), sel); 81 testassert(state == 4); 82 83 sel = sel_registerName("instanceMethod"); 84 m = class_getInstanceMethod(Sub_cls, sel); 85 testassert(m); 86 testassert(sel == method_getName(m)); 87 imp = method_getImplementation(m); 88 testassert(imp == class_getMethodImplementation(Sub_cls, sel)); 89 buf[0] = Sub_cls; 90 testassert(imp == object_getMethodImplementation(objc_unretainedObject(buf), sel)); 91 state = 0; 92 (*(imp_t)imp)(objc_unretainedObject(buf), sel); 93 testassert(state == 5); 94 95 sel = sel_registerName("instanceMethodSuperOnly"); 96 m = class_getInstanceMethod(Sub_cls, sel); 97 testassert(m); 98 testassert(sel == method_getName(m)); 99 imp = method_getImplementation(m); 100 testassert(imp == class_getMethodImplementation(Sub_cls, sel)); 101 buf[0] = Sub_cls; 102 testassert(imp == object_getMethodImplementation(objc_unretainedObject(buf), sel)); 103 state = 0; 104 (*(imp_t)imp)(objc_unretainedObject(buf), sel); 105 testassert(state == 6); 106 107 // check class_getClassMethod(cls) == class_getInstanceMethod(cls->isa) 108 sel = sel_registerName("classMethod"); 109 testassert(class_getClassMethod(Sub_cls, sel) == class_getInstanceMethod(object_getClass(Sub_cls), sel)); 110 111 sel = sel_registerName("nonexistent"); 112 testassert(! class_getInstanceMethod(Sub_cls, sel)); 113 testassert(! class_getClassMethod(Sub_cls, sel)); 114 testassert(class_getMethodImplementation(Sub_cls, sel) == (IMP)&_objc_msgForward); 115 buf[0] = Sub_cls; 116 testassert(object_getMethodImplementation(objc_unretainedObject(buf), sel) == (IMP)&_objc_msgForward); 117 testassert(class_getMethodImplementation_stret(Sub_cls, sel) == (IMP)&_objc_msgForward_stret); 118 testassert(object_getMethodImplementation_stret(objc_unretainedObject(buf), sel) == (IMP)&_objc_msgForward_stret); 119 120 testassert(! class_getInstanceMethod(NULL, NULL)); 121 testassert(! class_getInstanceMethod(NULL, sel)); 122 testassert(! class_getInstanceMethod(Sub_cls, NULL)); 123 testassert(! class_getClassMethod(NULL, NULL)); 124 testassert(! class_getClassMethod(NULL, sel)); 125 testassert(! class_getClassMethod(Sub_cls, NULL)); 126 127 succeed(__FILE__); 128} 129