mirror of
https://github.com/darlinghq/darling-libobjc2.git
synced 2024-11-23 20:29:50 +00:00
Rewrote class resolving code. Now it only resolves classes that actually need resolving, rather than iterating over the entire class table.
(This is part 1. Part 2 will lazily resolve classes.)
This commit is contained in:
parent
bfbd52709b
commit
8ce32fd1c9
23
NSBlocks.m
23
NSBlocks.m
@ -12,6 +12,7 @@ static struct objc_class _NSBlock;
|
||||
static struct objc_class _NSBlockMeta;
|
||||
|
||||
void __objc_update_dispatch_table_for_class(Class);
|
||||
void __objc_add_class_to_hash(Class);
|
||||
extern struct sarray *__objc_uninstalled_dtable;
|
||||
extern objc_mutex_t __objc_runtime_mutex;
|
||||
|
||||
@ -19,32 +20,20 @@ static void createNSBlockSubclass(Class superclass, Class newClass,
|
||||
Class metaClass, char *name)
|
||||
{
|
||||
// Initialize the metaclass
|
||||
metaClass->class_pointer = superclass->class_pointer;
|
||||
metaClass->super_class = superclass->class_pointer;
|
||||
//metaClass->class_pointer = superclass->class_pointer;
|
||||
//metaClass->super_class = superclass->class_pointer;
|
||||
metaClass->info = _CLS_META;
|
||||
metaClass->dtable = __objc_uninstalled_dtable;
|
||||
|
||||
// Set up the new class
|
||||
newClass->class_pointer = metaClass;
|
||||
newClass->super_class = superclass;
|
||||
newClass->super_class = superclass->name;
|
||||
newClass->name = name;
|
||||
newClass->info = _CLS_CLASS;
|
||||
newClass->dtable = __objc_uninstalled_dtable;
|
||||
|
||||
// Initialize the dispatch table for the class and metaclass.
|
||||
__objc_update_dispatch_table_for_class(metaClass);
|
||||
__objc_update_dispatch_table_for_class(newClass);
|
||||
CLS_SETINITIALIZED(metaClass);
|
||||
CLS_SETINITIALIZED(newClass);
|
||||
CLS_SETRESOLV(metaClass);
|
||||
CLS_SETRESOLV(newClass);
|
||||
// Add pointer from super class
|
||||
objc_mutex_lock(__objc_runtime_mutex);
|
||||
newClass->sibling_class = newClass->super_class->subclass_list;
|
||||
newClass->super_class->subclass_list = newClass;
|
||||
metaClass->sibling_class = metaClass->super_class->subclass_list;
|
||||
metaClass->super_class->subclass_list = metaClass;
|
||||
objc_mutex_unlock(__objc_runtime_mutex);
|
||||
__objc_add_class_to_hash(newClass);
|
||||
|
||||
}
|
||||
|
||||
#define NEW_CLASS(super, sub) \
|
||||
|
81
class.c
81
class.c
@ -224,87 +224,6 @@ objc_next_class (void **enum_state)
|
||||
return class;
|
||||
}
|
||||
|
||||
/* Resolve super/subclass links for all classes. The only thing we
|
||||
can be sure of is that the class_pointer for class objects point to
|
||||
the right meta class objects. */
|
||||
void
|
||||
__objc_resolve_class_links (void)
|
||||
{
|
||||
void *es = NULL;
|
||||
Class object_class = objc_get_class (ROOT_OBJECT_CLASS_NAME);
|
||||
Class class1;
|
||||
|
||||
assert (object_class);
|
||||
|
||||
LOCK(__objc_runtime_mutex);
|
||||
|
||||
|
||||
/* Assign subclass links. */
|
||||
while ((class1 = class_table_next (&es)))
|
||||
{
|
||||
/* Make sure we have what we think we have. */
|
||||
assert (CLS_ISCLASS (class1));
|
||||
assert (CLS_ISMETA (class1->class_pointer));
|
||||
|
||||
/* The class_pointer of all meta classes point to Object's meta
|
||||
class. */
|
||||
class1->class_pointer->class_pointer = object_class->class_pointer;
|
||||
|
||||
if (! CLS_ISRESOLV (class1))
|
||||
{
|
||||
CLS_SETRESOLV (class1);
|
||||
CLS_SETRESOLV (class1->class_pointer);
|
||||
|
||||
if (class1->super_class)
|
||||
{
|
||||
Class a_super_class
|
||||
= objc_get_class ((char *) class1->super_class);
|
||||
|
||||
assert (a_super_class);
|
||||
|
||||
DEBUG_PRINTF ("making class connections for: %s\n",
|
||||
class1->name);
|
||||
|
||||
/* Assign subclass links for superclass. */
|
||||
class1->sibling_class = a_super_class->subclass_list;
|
||||
a_super_class->subclass_list = class1;
|
||||
|
||||
/* Assign subclass links for meta class of superclass. */
|
||||
if (a_super_class->class_pointer)
|
||||
{
|
||||
class1->class_pointer->sibling_class
|
||||
= a_super_class->class_pointer->subclass_list;
|
||||
a_super_class->class_pointer->subclass_list
|
||||
= class1->class_pointer;
|
||||
}
|
||||
}
|
||||
else /* A root class, make its meta object be a subclass of
|
||||
Object. */
|
||||
{
|
||||
class1->class_pointer->sibling_class
|
||||
= object_class->subclass_list;
|
||||
object_class->subclass_list = class1->class_pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign superclass links. */
|
||||
es = NULL;
|
||||
while ((class1 = class_table_next (&es)))
|
||||
{
|
||||
Class sub_class;
|
||||
for (sub_class = class1->subclass_list; sub_class;
|
||||
sub_class = sub_class->sibling_class)
|
||||
{
|
||||
sub_class->super_class = class1;
|
||||
if (CLS_ISCLASS (sub_class))
|
||||
sub_class->class_pointer->super_class = class1->class_pointer;
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK(__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
Class
|
||||
class_pose_as (Class impostor, Class super_class)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user