/* GNU Objective C Runtime class related functions
- Copyright (C) 1993, 1995, 1996, 1997, 2001, 2002, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1993-2017 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup and Dennis Glatting.
Lock-free class table code designed and written from scratch by
return objc_get_class (name)->class_pointer;
}
+/* This is not used by GCC, but the clang compiler seems to use it
+ when targeting the GNU runtime. That's wrong, but we have it to
+ be compatible. */
+Class
+objc_lookup_class (const char *name)
+{
+ return objc_getClass (name);
+}
+
/* This is used when the implementation of a method changes. It goes
through all classes, looking for the ones that have these methods
(either method_a or method_b; method_b can be NULL), and reloads
while (node != NULL)
{
- /* Iterate over all methods in the class. */
- Class class = node->pointer;
- struct objc_method_list * method_list = class->methods;
-
- while (method_list)
+ /* We execute this loop twice: the first time, we iterate
+ over all methods in the class (instance methods), while
+ the second time we iterate over all methods in the meta
+ class (class methods). */
+ Class class = Nil;
+ BOOL done = NO;
+
+ while (done == NO)
{
- int i;
+ struct objc_method_list * method_list;
- for (i = 0; i < method_list->method_count; ++i)
+ if (class == Nil)
+ {
+ /* The first time, we work on the class. */
+ class = node->pointer;
+ }
+ else
{
- struct objc_method *method = &method_list->method_list[i];
+ /* The second time, we work on the meta class. */
+ class = class->class_pointer;
+ done = YES;
+ }
- /* If the method is one of the ones we are looking
- for, update the implementation. */
- if (method == method_a)
- sarray_at_put_safe (class->dtable,
- (sidx) method_a->method_name->sel_id,
- method_a->method_imp);
+ method_list = class->methods;
- if (method == method_b)
+ while (method_list)
+ {
+ int i;
+
+ for (i = 0; i < method_list->method_count; ++i)
{
- if (method_b != NULL)
+ struct objc_method *method = &method_list->method_list[i];
+
+ /* If the method is one of the ones we are
+ looking for, update the implementation. */
+ if (method == method_a)
sarray_at_put_safe (class->dtable,
- (sidx) method_b->method_name->sel_id,
- method_b->method_imp);
+ (sidx) method_a->method_name->sel_id,
+ method_a->method_imp);
+
+ if (method == method_b)
+ {
+ if (method_b != NULL)
+ sarray_at_put_safe (class->dtable,
+ (sidx) method_b->method_name->sel_id,
+ method_b->method_imp);
+ }
}
+
+ method_list = method_list->method_next;
}
-
- method_list = method_list->method_next;
}
node = node->next;
}
/* Classes that are in construction are not resolved, and still have
the class name (instead of a class pointer) in the
- class_->superclass field. In that case we need to lookup the
+ class_->super_class field. In that case we need to lookup the
superclass name to return the superclass. We can not resolve the
class until it is registered. */
if (CLS_IS_IN_CONSTRUCTION (class_))
- return objc_lookUpClass ((const char *)(class_->super_class));
+ {
+ if (CLS_ISMETA (class_))
+ return object_getClass ((id)objc_lookUpClass ((const char *)(class_->super_class)));
+ else
+ return objc_lookUpClass ((const char *)(class_->super_class));
+ }
/* If the class is not resolved yet, super_class would point to a
string (the name of the super class) as opposed to the actual