Import from recent gcc CVS. Bump version to 1.2.3

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/libobjc/trunk@16052 72102866-910b-0410-8b05-ffd578937521
main
fedor 23 years ago
parent 5c8c6241e1
commit f6d5ab7a58

@ -1,9 +1,253 @@
Tue Feb 11 17:11:00 2003 Richard Frith-Macdonald <richard@brainstorm.co.uk> 2003-02-20 Alexandre Oliva <aoliva@redhat.com>
* init.c: Don't do the check to see if Object and NXConstantString * configure.in: Propagate ORIGINAL_LD_FOR_MULTILIBS to
are set up before calling +load ... NXConstantString is never set config.status.
when we use gcc-3.0 and later in GNUstep ... which means that * configure: Rebuilt.
+load would never be sent.
2003-01-27 Alexandre Oliva <aoliva@redhat.com>
* aclocal.m4 (glibcpp_toolexeclibdir): Instead of
$(MULTISUBDIR), use `$CC -print-multi-os-directory`, unless
version_specific_libs is enabled.
* configure: Rebuilt.
2003-01-09 Christian Cornelssen <ccorn@cs.tu-berlin.de>
* Makefile.in (FLAGS_TO_PASS): Also pass DESTDIR.
(install-libs, install-headers): Prepend $(DESTDIR) to
destination paths in all (un)installation commands.
2002-12-02 Zack Weinberg <zack@codesourcery.com>
* thr-objc.c: Include coretypes.h and tm.h.
2002-12-01 Zack Weinberg <zack@codesourcery.com>
* encoding.c, sendmsg.c: Include coretypes.h and tm.h.
2002-11-26 Nathanael Nerode <neroden@gcc.gnu.org>
* configure.in: Remove skip-this-dir support.
* configure: Regenerate.
2002-09-22 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* Makefile.in (all): Fix multilib parallel build.
Thu Sep 12 12:44:37 2002 Nicola Pero <n.pero@mi.flashnet.it>
* sendmsg.c (nil_method): Declare not to take a variable number of
args.
(objc_msg_lookup): Cast nil_method to IMP before returning it.
(objc_msg_lookup_super): The same.
2002-09-10 Jan Hubicka <jh@suse.cz>
* nil_method.c (nil_method): No longer defined with variable
arguments.
2002-07-02 Rodney Brown <rbrown64@csc.com.au>
* objc/encoding.h: Fix formatting.
* objc/hash.h: Likewise.
* objc/objc-api.h: Likewise.
* objc/runtime.h: Likewise.
* objc/thr.h: Likewise.
* archive.c: Likewise.
* class.c: Likewise.
* encoding.c: Likewise.
* gc.c: Likewise.
* hash.c: Likewise.
* init.c: Likewise.
* misc.c: Likewise.
* nil_method.c: Likewise.
* objects.c: Likewise.
* sarray.c: Likewise.
* selector.c: Likewise.
* sendmsg.c: Likewise.
* thr-mach.c: Likewise.
* thr.c: Likewise.
2002-06-25 DJ Delorie <dj@redhat.com>
* aclocal.m4 (GLIBCPP_CONFIGURE): Split out
GLIBCPP_TOPREL_CONFIGURE.
* configure.in: Call it before AC_CANONICAL_SYSTEM.
* configure: Regenerate.
2002-06-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* Object.m (forward, read, write): Fix unused parameter warnings.
* encoding.c: Include <stdlib.h>.
(target_flags): Mark with attribute unused.
(atoi): Delete.
* runtime.h (__objc_selector_max_index): Change to unsigned int.
(__objc_generate_gc_type_description): Prototype.
* selector.c (__objc_selector_max_index): Change to unsigned int.
Mon Jun 17 18:37:42 2002 Nicola Pero <n.pero@mi.flashnet.it>
* sendmsg.c (__objc_get_forward_imp): Fix warning by making sure
we always have a return value: if __objc_msg_forward does not
supply a forwarding implementation, return the default
__builtin_apply based one.
2002-06-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* Object.m: Fix signed/unsigned warning.
* Protocol.m: Likewise.
* archive.c: Always include stdlib.h.
(objc_read_short, objc_read_unsigned_short, objc_read_int,
objc_read_long, __objc_read_nbyte_uint, __objc_read_nbyte_ulong):
Fix signed/unsigned warning.
(objc_write_type, objc_read_type, objc_write_types,
objc_read_types): Ensure ctype 8-bit safety.
(__objc_no_write, __objc_no_read): Mark unused parameters.
* class.c (class_table_setup): Specify void arg.
* encoding.c (atoi, objc_sizeof_type, objc_alignof_type,
objc_skip_typespec, objc_skip_offset,
objc_layout_structure_next_member): Ensure ctype 8-bit safety.
(objc_layout_structure_next_member): Ensure variables are
initialized.
* gc.c (__objc_generate_gc_type_description,
class_ivar_set_gcinvisible): Mark unused parameters.
* init.c (__objc_send_load, __objc_destroy_class_tree_node): Mark
unused parameters.
(__objc_init_protocols) Fix signed/unsigned warning.
* nil_method.c (nil_method): Mark unused parameters.
* thr.h (objc_thread_callback): Specify void arg.
* sarray.c (sarray_new, sarray_realloc, sarray_free): Fix
signed/unsigned warning.
(sarray_free): Fix formatting.
* selector.c (sel_types_match): Ensure ctype 8-bit safety.
* sendmsg.c (__objc_init_install_dtable) Mark unused parameters.
2002-06-09 Andreas Jaeger <aj@suse.de>
* encoding.c (objc_layout_structure_next_member): Remove unused
variable.
2002-05-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* Makefile.in (SHELL): Set to @SHELL@.
(WARN_CFLAGS): New.
(ALL_CFLAGS): Add $(WARN_CFLAGS).
2002-05-16 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
* aclocal.m4: Allow for PWDCMD to override hardcoded pwd.
* configure: Regenerate.
2002-05-08 Alexandre Oliva <aoliva@redhat.com>
* configure.in (ORIGINAL_LD_FOR_MULTILIBS): Preserve LD at
script entry, and set LD to it when configuring multilibs.
* configure: Rebuilt.
2002-04-19 David O'Brien <obrien@FreeBSD.org>
* encoding.c (MAX, MIN, ROUNDING): #undef before defining.
2002-04-09 Hans-Peter Nilsson <hp@bitrange.com>
PR objc/6107
* objc/objc-api.h (struct objc_protocol_list): Change type of
member count from int to size_t.
2002-02-11 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
PR libobjc/4039
* aclocal.m4: Replace with version copied from libstdc++-v3.
* configure.in: Update for changes to aclocal and Makefile.
* configure: Regenerate.
* Makefile.in: Correct install of multilibs and shared libs, use
INSTALL_DATA for include files.
Mon Dec 17 17:02:12 2001 Nicola Pero <nicola@brainstorm.co.uk>
* init.c (__objc_exec_class): Fixed bug in the loop on unclaimed
categories - when an unclaimed category was found, the loop was
doing two steps forward instead of one, so that in certain cases
it was failing to properly load all the categories. (Reported
with fix by Alexander Malmberg <alexander@malmberg.org>).
2001-11-14 Aldy Hernandez <aldyh@redhat.com>
* encoding.c: Add target_flags.
2001-11-07 Aldy Hernandez <aldyh@redhat.com>
* objc/objc-api.h (_C_VECTOR): New.
* encoding.c (VECTOR_TYPE): New.
Mon Oct 29 21:29:21 2001 Nicola Pero <n.pero@mi.flashnet.it>
* class.c: Rewritten the class table to use optimized, lock-free
lookup. This more than doubles the speed of class method
invocations. (class_table_setup), (class_table_insert),
(class_table_replace), (class_table_get_safe),
(class_table_next), (class_table_print),
(class_table_print_histogram): New functions.
(__objc_init_class_tables): Use class_table_setup.
(__objc_add_class_to_hash): Use class_table_get_safe and
class_table_insert. (objc_lookup_class), (objc_get_class): Do not
assert the existence of the table; do not lock the runtime; use
class_table_get_safe. (objc_next_class): Use class_table_next.
(__objc_resolve_class_links): Use class_table_next.
(class_pose_as): Use class_table_replace.
2001-09-10 Ovidiu Predescu <ovidiu@cup.hp.com>
* gc.c: Removed the DEBUG declaration.
Wed Jul 18 12:48:56 2001 Nicola Pero <n.pero@mi.flashnet.it>
* thr.c (objc_mutex_lock): Invoke __objc_thread_id directly,
rather than through objc_thread_id, to save a function call.
(objc_mutex_trylock, objc_mutex_unlock, objc_condition_wait):
Ditto.
Mon Jul 16 12:15:00 2001 Nicola Pero <n.pero@mi.flashnet.it>
* objc/objc-api.h (object_is_class): Fixed - buggy code was trying
to cast an id to a Class, which can not be done. Make the check
by using CLS_ISMETA on the class pointer instead.
(object_is_meta_class): Similar fix.
2001-06-09 Alexandre Oliva <aoliva@redhat.com>, Stephen L Moshier <moshier@mediaone.net>
* configure.in (AC_EXEEXT): Work around in case it expands to
nothing, as in autoconf 2.50.
* acinclude.m4: Likewise.
* configure: Rebuilt.
2001-06-08 Nicola Pero <n.pero@mi.flashnet.it>
* THREADS: Explain that when we compile libobjc inside GCC, we
always use thr-objc.c as a backend, which uses GCC's thread code.
2001-06-06 Richard Frith-Macdonald <rrfm@gnu.org>
* init.c (__objc_send_message_in_list): When setting a new entry
in __objc_load_methods use the method IMP as key, but check to see
if the method is in the hashtable by looking at the IMP also.
Also ... call the method after adding it to the hashtable rather
than before ... thus preventing an obscure possibility of infinite
recursion if a +load method itself loads a subclass.
2001-05-25 Ovidiu Predescu <ovidiu@cup.hp.com>
* init.c (__objc_send_message_in_list): When setting a new entry
in __objc_load_methods use the method name as key, not the method
IMP (reported by Richard Frith-Macdonald <richard@brainstorm.co.uk>).
2001-05-09 Joseph S. Myers <jsm28@cam.ac.uk>
* objc-features.texi: Move to ../gcc/objc.texi.
* fdl.texi: Remove.
* Makefile.in: Don't generate documentation from
objc-features.texi.
2001-05-01 Mark Mitchell <mark@codesourcery.com> 2001-05-01 Mark Mitchell <mark@codesourcery.com>
@ -15,6 +259,10 @@ Tue Feb 11 17:11:00 2003 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* objc-features.texi: Use the GFDL. * objc-features.texi: Use the GFDL.
Wed Mar 21 04:44:58 EST 2001 John Wehle (john@feith.com)
* encoding.c (REAL_TYPE): Define.
2001-03-19 David Edelsohn <edelsohn@gnu.org> 2001-03-19 David Edelsohn <edelsohn@gnu.org>
* encoding.c (TYPE_MODE): Define. * encoding.c (TYPE_MODE): Define.
@ -26,6 +274,15 @@ Tue Feb 11 17:11:00 2003 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* objc/thr.h: Declare them. * objc/thr.h: Declare them.
* libobjc.def: Mention them. * libobjc.def: Mention them.
2001-02-28 Ovidiu Predescu <ovidiu@cup.hp.com>
* objc-features.texi: Document the @compatibility_alias compiler
directive (description from Nicola Pero <n.pero@mi.flashnet.it>).
Fri Feb 23 18:12:00 2001 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
* sendmsg.c (__objc_forward): Delete strlen() declaration.
2001-02-08 Geoffrey Keating <geoffk@redhat.com> 2001-02-08 Geoffrey Keating <geoffk@redhat.com>
* configure.in: Don't run AC_PROG_CC_WORKS or AC_EXEEXT, because * configure.in: Don't run AC_PROG_CC_WORKS or AC_EXEEXT, because
@ -242,7 +499,7 @@ Sat Oct 17 05:21:31 1998 Ovidiu Predescu <ovidiu@slip.net>
Mon Oct 11 21:25:27 1998 Ovidiu Predescu <ovidiu@slip.net> Mon Oct 11 21:25:27 1998 Ovidiu Predescu <ovidiu@slip.net>
* encoding.c: Redefine get_inner_array_type to get the first entry * encoding.c: Redefine get_inner_array_type to get the first entry
in the structure. in the structure.
Thu Oct 8 12:21:14 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk> Thu Oct 8 12:21:14 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
@ -307,4 +564,3 @@ Mon Sep 21 23:27:10 1998 Ovidiu Predescu <ovidiu@slip.net>
1998-09-21 Ben Elliston <bje@cygnus.com> 1998-09-21 Ben Elliston <bje@cygnus.com>
* New directory. Moved files from ../gcc/objc. * New directory. Moved files from ../gcc/objc.

@ -1,3 +1,14 @@
2003-02-22 Adam Fedor <fedor@gnu.org>
* Import from recent gcc CVS. Bump version to 1.2.3
Tue Feb 11 17:11:00 2003 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* init.c: Don't do the check to see if Object and NXConstantString
are set up before calling +load ... NXConstantString is never set
when we use gcc-3.0 and later in GNUstep ... which means that
+load would never be sent.
Thu Sep 12 13:15:00 2002 Nicola Pero <n.pero@mi.flashnet.it> Thu Sep 12 13:15:00 2002 Nicola Pero <n.pero@mi.flashnet.it>
* libobjc.def (objc_set_error_handler): Added. * libobjc.def (objc_set_error_handler): Added.

@ -26,7 +26,7 @@
include $(GNUSTEP_SYSTEM_ROOT)/Makefiles/common.make include $(GNUSTEP_SYSTEM_ROOT)/Makefiles/common.make
PACKAGE_NAME = gnustep-objc PACKAGE_NAME = gnustep-objc
VERSION=1.2.2 VERSION=1.2.3
CVS_MODULE_NAME = objc CVS_MODULE_NAME = objc

@ -30,8 +30,6 @@ Boston, MA 02111-1307, USA. */
/* FIXME: This file has no business including tm.h. */ /* FIXME: This file has no business including tm.h. */
#include "tconfig.h" #include "tconfig.h"
#include "coretypes.h"
#include "tm.h"
#include "objc-api.h" #include "objc-api.h"
#include "encoding.h" #include "encoding.h"
#include <stdlib.h> #include <stdlib.h>

@ -47,7 +47,7 @@ hash_new (unsigned int size, hash_func_type hash_func,
/* Pass me a value greater than 0 and a power of 2. */ /* Pass me a value greater than 0 and a power of 2. */
assert (size); assert (size);
assert (!(size & (size - 1))); assert (! (size & (size - 1)));
/* Allocate the cache structure. calloc insures /* Allocate the cache structure. calloc insures
its initialization for default values. */ its initialization for default values. */
@ -196,7 +196,7 @@ hash_remove (cache_ptr cache, const void *key)
objc_free(node); objc_free(node);
} else } else
prev = node, node = node->next; prev = node, node = node->next;
} while (!removed && node); } while (! removed && node);
assert (removed); assert (removed);
} }
@ -210,7 +210,7 @@ hash_next (cache_ptr cache, node_ptr node)
{ {
/* If the scan is being started then reset the last node /* If the scan is being started then reset the last node
visitied pointer and bucket index. */ visitied pointer and bucket index. */
if (!node) if (! node)
cache->last_bucket = 0; cache->last_bucket = 0;
/* If there is a node visited last then check for another /* If there is a node visited last then check for another
@ -258,7 +258,7 @@ hash_value_for_key (cache_ptr cache, const void *key)
break; break;
} else } else
node = node->next; node = node->next;
} while (!retval && node); } while (! retval && node);
return retval; return retval;
} }

380
init.c

@ -1,5 +1,5 @@
/* GNU Objective C Runtime initialization /* GNU Objective C Runtime initialization
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup Contributed by Kresten Krab Thorup
+load support contributed by Ovidiu Predescu <ovidiu@net-community.com> +load support contributed by Ovidiu Predescu <ovidiu@net-community.com>
@ -27,62 +27,62 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "runtime.h" #include "runtime.h"
/* The version number of this runtime. This must match the number /* The version number of this runtime. This must match the number
defined in gcc (objc-act.c) */ defined in gcc (objc-act.c). */
#define OBJC_VERSION 8 #define OBJC_VERSION 8
#define PROTOCOL_VERSION 2 #define PROTOCOL_VERSION 2
/* This list contains all modules currently loaded into the runtime */ /* This list contains all modules currently loaded into the runtime. */
static struct objc_list* __objc_module_list = 0; /* !T:MUTEX */ static struct objc_list *__objc_module_list = 0; /* !T:MUTEX */
/* This list contains all proto_list's not yet assigned class links */ /* This list contains all proto_list's not yet assigned class links. */
static struct objc_list* unclaimed_proto_list = 0; /* !T:MUTEX */ static struct objc_list *unclaimed_proto_list = 0; /* !T:MUTEX */
/* List of unresolved static instances. */ /* List of unresolved static instances. */
static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */ static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */
/* Global runtime "write" mutex. */ /* Global runtime "write" mutex. */
objc_mutex_t __objc_runtime_mutex = 0; objc_mutex_t __objc_runtime_mutex = 0;
/* Number of threads that are alive. */ /* Number of threads that are alive. */
int __objc_runtime_threads_alive = 1; /* !T:MUTEX */ int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
/* Check compiler vs runtime version */ /* Check compiler vs runtime version. */
static void init_check_module_version (Module_t); static void init_check_module_version (Module_t);
/* Assign isa links to protos */ /* Assign isa links to protos. */
static void __objc_init_protocols (struct objc_protocol_list* protos); static void __objc_init_protocols (struct objc_protocol_list *protos);
/* Add protocol to class */ /* Add protocol to class. */
static void __objc_class_add_protocols (Class, struct objc_protocol_list*); static void __objc_class_add_protocols (Class, struct objc_protocol_list *);
/* This is a hook which is called by __objc_exec_class every time a class /* This is a hook which is called by __objc_exec_class every time a
or a category is loaded into the runtime. This may e.g. help a class or a category is loaded into the runtime. This may e.g. help
dynamic loader determine the classes that have been loaded when a dynamic loader determine the classes that have been loaded when
an object file is dynamically linked in */ an object file is dynamically linked in. */
void (*_objc_load_callback)(Class class, Category* category); /* !T:SAFE */ void (*_objc_load_callback) (Class class, Category *category); /* !T:SAFE */
/* Is all categories/classes resolved? */ /* Is all categories/classes resolved? */
BOOL __objc_dangling_categories = NO; /* !T:UNUSED */ BOOL __objc_dangling_categories = NO; /* !T:UNUSED */
extern SEL extern SEL
__sel_register_typed_name (const char *name, const char *types, __sel_register_typed_name (const char *name, const char *types,
struct objc_selector *orig, BOOL is_const); struct objc_selector *orig, BOOL is_const);
/* Sends +load to all classes and categories in certain situations. */ /* Sends +load to all classes and categories in certain situations. */
static void objc_send_load (void); static void objc_send_load (void);
/* Inserts all the classes defined in module in a tree of classes that /* Inserts all the classes defined in module in a tree of classes that
resembles the class hierarchy. This tree is traversed in preorder and the resembles the class hierarchy. This tree is traversed in preorder
classes in its nodes receive the +load message if these methods were not and the classes in its nodes receive the +load message if these
executed before. The algorithm ensures that when the +load method of a class methods were not executed before. The algorithm ensures that when
is executed all the superclasses have been already received the +load the +load method of a class is executed all the superclasses have
message. */ been already received the +load message. */
static void __objc_create_classes_tree (Module_t module); static void __objc_create_classes_tree (Module_t module);
static void __objc_call_callback (Module_t module); static void __objc_call_callback (Module_t module);
/* A special version that works only before the classes are completely /* A special version that works only before the classes are completely
installed in the runtime. */ installed in the runtime. */
static BOOL class_is_subclass_of_class (Class class, Class superclass); static BOOL class_is_subclass_of_class (Class class, Class superclass);
typedef struct objc_class_tree { typedef struct objc_class_tree {
@ -90,24 +90,26 @@ typedef struct objc_class_tree {
struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */ struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */
} objc_class_tree; } objc_class_tree;
/* This is a linked list of objc_class_tree trees. The head of these trees /* This is a linked list of objc_class_tree trees. The head of these
are root classes (their super class is Nil). These different trees trees are root classes (their super class is Nil). These different
represent different class hierarchies. */ trees represent different class hierarchies. */
static struct objc_list *__objc_class_tree_list = NULL; static struct objc_list *__objc_class_tree_list = NULL;
/* Keeps the +load methods who have been already executed. This hash should /* Keeps the +load methods who have been already executed. This hash
not be destroyed during the execution of the program. */ should not be destroyed during the execution of the program. */
static cache_ptr __objc_load_methods = NULL; static cache_ptr __objc_load_methods = NULL;
/* Creates a tree of classes whose topmost class is directly inherited from /* Creates a tree of classes whose topmost class is directly inherited
`upper' and the bottom class in this tree is `bottom_class'. The classes from `upper' and the bottom class in this tree is
in this tree are super classes of `bottom_class'. `subclasses' member `bottom_class'. The classes in this tree are super classes of
of each tree node point to the next subclass tree node. */ `bottom_class'. `subclasses' member of each tree node point to the
next subclass tree node. */
static objc_class_tree * static objc_class_tree *
create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper) create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
{ {
Class superclass = bottom_class->super_class ? Class superclass = bottom_class->super_class ?
objc_lookup_class ((char*)bottom_class->super_class) objc_lookup_class ((char *) bottom_class->super_class)
: Nil; : Nil;
objc_class_tree *tree, *prev; objc_class_tree *tree, *prev;
@ -126,7 +128,7 @@ create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
tree->class = superclass; tree->class = superclass;
tree->subclasses = list_cons (prev, tree->subclasses); tree->subclasses = list_cons (prev, tree->subclasses);
superclass = (superclass->super_class ? superclass = (superclass->super_class ?
objc_lookup_class ((char*)superclass->super_class) objc_lookup_class ((char *) superclass->super_class)
: Nil); : Nil);
prev = tree; prev = tree;
} }
@ -134,11 +136,13 @@ create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
return tree; return tree;
} }
/* Insert the `class' into the proper place in the `tree' class hierarchy. This /* Insert the `class' into the proper place in the `tree' class
function returns a new tree if the class has been successfully inserted into hierarchy. This function returns a new tree if the class has been
the tree or NULL if the class is not part of the classes hierarchy described successfully inserted into the tree or NULL if the class is not
by `tree'. This function is private to objc_tree_insert_class(), you should part of the classes hierarchy described by `tree'. This function is
not call it directly. */ private to objc_tree_insert_class (), you should not call it
directly. */
static objc_class_tree * static objc_class_tree *
__objc_tree_insert_class (objc_class_tree *tree, Class class) __objc_tree_insert_class (objc_class_tree *tree, Class class)
{ {
@ -154,21 +158,21 @@ __objc_tree_insert_class (objc_class_tree *tree, Class class)
return tree; return tree;
} }
else if ((class->super_class ? else if ((class->super_class ?
objc_lookup_class ((char*)class->super_class) objc_lookup_class ((char *) class->super_class)
: Nil) : Nil)
== tree->class) == tree->class)
{ {
/* If class is a direct subclass of tree->class then add class to the /* If class is a direct subclass of tree->class then add class to the
list of subclasses. First check to see if it wasn't already list of subclasses. First check to see if it wasn't already
inserted. */ inserted. */
struct objc_list *list = tree->subclasses; struct objc_list *list = tree->subclasses;
objc_class_tree *node; objc_class_tree *node;
while (list) while (list)
{ {
/* Class has been already inserted; do nothing just return /* Class has been already inserted; do nothing just return
the tree. */ the tree. */
if (((objc_class_tree*)list->head)->class == class) if (((objc_class_tree *) list->head)->class == class)
{ {
DEBUG_PRINTF ("2. class %s was previously inserted\n", DEBUG_PRINTF ("2. class %s was previously inserted\n",
class->name); class->name);
@ -186,24 +190,25 @@ __objc_tree_insert_class (objc_class_tree *tree, Class class)
} }
else else
{ {
/* The class is not a direct subclass of tree->class. Search for class's /* The class is not a direct subclass of tree->class. Search for
superclasses in the list of subclasses. */ class's superclasses in the list of subclasses. */
struct objc_list *subclasses = tree->subclasses; struct objc_list *subclasses = tree->subclasses;
/* Precondition: the class must be a subclass of tree->class; otherwise /* Precondition: the class must be a subclass of tree->class;
return NULL to indicate our caller that it must take the next tree. */ otherwise return NULL to indicate our caller that it must
if (!class_is_subclass_of_class (class, tree->class)) take the next tree. */
if (! class_is_subclass_of_class (class, tree->class))
return NULL; return NULL;
for (; subclasses != NULL; subclasses = subclasses->tail) for (; subclasses != NULL; subclasses = subclasses->tail)
{ {
Class aClass = ((objc_class_tree*)(subclasses->head))->class; Class aClass = ((objc_class_tree *) (subclasses->head))->class;
if (class_is_subclass_of_class (class, aClass)) if (class_is_subclass_of_class (class, aClass))
{ {
/* If we found one of class's superclasses we insert the class /* If we found one of class's superclasses we insert the
into its subtree and return the original tree since nothing class into its subtree and return the original tree
has been changed. */ since nothing has been changed. */
subclasses->head subclasses->head
= __objc_tree_insert_class (subclasses->head, class); = __objc_tree_insert_class (subclasses->head, class);
DEBUG_PRINTF ("4. class %s inserted\n", class->name); DEBUG_PRINTF ("4. class %s inserted\n", class->name);
@ -211,12 +216,12 @@ __objc_tree_insert_class (objc_class_tree *tree, Class class)
} }
} }
/* We haven't found a subclass of `class' in the `subclasses' list. /* We haven't found a subclass of `class' in the `subclasses'
Create a new tree of classes whose topmost class is a direct subclass list. Create a new tree of classes whose topmost class is a
of tree->class. */ direct subclass of tree->class. */
{ {
objc_class_tree *new_tree objc_class_tree *new_tree
= create_tree_of_subclasses_inherited_from (class, tree->class); = create_tree_of_subclasses_inherited_from (class, tree->class);
tree->subclasses = list_cons (new_tree, tree->subclasses); tree->subclasses = list_cons (new_tree, tree->subclasses);
DEBUG_PRINTF ("5. class %s inserted\n", class->name); DEBUG_PRINTF ("5. class %s inserted\n", class->name);
return tree; return tree;
@ -224,7 +229,8 @@ __objc_tree_insert_class (objc_class_tree *tree, Class class)
} }
} }
/* This function inserts `class' in the right tree hierarchy classes. */ /* This function inserts `class' in the right tree hierarchy classes. */
static void static void
objc_tree_insert_class (Class class) objc_tree_insert_class (Class class)
{ {
@ -244,20 +250,21 @@ objc_tree_insert_class (Class class)
list_node = list_node->tail; list_node = list_node->tail;
} }
/* If the list was finished but the class hasn't been inserted, insert it /* If the list was finished but the class hasn't been inserted,
here. */ insert it here. */
if (!list_node) if (! list_node)
{ {
__objc_class_tree_list = list_cons (NULL, __objc_class_tree_list); __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
__objc_class_tree_list->head = __objc_tree_insert_class (NULL, class); __objc_class_tree_list->head = __objc_tree_insert_class (NULL, class);
} }
} }
/* Traverse tree in preorder. Used to send +load. */ /* Traverse tree in preorder. Used to send +load. */
static void static void
objc_preorder_traverse (objc_class_tree *tree, objc_preorder_traverse (objc_class_tree *tree,
int level, int level,
void (*function)(objc_class_tree*, int)) void (*function) (objc_class_tree *, int))
{ {
struct objc_list *node; struct objc_list *node;
@ -266,11 +273,12 @@ objc_preorder_traverse (objc_class_tree *tree,
objc_preorder_traverse (node->head, level + 1, function); objc_preorder_traverse (node->head, level + 1, function);
} }
/* Traverse tree in postorder. Used to destroy a tree. */ /* Traverse tree in postorder. Used to destroy a tree. */
static void static void
objc_postorder_traverse (objc_class_tree *tree, objc_postorder_traverse (objc_class_tree *tree,
int level, int level,
void (*function)(objc_class_tree*, int)) void (*function) (objc_class_tree *, int))
{ {
struct objc_list *node; struct objc_list *node;
@ -279,7 +287,8 @@ objc_postorder_traverse (objc_class_tree *tree,
(*function) (tree, level); (*function) (tree, level);
} }
/* Used to print a tree class hierarchy. */ /* Used to print a tree class hierarchy. */
#ifdef DEBUG_RUNTIME #ifdef DEBUG_RUNTIME
static void static void
__objc_tree_print (objc_class_tree *tree, int level) __objc_tree_print (objc_class_tree *tree, int level)
@ -292,63 +301,68 @@ __objc_tree_print (objc_class_tree *tree, int level)
} }
#endif #endif
/* Walks on a linked list of methods in the reverse order and executes all /* Walks on a linked list of methods in the reverse order and executes
the methods corresponding to `op' selector. Walking in the reverse order all the methods corresponding to `op' selector. Walking in the
assures the +load of class is executed first and then +load of categories reverse order assures the +load of class is executed first and then
because of the way in which categories are added to the class methods. */ +load of categories because of the way in which categories are
added to the class methods. */
static void static void
__objc_send_message_in_list (MethodList_t method_list, Class class, SEL op) __objc_send_message_in_list (MethodList_t method_list, Class class, SEL op)
{ {
int i; int i;
if (!method_list) if (! method_list)
return; return;
/* First execute the `op' message in the following method lists */ /* First execute the `op' message in the following method lists */
__objc_send_message_in_list (method_list->method_next, class, op); __objc_send_message_in_list (method_list->method_next, class, op);
/* Search the method list. */ /* Search the method list. */
for (i = 0; i < method_list->method_count; i++) for (i = 0; i < method_list->method_count; i++)
{ {
Method_t mth = &method_list->method_list[i]; Method_t mth = &method_list->method_list[i];
if (mth->method_name && sel_eq (mth->method_name, op) if (mth->method_name && sel_eq (mth->method_name, op)
&& !hash_is_key_in_hash (__objc_load_methods, mth->method_imp)) && ! hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
{ {
/* The method was found and wasn't previously executed. */
(*mth->method_imp) ((id)class, mth->method_name);
/* Add this method into the +load hash table */ /* Add this method into the +load hash table */
hash_add (&__objc_load_methods, mth->method_imp, mth->method_imp); hash_add (&__objc_load_methods, mth->method_imp, mth->method_imp);
DEBUG_PRINTF ("sending +load in class: %s\n", class->name); DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
/* The method was found and wasn't previously executed. */
(*mth->method_imp) ((id)class, mth->method_name);
break; break;
} }
} }
} }
static void static void
__objc_send_load (objc_class_tree *tree, int level) __objc_send_load (objc_class_tree *tree,
int level __attribute__ ((__unused__)))
{ {
static SEL load_sel = 0; static SEL load_sel = 0;
Class class = tree->class; Class class = tree->class;
MethodList_t method_list = class->class_pointer->methods; MethodList_t method_list = class->class_pointer->methods;
if (!load_sel) if (! load_sel)
load_sel = sel_register_name ("load"); load_sel = sel_register_name ("load");
__objc_send_message_in_list (method_list, class, load_sel); __objc_send_message_in_list (method_list, class, load_sel);
} }
static void static void
__objc_destroy_class_tree_node (objc_class_tree *tree, int level) __objc_destroy_class_tree_node (objc_class_tree *tree,
int level __attribute__ ((__unused__)))
{ {
objc_free (tree); objc_free (tree);
} }
/* This is used to check if the relationship between two classes before the /* This is used to check if the relationship between two classes
runtime completely installs the classes. */ before the runtime completely installs the classes. */
static BOOL static BOOL
class_is_subclass_of_class (Class class, Class superclass) class_is_subclass_of_class (Class class, Class superclass)
{ {
@ -357,19 +371,19 @@ class_is_subclass_of_class (Class class, Class superclass)
if (class == superclass) if (class == superclass)
return YES; return YES;
class = (class->super_class ? class = (class->super_class ?
objc_lookup_class ((char*)class->super_class) objc_lookup_class ((char *) class->super_class)
: Nil); : Nil);
} }
return NO; return NO;
} }
/* This list contains all the classes in the runtime system for whom their /* This list contains all the classes in the runtime system for whom
superclasses are not yet know to the runtime. */ their superclasses are not yet known to the runtime. */
static struct objc_list* unresolved_classes = 0; static struct objc_list *unresolved_classes = 0;
/* Extern function used to reference the Object and NXConstantString classes. /* Extern function used to reference the Object and NXConstantString
*/ classes. */
extern void __objc_force_linking (void); extern void __objc_force_linking (void);
@ -380,15 +394,16 @@ __objc_force_linking (void)
__objc_linking (); __objc_linking ();
} }
/* Run through the statics list, removing modules as soon as all its statics /* Run through the statics list, removing modules as soon as all its
have been initialized. */ statics have been initialized. */
static void static void
objc_init_statics (void) objc_init_statics (void)
{ {
struct objc_list **cell = &uninitialized_statics; struct objc_list **cell = &uninitialized_statics;
struct objc_static_instances **statics_in_module; struct objc_static_instances **statics_in_module;
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
while (*cell) while (*cell)
{ {
@ -400,7 +415,7 @@ objc_init_statics (void)
struct objc_static_instances *statics = *statics_in_module; struct objc_static_instances *statics = *statics_in_module;
Class class = objc_lookup_class (statics->class_name); Class class = objc_lookup_class (statics->class_name);
if (!class) if (! class)
module_initialized = 0; module_initialized = 0;
/* Actually, the static's class_pointer will be NULL when we /* Actually, the static's class_pointer will be NULL when we
haven't been here before. However, the comparison is to be haven't been here before. However, the comparison is to be
@ -430,19 +445,19 @@ objc_init_statics (void)
/* Remove this module from the uninitialized list. */ /* Remove this module from the uninitialized list. */
struct objc_list *this = *cell; struct objc_list *this = *cell;
*cell = this->tail; *cell = this->tail;
objc_free(this); objc_free (this);
} }
else else
cell = &(*cell)->tail; cell = &(*cell)->tail;
} }
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
} /* objc_init_statics */ } /* objc_init_statics */
/* This function is called by constructor functions generated for each /* This function is called by constructor functions generated for each
module compiled. (_GLOBAL_$I$...) The purpose of this function is to module compiled. (_GLOBAL_$I$...) The purpose of this function is
gather the module pointers so that they may be processed by the to gather the module pointers so that they may be processed by the
initialization routines as soon as possible */ initialization routines as soon as possible. */
objc_DECLARE void objc_DECLARE void
__objc_exec_class (Module_t module) __objc_exec_class (Module_t module)
@ -451,7 +466,7 @@ __objc_exec_class (Module_t module)
indicate that some global data structures need to be built. */ indicate that some global data structures need to be built. */
static BOOL previous_constructors = 0; static BOOL previous_constructors = 0;
static struct objc_list* unclaimed_categories = 0; static struct objc_list *unclaimed_categories = 0;
/* The symbol table (defined in objc-api.h) generated by gcc */ /* The symbol table (defined in objc-api.h) generated by gcc */
Symtab_t symtab = module->symtab; Symtab_t symtab = module->symtab;
@ -461,7 +476,7 @@ __objc_exec_class (Module_t module)
= symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt]; = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
/* Entry used to traverse hash lists */ /* Entry used to traverse hash lists */
struct objc_list** cell; struct objc_list **cell;
/* The table of selector references for this module */ /* The table of selector references for this module */
SEL selectors = symtab->refs; SEL selectors = symtab->refs;
@ -472,19 +487,19 @@ __objc_exec_class (Module_t module)
DEBUG_PRINTF ("received module: %s\n", module->name); DEBUG_PRINTF ("received module: %s\n", module->name);
/* check gcc version */ /* check gcc version */
init_check_module_version(module); init_check_module_version (module);
/* On the first call of this routine, initialize some data structures. */ /* On the first call of this routine, initialize some data structures. */
if (!previous_constructors) if (! previous_constructors)
{ {
/* Initialize thread-safe system */ /* Initialize thread-safe system */
__objc_init_thread_system(); __objc_init_thread_system ();
__objc_runtime_threads_alive = 1; __objc_runtime_threads_alive = 1;
__objc_runtime_mutex = objc_mutex_allocate(); __objc_runtime_mutex = objc_mutex_allocate ();
__objc_init_selector_tables(); __objc_init_selector_tables ();
__objc_init_class_tables(); __objc_init_class_tables ();
__objc_init_dispatch_tables(); __objc_init_dispatch_tables ();
__objc_class_tree_list = list_cons (NULL, __objc_class_tree_list); __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
__objc_load_methods __objc_load_methods
= hash_new (128, (hash_func_type)hash_ptr, compare_ptrs); = hash_new (128, (hash_func_type)hash_ptr, compare_ptrs);
@ -492,8 +507,8 @@ __objc_exec_class (Module_t module)
} }
/* Save the module pointer for later processing. (not currently used) */ /* Save the module pointer for later processing. (not currently used) */
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
__objc_module_list = list_cons(module, __objc_module_list); __objc_module_list = list_cons (module, __objc_module_list);
/* Replace referenced selectors from names to SEL's. */ /* Replace referenced selectors from names to SEL's. */
if (selectors) if (selectors)
@ -501,12 +516,12 @@ __objc_exec_class (Module_t module)
for (i = 0; selectors[i].sel_id; ++i) for (i = 0; selectors[i].sel_id; ++i)
{ {
const char *name, *type; const char *name, *type;
name = (char*)selectors[i].sel_id; name = (char *) selectors[i].sel_id;
type = (char*)selectors[i].sel_types; type = (char *) selectors[i].sel_types;
/* Constructors are constant static data so we can safely store /* Constructors are constant static data so we can safely store
pointers to them in the runtime structures. is_const == YES */ pointers to them in the runtime structures. is_const == YES */
__sel_register_typed_name (name, type, __sel_register_typed_name (name, type,
(struct objc_selector*)&(selectors[i]), (struct objc_selector *) &(selectors[i]),
YES); YES);
} }
} }
@ -516,15 +531,15 @@ __objc_exec_class (Module_t module)
for (i = 0; i < symtab->cls_def_cnt; ++i) for (i = 0; i < symtab->cls_def_cnt; ++i)
{ {
Class class = (Class) symtab->defs[i]; Class class = (Class) symtab->defs[i];
const char* superclass = (char*)class->super_class; const char *superclass = (char *) class->super_class;
/* Make sure we have what we think. */ /* Make sure we have what we think. */
assert (CLS_ISCLASS(class)); assert (CLS_ISCLASS (class));
assert (CLS_ISMETA(class->class_pointer)); assert (CLS_ISMETA (class->class_pointer));
DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name); DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
/* Initialize the subclass list to be NULL. /* Initialize the subclass list to be NULL.
In some cases it isn't and this crashes the program. */ In some cases it isn't and this crashes the program. */
class->subclass_list = NULL; class->subclass_list = NULL;
/* Store the class in the class table and assign class numbers. */ /* Store the class in the class table and assign class numbers. */
@ -535,19 +550,19 @@ __objc_exec_class (Module_t module)
__objc_register_selectors_from_class ((Class) class->class_pointer); __objc_register_selectors_from_class ((Class) class->class_pointer);
/* Install the fake dispatch tables */ /* Install the fake dispatch tables */
__objc_install_premature_dtable(class); __objc_install_premature_dtable (class);
__objc_install_premature_dtable(class->class_pointer); __objc_install_premature_dtable (class->class_pointer);
/* Register the instance methods as class methods, this is /* Register the instance methods as class methods, this is
only done for root classes. */ only done for root classes. */
__objc_register_instance_methods_to_class(class); __objc_register_instance_methods_to_class (class);
if (class->protocols) if (class->protocols)
__objc_init_protocols (class->protocols); __objc_init_protocols (class->protocols);
/* Check to see if the superclass is known in this point. If it's not /* Check to see if the superclass is known in this point. If it's not
add the class to the unresolved_classes list. */ add the class to the unresolved_classes list. */
if (superclass && !objc_lookup_class (superclass)) if (superclass && ! objc_lookup_class (superclass))
unresolved_classes = list_cons (class, unresolved_classes); unresolved_classes = list_cons (class, unresolved_classes);
} }
@ -581,14 +596,14 @@ __objc_exec_class (Module_t module)
} }
/* Register the instance methods as class methods, this is /* Register the instance methods as class methods, this is
only done for root classes. */ only done for root classes. */
__objc_register_instance_methods_to_class(class); __objc_register_instance_methods_to_class (class);
} }
else else
{ {
/* The object to which the category methods belong can't be found. /* The object to which the category methods belong can't be found.
Save the information. */ Save the information. */
unclaimed_categories = list_cons(category, unclaimed_categories); unclaimed_categories = list_cons (category, unclaimed_categories);
} }
} }
@ -599,9 +614,7 @@ __objc_exec_class (Module_t module)
/* Scan the unclaimed category hash. Attempt to attach any unclaimed /* Scan the unclaimed category hash. Attempt to attach any unclaimed
categories to objects. */ categories to objects. */
for (cell = &unclaimed_categories; for (cell = &unclaimed_categories; *cell; )
*cell;
({ if (*cell) cell = &(*cell)->tail; }))
{ {
Category_t category = (*cell)->head; Category_t category = (*cell)->head;
Class class = objc_lookup_class (category->class_name); Class class = objc_lookup_class (category->class_name);
@ -627,37 +640,41 @@ __objc_exec_class (Module_t module)
} }
/* Register the instance methods as class methods, this is /* Register the instance methods as class methods, this is
only done for root classes. */ only done for root classes. */
__objc_register_instance_methods_to_class(class); __objc_register_instance_methods_to_class (class);
} }
else
cell = &(*cell)->tail;
} }
if (unclaimed_proto_list && objc_lookup_class ("Protocol")) if (unclaimed_proto_list && objc_lookup_class ("Protocol"))
{ {
list_mapcar (unclaimed_proto_list,(void(*)(void*))__objc_init_protocols); list_mapcar (unclaimed_proto_list,
(void (*) (void *))__objc_init_protocols);
list_free (unclaimed_proto_list); list_free (unclaimed_proto_list);
unclaimed_proto_list = 0; unclaimed_proto_list = 0;
} }
objc_send_load (); objc_send_load ();
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
} }
static void objc_send_load (void) static void
objc_send_load (void)
{ {
if (!__objc_module_list) if (! __objc_module_list)
return; return;
/* Try to find out if all the classes loaded so far also have their /* Try to find out if all the classes loaded so far also have their
superclasses known to the runtime. We suppose that the objects that are superclasses known to the runtime. We suppose that the objects
allocated in the +load method are in general of a class declared in the that are allocated in the +load method are in general of a class
same module. */ declared in the same module. */
if (unresolved_classes) if (unresolved_classes)
{ {
Class class = unresolved_classes->head; Class class = unresolved_classes->head;
while (objc_lookup_class ((char*)class->super_class)) while (objc_lookup_class ((char *) class->super_class))
{ {
list_remove_head (&unresolved_classes); list_remove_head (&unresolved_classes);
if (unresolved_classes) if (unresolved_classes)
@ -666,10 +683,9 @@ static void objc_send_load (void)
break; break;
} }
/* /* If we still have classes for whom we don't have yet their
* If we still have classes for whom we don't have yet their super super classes known to the runtime we don't send the +load
* classes known to the runtime we don't send the +load messages. messages. */
*/
if (unresolved_classes) if (unresolved_classes)
return; return;
} }
@ -693,10 +709,11 @@ static void objc_send_load (void)
return; return;
#endif #endif
/* Iterate over all modules in the __objc_module_list and call on them the /* Iterate over all modules in the __objc_module_list and call on
__objc_create_classes_tree function. This function creates a tree of them the __objc_create_classes_tree function. This function
classes that resembles the class hierarchy. */ creates a tree of classes that resembles the class hierarchy. */
list_mapcar (__objc_module_list, (void(*)(void*))__objc_create_classes_tree); list_mapcar (__objc_module_list,
(void (*) (void *)) __objc_create_classes_tree);
while (__objc_class_tree_list) while (__objc_class_tree_list)
{ {
@ -711,7 +728,7 @@ static void objc_send_load (void)
list_remove_head (&__objc_class_tree_list); list_remove_head (&__objc_class_tree_list);
} }
list_mapcar (__objc_module_list, (void(*)(void*))__objc_call_callback); list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_callback);
list_free (__objc_module_list); list_free (__objc_module_list);
__objc_module_list = NULL; __objc_module_list = NULL;
} }
@ -724,8 +741,8 @@ __objc_create_classes_tree (Module_t module)
Symtab_t symtab = module->symtab; Symtab_t symtab = module->symtab;
int i; int i;
/* Iterate thru classes defined in this module and insert them in the classes /* Iterate thru classes defined in this module and insert them in
tree hierarchy. */ the classes tree hierarchy. */
for (i = 0; i < symtab->cls_def_cnt; i++) for (i = 0; i < symtab->cls_def_cnt; i++)
{ {
Class class = (Class) symtab->defs[i]; Class class = (Class) symtab->defs[i];
@ -737,72 +754,74 @@ __objc_create_classes_tree (Module_t module)
static void static void
__objc_call_callback (Module_t module) __objc_call_callback (Module_t module)
{ {
/* The runtime mutex is locked in this point */ /* The runtime mutex is locked in this point. */
Symtab_t symtab = module->symtab; Symtab_t symtab = module->symtab;
int i; int i;
/* Iterate thru classes defined in this module and call the callback for /* Iterate thru classes defined in this module and call the callback
each one. */ for each one. */
for (i = 0; i < symtab->cls_def_cnt; i++) for (i = 0; i < symtab->cls_def_cnt; i++)
{ {
Class class = (Class) symtab->defs[i]; Class class = (Class) symtab->defs[i];
/* Call the _objc_load_callback for this class. */ /* Call the _objc_load_callback for this class. */
if (_objc_load_callback) if (_objc_load_callback)
_objc_load_callback(class, 0); _objc_load_callback (class, 0);
} }
/* Call the _objc_load_callback for categories. Don't register the instance /* Call the _objc_load_callback for categories. Don't register the
methods as class methods for categories to root classes since they were instance methods as class methods for categories to root classes
already added in the class. */ since they were already added in the class. */
for (i = 0; i < symtab->cat_def_cnt; i++) for (i = 0; i < symtab->cat_def_cnt; i++)
{ {
Category_t category = symtab->defs[i + symtab->cls_def_cnt]; Category_t category = symtab->defs[i + symtab->cls_def_cnt];
Class class = objc_lookup_class (category->class_name); Class class = objc_lookup_class (category->class_name);
if (_objc_load_callback) if (_objc_load_callback)
_objc_load_callback(class, category); _objc_load_callback (class, category);
} }
} }
/* Sanity check the version of gcc used to compile `module'*/ /* Sanity check the version of gcc used to compile `module'. */
static void init_check_module_version(Module_t module)
static void
init_check_module_version (Module_t module)
{ {
if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module))) if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))
{ {
int code; int code;
if(module->version > OBJC_VERSION) if (module->version > OBJC_VERSION)
code = OBJC_ERR_OBJC_VERSION; code = OBJC_ERR_OBJC_VERSION;
else if (module->version < OBJC_VERSION) else if (module->version < OBJC_VERSION)
code = OBJC_ERR_GCC_VERSION; code = OBJC_ERR_GCC_VERSION;
else else
code = OBJC_ERR_MODULE_SIZE; code = OBJC_ERR_MODULE_SIZE;
objc_error(nil, code, "Module %s version %d doesn't match runtime %d\n", objc_error (nil, code, "Module %s version %d doesn't match runtime %d\n",
module->name, (int)module->version, OBJC_VERSION); module->name, (int)module->version, OBJC_VERSION);
} }
} }
static void static void
__objc_init_protocols (struct objc_protocol_list* protos) __objc_init_protocols (struct objc_protocol_list *protos)
{ {
int i; size_t i;
static Class proto_class = 0; static Class proto_class = 0;
if (! protos) if (! protos)
return; return;
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
if (!proto_class) if (! proto_class)
proto_class = objc_lookup_class("Protocol"); proto_class = objc_lookup_class ("Protocol");
if (!proto_class) if (! proto_class)
{ {
unclaimed_proto_list = list_cons (protos, unclaimed_proto_list); unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
return; return;
} }
@ -810,9 +829,9 @@ __objc_init_protocols (struct objc_protocol_list* protos)
assert (protos->next == 0); /* only single ones allowed */ assert (protos->next == 0); /* only single ones allowed */
#endif #endif
for(i = 0; i < protos->count; i++) for (i = 0; i < protos->count; i++)
{ {
struct objc_protocol* aProto = protos->list[i]; struct objc_protocol *aProto = protos->list[i];
if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION) if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION)
{ {
/* assign class pointer */ /* assign class pointer */
@ -823,24 +842,25 @@ __objc_init_protocols (struct objc_protocol_list* protos)
} }
else if (protos->list[i]->class_pointer != proto_class) else if (protos->list[i]->class_pointer != proto_class)
{ {
objc_error(nil, OBJC_ERR_PROTOCOL_VERSION, objc_error (nil, OBJC_ERR_PROTOCOL_VERSION,
"Version %d doesn't match runtime protocol version %d\n", "Version %d doesn't match runtime protocol version %d\n",
(int)((char*)protos->list[i]->class_pointer-(char*)0), (int) ((char *) protos->list[i]->class_pointer
- (char *) 0),
PROTOCOL_VERSION); PROTOCOL_VERSION);
} }
} }
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
} }
static void __objc_class_add_protocols (Class class, static void
struct objc_protocol_list* protos) __objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
{ {
/* Well... */ /* Well... */
if (! protos) if (! protos)
return; return;
/* Add it... */ /* Add it... */
protos->next = class->protocols; protos->next = class->protocols;
class->protocols = protos; class->protocols = protos;
} }

@ -61,7 +61,7 @@ typedef struct cache_node
* typedef. Therefore, to remove compiler warnings the functions passed to * typedef. Therefore, to remove compiler warnings the functions passed to
* hash_new will have to be casted to this type. * hash_new will have to be casted to this type.
*/ */
typedef unsigned int (*hash_func_type)(void *, const void *); typedef unsigned int (*hash_func_type) (void *, const void *);
/* /*
* This data type is the function that compares two hash keys and returns an * This data type is the function that compares two hash keys and returns an
@ -70,7 +70,7 @@ typedef unsigned int (*hash_func_type)(void *, const void *);
* second. * second.
*/ */
typedef int (*compare_func_type)(const void *, const void *); typedef int (*compare_func_type) (const void *, const void *);
/* /*
@ -175,8 +175,8 @@ hash_string (cache_ptr cache, const void *key)
unsigned int ctr = 0; unsigned int ctr = 0;
while (*(char*)key) { while (*(char *) key) {
ret ^= *(char*)key++ << ctr; ret ^= *(char *) key++ << ctr;
ctr = (ctr + 1) % sizeof (void *); ctr = (ctr + 1) % sizeof (void *);
} }
@ -188,7 +188,7 @@ hash_string (cache_ptr cache, const void *key)
static inline int static inline int
compare_ptrs (const void *k1, const void *k2) compare_ptrs (const void *k1, const void *k2)
{ {
return !(k1 - k2); return ! (k1 - k2);
} }
@ -201,7 +201,7 @@ compare_strings (const void *k1, const void *k2)
else if (k1 == 0 || k2 == 0) else if (k1 == 0 || k2 == 0)
return 0; return 0;
else else
return !strcmp (k1, k2); return ! strcmp (k1, k2);
} }

@ -1,5 +1,5 @@
/* GNU Objective-C Runtime API. /* GNU Objective-C Runtime API.
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
This file is part of GNU CC. This file is part of GNU CC.
@ -76,6 +76,7 @@ struct objc_method_description
#define _C_UNION_E ')' #define _C_UNION_E ')'
#define _C_STRUCT_B '{' #define _C_STRUCT_B '{'
#define _C_STRUCT_E '}' #define _C_STRUCT_E '}'
#define _C_VECTOR '!'
/* /*
@ -261,7 +262,7 @@ typedef struct objc_method_list {
struct objc_protocol_list { struct objc_protocol_list {
struct objc_protocol_list *next; struct objc_protocol_list *next;
int count; size_t count;
Protocol *list[1]; Protocol *list[1];
}; };
@ -579,21 +580,23 @@ object_get_super_class
} }
static inline BOOL static inline BOOL
object_is_class(id object) object_is_class (id object)
{ {
return CLS_ISCLASS((Class)object); return ((object != nil) && CLS_ISMETA (object->class_pointer));
} }
static inline BOOL static inline BOOL
object_is_instance(id object) object_is_instance (id object)
{ {
return (object!=nil)&&CLS_ISCLASS(object->class_pointer); return ((object != nil) && CLS_ISCLASS (object->class_pointer));
} }
static inline BOOL static inline BOOL
object_is_meta_class(id object) object_is_meta_class (id object)
{ {
return CLS_ISMETA((Class)object); return ((object != nil)
&& !object_is_instance (object)
&& !object_is_class (object));
} }
struct sarray* struct sarray*

@ -1,5 +1,5 @@
/* GNU Objective C Runtime internal declarations /* GNU Objective C Runtime internal declarations
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup Contributed by Kresten Krab Thorup
This file is part of GNU CC. This file is part of GNU CC.
@ -65,7 +65,8 @@ objc_EXPORT Method_t search_for_method_in_list(MethodList_t list, SEL op);
objc_EXPORT BOOL __objc_class_links_resolved; objc_EXPORT BOOL __objc_class_links_resolved;
/* Number of selectors stored in each of the selector tables */ /* Number of selectors stored in each of the selector tables */
objc_EXPORT int __objc_selector_max_index; objc_EXPORT unsigned int __objc_selector_max_index;
extern unsigned int __objc_selector_max_index;
/* Mutex locking __objc_selector_max_index and its arrays. */ /* Mutex locking __objc_selector_max_index and its arrays. */
objc_EXPORT objc_mutex_t __objc_runtime_mutex; objc_EXPORT objc_mutex_t __objc_runtime_mutex;
@ -82,6 +83,7 @@ objc_EXPORT int __objc_runtime_threads_alive;
BOOL __objc_responds_to (id object, SEL sel); /* for internal use only! */ BOOL __objc_responds_to (id object, SEL sel); /* for internal use only! */
SEL __sel_register_typed_name (const char*, const char*, SEL __sel_register_typed_name (const char*, const char*,
struct objc_selector*, BOOL is_const); struct objc_selector*, BOOL is_const);
extern void __objc_generate_gc_type_description (Class);
#endif /* not __objc_runtime_INCLUDE_GNU */ #endif /* not __objc_runtime_INCLUDE_GNU */

@ -1,5 +1,5 @@
/* GNU Objective C Runtime selector related functions /* GNU Objective C Runtime selector related functions
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup Contributed by Kresten Krab Thorup
This file is part of GNU CC. This file is part of GNU CC.
@ -31,16 +31,16 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define SELECTOR_HASH_SIZE 128 #define SELECTOR_HASH_SIZE 128
/* Tables mapping selector names to uid and opposite */ /* Tables mapping selector names to uid and opposite */
static struct sarray* __objc_selector_array = 0; /* uid -> sel !T:MUTEX */ static struct sarray *__objc_selector_array = 0; /* uid -> sel !T:MUTEX */
static struct sarray* __objc_selector_names = 0; /* uid -> name !T:MUTEX */ static struct sarray *__objc_selector_names = 0; /* uid -> name !T:MUTEX */
static cache_ptr __objc_selector_hash = 0; /* name -> uid !T:MUTEX */ static cache_ptr __objc_selector_hash = 0; /* name -> uid !T:MUTEX */
static void register_selectors_from_list(MethodList_t); static void register_selectors_from_list (MethodList_t);
/* Number of selectors stored in each of the above tables */ /* Number of selectors stored in each of the above tables */
int __objc_selector_max_index = 0; /* !T:MUTEX */ unsigned int __objc_selector_max_index = 0; /* !T:MUTEX */
void __objc_init_selector_tables() void __objc_init_selector_tables ()
{ {
__objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0); __objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0);
__objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0); __objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0);
@ -81,15 +81,15 @@ register_selectors_from_list (MethodList_t method_list)
{ {
Method_t method = &method_list->method_list[i]; Method_t method = &method_list->method_list[i];
method->method_name method->method_name
= sel_register_typed_name ((const char*)method->method_name, = sel_register_typed_name ((const char *) method->method_name,
method->method_types); method->method_types);
i += 1; i += 1;
} }
} }
/* Register instance methods as class methods for root classes */ /* Register instance methods as class methods for root classes */
void __objc_register_instance_methods_to_class(Class class) void __objc_register_instance_methods_to_class (Class class)
{ {
MethodList_t method_list; MethodList_t method_list;
MethodList_t class_method_list; MethodList_t class_method_list;
@ -98,12 +98,12 @@ void __objc_register_instance_methods_to_class(Class class)
Method_t curr_method; Method_t curr_method;
/* Only if a root class. */ /* Only if a root class. */
if(class->super_class) if (class->super_class)
return; return;
/* Allocate a method list to hold the new class methods */ /* Allocate a method list to hold the new class methods */
new_list = objc_calloc(sizeof(struct objc_method_list) new_list = objc_calloc (sizeof (struct objc_method_list)
+ sizeof(struct objc_method[max_methods_no]), 1); + sizeof (struct objc_method[max_methods_no]), 1);
method_list = class->methods; method_list = class->methods;
class_method_list = class->class_pointer->methods; class_method_list = class->class_pointer->methods;
curr_method = &new_list->method_list[0]; curr_method = &new_list->method_list[0];
@ -118,7 +118,7 @@ void __objc_register_instance_methods_to_class(Class class)
{ {
Method_t mth = &method_list->method_list[i]; Method_t mth = &method_list->method_list[i];
if (mth->method_name if (mth->method_name
&& !search_for_method_in_list (class_method_list, && ! search_for_method_in_list (class_method_list,
mth->method_name)) mth->method_name))
{ {
/* This instance method isn't a class method. /* This instance method isn't a class method.
@ -126,10 +126,10 @@ void __objc_register_instance_methods_to_class(Class class)
*curr_method = *mth; *curr_method = *mth;
/* Reallocate the method list if necessary */ /* Reallocate the method list if necessary */
if(++new_list->method_count == max_methods_no) if (++new_list->method_count == max_methods_no)
new_list = new_list =
objc_realloc(new_list, sizeof(struct objc_method_list) objc_realloc (new_list, sizeof (struct objc_method_list)
+ sizeof(struct + sizeof (struct
objc_method[max_methods_no += 16])); objc_method[max_methods_no += 16]));
curr_method = &new_list->method_list[new_list->method_count]; curr_method = &new_list->method_list[new_list->method_count];
} }
@ -143,8 +143,8 @@ void __objc_register_instance_methods_to_class(Class class)
if (new_list->method_count) if (new_list->method_count)
{ {
new_list = new_list =
objc_realloc(new_list, sizeof(struct objc_method_list) objc_realloc (new_list, sizeof (struct objc_method_list)
+ sizeof(struct objc_method[new_list->method_count])); + sizeof (struct objc_method[new_list->method_count]));
new_list->method_next = class->class_pointer->methods; new_list->method_next = class->class_pointer->methods;
class->class_pointer->methods = new_list; class->class_pointer->methods = new_list;
} }
@ -156,21 +156,21 @@ void __objc_register_instance_methods_to_class(Class class)
/* Returns YES iff t1 and t2 have same method types, but we ignore /* Returns YES iff t1 and t2 have same method types, but we ignore
the argframe layout */ the argframe layout */
BOOL BOOL
sel_types_match (const char* t1, const char* t2) sel_types_match (const char *t1, const char *t2)
{ {
if (!t1 || !t2) if (! t1 || ! t2)
return NO; return NO;
while (*t1 && *t2) while (*t1 && *t2)
{ {
if (*t1 == '+') t1++; if (*t1 == '+') t1++;
if (*t2 == '+') t2++; if (*t2 == '+') t2++;
while (isdigit(*t1)) t1++; while (isdigit ((unsigned char) *t1)) t1++;
while (isdigit(*t2)) t2++; while (isdigit ((unsigned char) *t2)) t2++;
/* xxx Remove these next two lines when qualifiers are put in /* xxx Remove these next two lines when qualifiers are put in
all selectors, not just Protocol selectors. */ all selectors, not just Protocol selectors. */
t1 = objc_skip_type_qualifiers(t1); t1 = objc_skip_type_qualifiers (t1);
t2 = objc_skip_type_qualifiers(t2); t2 = objc_skip_type_qualifiers (t2);
if (!*t1 && !*t2) if (! *t1 && ! *t2)
return YES; return YES;
if (*t1 != *t2) if (*t1 != *t2)
return NO; return NO;
@ -187,35 +187,35 @@ sel_get_typed_uid (const char *name, const char *types)
struct objc_list *l; struct objc_list *l;
sidx i; sidx i;
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
i = (sidx) hash_value_for_key (__objc_selector_hash, name); i = (sidx) hash_value_for_key (__objc_selector_hash, name);
if (i == 0) if (i == 0)
{ {
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
return 0; return 0;
} }
for (l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
l; l = l->tail) l; l = l->tail)
{ {
SEL s = (SEL)l->head; SEL s = (SEL) l->head;
if (types == 0 || s->sel_types == 0) if (types == 0 || s->sel_types == 0)
{ {
if (s->sel_types == types) if (s->sel_types == types)
{ {
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
return s; return s;
} }
} }
else if (sel_types_match (s->sel_types, types)) else if (sel_types_match (s->sel_types, types))
{ {
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
return s; return s;
} }
} }
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
return 0; return 0;
} }
@ -227,27 +227,27 @@ sel_get_any_typed_uid (const char *name)
sidx i; sidx i;
SEL s = NULL; SEL s = NULL;
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
i = (sidx) hash_value_for_key (__objc_selector_hash, name); i = (sidx) hash_value_for_key (__objc_selector_hash, name);
if (i == 0) if (i == 0)
{ {
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
return 0; return 0;
} }
for (l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
l; l = l->tail) l; l = l->tail)
{ {
s = (SEL) l->head; s = (SEL) l->head;
if (s->sel_types) if (s->sel_types)
{ {
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
return s; return s;
} }
} }
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
return s; return s;
} }
@ -258,22 +258,22 @@ sel_get_any_uid (const char *name)
struct objc_list *l; struct objc_list *l;
sidx i; sidx i;
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
i = (sidx) hash_value_for_key (__objc_selector_hash, name); i = (sidx) hash_value_for_key (__objc_selector_hash, name);
if (soffset_decode (i) == 0) if (soffset_decode (i) == 0)
{ {
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
return 0; return 0;
} }
l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
if (l == 0) if (l == 0)
return 0; return 0;
return (SEL)l->head; return (SEL) l->head;
} }
/* return selector representing name */ /* return selector representing name */
@ -285,18 +285,17 @@ sel_get_uid (const char *name)
/* Get name of selector. If selector is unknown, the empty string "" /* Get name of selector. If selector is unknown, the empty string ""
is returned */ is returned */
const char* const char *sel_get_name (SEL selector)
sel_get_name (SEL selector)
{ {
const char *ret; const char *ret;
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
if ((soffset_decode((sidx)selector->sel_id) > 0) if ((soffset_decode ((sidx)selector->sel_id) > 0)
&& (soffset_decode((sidx)selector->sel_id) <= __objc_selector_max_index)) && (soffset_decode ((sidx)selector->sel_id) <= __objc_selector_max_index))
ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id); ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id);
else else
ret = 0; ret = 0;
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
return ret; return ret;
} }
@ -308,8 +307,7 @@ sel_is_mapped (SEL selector)
} }
const char* const char *sel_get_type (SEL selector)
sel_get_type (SEL selector)
{ {
if (selector) if (selector)
return selector->sel_types; return selector->sel_types;
@ -318,7 +316,7 @@ sel_get_type (SEL selector)
} }
/* The uninstalled dispatch table */ /* The uninstalled dispatch table */
extern struct sarray* __objc_uninstalled_dtable; extern struct sarray *__objc_uninstalled_dtable;
/* Store the passed selector name in the selector record and return its /* Store the passed selector name in the selector record and return its
selector value (value returned by sel_get_uid). selector value (value returned by sel_get_uid).
@ -331,35 +329,35 @@ SEL
__sel_register_typed_name (const char *name, const char *types, __sel_register_typed_name (const char *name, const char *types,
struct objc_selector *orig, BOOL is_const) struct objc_selector *orig, BOOL is_const)
{ {
struct objc_selector* j; struct objc_selector *j;
sidx i; sidx i;
struct objc_list *l; struct objc_list *l;
i = (sidx) hash_value_for_key (__objc_selector_hash, name); i = (sidx) hash_value_for_key (__objc_selector_hash, name);
if (soffset_decode (i) != 0) if (soffset_decode (i) != 0)
{ {
for (l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
l; l = l->tail) l; l = l->tail)
{ {
SEL s = (SEL)l->head; SEL s = (SEL) l->head;
if (types == 0 || s->sel_types == 0) if (types == 0 || s->sel_types == 0)
{ {
if (s->sel_types == types) if (s->sel_types == types)
{ {
if (orig) if (orig)
{ {
orig->sel_id = (void*)i; orig->sel_id = (void *) i;
return orig; return orig;
} }
else else
return s; return s;
} }
} }
else if (!strcmp (s->sel_types, types)) else if (! strcmp (s->sel_types, types))
{ {
if (orig) if (orig)
{ {
orig->sel_id = (void*)i; orig->sel_id = (void *) i;
return orig; return orig;
} }
else else
@ -371,32 +369,32 @@ __sel_register_typed_name (const char *name, const char *types,
else else
j = objc_malloc (sizeof (struct objc_selector)); j = objc_malloc (sizeof (struct objc_selector));
j->sel_id = (void*)i; j->sel_id = (void *) i;
/* Can we use the pointer or must copy types? Don't copy if NULL */ /* Can we use the pointer or must copy types? Don't copy if NULL */
if ((is_const) || (types == 0)) if ((is_const) || (types == 0))
j->sel_types = (const char*)types; j->sel_types = (const char *) types;
else { else {
j->sel_types = (char *) objc_malloc(strlen(types)+1); j->sel_types = (char *) objc_malloc (strlen (types) + 1);
strcpy((char *)j->sel_types, types); strcpy ((char *) j->sel_types, types);
} }
l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
} }
else else
{ {
__objc_selector_max_index += 1; __objc_selector_max_index += 1;
i = soffset_encode(__objc_selector_max_index); i = soffset_encode (__objc_selector_max_index);
if (orig) if (orig)
j = orig; j = orig;
else else
j = objc_malloc (sizeof (struct objc_selector)); j = objc_malloc (sizeof (struct objc_selector));
j->sel_id = (void*)i; j->sel_id = (void *) i;
/* Can we use the pointer or must copy types? Don't copy if NULL */ /* Can we use the pointer or must copy types? Don't copy if NULL */
if ((is_const) || (types == 0)) if ((is_const) || (types == 0))
j->sel_types = (const char*)types; j->sel_types = (const char *) types;
else { else {
j->sel_types = (char *) objc_malloc(strlen(types)+1); j->sel_types = (char *) objc_malloc (strlen (types) + 1);
strcpy((char *)j->sel_types, types); strcpy ((char *) j->sel_types, types);
} }
l = 0; l = 0;
} }
@ -412,18 +410,18 @@ __sel_register_typed_name (const char *name, const char *types,
if ((is_const) || (name == 0)) if ((is_const) || (name == 0))
new_name = name; new_name = name;
else { else {
new_name = (char *) objc_malloc(strlen(name)+1); new_name = (char *) objc_malloc (strlen (name) + 1);
strcpy((char *)new_name, name); strcpy ((char *) new_name, name);
} }
l = list_cons ((void*)j, l); l = list_cons ((void *) j, l);
sarray_at_put_safe (__objc_selector_names, i, (void *) new_name); sarray_at_put_safe (__objc_selector_names, i, (void *) new_name);
sarray_at_put_safe (__objc_selector_array, i, (void *) l); sarray_at_put_safe (__objc_selector_array, i, (void *) l);
if (is_new) if (is_new)
hash_add (&__objc_selector_hash, (void *) new_name, (void *) i); hash_add (&__objc_selector_hash, (void *) new_name, (void *) i);
} }
sarray_realloc(__objc_uninstalled_dtable, __objc_selector_max_index+1); sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1);
return (SEL) j; return (SEL) j;
} }
@ -433,11 +431,11 @@ sel_register_name (const char *name)
{ {
SEL ret; SEL ret;
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
/* Assume that name is not constant static memory and needs to be /* Assume that name is not constant static memory and needs to be
copied before put into a runtime structure. is_const == NO */ copied before put into a runtime structure. is_const == NO */
ret = __sel_register_typed_name (name, 0, 0, NO); ret = __sel_register_typed_name (name, 0, 0, NO);
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
return ret; return ret;
} }
@ -447,12 +445,11 @@ sel_register_typed_name (const char *name, const char *type)
{ {
SEL ret; SEL ret;
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
/* Assume that name and type are not constant static memory and need to /* Assume that name and type are not constant static memory and need to
be copied before put into a runtime structure. is_const == NO */ be copied before put into a runtime structure. is_const == NO */
ret = __sel_register_typed_name (name, type, 0, NO); ret = __sel_register_typed_name (name, type, 0, NO);
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
return ret; return ret;
} }

@ -1,6 +1,6 @@
/* GNU Objective C Runtime message lookup /* GNU Objective C Runtime message lookup
Copyright (C) 1993, 1995, 1996, 1997, 1998, Copyright (C) 1993, 1995, 1996, 1997, 1998,
2001 Free Software Foundation, Inc. 2001, 2002 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup Contributed by Kresten Krab Thorup
This file is part of GNU CC. This file is part of GNU CC.
@ -25,6 +25,8 @@ Boston, MA 02111-1307, USA. */
however invalidate any other reasons why the executable file might be however invalidate any other reasons why the executable file might be
covered by the GNU General Public License. */ covered by the GNU General Public License. */
/* FIXME: This file has no business including tm.h. */
#include "tconfig.h" #include "tconfig.h"
#include "runtime.h" #include "runtime.h"
#include "sarray.h" #include "sarray.h"
@ -37,27 +39,27 @@ Boston, MA 02111-1307, USA. */
#define gen_rtx_REG(args...) 1 #define gen_rtx_REG(args...) 1
#define rtx int #define rtx int
#if !defined(STRUCT_VALUE) || STRUCT_VALUE == 0 #if ! defined (STRUCT_VALUE) || STRUCT_VALUE == 0
#define INVISIBLE_STRUCT_RETURN 1 #define INVISIBLE_STRUCT_RETURN 1
#else #else
#define INVISIBLE_STRUCT_RETURN 0 #define INVISIBLE_STRUCT_RETURN 0
#endif #endif
/* The uninstalled dispatch table */ /* The uninstalled dispatch table */
struct sarray* __objc_uninstalled_dtable = 0; /* !T:MUTEX */ struct sarray *__objc_uninstalled_dtable = 0; /* !T:MUTEX */
/* Hook for method forwarding. If it is set, is invoked to return a /* Hook for method forwarding. If it is set, is invoked to return a
function that performs the real forwarding. Otherwise the libgcc function that performs the real forwarding. Otherwise the libgcc
based functions (__builtin_apply and friends) are used. */ based functions (__builtin_apply and friends) are used. */
IMP (*__objc_msg_forward)(SEL) = NULL; IMP (*__objc_msg_forward) (SEL) = NULL;
/* Send +initialize to class */ /* Send +initialize to class */
static void __objc_send_initialize(Class); static void __objc_send_initialize (Class);
static void __objc_install_dispatch_table_for_class (Class); static void __objc_install_dispatch_table_for_class (Class);
/* Forward declare some functions */ /* Forward declare some functions */
static void __objc_init_install_dtable(id, SEL); static void __objc_init_install_dtable (id, SEL);
extern void __objc_generate_gc_type_description (Class class); extern void __objc_generate_gc_type_description (Class class);
@ -67,37 +69,41 @@ extern void __objc_generate_gc_type_description (Class class);
__objc_double_forward for floats/doubles. __objc_double_forward for floats/doubles.
__objc_word_forward for pointers or types that fit in registers. __objc_word_forward for pointers or types that fit in registers.
*/ */
static double __objc_double_forward(id, SEL, ...); static double __objc_double_forward (id, SEL, ...);
static id __objc_word_forward(id, SEL, ...); static id __objc_word_forward (id, SEL, ...);
typedef struct { id many[8]; } __big; typedef struct { id many[8]; } __big;
#if INVISIBLE_STRUCT_RETURN #if INVISIBLE_STRUCT_RETURN
static __big static __big
#else #else
static id static id
#endif #endif
__objc_block_forward(id, SEL, ...); __objc_block_forward (id, SEL, ...);
static Method_t search_for_method_in_hierarchy (Class class, SEL sel); static Method_t search_for_method_in_hierarchy (Class class, SEL sel);
Method_t search_for_method_in_list(MethodList_t list, SEL op); Method_t search_for_method_in_list (MethodList_t list, SEL op);
id nil_method(id, SEL, ...); id nil_method (id, SEL);
/* Given a selector, return the proper forwarding implementation. */ /* Given a selector, return the proper forwarding implementation. */
__inline__ __inline__
IMP IMP
__objc_get_forward_imp (SEL sel) __objc_get_forward_imp (SEL sel)
{ {
/* If a custom forwarding hook was registered, try getting a forwarding
* function from it. */
if (__objc_msg_forward) if (__objc_msg_forward)
{ {
IMP result; IMP result;
if ((result = __objc_msg_forward (sel))) if ((result = __objc_msg_forward (sel)) != NULL)
return result; return result;
} }
else
/* In all other cases, use the default forwarding functions built using
* __builtin_apply and friends. */
{ {
const char *t = sel->sel_types; const char *t = sel->sel_types;
if (t && (*t == '[' || *t == '(' || *t == '{') if (t && (*t == '[' || *t == '(' || *t == '{')
#ifdef OBJC_MAX_STRUCT_BY_VALUE #ifdef OBJC_MAX_STRUCT_BY_VALUE
&& objc_sizeof_type(t) > OBJC_MAX_STRUCT_BY_VALUE && objc_sizeof_type (t) > OBJC_MAX_STRUCT_BY_VALUE
#endif #endif
) )
return (IMP)__objc_block_forward; return (IMP)__objc_block_forward;
@ -113,26 +119,26 @@ __inline__
IMP IMP
get_imp (Class class, SEL sel) get_imp (Class class, SEL sel)
{ {
void* res = sarray_get_safe (class->dtable, (size_t) sel->sel_id); void *res = sarray_get_safe (class->dtable, (size_t) sel->sel_id);
if (res == 0) if (res == 0)
{ {
/* Not a valid method */ /* Not a valid method */
if(class->dtable == __objc_uninstalled_dtable) if (class->dtable == __objc_uninstalled_dtable)
{ {
/* The dispatch table needs to be installed. */ /* The dispatch table needs to be installed. */
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
__objc_install_dispatch_table_for_class (class); __objc_install_dispatch_table_for_class (class);
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
/* Call ourselves with the installed dispatch table /* Call ourselves with the installed dispatch table
and get the real method */ and get the real method */
res = get_imp(class, sel); res = get_imp (class, sel);
} }
else else
{ {
/* The dispatch table has been installed so the /* The dispatch table has been installed so the
method just doesn't exist for the class. method just doesn't exist for the class.
Return the forwarding implementation. */ Return the forwarding implementation. */
res = __objc_get_forward_imp(sel); res = __objc_get_forward_imp (sel);
} }
} }
return res; return res;
@ -145,14 +151,14 @@ __inline__
BOOL BOOL
__objc_responds_to (id object, SEL sel) __objc_responds_to (id object, SEL sel)
{ {
void* res; void *res;
/* Install dispatch table if need be */ /* Install dispatch table if need be */
if (object->class_pointer->dtable == __objc_uninstalled_dtable) if (object->class_pointer->dtable == __objc_uninstalled_dtable)
{ {
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
__objc_install_dispatch_table_for_class (object->class_pointer); __objc_install_dispatch_table_for_class (object->class_pointer);
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
} }
/* Get the method from the dispatch table */ /* Get the method from the dispatch table */
@ -165,37 +171,37 @@ __objc_responds_to (id object, SEL sel)
needs to be installed or it doesn't exist and forwarding is attempted. */ needs to be installed or it doesn't exist and forwarding is attempted. */
__inline__ __inline__
IMP IMP
objc_msg_lookup(id receiver, SEL op) objc_msg_lookup (id receiver, SEL op)
{ {
IMP result; IMP result;
if(receiver) if (receiver)
{ {
result = sarray_get_safe (receiver->class_pointer->dtable, result = sarray_get_safe (receiver->class_pointer->dtable,
(sidx)op->sel_id); (sidx)op->sel_id);
if (result == 0) if (result == 0)
{ {
/* Not a valid method */ /* Not a valid method */
if(receiver->class_pointer->dtable == __objc_uninstalled_dtable) if (receiver->class_pointer->dtable == __objc_uninstalled_dtable)
{ {
/* The dispatch table needs to be installed. /* The dispatch table needs to be installed.
This happens on the very first method call to the class. */ This happens on the very first method call to the class. */
__objc_init_install_dtable(receiver, op); __objc_init_install_dtable (receiver, op);
/* Get real method for this in newly installed dtable */ /* Get real method for this in newly installed dtable */
result = get_imp(receiver->class_pointer, op); result = get_imp (receiver->class_pointer, op);
} }
else else
{ {
/* The dispatch table has been installed so the /* The dispatch table has been installed so the
method just doesn't exist for the class. method just doesn't exist for the class.
Attempt to forward the method. */ Attempt to forward the method. */
result = __objc_get_forward_imp(op); result = __objc_get_forward_imp (op);
} }
} }
return result; return result;
} }
else else
return nil_method; return (IMP)nil_method;
} }
IMP IMP
@ -204,96 +210,95 @@ objc_msg_lookup_super (Super_t super, SEL sel)
if (super->self) if (super->self)
return get_imp (super->class, sel); return get_imp (super->class, sel);
else else
return nil_method; return (IMP)nil_method;
} }
int method_get_sizeof_arguments (Method*); int method_get_sizeof_arguments (Method *);
retval_t retval_t
objc_msg_sendv(id object, SEL op, arglist_t arg_frame) objc_msg_sendv (id object, SEL op, arglist_t arg_frame)
{ {
Method* m = class_get_instance_method(object->class_pointer, op); Method *m = class_get_instance_method (object->class_pointer, op);
const char *type; const char *type;
*((id*)method_get_first_argument (m, arg_frame, &type)) = object; *((id *) method_get_first_argument (m, arg_frame, &type)) = object;
*((SEL*)method_get_next_argument (arg_frame, &type)) = op; *((SEL *) method_get_next_argument (arg_frame, &type)) = op;
return __builtin_apply((apply_t)m->method_imp, return __builtin_apply ((apply_t) m->method_imp,
arg_frame, arg_frame,
method_get_sizeof_arguments (m)); method_get_sizeof_arguments (m));
} }
void void
__objc_init_dispatch_tables() __objc_init_dispatch_tables ()
{ {
__objc_uninstalled_dtable __objc_uninstalled_dtable = sarray_new (200, 0);
= sarray_new(200, 0);
} }
/* This function is called by objc_msg_lookup when the /* This function is called by objc_msg_lookup when the
dispatch table needs to be installed; thus it is called once dispatch table needs to be installed; thus it is called once
for each class, namely when the very first message is sent to it. */ for each class, namely when the very first message is sent to it. */
static void static void
__objc_init_install_dtable(id receiver, SEL op) __objc_init_install_dtable (id receiver, SEL op __attribute__ ((__unused__)))
{ {
/* This may happen, if the programmer has taken the address of a /* This may happen, if the programmer has taken the address of a
method before the dtable was initialized... too bad for him! */ method before the dtable was initialized... too bad for him! */
if(receiver->class_pointer->dtable != __objc_uninstalled_dtable) if (receiver->class_pointer->dtable != __objc_uninstalled_dtable)
return; return;
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
if(CLS_ISCLASS(receiver->class_pointer)) if (CLS_ISCLASS (receiver->class_pointer))
{ {
/* receiver is an ordinary object */ /* receiver is an ordinary object */
assert(CLS_ISCLASS(receiver->class_pointer)); assert (CLS_ISCLASS (receiver->class_pointer));
/* install instance methods table */ /* install instance methods table */
__objc_install_dispatch_table_for_class (receiver->class_pointer); __objc_install_dispatch_table_for_class (receiver->class_pointer);
/* call +initialize -- this will in turn install the factory /* call +initialize -- this will in turn install the factory
dispatch table if not already done :-) */ dispatch table if not already done :-) */
__objc_send_initialize(receiver->class_pointer); __objc_send_initialize (receiver->class_pointer);
} }
else else
{ {
/* receiver is a class object */ /* receiver is a class object */
assert(CLS_ISCLASS((Class)receiver)); assert (CLS_ISCLASS ((Class)receiver));
assert(CLS_ISMETA(receiver->class_pointer)); assert (CLS_ISMETA (receiver->class_pointer));
/* Install real dtable for factory methods */ /* Install real dtable for factory methods */
__objc_install_dispatch_table_for_class (receiver->class_pointer); __objc_install_dispatch_table_for_class (receiver->class_pointer);
__objc_send_initialize((Class)receiver); __objc_send_initialize ((Class)receiver);
} }
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
} }
/* Install dummy table for class which causes the first message to /* Install dummy table for class which causes the first message to
that class (or instances hereof) to be initialized properly */ that class (or instances hereof) to be initialized properly */
void void
__objc_install_premature_dtable(Class class) __objc_install_premature_dtable (Class class)
{ {
assert(__objc_uninstalled_dtable); assert (__objc_uninstalled_dtable);
class->dtable = __objc_uninstalled_dtable; class->dtable = __objc_uninstalled_dtable;
} }
/* Send +initialize to class if not already done */ /* Send +initialize to class if not already done */
static void static void
__objc_send_initialize(Class class) __objc_send_initialize (Class class)
{ {
/* This *must* be a class object */ /* This *must* be a class object */
assert(CLS_ISCLASS(class)); assert (CLS_ISCLASS (class));
assert(!CLS_ISMETA(class)); assert (! CLS_ISMETA (class));
if (!CLS_ISINITIALIZED(class)) if (! CLS_ISINITIALIZED (class))
{ {
CLS_SETINITIALIZED(class); CLS_SETINITIALIZED (class);
CLS_SETINITIALIZED(class->class_pointer); CLS_SETINITIALIZED (class->class_pointer);
/* Create the garbage collector type memory description */ /* Create the garbage collector type memory description */
__objc_generate_gc_type_description (class); __objc_generate_gc_type_description (class);
if(class->super_class) if (class->super_class)
__objc_send_initialize(class->super_class); __objc_send_initialize (class->super_class);
{ {
SEL op = sel_register_name ("initialize"); SEL op = sel_register_name ("initialize");
@ -304,7 +309,7 @@ __objc_send_initialize(Class class)
int i; int i;
Method_t method; Method_t method;
for (i = 0; i< method_list->method_count; i++) { for (i = 0; i < method_list->method_count; i++) {
method = &(method_list->method_list[i]); method = &(method_list->method_list[i]);
if (method->method_name if (method->method_name
&& method->method_name->sel_id == op->sel_id) { && method->method_name->sel_id == op->sel_id) {
@ -320,7 +325,7 @@ __objc_send_initialize(Class class)
} }
if (imp) if (imp)
(*imp)((id)class, op); (*imp) ((id) class, op);
} }
} }
@ -337,7 +342,7 @@ __objc_install_methods_in_dtable (Class class, MethodList_t method_list)
{ {
int i; int i;
if (!method_list) if (! method_list)
return; return;
if (method_list->method_next) if (method_list->method_next)
@ -360,8 +365,8 @@ __objc_install_dispatch_table_for_class (Class class)
/* If the class has not yet had its class links resolved, we must /* If the class has not yet had its class links resolved, we must
re-compute all class links */ re-compute all class links */
if(!CLS_ISRESOLV(class)) if (! CLS_ISRESOLV (class))
__objc_resolve_class_links(); __objc_resolve_class_links ();
super = class->super_class; super = class->super_class;
@ -371,9 +376,9 @@ __objc_install_dispatch_table_for_class (Class class)
/* Allocate dtable if necessary */ /* Allocate dtable if necessary */
if (super == 0) if (super == 0)
{ {
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
class->dtable = sarray_new (__objc_selector_max_index, 0); class->dtable = sarray_new (__objc_selector_max_index, 0);
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
} }
else else
class->dtable = sarray_lazy_copy (super->dtable); class->dtable = sarray_lazy_copy (super->dtable);
@ -391,7 +396,7 @@ __objc_update_dispatch_table_for_class (Class class)
if (class->dtable == __objc_uninstalled_dtable) if (class->dtable == __objc_uninstalled_dtable)
return; return;
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
arr = class->dtable; arr = class->dtable;
__objc_install_premature_dtable (class); /* someone might require it... */ __objc_install_premature_dtable (class); /* someone might require it... */
@ -404,7 +409,7 @@ __objc_update_dispatch_table_for_class (Class class)
for (next = class->subclass_list; next; next = next->sibling_class) for (next = class->subclass_list; next; next = next->sibling_class)
__objc_update_dispatch_table_for_class (next); __objc_update_dispatch_table_for_class (next);
objc_mutex_unlock(__objc_runtime_mutex); objc_mutex_unlock (__objc_runtime_mutex);
} }
@ -421,7 +426,7 @@ class_add_method_list (Class class, MethodList_t list)
int i; int i;
/* Passing of a linked list is not allowed. Do multiple calls. */ /* Passing of a linked list is not allowed. Do multiple calls. */
assert (!list->method_next); assert (! list->method_next);
/* Check for duplicates. */ /* Check for duplicates. */
for (i = 0; i < list->method_count; ++i) for (i = 0; i < list->method_count; ++i)
@ -432,7 +437,7 @@ class_add_method_list (Class class, MethodList_t list)
{ {
/* This is where selector names are transmogrified to SEL's */ /* This is where selector names are transmogrified to SEL's */
method->method_name = method->method_name =
sel_register_typed_name ((const char*)method->method_name, sel_register_typed_name ((const char *) method->method_name,
method->method_types); method->method_types);
} }
} }
@ -446,15 +451,15 @@ class_add_method_list (Class class, MethodList_t list)
} }
Method_t Method_t
class_get_instance_method(Class class, SEL op) class_get_instance_method (Class class, SEL op)
{ {
return search_for_method_in_hierarchy(class, op); return search_for_method_in_hierarchy (class, op);
} }
Method_t Method_t
class_get_class_method(MetaClass class, SEL op) class_get_class_method (MetaClass class, SEL op)
{ {
return search_for_method_in_hierarchy(class, op); return search_for_method_in_hierarchy (class, op);
} }
@ -578,13 +583,13 @@ __objc_forward (id object, SEL sel, arglist_t args)
SEL err_sel; SEL err_sel;
/* first try if the object understands forward:: */ /* first try if the object understands forward:: */
if (!frwd_sel) if (! frwd_sel)
frwd_sel = sel_get_any_uid("forward::"); frwd_sel = sel_get_any_uid ("forward::");
if (__objc_responds_to (object, frwd_sel)) if (__objc_responds_to (object, frwd_sel))
{ {
imp = get_imp(object->class_pointer, frwd_sel); imp = get_imp (object->class_pointer, frwd_sel);
return (*imp)(object, frwd_sel, sel, args); return (*imp) (object, frwd_sel, sel, args);
} }
/* If the object recognizes the doesNotRecognize: method then we're going /* If the object recognizes the doesNotRecognize: method then we're going
@ -599,12 +604,11 @@ __objc_forward (id object, SEL sel, arglist_t args)
/* The object doesn't recognize the method. Check for responding to /* The object doesn't recognize the method. Check for responding to
error:. If it does then sent it. */ error:. If it does then sent it. */
{ {
size_t strlen (const char*); char msg[256 + strlen ((const char *) sel_get_name (sel))
char msg[256 + strlen ((const char*)sel_get_name (sel)) + strlen ((const char *) object->class_pointer->name)];
+ strlen ((const char*)object->class_pointer->name)];
sprintf (msg, "(%s) %s does not recognize %s", sprintf (msg, "(%s) %s does not recognize %s",
(CLS_ISMETA(object->class_pointer) (CLS_ISMETA (object->class_pointer)
? "class" ? "class"
: "instance" ), : "instance" ),
object->class_pointer->name, sel_get_name (sel)); object->class_pointer->name, sel_get_name (sel));
@ -625,40 +629,41 @@ __objc_forward (id object, SEL sel, arglist_t args)
} }
void void
__objc_print_dtable_stats() __objc_print_dtable_stats ()
{ {
int total = 0; int total = 0;
objc_mutex_lock(__objc_runtime_mutex); objc_mutex_lock (__objc_runtime_mutex);
#ifdef OBJC_SPARSE2 #ifdef OBJC_SPARSE2
printf("memory usage: (%s)\n", "2-level sparse arrays"); printf ("memory usage: (%s)\n", "2-level sparse arrays");
#else #else
printf("memory usage: (%s)\n", "3-level sparse arrays"); printf ("memory usage: (%s)\n", "3-level sparse arrays");
#endif #endif
printf("arrays: %d = %ld bytes\n", narrays, printf ("arrays: %d = %ld bytes\n", narrays,
(long)narrays*sizeof(struct sarray)); (long) narrays * sizeof (struct sarray));
total += narrays*sizeof(struct sarray); total += narrays * sizeof (struct sarray);
printf("buckets: %d = %ld bytes\n", nbuckets, printf ("buckets: %d = %ld bytes\n", nbuckets,
(long)nbuckets*sizeof(struct sbucket)); (long) nbuckets * sizeof (struct sbucket));
total += nbuckets*sizeof(struct sbucket); total += nbuckets * sizeof (struct sbucket);
printf("idxtables: %d = %ld bytes\n", idxsize, (long)idxsize*sizeof(void*)); printf ("idxtables: %d = %ld bytes\n",
total += idxsize*sizeof(void*); idxsize, (long) idxsize * sizeof (void *));
printf("-----------------------------------\n"); total += idxsize * sizeof (void *);
printf("total: %d bytes\n", total); printf ("-----------------------------------\n");
printf("===================================\n"); printf ("total: %d bytes\n", total);
printf ("===================================\n");
objc_mutex_unlock(__objc_runtime_mutex);
objc_mutex_unlock (__objc_runtime_mutex);
} }
/* Returns the uninstalled dispatch table indicator. /* Returns the uninstalled dispatch table indicator.
If a class' dispatch table points to __objc_uninstalled_dtable If a class' dispatch table points to __objc_uninstalled_dtable
then that means it needs its dispatch table to be installed. */ then that means it needs its dispatch table to be installed. */
__inline__ __inline__
struct sarray* struct sarray *
objc_get_uninstalled_dtable() objc_get_uninstalled_dtable ()
{ {
return __objc_uninstalled_dtable; return __objc_uninstalled_dtable;
} }

Loading…
Cancel
Save