123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- /*
- TEST_BUILD_OUTPUT
- .*getMethod.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
- .*getMethod.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
- .*getMethod.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
- .*getMethod.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
- END
- */
- #include "test.h"
- #include "testroot.i"
- #include <objc/runtime.h>
- #include <objc/message.h>
- static int state = 0;
- @interface Super : TestRoot @end
- @implementation Super
- +(void)classMethod { state = 1; }
- -(void)instanceMethod { state = 4; }
- +(void)classMethodSuperOnly { state = 3; }
- -(void)instanceMethodSuperOnly { state = 6; }
- @end
- @interface Sub : Super @end
- @implementation Sub
- +(void)classMethod { state = 2; }
- -(void)instanceMethod { state = 5; }
- @end
- typedef void (*imp_t)(id, SEL);
- int main()
- {
- Class Super_cls, Sub_cls;
- Class buf[10];
- Method m;
- SEL sel;
- IMP imp;
- id bufobj = (__bridge_transfer id)(void*)buf;
-
- // don't use [Super class] to check laziness handing
- Super_cls = objc_getClass("Super");
- Sub_cls = objc_getClass("Sub");
- sel = sel_registerName("classMethod");
- m = class_getClassMethod(Super_cls, sel);
- testassert(m);
- testassert(sel == method_getName(m));
- imp = method_getImplementation(m);
- testassert(imp == class_getMethodImplementation(object_getClass(Super_cls), sel));
- testassert(imp == object_getMethodImplementation(Super_cls, sel));
- state = 0;
- (*(imp_t)imp)(Super_cls, sel);
- testassert(state == 1);
- sel = sel_registerName("classMethod");
- m = class_getClassMethod(Sub_cls, sel);
- testassert(m);
- testassert(sel == method_getName(m));
- imp = method_getImplementation(m);
- testassert(imp == class_getMethodImplementation(object_getClass(Sub_cls), sel));
- testassert(imp == object_getMethodImplementation(Sub_cls, sel));
- state = 0;
- (*(imp_t)imp)(Sub_cls, sel);
- testassert(state == 2);
- sel = sel_registerName("classMethodSuperOnly");
- m = class_getClassMethod(Sub_cls, sel);
- testassert(m);
- testassert(sel == method_getName(m));
- imp = method_getImplementation(m);
- testassert(imp == class_getMethodImplementation(object_getClass(Sub_cls), sel));
- testassert(imp == object_getMethodImplementation(Sub_cls, sel));
- state = 0;
- (*(imp_t)imp)(Sub_cls, sel);
- testassert(state == 3);
-
- sel = sel_registerName("instanceMethod");
- m = class_getInstanceMethod(Super_cls, sel);
- testassert(m);
- testassert(sel == method_getName(m));
- imp = method_getImplementation(m);
- testassert(imp == class_getMethodImplementation(Super_cls, sel));
- buf[0] = Super_cls;
- testassert(imp == object_getMethodImplementation(bufobj, sel));
- state = 0;
- (*(imp_t)imp)(bufobj, sel);
- testassert(state == 4);
- sel = sel_registerName("instanceMethod");
- m = class_getInstanceMethod(Sub_cls, sel);
- testassert(m);
- testassert(sel == method_getName(m));
- imp = method_getImplementation(m);
- testassert(imp == class_getMethodImplementation(Sub_cls, sel));
- buf[0] = Sub_cls;
- testassert(imp == object_getMethodImplementation(bufobj, sel));
- state = 0;
- (*(imp_t)imp)(bufobj, sel);
- testassert(state == 5);
- sel = sel_registerName("instanceMethodSuperOnly");
- m = class_getInstanceMethod(Sub_cls, sel);
- testassert(m);
- testassert(sel == method_getName(m));
- imp = method_getImplementation(m);
- testassert(imp == class_getMethodImplementation(Sub_cls, sel));
- buf[0] = Sub_cls;
- testassert(imp == object_getMethodImplementation(bufobj, sel));
- state = 0;
- (*(imp_t)imp)(bufobj, sel);
- testassert(state == 6);
- // check class_getClassMethod(cls) == class_getInstanceMethod(cls->isa)
- sel = sel_registerName("classMethod");
- testassert(class_getClassMethod(Sub_cls, sel) == class_getInstanceMethod(object_getClass(Sub_cls), sel));
- sel = sel_registerName("nonexistent");
- testassert(! class_getInstanceMethod(Sub_cls, sel));
- testassert(! class_getClassMethod(Sub_cls, sel));
- testassert(class_getMethodImplementation(Sub_cls, sel) == (IMP)&_objc_msgForward);
- buf[0] = Sub_cls;
- testassert(object_getMethodImplementation(bufobj, sel) == (IMP)&_objc_msgForward);
- #if !__arm64__
- testassert(class_getMethodImplementation_stret(Sub_cls, sel) == (IMP)&_objc_msgForward_stret);
- testassert(object_getMethodImplementation_stret(bufobj, sel) == (IMP)&_objc_msgForward_stret);
- #endif
- testassert(! class_getInstanceMethod(NULL, NULL));
- testassert(! class_getInstanceMethod(NULL, sel));
- testassert(! class_getInstanceMethod(Sub_cls, NULL));
- testassert(! class_getClassMethod(NULL, NULL));
- testassert(! class_getClassMethod(NULL, sel));
- testassert(! class_getClassMethod(Sub_cls, NULL));
- succeed(__FILE__);
- }
|