Skip to content

Commit ca2c7d1

Browse files
author
theraven
committed
Stop treating NSObject as magic and do what OS X does with regard to root objects and metaclasses.
1 parent 395c5fe commit ca2c7d1

File tree

5 files changed

+40
-42
lines changed

5 files changed

+40
-42
lines changed

class_table.c

+31-32
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#include "magic_objects.h"
21
#include "objc/runtime.h"
32
#include "objc/hooks.h"
43
#include "objc/developer.h"
@@ -161,21 +160,6 @@ BOOL objc_resolve_class(Class cls)
161160
}
162161

163162

164-
// Give up if we can't resolve the root class yet...
165-
static Class root_class = Nil;
166-
if (Nil == root_class)
167-
{
168-
root_class = (Class)objc_getClass(ROOT_OBJECT_CLASS_NAME);
169-
if (Nil == root_class) { return NO; }
170-
171-
if (cls != root_class && !objc_test_class_flag(root_class, objc_class_flag_resolved))
172-
{
173-
objc_resolve_class(root_class);
174-
}
175-
assert(root_class);
176-
}
177-
178-
179163
// Remove the class from the unresolved class list
180164
if (Nil == cls->unresolved_class_prev)
181165
{
@@ -194,45 +178,60 @@ BOOL objc_resolve_class(Class cls)
194178
cls->unresolved_class_prev = Nil;
195179
cls->unresolved_class_next = Nil;
196180

197-
// Resolve the superclass pointer
181+
// The superclass for the metaclass. This is the metaclass for the
182+
// superclass if one exists, otherwise it is the root class itself
183+
Class superMeta = Nil;
184+
// The metaclass for the metaclass. This is always the root class's
185+
// metaclass.
186+
Class metaMeta = Nil;
198187

199-
// If this class has no superclass, use [NS]Object
200-
Class super = root_class;
201-
Class superMeta = root_class;
202-
Class meta = cls->isa;
188+
// Resolve the superclass pointer
203189

204-
if (NULL != cls->super_class)
190+
if (NULL == cls->super_class)
191+
{
192+
superMeta = cls;
193+
metaMeta = cls->isa;
194+
}
195+
else
205196
{
206197
// Resolve the superclass if it isn't already resolved
207-
super = (Class)objc_getClass((char*)cls->super_class);
198+
Class super = (Class)objc_getClass((char*)cls->super_class);
208199
if (!objc_test_class_flag(super, objc_class_flag_resolved))
209200
{
210201
objc_resolve_class(super);
211202
}
212203
superMeta = super->isa;
213204
// Set the superclass pointer for the class and the superclass
214205
cls->super_class = super;
206+
do
207+
{
208+
metaMeta = super->isa;
209+
super = super->super_class;
210+
} while (Nil != super);
215211
}
212+
Class meta = cls->isa;
216213

217-
// Don't make the root class a subclass of itself
218-
if (cls != super)
214+
// Make the root class the superclass of the metaclass (e.g. NSObject is
215+
// the superclass of all metaclasses in classes that inherit from NSObject)
216+
meta->super_class = superMeta;
217+
meta->isa = metaMeta;
218+
219+
// Don't register root classes as children of anything
220+
if (Nil != cls->super_class)
219221
{
220222
// Set up the class links
221-
cls->sibling_class = super->subclass_list;
222-
super->subclass_list = cls;
223+
cls->sibling_class = cls->super_class->subclass_list;
224+
cls->super_class->subclass_list = cls;
223225
}
224-
// Make the root class the superclass of the metaclass (e.g. NSObject is
225-
// the superclass of all metaclasses)
226-
meta->super_class = superMeta;
227226
// Set up the metaclass links
228227
meta->sibling_class = superMeta->subclass_list;
229228
superMeta->subclass_list = meta;
230229

231230
// Mark this class (and its metaclass) as resolved
232231
objc_set_class_flag(cls, objc_class_flag_resolved);
233232
objc_set_class_flag(cls->isa, objc_class_flag_resolved);
234-
cls->isa->isa = (Nil == cls->isa->isa) ? root_class->isa :
235-
((Class)objc_getClass((char*)cls->isa->isa))->isa;
233+
234+
236235
// Fix up the ivar offsets
237236
objc_compute_ivar_offsets(cls);
238237
// Send the +load message, if required

constant_string.h

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef CONSTANT_STRING_CLASS
2+
# ifdef GNUSTEP
3+
# define CONSTANT_STRING_CLASS "NSConstantString"
4+
# else
5+
# define CONSTANT_STRING_CLASS "NXConstantString"
6+
# endif
7+
#endif

loader.c

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include "objc/runtime.h"
44
#include "lock.h"
55
#include "loader.h"
6-
#include "magic_objects.h"
76

87
/**
98
* Runtime lock. This is exposed in

magic_objects.h

-7
This file was deleted.

statics_loader.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include <stdio.h>
33
#include "objc/runtime.h"
44
#include "module.h"
5-
#include "magic_objects.h"
5+
#include "constant_string.h"
66

77
#define BUFFER_TYPE struct objc_static_instance_list
88
#include "buffer.h"
@@ -21,7 +21,7 @@ static BOOL try_init_statics(struct objc_static_instance_list *statics)
2121
// NXConstantString instances. This is a mess. We hack around this by
2222
// silently assuming that the user meant NSConstantString when they said
2323
// NXConstantString if NSConstantString is set as the constant string class
24-
// in magic_objects.h
24+
// in string_class.h or by an external -D flag.
2525
if (strcmp(class_name, "NXConstantString") == 0)
2626
{
2727
class_name = CONSTANT_STRING_CLASS;

0 commit comments

Comments
 (0)