|
|
|
|
@ -1,6 +1,8 @@
|
|
|
|
|
#include "magic_objects.h"
|
|
|
|
|
#include "objc/objc-api.h"
|
|
|
|
|
#include "lock.h"
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
|
|
// Get the functions for string hashing
|
|
|
|
|
#include "string_hash.h"
|
|
|
|
|
@ -26,8 +28,25 @@ static int class_hash(const Class class)
|
|
|
|
|
|
|
|
|
|
static class_table_internal_table *class_table;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define unresolved_class_next subclass_list
|
|
|
|
|
#define unresolved_class_prev sibling_class
|
|
|
|
|
/**
|
|
|
|
|
* Linked list using the subclass_list pointer in unresolved classes.
|
|
|
|
|
*/
|
|
|
|
|
static Class unresolved_class_list;
|
|
|
|
|
|
|
|
|
|
void class_table_insert(Class class)
|
|
|
|
|
{
|
|
|
|
|
if (!CLS_ISRESOLV(class))
|
|
|
|
|
{
|
|
|
|
|
if (Nil != unresolved_class_list)
|
|
|
|
|
{
|
|
|
|
|
unresolved_class_list->unresolved_class_prev = class;
|
|
|
|
|
}
|
|
|
|
|
class->unresolved_class_next = unresolved_class_list;
|
|
|
|
|
unresolved_class_list = class;
|
|
|
|
|
}
|
|
|
|
|
class_table_internal_insert(class_table, class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -36,8 +55,7 @@ Class class_table_get_safe(const char *class_name)
|
|
|
|
|
return class_table_internal_table_get(class_table, class_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Class
|
|
|
|
|
class_table_next (void **e)
|
|
|
|
|
Class class_table_next(void **e)
|
|
|
|
|
{
|
|
|
|
|
return class_table_internal_next(class_table,
|
|
|
|
|
(struct class_table_internal_table_enumerator**)e);
|
|
|
|
|
@ -47,3 +65,75 @@ void __objc_init_class_tables(void)
|
|
|
|
|
{
|
|
|
|
|
class_table = class_table_internal_create(16);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void objc_resolve_class(Class cls)
|
|
|
|
|
{
|
|
|
|
|
// Skip this if the class is already resolved.
|
|
|
|
|
if (CLS_ISRESOLV(cls)) { return; }
|
|
|
|
|
// Remove the class from the unresolved class list
|
|
|
|
|
if (Nil == cls->unresolved_class_prev)
|
|
|
|
|
{
|
|
|
|
|
unresolved_class_list = cls->unresolved_class_next;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
cls->unresolved_class_prev->unresolved_class_next =
|
|
|
|
|
cls->unresolved_class_next;
|
|
|
|
|
}
|
|
|
|
|
if (Nil != cls->unresolved_class_next)
|
|
|
|
|
{
|
|
|
|
|
cls->unresolved_class_next->unresolved_class_prev =
|
|
|
|
|
cls->unresolved_class_prev;
|
|
|
|
|
}
|
|
|
|
|
cls->unresolved_class_prev = Nil;
|
|
|
|
|
cls->unresolved_class_next = Nil;
|
|
|
|
|
|
|
|
|
|
static Class root_class = Nil;
|
|
|
|
|
if (Nil == root_class)
|
|
|
|
|
{
|
|
|
|
|
root_class = objc_get_class(ROOT_OBJECT_CLASS_NAME);
|
|
|
|
|
if (!CLS_ISRESOLV(root_class))
|
|
|
|
|
{
|
|
|
|
|
objc_resolve_class(root_class);
|
|
|
|
|
}
|
|
|
|
|
assert(root_class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Resolve the superclass pointer
|
|
|
|
|
|
|
|
|
|
// If this class has no superclass, use [NS]Object
|
|
|
|
|
Class super = root_class;
|
|
|
|
|
Class superMeta = root_class;
|
|
|
|
|
if (NULL != cls->super_class)
|
|
|
|
|
{
|
|
|
|
|
// Resolve the superclass if it isn't already resolved
|
|
|
|
|
super = objc_get_class((char*)cls->super_class);
|
|
|
|
|
if (!CLS_ISRESOLV(super))
|
|
|
|
|
{
|
|
|
|
|
objc_resolve_class(super);
|
|
|
|
|
}
|
|
|
|
|
superMeta = super->class_pointer;
|
|
|
|
|
// Set the superclass pointer for the class and the superclass
|
|
|
|
|
cls->super_class = super;
|
|
|
|
|
cls->class_pointer->super_class = super->class_pointer;
|
|
|
|
|
}
|
|
|
|
|
// Set up the class links
|
|
|
|
|
cls->sibling_class = super->subclass_list;
|
|
|
|
|
super->subclass_list = cls;
|
|
|
|
|
// Set up the metaclass links
|
|
|
|
|
cls->class_pointer->sibling_class = superMeta->subclass_list;
|
|
|
|
|
superMeta->subclass_list = cls->class_pointer;
|
|
|
|
|
// Mark this class (and its metaclass) as resolved
|
|
|
|
|
CLS_SETRESOLV(cls);
|
|
|
|
|
CLS_SETRESOLV(cls->class_pointer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void __objc_resolve_class_links(void)
|
|
|
|
|
{
|
|
|
|
|
LOCK(__objc_runtime_mutex);
|
|
|
|
|
Class class;
|
|
|
|
|
while ((class = unresolved_class_list))
|
|
|
|
|
{
|
|
|
|
|
objc_resolve_class(class);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|