Overview
Context
Changes
Modified src/runtime/autorelease.m
from [43d183da0e]
to [c7e0c15de1].
︙ | | |
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
-
+
|
static of_tlskey_t objectsKey, topKey, sizeKey;
static void __attribute__((constructor))
init(void)
{
if (!of_tlskey_new(&objectsKey) || !of_tlskey_new(&sizeKey) ||
!of_tlskey_new(&topKey))
ERROR("Unable to create TLS key for autorelease pools!")
OBJC_ERROR("Unable to create TLS key for autorelease pools!")
}
#endif
id
objc_autorelease(id object)
{
return [object autorelease];
|
︙ | | |
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
objects = NULL;
top = NULL;
}
#ifndef OF_COMPILER_TLS
if (!of_tlskey_set(objectsKey, objects) ||!of_tlskey_set(topKey, top))
ERROR("Failed to set TLS key!")
OBJC_ERROR("Failed to set TLS key!")
#endif
}
id
_objc_rootAutorelease(id object)
{
#ifndef OF_COMPILER_TLS
id *top = of_tlskey_get(topKey);
id *objects = of_tlskey_get(objectsKey);
size_t size = (size_t)(uintptr_t)of_tlskey_get(sizeKey);
#endif
if (objects == NULL) {
if ((objects = malloc(of_pagesize)) == NULL)
ERROR("Out of memory for autorelease pools!")
OBJC_ERROR("Out of memory for autorelease pools!")
#ifndef OF_COMPILER_TLS
if (!of_tlskey_set(objectsKey, objects))
ERROR("Failed to set TLS key!")
OBJC_ERROR("Failed to set TLS key!")
if (!of_tlskey_set(sizeKey, (void*)(uintptr_t)of_pagesize))
ERROR("Failed to set TLS key!")
OBJC_ERROR("Failed to set TLS key!")
#endif
top = objects;
size = of_pagesize;
}
if ((uintptr_t)top >= (uintptr_t)objects + size) {
ptrdiff_t diff = top - objects;
size += of_pagesize;
if ((objects = realloc(objects, size)) == NULL)
ERROR("Out of memory for autorelease pools!")
OBJC_ERROR("Out of memory for autorelease pools!")
#ifndef OF_COMPILER_TLS
if (!of_tlskey_set(objectsKey, objects))
ERROR("Failed to set TLS key!")
OBJC_ERROR("Failed to set TLS key!")
if (!of_tlskey_set(sizeKey, (void*)(uintptr_t)size))
ERROR("Failed to set TLS key!")
OBJC_ERROR("Failed to set TLS key!")
#endif
top = objects + diff;
}
*top = object;
top++;
#ifndef OF_COMPILER_TLS
if (!of_tlskey_set(topKey, objects))
ERROR("Failed to set TLS key!")
OBJC_ERROR("Failed to set TLS key!")
#endif
return object;
}
|
Modified src/runtime/category.m
from [c947f89bcc]
to [9fd764b81d].
︙ | | |
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
|
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
|
-
-
+
+
-
+
|
struct objc_abi_category **ncats;
size_t i;
for (i = 0; cats[i] != NULL; i++);
if ((ncats = realloc(cats,
(i + 2) * sizeof(struct objc_abi_category*))) == NULL)
ERROR("Not enough memory for category %s of class %s!",
cat->category_name, cat->class_name);
OBJC_ERROR("Not enough memory for category %s of "
"class %s!", cat->category_name, cat->class_name);
ncats[i] = cat;
ncats[i + 1] = NULL;
objc_hashtable_set(categories, cat->class_name, ncats);
if (cls != Nil && cls->info & OBJC_CLASS_INFO_SETUP) {
objc_update_dtable(cls);
objc_update_dtable(cls->isa);
}
return;
}
if ((cats = malloc(2 * sizeof(struct objc_abi_category*))) == NULL)
ERROR("Not enough memory for category %s of class %s!\n",
OBJC_ERROR("Not enough memory for category %s of class %s!\n",
cat->category_name, cat->class_name);
cats[0] = cat;
cats[1] = NULL;
objc_hashtable_set(categories, cat->class_name, cats);
if (cls != Nil && cls->info & OBJC_CLASS_INFO_SETUP) {
|
︙ | | |
Modified src/runtime/class.m
from [2ee4c27804]
to [0f8bf1f4e6].
︙ | | |
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
-
+
-
+
|
add_subclass(Class cls)
{
size_t i;
if (cls->superclass->subclass_list == NULL) {
if ((cls->superclass->subclass_list =
malloc(2 * sizeof(Class))) == NULL)
ERROR("Not enough memory for subclass list of "
OBJC_ERROR("Not enough memory for subclass list of "
"class %s!", cls->superclass->name);
cls->superclass->subclass_list[0] = cls;
cls->superclass->subclass_list[1] = Nil;
return;
}
for (i = 0; cls->superclass->subclass_list[i] != Nil; i++);
cls->superclass->subclass_list =
realloc(cls->superclass->subclass_list, (i + 2) * sizeof(Class));
if (cls->superclass->subclass_list == NULL)
ERROR("Not enough memory for subclass list of class %s\n",
OBJC_ERROR("Not enough memory for subclass list of class %s\n",
cls->superclass->name);
cls->superclass->subclass_list[i] = cls;
cls->superclass->subclass_list[i + 1] = Nil;
}
static void
|
︙ | | |
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
|
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
|
-
+
|
load_queue = malloc(sizeof(Class));
else
load_queue = realloc(load_queue,
sizeof(Class) *
(load_queue_cnt + 1));
if (load_queue == NULL)
ERROR("Not enough memory for load "
OBJC_ERROR("Not enough memory for load "
"queue!");
load_queue[load_queue_cnt++] = cls;
}
} else
cls->info |= OBJC_CLASS_INFO_LOADED;
}
|
︙ | | |
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
|
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
|
-
+
|
load_queue[i] = load_queue[load_queue_cnt];
load_queue = realloc(load_queue,
sizeof(Class) * load_queue_cnt);
if (load_queue == NULL)
ERROR("Not enough memory for load queue!");
OBJC_ERROR("Not enough memory for load queue!");
}
}
}
inline Class
objc_lookup_class(const char *name)
{
|
︙ | | |
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
|
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
|
-
+
|
Class
objc_get_class(const char *name)
{
Class cls;
if ((cls = objc_lookup_class(name)) == Nil)
ERROR("Class %s not found!", name);
OBJC_ERROR("Class %s not found!", name);
return cls;
}
const char*
class_getName(Class cls)
{
|
︙ | | |
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
|
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
|
-
+
|
}
}
}
}
/* FIXME: We need a way to free this at objc_exit() */
if ((ml = malloc(sizeof(struct objc_method_list))) == NULL)
ERROR("Not enough memory to replace method!");
OBJC_ERROR("Not enough memory to replace method!");
ml->next = cls->methodlist;
ml->count = 1;
ml->methods[0].sel.uid = sel->uid;
ml->methods[0].sel.types = types;
ml->methods[0].imp = newimp;
|
︙ | | |
Modified src/runtime/hashtable.m
from [f9877d131a]
to [3bc4ddb944].
︙ | | |
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
-
+
-
+
|
struct objc_hashtable*
objc_hashtable_new(uint32_t size)
{
struct objc_hashtable *h;
uint32_t i;
if ((h = malloc(sizeof(struct objc_hashtable))) == NULL)
ERROR("Not enough memory to allocate hash table!");
OBJC_ERROR("Not enough memory to allocate hash table!");
h->count = 0;
h->last_idx = size - 1;
h->data = malloc(size * sizeof(struct objc_hashtable_bucket*));
if (h->data == NULL)
ERROR("Not enough memory to allocate hash table!");
OBJC_ERROR("Not enough memory to allocate hash table!");
for (i = 0; i < size; i++)
h->data[i] = NULL;
return h;
}
|
︙ | | |
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
-
+
+
|
struct objc_hashtable_bucket **ndata;
uint32_t nsize = (h->last_idx + 1) << 1;
assert(nsize > 0);
ndata = malloc(nsize * sizeof(struct objc_hashtable_bucket*));
if (ndata == NULL)
ERROR("Not enough memory to insert into hash table!");
OBJC_ERROR("Not enough memory to insert into hash "
"table!");
for (i = 0; i < nsize; i++)
ndata[i] = NULL;
for (i = 0; i <= h->last_idx; i++) {
if (h->data[i] != NULL) {
uint32_t j;
|
︙ | | |
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
-
+
|
last = h->data[i]->hash & (nsize - 1);
for (j = 0; j < last &&
ndata[j] != NULL; j++);
}
if (j >= last)
ERROR("No free bucket!");
OBJC_ERROR("No free bucket!");
ndata[j] = h->data[i];
}
}
free(h->data);
h->data = ndata;
|
︙ | | |
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
-
+
-
+
|
if (i >= last) {
last = hash & h->last_idx;
for (i = 0; i < last && h->data[i] != NULL; i++);
}
if (i >= last)
ERROR("No free bucket!");
OBJC_ERROR("No free bucket!");
if ((bucket = malloc(sizeof(struct objc_hashtable_bucket))) == NULL)
ERROR("Not enough memory to allocate hash table bucket!");
OBJC_ERROR("Not enough memory to allocate hash table bucket!");
bucket->key = key;
bucket->hash = hash;
bucket->obj = obj;
h->data[i] = bucket;
h->count++;
|
︙ | | |
Modified src/runtime/lookup.m
from [34d39a737b]
to [ef50fd350e].
︙ | | |
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
|
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
|
-
+
-
+
|
objc_initialize_class(cls);
if (!(cls->info & OBJC_CLASS_INFO_SETUP)) {
if (is_class)
return objc_msg_lookup(nil, sel);
else
ERROR("Could not dispatch message for "
OBJC_ERROR("Could not dispatch message for "
"incomplete class %s!", cls->name);
}
/*
* We don't need to handle the case that super was called.
* The reason for this is that a call to super is not possible
* before a message to the class has been sent and it thus has
* been initialized together with its superclasses.
*/
return objc_msg_lookup(obj, sel);
}
if (objc_forward_handler != NULL)
return objc_forward_handler(obj, sel);
ERROR("Selector %s is not implemented for class %s!",
OBJC_ERROR("Selector %s is not implemented for class %s!",
sel_getName(sel), object_getClassName(obj));
}
BOOL
class_respondsToSelector(Class cls, SEL sel)
{
if (cls == Nil)
|
︙ | | |
Modified src/runtime/runtime-private.h
from [3a008110cb]
to [fdc49ba79e].
︙ | | |
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
-
+
|
uint8_t i = idx >> 8;
uint8_t j = idx;
return (void*)s->buckets[i]->buckets[j];
#endif
}
#define ERROR(...) \
#define OBJC_ERROR(...) \
{ \
fprintf(stderr, "[objc @ " __FILE__ ":%d] ", __LINE__); \
fprintf(stderr, __VA_ARGS__); \
fputs("\n", stderr); \
abort(); \
}
|
Modified src/runtime/selector.m
from [f1aef89fda]
to [c767975d02].
︙ | | |
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
-
+
|
selector_names = objc_sparsearray_new();
name = sel->name;
rsel = (struct objc_selector*)sel;
rsel->uid = selectors_cnt++;
if (selectors_cnt > SEL_MAX)
ERROR("Out of selector slots!");
OBJC_ERROR("Out of selector slots!");
objc_hashtable_set(selectors, name, rsel);
objc_sparsearray_set(selector_names, (uint32_t)rsel->uid, name);
}
SEL
sel_registerName(const char *name)
|
︙ | | |
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
-
+
-
+
|
(rsel = objc_hashtable_get(selectors, name)) != NULL) {
objc_global_mutex_unlock();
return (SEL)rsel;
}
/* FIXME: Free on objc_exit() */
if ((sel = malloc(sizeof(struct objc_abi_selector))) == NULL)
ERROR("Not enough memory to allocate selector!");
OBJC_ERROR("Not enough memory to allocate selector!");
if ((sel->name = strdup(name)) == NULL)
ERROR("Not enough memory to allocate selector!");
OBJC_ERROR("Not enough memory to allocate selector!");
sel->types = NULL;
objc_register_selector(sel);
objc_global_mutex_unlock();
return (SEL)sel;
|
︙ | | |
Modified src/runtime/sparsearray.m
from [e7f682556c]
to [ac1c630c4c].
︙ | | |
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
-
+
-
+
|
static void
init(void)
{
uint_fast16_t i;
empty_level2 = malloc(sizeof(struct objc_sparsearray_level2));
if (empty_level2 == NULL)
ERROR("Not enough memory to allocate sparse array!");
OBJC_ERROR("Not enough memory to allocate sparse array!");
empty_level2->empty = YES;
#ifndef OF_SELUID16
empty_level3 = malloc(sizeof(struct objc_sparsearray_level3));
if (empty_level3 == NULL)
ERROR("Not enough memory to allocate sparse array!");
OBJC_ERROR("Not enough memory to allocate sparse array!");
empty_level3->empty = YES;
#endif
#ifndef OF_SELUID16
for (i = 0; i < 256; i++) {
empty_level2->buckets[i] = empty_level3;
|
︙ | | |
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
-
+
|
init();
#else
if (empty_level2 == NULL)
init();
#endif
if ((s = malloc(sizeof(struct objc_sparsearray))) == NULL)
ERROR("Not enough memory to allocate sparse array!");
OBJC_ERROR("Not enough memory to allocate sparse array!");
for (i = 0; i < 256; i++)
s->buckets[i] = empty_level2;
return s;
}
|
︙ | | |
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
-
+
+
|
if (s->buckets[i]->empty) {
struct objc_sparsearray_level2 *t;
uint_fast16_t l;
t = malloc(sizeof(struct objc_sparsearray_level2));
if (t == NULL)
ERROR("Not enough memory to insert into sparse array!");
OBJC_ERROR("Not enough memory to insert into sparse "
"array!");
t->empty = NO;
for (l = 0; l < 256; l++)
#ifndef OF_SELUID16
t->buckets[l] = empty_level3;
#else
|
︙ | | |
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
-
+
+
|
if (s->buckets[i]->buckets[j]->empty) {
struct objc_sparsearray_level3 *t;
uint_fast16_t l;
t = malloc(sizeof(struct objc_sparsearray_level3));
if (t == NULL)
ERROR("Not enough memory to insert into sparse array!");
OBJC_ERROR("Not enough memory to insert into sparse "
"array!");
t->empty = NO;
for (l = 0; l < 256; l++)
t->buckets[l] = NULL;
s->buckets[i]->buckets[j] = t;
|
︙ | | |
Modified src/runtime/static-instances.m
from [3523e88639]
to [f95b35ea0d].
︙ | | |
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
-
-
+
+
|
static_instances[static_instances_cnt];
static_instances = realloc(static_instances,
sizeof(struct objc_abi_static_instances*) *
static_instances_cnt);
if (static_instances == NULL)
ERROR("Not enough memory for list of static "
"instances!");
OBJC_ERROR("Not enough memory for list of "
"static instances!");
}
}
si = (struct objc_abi_static_instances**)
symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
if (si == NULL)
|
︙ | | |
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
-
-
+
+
|
struct objc_abi_static_instances*));
else
static_instances = realloc(static_instances,
sizeof(struct objc_abi_static_instances*) *
(static_instances_cnt + 1));
if (static_instances == NULL)
ERROR("Not enough memory for list of static "
"instances!");
OBJC_ERROR("Not enough memory for list of "
"static instances!");
static_instances[static_instances_cnt++] = *si;
}
}
}
|
Modified src/runtime/threading.m
from [92014702e9]
to [1343be0c29].
︙ | | |
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
|
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
|
-
+
-
+
-
+
-
+
|
return of_mutex_free(&mutex->mutex);
}
static void
objc_global_mutex_new(void)
{
if (!objc_mutex_new(&global_mutex))
ERROR("Failed to create global mutex!");
OBJC_ERROR("Failed to create global mutex!");
global_mutex_init = YES;
}
void
objc_global_mutex_lock(void)
{
if (!global_mutex_init)
objc_global_mutex_new();
if (!objc_mutex_lock(&global_mutex))
ERROR("Failed to lock global mutex!");
OBJC_ERROR("Failed to lock global mutex!");
}
void
objc_global_mutex_unlock(void)
{
if (!objc_mutex_unlock(&global_mutex))
ERROR("Failed to unlock global mutex!");
OBJC_ERROR("Failed to unlock global mutex!");
}
void
objc_global_mutex_free(void)
{
if (!objc_mutex_free(&global_mutex))
ERROR("Failed to free global mutex!");
OBJC_ERROR("Failed to free global mutex!");
}
|