]> git.saurik.com Git - apple/objc4.git/blobdiff - test/ivar.m
objc4-437.tar.gz
[apple/objc4.git] / test / ivar.m
diff --git a/test/ivar.m b/test/ivar.m
new file mode 100644 (file)
index 0000000..56b097f
--- /dev/null
@@ -0,0 +1,116 @@
+#include "test.h"
+#include <stdint.h>
+#include <string.h>
+#include <objc/objc-runtime.h>
+
+@interface Super { 
+  @public
+    id isa;
+  char superIvar;
+}
+@end
+
+@implementation Super 
++(void)initialize { } 
++class { return self; }
++new { return class_createInstance(self, 0); }
+@end
+
+
+@interface Sub : Super {
+  @public 
+    uintptr_t subIvar;
+}
+@end
+
+@implementation Sub @end
+
+int main()
+{
+    /* 
+       Runtime layout of Sub:
+         [0] isa
+         [1] superIvar
+         [2] subIvar
+    */
+    
+    Ivar ivar;
+    uintptr_t value;
+    Sub *sub = [Sub new];
+    sub->subIvar = 10;
+    testassert(((uintptr_t *)sub)[2] == 10);
+
+    ivar = class_getInstanceVariable([Sub class], "subIvar");
+    testassert(ivar);
+    testassert(2*sizeof(intptr_t) == ivar_getOffset(ivar));
+    testassert(0 == strcmp(ivar_getName(ivar), "subIvar"));
+#if __LP64__
+    testassert(0 == strcmp(ivar_getTypeEncoding(ivar), "Q"));
+#else
+    testassert(0 == strcmp(ivar_getTypeEncoding(ivar), "I"));
+#endif
+
+    ivar = class_getInstanceVariable([Super class], "superIvar");
+    testassert(ivar);
+    testassert(sizeof(intptr_t) == ivar_getOffset(ivar));
+    testassert(0 == strcmp(ivar_getName(ivar), "superIvar"));
+    testassert(0 == strcmp(ivar_getTypeEncoding(ivar), "c"));
+    testassert(ivar == class_getInstanceVariable([Sub class], "superIvar"));
+
+    ivar = class_getInstanceVariable([Super class], "subIvar");
+    testassert(!ivar);
+
+    ivar = class_getInstanceVariable([Sub class]->isa, "subIvar");
+    testassert(!ivar);
+
+
+    sub->subIvar = 10;
+    value = 0;
+    object_getInstanceVariable(sub, "subIvar", (void **)&value);
+    testassert(value == 10);
+    
+    object_setInstanceVariable(sub, "subIvar", (void *)11);
+    testassert(sub->subIvar == 11);
+
+    ivar = class_getInstanceVariable([Sub class], "subIvar");
+    object_setIvar(sub, ivar, (id)12);
+    testassert(sub->subIvar == 12);
+    testassert((id)12 == object_getIvar(sub, ivar));
+
+    ivar = class_getInstanceVariable([Sub class], "subIvar");
+    testassert(ivar == object_getInstanceVariable(sub, "subIvar", NULL));
+    
+
+    testassert(NULL == class_getInstanceVariable(NULL, "foo"));
+    testassert(NULL == class_getInstanceVariable([Sub class], NULL));
+    testassert(NULL == class_getInstanceVariable(NULL, NULL));
+
+    testassert(NULL == object_getIvar(sub, NULL));
+    testassert(NULL == object_getIvar(NULL, ivar));
+    testassert(NULL == object_getIvar(NULL, NULL));
+
+    testassert(NULL == object_getInstanceVariable(sub, NULL, NULL));
+    testassert(NULL == object_getInstanceVariable(NULL, "foo", NULL));
+    testassert(NULL == object_getInstanceVariable(NULL, NULL, NULL));
+    value = 10;
+    testassert(NULL == object_getInstanceVariable(sub, NULL, (void **)&value));
+    testassert(value == 0);
+    value = 10;
+    testassert(NULL == object_getInstanceVariable(NULL, "foo", (void **)&value));
+    testassert(value == 0);
+    value = 10;
+    testassert(NULL == object_getInstanceVariable(NULL, NULL, (void **)&value));
+    testassert(value == 0);
+
+    object_setIvar(sub, NULL, NULL);
+    object_setIvar(NULL, ivar, NULL);
+    object_setIvar(NULL, NULL, NULL);
+
+    testassert(NULL == object_setInstanceVariable(sub, NULL, NULL));
+    testassert(NULL == object_setInstanceVariable(NULL, "foo", NULL));
+    testassert(NULL == object_setInstanceVariable(NULL, NULL, NULL));
+
+    succeed(__FILE__);
+    return 0;
+}