-
Notifications
You must be signed in to change notification settings - Fork 517
/
Copy pathcopyIvarList.m
115 lines (96 loc) · 2.53 KB
/
copyIvarList.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// TEST_CONFIG
#include "test.h"
#include <string.h>
#include <malloc/malloc.h>
#include <objc/objc-runtime.h>
OBJC_ROOT_CLASS
@interface SuperIvars {
id isa;
int ivar1;
int ivar2;
} @end
@implementation SuperIvars @end
@interface SubIvars : SuperIvars {
int ivar3;
int ivar4;
} @end
@implementation SubIvars @end
OBJC_ROOT_CLASS
@interface FourIvars {
int ivar1;
int ivar2;
int ivar3;
int ivar4;
} @end
@implementation FourIvars @end
OBJC_ROOT_CLASS
@interface NoIvars { } @end
@implementation NoIvars @end
static int isNamed(Ivar iv, const char *name)
{
return (0 == strcmp(name, ivar_getName(iv)));
}
int main()
{
Ivar *ivars;
unsigned int count;
Class cls;
cls = objc_getClass("SubIvars");
testassert(cls);
count = 100;
ivars = class_copyIvarList(cls, &count);
testassert(ivars);
testassert(count == 2);
testassert(isNamed(ivars[0], "ivar3"));
testassert(isNamed(ivars[1], "ivar4"));
// ivars[] should be null-terminated
testassert(ivars[2] == NULL);
free(ivars);
cls = objc_getClass("SuperIvars");
testassert(cls);
count = 100;
ivars = class_copyIvarList(cls, &count);
testassert(ivars);
testassert(count == 3);
testassert(isNamed(ivars[0], "isa"));
testassert(isNamed(ivars[1], "ivar1"));
testassert(isNamed(ivars[2], "ivar2"));
// ivars[] should be null-terminated
testassert(ivars[3] == NULL);
free(ivars);
// Check null-termination - this ivar list block would be 16 bytes
// if it weren't for the terminator
cls = objc_getClass("FourIvars");
testassert(cls);
count = 100;
ivars = class_copyIvarList(cls, &count);
testassert(ivars);
testassert(count == 4);
testassert(malloc_size(ivars) >= 5 * sizeof(Ivar));
testassert(ivars[3] != NULL);
testassert(ivars[4] == NULL);
free(ivars);
// Check NULL count parameter
ivars = class_copyIvarList(cls, NULL);
testassert(ivars);
testassert(ivars[4] == NULL);
testassert(ivars[3] != NULL);
free(ivars);
// Check NULL class parameter
count = 100;
ivars = class_copyIvarList(NULL, &count);
testassert(!ivars);
testassert(count == 0);
// Check NULL class and count
ivars = class_copyIvarList(NULL, NULL);
testassert(!ivars);
// Check class with no ivars
cls = objc_getClass("NoIvars");
testassert(cls);
count = 100;
ivars = class_copyIvarList(cls, &count);
testassert(!ivars);
testassert(count == 0);
succeed(__FILE__);
return 0;
}