5 #include <objc/runtime.h>
6 #include <objc/message.h>
10 @interface Super : TestRoot @end
12 +(void)classMethod { state = 1; }
13 -(void)instanceMethod { state = 4; }
14 +(void)classMethodSuperOnly { state = 3; }
15 -(void)instanceMethodSuperOnly { state = 6; }
18 @interface Sub : Super @end
20 +(void)classMethod { state = 2; }
21 -(void)instanceMethod { state = 5; }
24 typedef void (*imp_t)(id, SEL);
28 Class Super_cls, Sub_cls;
34 // don't use [Super class] to check laziness handing
35 Super_cls = objc_getClass("Super");
36 Sub_cls = objc_getClass("Sub");
38 sel = sel_registerName("classMethod");
39 m = class_getClassMethod(Super_cls, sel);
41 testassert(sel == method_getName(m));
42 imp = method_getImplementation(m);
43 testassert(imp == class_getMethodImplementation(object_getClass(Super_cls), sel));
45 (*(imp_t)imp)(Super_cls, sel);
46 testassert(state == 1);
48 sel = sel_registerName("classMethod");
49 m = class_getClassMethod(Sub_cls, sel);
51 testassert(sel == method_getName(m));
52 imp = method_getImplementation(m);
53 testassert(imp == class_getMethodImplementation(object_getClass(Sub_cls), sel));
55 (*(imp_t)imp)(Sub_cls, sel);
56 testassert(state == 2);
58 sel = sel_registerName("classMethodSuperOnly");
59 m = class_getClassMethod(Sub_cls, sel);
61 testassert(sel == method_getName(m));
62 imp = method_getImplementation(m);
63 testassert(imp == class_getMethodImplementation(object_getClass(Sub_cls), sel));
65 (*(imp_t)imp)(Sub_cls, sel);
66 testassert(state == 3);
68 sel = sel_registerName("instanceMethod");
69 m = class_getInstanceMethod(Super_cls, sel);
71 testassert(sel == method_getName(m));
72 imp = method_getImplementation(m);
73 testassert(imp == class_getMethodImplementation(Super_cls, sel));
76 (*(imp_t)imp)(objc_unretainedObject(buf), sel);
77 testassert(state == 4);
79 sel = sel_registerName("instanceMethod");
80 m = class_getInstanceMethod(Sub_cls, sel);
82 testassert(sel == method_getName(m));
83 imp = method_getImplementation(m);
84 testassert(imp == class_getMethodImplementation(Sub_cls, sel));
87 (*(imp_t)imp)(objc_unretainedObject(buf), sel);
88 testassert(state == 5);
90 sel = sel_registerName("instanceMethodSuperOnly");
91 m = class_getInstanceMethod(Sub_cls, sel);
93 testassert(sel == method_getName(m));
94 imp = method_getImplementation(m);
95 testassert(imp == class_getMethodImplementation(Sub_cls, sel));
98 (*(imp_t)imp)(objc_unretainedObject(buf), sel);
99 testassert(state == 6);
101 // check class_getClassMethod(cls) == class_getInstanceMethod(cls->isa)
102 sel = sel_registerName("classMethod");
103 testassert(class_getClassMethod(Sub_cls, sel) == class_getInstanceMethod(object_getClass(Sub_cls), sel));
105 sel = sel_registerName("nonexistent");
106 testassert(! class_getInstanceMethod(Sub_cls, sel));
107 testassert(! class_getClassMethod(Sub_cls, sel));
108 testassert(class_getMethodImplementation(Sub_cls, sel) == (IMP)&_objc_msgForward);
109 testassert(class_getMethodImplementation_stret(Sub_cls, sel) == (IMP)&_objc_msgForward_stret);
111 testassert(! class_getInstanceMethod(NULL, NULL));
112 testassert(! class_getInstanceMethod(NULL, sel));
113 testassert(! class_getInstanceMethod(Sub_cls, NULL));
114 testassert(! class_getClassMethod(NULL, NULL));
115 testassert(! class_getClassMethod(NULL, sel));
116 testassert(! class_getClassMethod(Sub_cls, NULL));