aboutsummaryrefslogtreecommitdiff
path: root/libobjc/class.c
diff options
context:
space:
mode:
authorNicola Pero <nicola.pero@meta-innovation.com>2010-10-11 18:17:19 +0000
committerNicola Pero <nicola@gcc.gnu.org>2010-10-11 18:17:19 +0000
commit90a2689f4d6b68b7542b0f7b04d66fea1cee5c0f (patch)
tree10e40b8bd1fa671cf3389ef739344e4e40b99999 /libobjc/class.c
parent6c0098673b7e6e47c026b9827ce3e0d6ccc149db (diff)
downloadgcc-90a2689f4d6b68b7542b0f7b04d66fea1cee5c0f.zip
gcc-90a2689f4d6b68b7542b0f7b04d66fea1cee5c0f.tar.gz
gcc-90a2689f4d6b68b7542b0f7b04d66fea1cee5c0f.tar.bz2
In libobjc/: 2010-10-11 Nicola Pero <nicola.pero@meta-innovation.com>
In libobjc/: 2010-10-11 Nicola Pero <nicola.pero@meta-innovation.com> * class.c (objc_getClassList): New. (objc_getRequiredClass): New. (objc_getMetaClass): New. (objc_lookupClass): New. (objc_getClass): New. (__objc_get_unknown_class_handler): New. (objc_setGetUnknownClassHandler): New. (objc_get_class): Use __objc_get_unknown_class_handler. (objc_lookup_class): Call objc_getClass. * objc/objc-api.h: Updated comment and copyright notice. * objc/runtime.h: Updated comments. (objc_getClass): New. (objc_lookupClass): New. (objc_getMetaClass): New. (objc_getRequiredClass): New. (objc_getClassList): New. (objc_setGetUnknownClassHandler): New. (objc_get_unknown_class_handler): New. * objc-private/runtime.h: Use __objc_private_runtime_INCLUDE_GNU instead of __objc_runtime_INCLUDE_GNU as include guard. * objc-private/error.h (_objc_abort): Mark as noreturn. From-SVN: r165326
Diffstat (limited to 'libobjc/class.c')
-rw-r--r--libobjc/class.c128
1 files changed, 119 insertions, 9 deletions
diff --git a/libobjc/class.c b/libobjc/class.c
index cba9b84..216d6ac 100644
--- a/libobjc/class.c
+++ b/libobjc/class.c
@@ -408,9 +408,36 @@ class_table_print_histogram (void)
/* This is a hook which is called by objc_get_class and
objc_lookup_class if the runtime is not able to find the class.
- This may e.g. try to load in the class using dynamic loading. */
+ This may e.g. try to load in the class using dynamic loading.
+
+ This hook was a public, global variable in the Traditional GNU
+ Objective-C Runtime API (objc/objc-api.h). The modern GNU
+ Objective-C Runtime API (objc/runtime.h) provides the
+ objc_setGetUnknownClassHandler() function instead.
+*/
Class (*_objc_lookup_class) (const char *name) = 0; /* !T:SAFE */
+/* Temporarily while we still include objc/objc-api.h instead of objc/runtime.h. */
+#ifndef __objc_runtime_INCLUDE_GNU
+typedef Class (*objc_get_unknown_class_handler)(const char *class_name);
+#endif
+
+/* The handler currently in use. PS: if both
+ __obj_get_unknown_class_handler and _objc_lookup_class are defined,
+ __objc_get_unknown_class_handler is called first. */
+static objc_get_unknown_class_handler
+__objc_get_unknown_class_handler = NULL;
+
+objc_get_unknown_class_handler
+objc_setGetUnknownClassHandler (objc_get_unknown_class_handler
+ new_handler)
+{
+ objc_get_unknown_class_handler old_handler
+ = __objc_get_unknown_class_handler;
+ __objc_get_unknown_class_handler = new_handler;
+ return old_handler;
+}
+
/* True when class links has been resolved. */
BOOL __objc_class_links_resolved = NO; /* !T:UNUSED */
@@ -464,25 +491,106 @@ __objc_add_class_to_hash (Class class)
objc_mutex_unlock (__objc_runtime_mutex);
}
-/* Get the class object for the class named NAME. If NAME does not
- identify a known class, the hook _objc_lookup_class is called. If
- this fails, nil is returned. */
Class
-objc_lookup_class (const char *name)
+objc_getClass (const char *name)
{
Class class;
- class = class_table_get_safe (name);
+ if (name == NULL)
+ return Nil;
+ class = class_table_get_safe (name);
+
if (class)
return class;
+
+ if (__objc_get_unknown_class_handler)
+ return (*__objc_get_unknown_class_handler) (name);
if (_objc_lookup_class)
return (*_objc_lookup_class) (name);
+
+ return Nil;
+}
+
+Class
+objc_lookupClass (const char *name)
+{
+ if (name == NULL)
+ return Nil;
+ else
+ return class_table_get_safe (name);
+}
+
+Class
+objc_getMetaClass (const char *name)
+{
+ Class class = objc_getClass (name);
+
+ if (class)
+ return class->class_pointer;
else
- return 0;
+ return Nil;
}
+Class
+objc_getRequiredClass (const char *name)
+{
+ Class class = objc_getClass (name);
+
+ if (class)
+ return class;
+ else
+ _objc_abort ("objc_getRequiredClass ('%s') failed: class not found\n", name);
+}
+
+int
+objc_getClassList (Class *returnValue, int maxNumberOfClassesToReturn)
+{
+ /* Iterate over all entries in the table. */
+ int hash, count = 0;
+
+ objc_mutex_lock (__class_table_lock);
+
+ for (hash = 0; hash < CLASS_TABLE_SIZE; hash++)
+ {
+ class_node_ptr node = class_table_array[hash];
+
+ while (node != NULL)
+ {
+ if (returnValue)
+ {
+ if (count < maxNumberOfClassesToReturn)
+ returnValue[count] = node->pointer;
+ else
+ {
+ objc_mutex_unlock (__class_table_lock);
+ return count;
+ }
+ }
+ count++;
+ node = node->next;
+ }
+ }
+
+ objc_mutex_unlock (__class_table_lock);
+ return count;
+}
+
+/* Traditional GNU Objective-C Runtime API. */
+/* Get the class object for the class named NAME. If NAME does not
+ identify a known class, the hook _objc_lookup_class is called. If
+ this fails, nil is returned. */
+Class
+objc_lookup_class (const char *name)
+{
+ return objc_getClass (name);
+}
+
+/* Traditional GNU Objective-C Runtime API. Important: this method is
+ called automatically by the compiler while messaging (if using the
+ traditional ABI), so it is worth keeping it fast; don't make it
+ just a wrapper around objc_getClass(). */
/* Get the class object for the class named NAME. If NAME does not
identify a known class, the hook _objc_lookup_class is called. If
this fails, an error message is issued and the system aborts. */
@@ -496,13 +604,15 @@ objc_get_class (const char *name)
if (class)
return class;
- if (_objc_lookup_class)
+ if (__objc_get_unknown_class_handler)
+ class = (*__objc_get_unknown_class_handler) (name);
+
+ if ((!class) && _objc_lookup_class)
class = (*_objc_lookup_class) (name);
if (class)
return class;
- /* FIXME: Should we abort the program here ? */
_objc_abort ("objc runtime: cannot find class %s\n", name);
return 0;