diff options
Diffstat (limited to 'gnu/gcc2/libobjc/class.c')
| -rw-r--r-- | gnu/gcc2/libobjc/class.c | 350 |
1 files changed, 0 insertions, 350 deletions
diff --git a/gnu/gcc2/libobjc/class.c b/gnu/gcc2/libobjc/class.c deleted file mode 100644 index c9af0eb1bbf2..000000000000 --- a/gnu/gcc2/libobjc/class.c +++ /dev/null @@ -1,350 +0,0 @@ -/* GNU Objective C Runtime class related functions - Copyright (C) 1993 Free Software Foundation, Inc. - -Author: Kresten Krab Thorup, Dennis Glatting - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 2, or (at your option) any later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - details. - -You should have received a copy of the GNU General Public License along with - GNU CC; see the file COPYING. If not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* As a special exception, if you link this library with files compiled with - GCC to produce an executable, this does not cause the resulting executable - to be covered by the GNU General Public License. This exception does not - however invalidate any other reasons why the executable file might be - covered by the GNU General Public License. */ - -#include "runtime.h" /* the kitchen sink */ - - -/* The table of classname->class. Used for objc_lookup_class and friends */ -static cache_ptr __objc_class_hash = 0; - -/* This is a hook which is called by objc_get_class and - objc_lookup_class if the runtime is not able to find the class. - This may e.g. try to load in the class using dynamic loading */ -Class* (*_objc_lookup_class)(const char* name) = 0; - - -/* True when class links has been resolved */ -BOOL __objc_class_links_resolved = NO; - - -/* Initial number of buckets size of class hash table. */ -#define CLASS_HASH_SIZE 32 - -void __objc_init_class_tables() -{ - /* Allocate the class hash table */ - - if(__objc_class_hash) - return; - - __objc_class_hash - = hash_new (CLASS_HASH_SIZE, - (hash_func_type) hash_string, - (compare_func_type) compare_strings); -} - -/* This function adds a class to the class hash table, and assigns the - class a number, unless it's already known */ -void -__objc_add_class_to_hash(Class* class) -{ - Class* h_class; - - /* make sure the table is there */ - assert(__objc_class_hash); - - /* make sure it's not a meta class */ - assert(CLS_ISCLASS(class)); - - /* Check to see if the class is already in the hash table. */ - h_class = hash_value_for_key (__objc_class_hash, class->name); - if (!h_class) - { - /* The class isn't in the hash table. Add the class and assign a class - number. */ - static unsigned int class_number = 1; - - CLS_SETNUMBER(class, class_number); - CLS_SETNUMBER(class->class_pointer, class_number); - - ++class_number; - hash_add (&__objc_class_hash, class->name, class); - } -} - -/* Get the class object for the class named NAME. If NAME does not - identify a known class, the hook _objc_lookup_class is called. If - this fails, nil is returned */ -Class* objc_lookup_class (const char* name) -{ - Class* class; - - /* Make sure the class hash table exists. */ - assert (__objc_class_hash); - - class = hash_value_for_key (__objc_class_hash, name); - - if (class) - return class; - - if (_objc_lookup_class) - return (*_objc_lookup_class)(name); - else - return 0; -} - -/* Get the class object for the class named NAME. If NAME does not - identify a known class, the hook _objc_lookup_class is called. If - this fails, an error message is issued and the system aborts */ -Class* -objc_get_class (const char *name) -{ - Class* class; - - /* Make sure the class hash table exists. */ - assert (__objc_class_hash); - - class = hash_value_for_key (__objc_class_hash, name); - - if (class) - return class; - - if (_objc_lookup_class) - class = (*_objc_lookup_class)(name); - - if(class) - return class; - - fprintf(stderr, "objc runtime: cannot find class %s\n", name); - abort(); -} - - -/* Resolve super/subclass links for all classes. The only thing we - can be sure of is that the class_pointer for class objects point - to the right meta class objects */ -void __objc_resolve_class_links() -{ - node_ptr node; - Class* object_class = objc_get_class ("Object"); - - assert(object_class); - - /* Assign subclass links */ - for (node = hash_next (__objc_class_hash, NULL); node; - node = hash_next (__objc_class_hash, node)) - { - Class* class1 = node->value; - - /* Make sure we have what we think we have. */ - assert (CLS_ISCLASS(class1)); - assert (CLS_ISMETA(class1->class_pointer)); - - /* The class_pointer of all meta classes point to Object's meta class. */ - class1->class_pointer->class_pointer = object_class->class_pointer; - - if (!(CLS_ISRESOLV(class1))) - { - CLS_SETRESOLV(class1); - CLS_SETRESOLV(class1->class_pointer); - - if(class1->super_class) - { - Class* a_super_class - = objc_get_class ((char *) class1->super_class); - - assert (a_super_class); - - DEBUG_PRINTF ("making class connections for: %s\n", - class1->name); - - /* assign subclass links for superclass */ - class1->sibling_class = a_super_class->subclass_list; - a_super_class->subclass_list = class1; - - /* Assign subclass links for meta class of superclass */ - if (a_super_class->class_pointer) - { - class1->class_pointer->sibling_class - = a_super_class->class_pointer->subclass_list; - a_super_class->class_pointer->subclass_list - = class1->class_pointer; - } - } - else /* a root class, make its meta object */ - /* be a subclass of Object */ - { - class1->class_pointer->sibling_class - = object_class->subclass_list; - object_class->subclass_list = class1->class_pointer; - } - } - } - - /* Assign superclass links */ - for (node = hash_next (__objc_class_hash, NULL); node; - node = hash_next (__objc_class_hash, node)) - { - Class* class1 = node->value; - Class* sub_class; - for (sub_class = class1->subclass_list; sub_class; - sub_class = sub_class->sibling_class) - { - sub_class->super_class = class1; - if(CLS_ISCLASS(sub_class)) - sub_class->class_pointer->super_class = class1->class_pointer; - } - } -} - - -/* This is a incomplete implementation of posing. This function does the - bulk of the work but does not initialize the class method caches. That is - a run-time specific operation. - -I implement posing by hiding SUPER_CLASS, creating new class and meta class - structures, initializing it with IMPOSTOR, and changing it such that it is - identified as SUPER_CLASS. SUPER_CLASS remains in the hierarchy but is - inaccessible by the means. The class hierarchy is then re arranged such - that all of the subclasses of SUPER_CLASS now inherit from the new class - structures -- except the impostor itself. The only dramatic effect on the - application is that subclasses of SUPER_CLASS cannot do a [ .... - super_class ] and expect their real super class. */ -Class* -class_pose_as (Class* impostor, Class* super_class) -{ - Class* new_class = (Class*) __objc_xcalloc (1, sizeof (Class)); - MetaClass* new_meta_class = - (MetaClass*) __objc_xmalloc(sizeof (MetaClass)); - char *new_name = (char *)__objc_xmalloc ((size_t)strlen ((char*)super_class->name) + 12); - - /* We must know the state of the hierachy. Do initial setup if needed */ - if(!CLS_ISRESOLV(impostor)) - __objc_resolve_class_links(); - - assert (new_class); - assert (new_meta_class); - assert (new_name); - - assert (CLS_ISCLASS(impostor)); - assert (CLS_ISCLASS(super_class)); - - assert (impostor->instance_size == super_class->instance_size); - - /* Create the impostor class. */ - new_class->class_pointer = new_meta_class; - new_class->super_class = super_class; - new_class->name = super_class->name; - new_class->version = super_class->version; - new_class->info = super_class->info; - new_class->instance_size = super_class->instance_size; - new_class->ivars = super_class->ivars; - new_class->methods = impostor->methods; - new_class->dtable = impostor->dtable; - - /* Create the impostor meta class. */ - new_meta_class->class_pointer = super_class->class_pointer->class_pointer; - new_meta_class->super_class = super_class->class_pointer->super_class; - new_meta_class->name = super_class->class_pointer->name; - new_meta_class->version = super_class->class_pointer->version; - new_meta_class->info = super_class->class_pointer->info; - new_meta_class->instance_size = super_class->class_pointer->instance_size; - new_meta_class->ivars = super_class->class_pointer->ivars; - new_meta_class->methods = impostor->class_pointer->methods; - new_meta_class->dtable = impostor->class_pointer->dtable; - - /* Now change super/subclass links of all related classes. This is rather - complex, since we have both super_class link, and subclass_list for the - involved classes. */ - { - Class* *classpp; - MetaClass* *metaclasspp; - - /* Remove impostor from subclass list of super_class */ - for (classpp = &(super_class->subclass_list); - *classpp; - classpp = &((*classpp)->sibling_class)) - { - if (*classpp == impostor) - *classpp = (*classpp)->sibling_class; - if (*classpp == 0) - break; - } - - /* Do the same for the meta classes */ - - for (metaclasspp = &(super_class->class_pointer->subclass_list); - *metaclasspp; - metaclasspp = &((*metaclasspp)->sibling_class)) - { - if (*metaclasspp == impostor->class_pointer) - *metaclasspp = (*metaclasspp)->sibling_class; - if (*metaclasspp == 0) - break; - } - - /* From the loop above, classpp now points to the sibling_class entry */ - /* of the last element in the list of subclasses for super_class */ - - /* Append the subclass list of impostor to the subclass list of */ - /* superclass, and excange those two and set subclass of */ - /* super_class to be impostor only */ - - *classpp = impostor->subclass_list; - new_class->subclass_list = super_class->subclass_list; - super_class->subclass_list = new_class; - new_class->sibling_class = 0; - - /* Do the same thing for the meta classes */ - *metaclasspp = impostor->class_pointer->subclass_list; - new_meta_class->subclass_list = super_class->class_pointer->subclass_list; - super_class->class_pointer->subclass_list = new_meta_class; - new_meta_class->sibling_class = 0; - - /* Update superclass links for all subclasses of new_class */ - for (classpp = &(new_class->subclass_list); *classpp; - classpp = &((*classpp)->sibling_class)) - (*classpp)->super_class = new_class; - - for (metaclasspp = &(new_meta_class->subclass_list); *metaclasspp; - metaclasspp = &((*metaclasspp)->sibling_class)) - (*metaclasspp)->super_class = new_meta_class; - - } - - /* Delete the class from the hash table, change its name so that it can no - longer be found, then place it back into the hash table using its new - name. - - Don't worry about the class number. It is already assigned. - memory is lost with the hash key.) */ - hash_remove (__objc_class_hash, super_class->name); - sprintf (new_name, "%s*", super_class->name); - super_class->name = new_name; - super_class->class_pointer->name = new_name; - hash_add (&__objc_class_hash, super_class->name, super_class); - - /* Place the impostor class in class hash table and assign it a class - number. */ - __objc_add_class_to_hash (new_class); - - /* Now update dispatch tables for new_class and it's subclasses */ - __objc_update_dispatch_table_for_class ((Class*) new_meta_class); - __objc_update_dispatch_table_for_class (new_class); - - return new_class; -} - |
