diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-10-11 21:44:44 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-10-11 21:44:44 +0000 |
commit | 77d3568815aaad6487a295a42e0fce17c1c71b19 (patch) | |
tree | f9fd5b7f95f54528ed914ff8348f63ec1722000e /libobjc | |
parent | 5f5dce8d85baa565d58eb34f4723b14b828417b4 (diff) | |
download | gcc-77d3568815aaad6487a295a42e0fce17c1c71b19.tar.gz |
2010-10-11 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 165329
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@165333 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libobjc')
33 files changed, 1520 insertions, 302 deletions
diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog index ac51fcb3c50..e2d93108abf 100644 --- a/libobjc/ChangeLog +++ b/libobjc/ChangeLog @@ -1,3 +1,173 @@ +2010-10-11 Nicola Pero <nicola.pero@meta-innovation.com> + + * class.c (objc_getClassList): New. + (objc_getRequiredClass): New. + (objc_getMetaClass): New. + (objc_lookupClass): New. + (objc_getClass): New. + (__objc_get_unknown_class_handler): New. + (objc_setGetUnknownClassHandler): New. + (objc_get_class): Use __objc_get_unknown_class_handler. + (objc_lookup_class): Call objc_getClass. + * objc/objc-api.h: Updated comment and copyright notice. + * objc/runtime.h: Updated comments. + (objc_getClass): New. + (objc_lookupClass): New. + (objc_getMetaClass): New. + (objc_getRequiredClass): New. + (objc_getClassList): New. + (objc_setGetUnknownClassHandler): New. + (objc_get_unknown_class_handler): New. + * objc-private/runtime.h: Use __objc_private_runtime_INCLUDE_GNU + instead of __objc_runtime_INCLUDE_GNU as include guard. + * objc-private/error.h (_objc_abort): Mark as noreturn. + +2010-10-11 Nicola Pero <nicola.pero@meta-innovation.com> + + * Makefile.in (C_SOURCE_FILES): Added ivars.c. + * ivars.c: New. + * objc/objc.h: Updated comments. + * objc/runtime.h (object_getClass): New. + (object_getClassName): New. + (object_setClass): New. + (class_getInstanceVariable): New. + (object_getIndexedIvars): New. + (object_getInstanceVariable): New. + (object_setInstanceVariable): New. + (object_getIvar): New. + (object_setIvar): New. + (ivar_getName): New. + (ivar_getOffset): New. + (ivar_getTypeEncoding): New. + * objc-private/module-abi-8.h (struct objc_class): Added. + * objects.c (object_getClassName): New. + (object_setClass): New. + +2010-10-11 Nicola Pero <nicola.pero@meta-innovation.com> + + * objc/objc.h: Updated comments. + * objc/objc-api.h: (object_copy): Added one argument; use a + #define to maintain backwards-compatibility. Moved + _objc_object_alloc, _objc_object_copy, _objc_object_dispose and + objc_get_uninstalled_dtable into + objc/deprecated/objc_get_uninstalled_dtable.h and + objc/deprecated/objc_object_alloc.h. Include these files. + * objc/deprecated/objc_get_uninstalled_dtable.h: New. + * objc/deprecated/objc_object_alloc.h: New. + * objc/runtime.h (set_getName): New. + (sel_getType): New. + (sel_getUid): New. + (sel_registerName): New. + (sel_registerTypedName): New. + (sel_isEqual): New. + (class_createInstance): New. + (object_copy): New. + (object_dispose): New. + * objects.c: Do not include tconfig.h. Include gc_typed.h if + building the garbage collection version. + (__objc_object_alloc): Removed. + (__objc_object_copy): Removed. + (__objc_object_dispose): Removed. + (class_createInstance): New from code in class_create_instance. + Cast second argument of GC_malloc_explicitly_typed. Use + objc_calloc. Do not call _objc_object_alloc. + (class_create_instance): Call class_createInstance. + (object_copy): Added extraBytes argument. Do not call + _objc_object_copy. + (object_dispose): Do not call _objc_object_dispose. + * memory.c (objc_free): When using garbage collection, mark the + argument as unused. + * selector.c (sel_getName): New. + (sel_get_name): Call sel_getName. + (sel_getType): New. + (sel_get_type): Call sel_getType. + (sel_registerName): New. + (sel_register_name): Call sel_registerName. + (sel_registerTypedName): New. + (sel_register_typed_name): Call sel_registerTypedName. + (sel_getUid): New. + (sel_get_uid): Call sel_getUid. + +2010-10-10 Nicola Pero <nicola.pero@meta-innovation.com> + + * objc/objc-api.h: Define Method, Method_t, Category and + Category_t. Prevent including this file at the same time as + objc/runtime.h. Updated comments. + * objc/deprecated/struct_objc_method.h: Do not define Method, + Method_t. + * objc/deprecated/struct_objc_category.h: Do not define Category, + Category_t. + * objc-private/module-abi-8.h: New file containing a copy of all + the structure definitions. Not used yet. + * objc/encoding.h (objc_aligned_size): Removed duplicate + declaration. Updated comments. + * objc/runtime.h: Added Ivar, objc_property_t, Property, Method, + Category, struct objc_method_description, _C_ID and similar, + _C_CONST and similar and _F_CONST and similar. Added + objc_sizeof_type, objc_alignof_type, objc_aligned_size, + objc_promoted_size, objc_skip_type_qualifier, objc_skip_typespec, + objc_skip_offset, objc_skip_argspec, objc_get_type_qualifiers, + struct objc_struct_layout, objc_layout_structure, + objc_layout_structure_next_member, objc_layout_finish_structure, + objc_layout_structure_get_info. Prevent including this file at + the same time as objc/objc-api.h. + +2010-10-10 Nicola Pero <nicola.pero@meta-innovation.com> + + * Makefile.in (OBJC_DEPRECATED_H): Added struct_objc_category.h, + struct_objc_ivar.h, struct_objc_ivar_list.h, struct_objc_method.h, + struct_objc_method_list.h, struct_objc_module.h, + struct_objc_protocol_list.h, struct_objc_symtab.h. + * objc/deprecated/struct_objc_category.h: New. + * objc/deprecated/struct_objc_ivar.h: New. + * objc/deprecated/struct_objc_ivar_list.h: New. + * objc/deprecated/struct_objc_method.h: New. + * objc/deprecated/struct_objc_method_list.h: New. + * objc/deprecated/struct_objc_module.h: New. + * objc/deprecated/struct_objc_protocol_list.h: New. + * objc/deprecated/struct_objc_symtab.h: New. + * objc/deprecated/struct_objc_static_instances.h: New. + * objc/objc-api.h: Definitions of deprecated structures moved into + the above header fragment files in objc/deprecated/. Include the + files instead of definition the structures here. Updated + comments. + * objc/runtime.h: Updated comments. Do not include objc-api.h. + (objc_set_enumeration_mutation_handler): Renamed to + objc_setEnumerationMutationHandler. + * objc-foreach.c (objc_set_enumeration_mutation_handler): Renamed + to objc_setEnumerationMutationHandler. + * objc/objc-exception.h (objc_set_exception_matcher): Renamed to + objc_setExceptionMatcher. + (objc_set_uncaught_exception_handler): Renamed to + objc_setUncaughtExceptionHandler. + * exception.c: Same changes. + +2010-10-10 Nicola Pero <nicola.pero@meta-innovation.com> + + * objc-sync.c: Include objc-private/common.h. + +2010-10-10 Nicola Pero <nicola.pero@meta-innovation.com> + + * objc-foreach.c: Include objc-private/common.h. + * objc/deprecated/METHOD_NULL.h: New file. + * objc/objc-api.h: Include deprecated/METHOD_NULL.h instead of + defining METHOD_NULL here. + * Makefile.in (OBJC_DEPRECATED_H): Added METHOD_NULL.h. + * Object.m ([+instancesRespondTo:]): Use (Method_t)0 instead of + METHOD_NULL. + ([-respondsTo:]): Same change. + * objc/objc-api.h (method_get_imp): Converted it into a normal + function so that we can hide the internals of struct objc_method. + * sendmsg.c (method_get_imp): Implemented. + +2010-10-09 Nicola Pero <nicola.pero@meta-innovation.com> + + * objc/objc-api.h (struct objc_super, Super, Super_t, + objc_msg_lookup_super, objc_msg_sendv, objc_msg_forward, + objc_msg_forward2): Declarations moved to objc/message.h. Include + message.h here. + * objc/message.h: Added such declarations; updated comments. + 2010-10-06 Nicola Pero <nicola.pero@meta-innovation.com> Implemented fast enumeration for Objective-C. diff --git a/libobjc/Makefile.in b/libobjc/Makefile.in index d99ab26a0a6..86f65bad844 100644 --- a/libobjc/Makefile.in +++ b/libobjc/Makefile.in @@ -131,6 +131,7 @@ OBJC_H = \ # User-visible header files containing deprecated APIs, from the # objc/deprecated directory OBJC_DEPRECATED_H = \ + METHOD_NULL.h \ MetaClass.h \ Object.h \ STR.h \ @@ -141,9 +142,17 @@ OBJC_DEPRECATED_H = \ objc_unexpected_exception.h \ objc_valloc.h \ sarray.h \ + struct_objc_category.h \ struct_objc_class.h \ + struct_objc_ivar.h \ + struct_objc_ivar_list.h \ + struct_objc_method.h \ + struct_objc_method_list.h \ + struct_objc_module.h \ struct_objc_protocol.h \ + struct_objc_protocol_list.h \ struct_objc_selector.h \ + struct_objc_symtab.h \ typedstream.h # Objective-C source files to compile @@ -162,6 +171,7 @@ C_SOURCE_FILES = \ gc.c \ hash.c \ init.c \ + ivars.c \ memory.c \ nil_method.c \ objc-foreach.c \ diff --git a/libobjc/Object.m b/libobjc/Object.m index 3a5bcb31688..441c471b2a1 100644 --- a/libobjc/Object.m +++ b/libobjc/Object.m @@ -172,14 +172,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + (BOOL)instancesRespondTo:(SEL)aSel { - return class_get_instance_method(self, aSel)!=METHOD_NULL; + return class_get_instance_method(self, aSel) != (Method_t)0; } - (BOOL)respondsTo:(SEL)aSel { return ((object_is_instance(self) ?class_get_instance_method(self->isa, aSel) - :class_get_class_method(self->isa, aSel))!=METHOD_NULL); + :class_get_class_method(self->isa, aSel)) != (Method_t)0); } + (IMP)instanceMethodFor:(SEL)aSel diff --git a/libobjc/class.c b/libobjc/class.c index cba9b843355..216d6ace0dc 100644 --- a/libobjc/class.c +++ b/libobjc/class.c @@ -408,9 +408,36 @@ class_table_print_histogram (void) /* This is a hook which is called by objc_get_class and objc_lookup_class if the runtime is not able to find the class. - This may e.g. try to load in the class using dynamic loading. */ + This may e.g. try to load in the class using dynamic loading. + + This hook was a public, global variable in the Traditional GNU + Objective-C Runtime API (objc/objc-api.h). The modern GNU + Objective-C Runtime API (objc/runtime.h) provides the + objc_setGetUnknownClassHandler() function instead. +*/ Class (*_objc_lookup_class) (const char *name) = 0; /* !T:SAFE */ +/* Temporarily while we still include objc/objc-api.h instead of objc/runtime.h. */ +#ifndef __objc_runtime_INCLUDE_GNU +typedef Class (*objc_get_unknown_class_handler)(const char *class_name); +#endif + +/* The handler currently in use. PS: if both + __obj_get_unknown_class_handler and _objc_lookup_class are defined, + __objc_get_unknown_class_handler is called first. */ +static objc_get_unknown_class_handler +__objc_get_unknown_class_handler = NULL; + +objc_get_unknown_class_handler +objc_setGetUnknownClassHandler (objc_get_unknown_class_handler + new_handler) +{ + objc_get_unknown_class_handler old_handler + = __objc_get_unknown_class_handler; + __objc_get_unknown_class_handler = new_handler; + return old_handler; +} + /* True when class links has been resolved. */ BOOL __objc_class_links_resolved = NO; /* !T:UNUSED */ @@ -464,25 +491,106 @@ __objc_add_class_to_hash (Class class) objc_mutex_unlock (__objc_runtime_mutex); } -/* Get the class object for the class named NAME. If NAME does not - identify a known class, the hook _objc_lookup_class is called. If - this fails, nil is returned. */ Class -objc_lookup_class (const char *name) +objc_getClass (const char *name) { Class class; - class = class_table_get_safe (name); + if (name == NULL) + return Nil; + class = class_table_get_safe (name); + if (class) return class; + + if (__objc_get_unknown_class_handler) + return (*__objc_get_unknown_class_handler) (name); if (_objc_lookup_class) return (*_objc_lookup_class) (name); + + return Nil; +} + +Class +objc_lookupClass (const char *name) +{ + if (name == NULL) + return Nil; + else + return class_table_get_safe (name); +} + +Class +objc_getMetaClass (const char *name) +{ + Class class = objc_getClass (name); + + if (class) + return class->class_pointer; else - return 0; + return Nil; } +Class +objc_getRequiredClass (const char *name) +{ + Class class = objc_getClass (name); + + if (class) + return class; + else + _objc_abort ("objc_getRequiredClass ('%s') failed: class not found\n", name); +} + +int +objc_getClassList (Class *returnValue, int maxNumberOfClassesToReturn) +{ + /* Iterate over all entries in the table. */ + int hash, count = 0; + + objc_mutex_lock (__class_table_lock); + + for (hash = 0; hash < CLASS_TABLE_SIZE; hash++) + { + class_node_ptr node = class_table_array[hash]; + + while (node != NULL) + { + if (returnValue) + { + if (count < maxNumberOfClassesToReturn) + returnValue[count] = node->pointer; + else + { + objc_mutex_unlock (__class_table_lock); + return count; + } + } + count++; + node = node->next; + } + } + + objc_mutex_unlock (__class_table_lock); + return count; +} + +/* Traditional GNU Objective-C Runtime API. */ +/* Get the class object for the class named NAME. If NAME does not + identify a known class, the hook _objc_lookup_class is called. If + this fails, nil is returned. */ +Class +objc_lookup_class (const char *name) +{ + return objc_getClass (name); +} + +/* Traditional GNU Objective-C Runtime API. Important: this method is + called automatically by the compiler while messaging (if using the + traditional ABI), so it is worth keeping it fast; don't make it + just a wrapper around objc_getClass(). */ /* Get the class object for the class named NAME. If NAME does not identify a known class, the hook _objc_lookup_class is called. If this fails, an error message is issued and the system aborts. */ @@ -496,13 +604,15 @@ objc_get_class (const char *name) if (class) return class; - if (_objc_lookup_class) + if (__objc_get_unknown_class_handler) + class = (*__objc_get_unknown_class_handler) (name); + + if ((!class) && _objc_lookup_class) class = (*_objc_lookup_class) (name); if (class) return class; - /* FIXME: Should we abort the program here ? */ _objc_abort ("objc runtime: cannot find class %s\n", name); return 0; diff --git a/libobjc/exception.c b/libobjc/exception.c index 0225d6789a4..a221a3e77e3 100644 --- a/libobjc/exception.c +++ b/libobjc/exception.c @@ -69,7 +69,7 @@ static objc_exception_matcher __objc_exception_matcher = is_kind_of_exception_matcher; objc_exception_matcher -objc_set_exception_matcher (objc_exception_matcher new_matcher) +objc_setExceptionMatcher (objc_exception_matcher new_matcher) { objc_exception_matcher old_matcher = __objc_exception_matcher; __objc_exception_matcher = new_matcher; @@ -81,8 +81,8 @@ static objc_uncaught_exception_handler __objc_uncaught_exception_handler = NULL; objc_uncaught_exception_handler -objc_set_uncaught_exception_handler (objc_uncaught_exception_handler - new_handler) +objc_setUncaughtExceptionHandler (objc_uncaught_exception_handler + new_handler) { objc_uncaught_exception_handler old_handler = __objc_uncaught_exception_handler; diff --git a/libobjc/ivars.c b/libobjc/ivars.c new file mode 100644 index 00000000000..18c6e8af29d --- /dev/null +++ b/libobjc/ivars.c @@ -0,0 +1,151 @@ +/* GNU Objective C Runtime ivar related functions. + Copyright (C) 2010 Free Software Foundation, Inc. + Contributed by Nicola Pero + +This file is part of GCC. + +GCC 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 3, or (at your option) any later version. + +GCC 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. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "objc-private/common.h" +#include "objc/objc.h" +#include "objc/objc-api.h" +#include "objc-private/runtime.h" /* the kitchen sink */ +#include <string.h> /* For strcmp */ + +struct objc_ivar * +class_getInstanceVariable (Class class_, const char *name) +{ + if (class_ != Nil && name != NULL) + { + objc_mutex_lock (__objc_runtime_mutex); + while (class_ != Nil) + { + struct objc_ivar_list *ivars = class_->ivars; + if (ivars != NULL) + { + int i; + + for (i = 0; i < ivars->ivar_count; i++) + { + struct objc_ivar *ivar = &(ivars->ivar_list[i]); + + if (!strcmp (ivar->ivar_name, name)) + { + objc_mutex_unlock (__objc_runtime_mutex); + return ivar; + } + } + } + class_ = class_->super_class; + } + objc_mutex_unlock (__objc_runtime_mutex); + } + return NULL; +} + +void * +object_getIndexedIvars (id object) +{ + if (object == nil) + return NULL; + else + { + return (void *)(((char *)object) + + object->class_pointer->instance_size); + } +} + +struct objc_ivar * +object_getInstanceVariable (id object, const char *name, void **returnValue) +{ + if (object == nil || name == NULL) + return NULL; + else + { + struct objc_ivar * variable = class_getInstanceVariable (object->class_pointer, name); + + if (variable != NULL && returnValue != NULL) + { + char *location = (char *)object + variable->ivar_offset; + + *returnValue = *((id *)location); + } + + return variable; + } +} + +struct objc_ivar * +object_setInstanceVariable (id object, const char *name, void *newValue) +{ + if (object == nil || name == NULL) + return NULL; + else + { + struct objc_ivar * variable = class_getInstanceVariable (object->class_pointer, name); + + if (variable != NULL) + { + char *location = (char *)object + variable->ivar_offset; + + *((id *)location) = (id)newValue; + } + + return variable; + } +} + +id object_getIvar (id object, struct objc_ivar * variable) +{ + if (object == nil || variable == NULL) + return nil; + else + { + char *location = (char *)object + variable->ivar_offset; + + return *((id *)location); + } +} + +void object_setIvar (id object, struct objc_ivar * variable, id value) +{ + if (object == nil || variable == NULL) + return; + else + { + char *location = (char *)object + variable->ivar_offset; + + *((id *)location) = value; + } +} + +const char * ivar_getName (struct objc_ivar * variable) +{ + return variable->ivar_name; +} + +ptrdiff_t ivar_getOffset (struct objc_ivar * variable) +{ + return (ptrdiff_t)(variable->ivar_offset); +} + +const char * ivar_getTypeEncoding (struct objc_ivar * variable) +{ + return variable->ivar_type; +} diff --git a/libobjc/memory.c b/libobjc/memory.c index 19a450ad860..a0d6e130ad9 100644 --- a/libobjc/memory.c +++ b/libobjc/memory.c @@ -30,6 +30,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see so that they work properly with garbage collectors. */ +/* TODO: Turn these into macros or inline functions. */ + #include "objc-private/common.h" #include "objc-private/error.h" @@ -85,7 +87,7 @@ objc_calloc (size_t nelem, size_t size) } void -objc_free (void *mem) +objc_free (void *mem __attribute__ ((__unused__))) { return; } diff --git a/libobjc/objc-foreach.c b/libobjc/objc-foreach.c index 83a91011d12..047f0cbbf44 100644 --- a/libobjc/objc-foreach.c +++ b/libobjc/objc-foreach.c @@ -27,14 +27,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see objc_set_enumeration_mutation_handler(), the two functions required to handle mutations during a fast enumeration. */ -#include "objc/runtime.h" /* For objc_enumerationMutation() and objc_set_enumeration_mutation_handler() */ +#include "objc-private/common.h" #include "objc-private/error.h" /* For _objc_abort() */ +#include "objc/runtime.h" /* For objc_enumerationMutation() and objc_set_enumeration_mutation_handler() */ /* The enumeration mutation handler currently in use. */ static void (*__objc_enumeration_mutation_handler)(id) = NULL; void -objc_set_enumeration_mutation_handler (void (*handler)(id)) +objc_setEnumerationMutationHandler (void (*handler)(id)) { __objc_enumeration_mutation_handler = handler; } diff --git a/libobjc/objc-private/error.h b/libobjc/objc-private/error.h index 2df9cb733ec..e8673f722ed 100644 --- a/libobjc/objc-private/error.h +++ b/libobjc/objc-private/error.h @@ -29,9 +29,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see This should only be used for errors that really are unrecorevable: failure to allocate memory, and failure to load an Objective-C module. All other usages of this function should be converted into - some milder type of error. + some milder type of error (unless aborting is explicitly required + by the documentation/API). */ void -_objc_abort (const char *fmt, ...); +_objc_abort (const char *fmt, ...) __attribute__ ((noreturn)); #endif /* __objc_private_error_INCLUDE_GNU */ diff --git a/libobjc/objc-private/module-abi-8.h b/libobjc/objc-private/module-abi-8.h new file mode 100644 index 00000000000..a20e3a3ae6e --- /dev/null +++ b/libobjc/objc-private/module-abi-8.h @@ -0,0 +1,229 @@ +/* Definitions of Module Structures used by ABI version 8 + Copyright (C) 1993, 1995, 1996, 1997, 2001, 2002, 2003, 2004, 2005, + 2007, 2009, 2010 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC 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 3, or (at your option) any later version. + +GCC 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. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#ifndef __objc_private_module_abi_8_INCLUDE_GNU +#define __objc_private_module_abi_8_INCLUDE_GNU + +/* For every class which happens to have statically allocated instances in + this module, one OBJC_STATIC_INSTANCES is allocated by the compiler. + INSTANCES is NULL terminated and points to all statically allocated + instances of this class. */ +struct objc_static_instances +{ + char *class_name; +#ifdef __cplusplus + id instances[1]; +#else + id instances[0]; +#endif +}; + +/* Whereas a Module (defined further down) is the root (typically) of a file, + a Symtab is the root of the class and category definitions within the + module. + + A Symtab contains a variable length array of pointers to classes and + categories defined in the module. */ +struct objc_symtab +{ + unsigned long sel_ref_cnt; /* Unknown. */ + SEL refs; /* Unknown. */ + unsigned short cls_def_cnt; /* Number of classes compiled (defined) + in the module. */ + unsigned short cat_def_cnt; /* Number of categories compiled + (defined) in the module. */ + void *defs[1]; /* Variable array of pointers. + cls_def_cnt of type Class followed by + cat_def_cnt of type Category_t, + followed by a NULL terminated array + of objc_static_instances. */ +}; + +/* The compiler generates one of these structures for each module that + composes the executable (eg main.m). + + This data structure is the root of the definition tree for the + module. + + A collect program runs between ld stages and creates a ObjC ctor + array. That array holds a pointer to each module structure of the + executable. */ +struct objc_module +{ + unsigned long version; /* Version of the Module data + structure. */ + unsigned long size; /* sizeof(Module) according to the + compiler - only used to sanity check + that it matches sizeof(Module) + according to the runtime. */ + const char* name; /* Name of the file used to compile the + module - not set by modern compilers + for security reasons. */ + struct objc_symtab *symtab; /* Pointer to the Symtab of the module. + The Symtab holds an array of pointers + to the classes and categories defined + in the module. */ +}; + +/* The compiler generates one of these structures for a class that has + instance variables defined in its specification. */ +struct objc_ivar +{ + const char* ivar_name; /* Name of the instance variable as entered + in the class definition. */ + const char* ivar_type; /* Description of the Ivar's type. Useful + for debuggers. */ + int ivar_offset; /* Byte offset from the base address of the + instance structure to the variable. */ +}; + +struct objc_ivar_list +{ + int ivar_count; /* Number of structures (Ivar) + contained in the list. One + structure per instance variable + defined in the class. */ + struct objc_ivar ivar_list[1]; /* Variable length structure. */ +}; + +/* The compiler generates one (or more) of these structures for a + class that has methods defined in its specification. + + The implementation of a class can be broken into separate pieces in + a file and categories can break them across modules. To handle this + problem is a singly linked list of methods. */ +struct objc_method +{ + SEL method_name; /* This variable is the method's name. It + is a char*. The unique integer passed + to objc_msg_send is a char* too. It is + compared against method_name using + strcmp. */ + const char* method_types; /* Description of the method's parameter + list. Useful for debuggers. */ + IMP method_imp; /* Address of the method in the + executable. */ +}; + +struct objc_method_list +{ + struct objc_method_list* method_next; /* This variable is used to + link a method list to + another. It is a singly + linked list. */ + int method_count; /* Number of methods defined + in this structure. */ + struct objc_method method_list[1]; /* Variable length + structure. */ +}; + +struct objc_protocol_list +{ + struct objc_protocol_list *next; + size_t count; + Protocol *list[1]; +}; + +/* + The compiler generates one of these structures for each class. + + This structure is the definition for classes. + + This structure is generated by the compiler in the executable and + used by the run-time during normal messaging operations. Therefore + some members change type. The compiler generates "char* const" and + places a string in the following member variables: super_class. +*/ +struct objc_class { + struct objc_class* class_pointer; /* Pointer to the class's meta + class. */ + struct objc_class* super_class; /* Pointer to the super + class. NULL for class + Object. */ + const char* name; /* Name of the class. */ + long version; /* Unknown. */ + unsigned long info; /* Bit mask. See class masks + defined above. */ + long instance_size; /* Size in bytes of the class. + The sum of the class + definition and all super + class definitions. */ +#ifdef _WIN64 + /* We pad the structure manually to prevent warning when -Wpadded is + used. The compiler automatically pads the structures that it + generates, so this manually padded structure still matches the + one generated by the compiler, but if we don't pad manually, + -Wpadded detects that padding is being added and generates + annoying warnings. This hack is necessary as on LLP64 targets + sizeof (long) isn't equal to sizeof (void *). */ + long pad; +#endif + struct objc_ivar_list* ivars; /* Pointer to a structure that + describes the instance + variables in the class + definition. NULL indicates + no instance variables. + Does not include super + class variables. */ + struct objc_method_list* methods; /* Linked list of instance + methods defined for the + class. */ + struct sarray * dtable; /* Pointer to instance method + dispatch table. */ + struct objc_class* subclass_list; /* Subclasses */ + struct objc_class* sibling_class; + + struct objc_protocol_list *protocols; /* Protocols conformed to */ + void* gc_object_type; +}; + +/* The compiler generates one of these structures for each category. + A class may have many categories and contain both instance and + factory methods. */ +struct objc_category +{ + const char* category_name; /* Name of the category. + Name contained in the + () of the category + definition. */ + const char* class_name; /* Name of the class to + which the category + belongs. */ + struct objc_method_list *instance_methods; /* Linked list of + instance methods + defined in the + category. NULL + indicates no instance + methods defined. */ + struct objc_method_list *class_methods; /* Linked list of + factory methods + defined in the + category. NULL + indicates no class + methods defined. */ + struct objc_protocol_list *protocols; /* List of Protocols + conformed to. */ +}; + +#endif /* __objc_private_module_abi_8_INCLUDE_GNU */ diff --git a/libobjc/objc-private/runtime.h b/libobjc/objc-private/runtime.h index c924e4d4975..690427ed5a3 100644 --- a/libobjc/objc-private/runtime.h +++ b/libobjc/objc-private/runtime.h @@ -36,8 +36,8 @@ but can almost certainly be shrinked down. */ -#ifndef __objc_runtime_INCLUDE_GNU -#define __objc_runtime_INCLUDE_GNU +#ifndef __objc_private_runtime_INCLUDE_GNU +#define __objc_private_runtime_INCLUDE_GNU #include <stdarg.h> /* for varargs and va_list's */ @@ -98,4 +98,4 @@ extern void __objc_generate_gc_type_description (Class); } #endif /* __cplusplus */ -#endif /* not __objc_runtime_INCLUDE_GNU */ +#endif /* not __objc_private_runtime_INCLUDE_GNU */ diff --git a/libobjc/objc-sync.c b/libobjc/objc-sync.c index 7f42115bfb0..97349e64029 100644 --- a/libobjc/objc-sync.c +++ b/libobjc/objc-sync.c @@ -77,6 +77,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # define SYNC_CACHE_DISABLE #endif +#include "objc-private/common.h" #include "objc/objc-sync.h" /* For objc_sync_enter(), objc_sync_exit() */ #include "objc/objc-api.h" /* For objc_malloc() */ #include "objc/thr.h" /* For objc_mutex_loc() and similar */ diff --git a/libobjc/objc/deprecated/METHOD_NULL.h b/libobjc/objc/deprecated/METHOD_NULL.h new file mode 100644 index 00000000000..6912be345e1 --- /dev/null +++ b/libobjc/objc/deprecated/METHOD_NULL.h @@ -0,0 +1,2 @@ +/* For functions which return Method_t */ +#define METHOD_NULL (Method_t)0 diff --git a/libobjc/objc/deprecated/objc_get_uninstalled_dtable.h b/libobjc/objc/deprecated/objc_get_uninstalled_dtable.h new file mode 100644 index 00000000000..48d508a1592 --- /dev/null +++ b/libobjc/objc/deprecated/objc_get_uninstalled_dtable.h @@ -0,0 +1,2 @@ +objc_EXPORT struct sarray* +objc_get_uninstalled_dtable(void); diff --git a/libobjc/objc/deprecated/objc_object_alloc.h b/libobjc/objc/deprecated/objc_object_alloc.h new file mode 100644 index 00000000000..f6336ca8efa --- /dev/null +++ b/libobjc/objc/deprecated/objc_object_alloc.h @@ -0,0 +1,8 @@ +/* These functions are deprecated and currently ignored. */ +/* +** Hook functions for allocating, copying and disposing of instances +*/ +objc_EXPORT id (*_objc_object_alloc)(Class _class); +objc_EXPORT id (*_objc_object_copy)(id object); +objc_EXPORT id (*_objc_object_dispose)(id object); + diff --git a/libobjc/objc/deprecated/struct_objc_category.h b/libobjc/objc/deprecated/struct_objc_category.h new file mode 100644 index 00000000000..6de3980a905 --- /dev/null +++ b/libobjc/objc/deprecated/struct_objc_category.h @@ -0,0 +1,21 @@ +/* +** The compiler generates one of these structures for each category. A class +** may have many categories and contain both instance and factory methods. +*/ +struct objc_category { + const char* category_name; /* Name of the category. Name + contained in the () of the + category definition. */ + const char* class_name; /* Name of the class to which + the category belongs. */ + MethodList_t instance_methods; /* Linked list of instance + methods defined in the + category. NULL indicates no + instance methods defined. */ + MethodList_t class_methods; /* Linked list of factory + methods defined in the + category. NULL indicates no + class methods defined. */ + struct objc_protocol_list *protocols; /* List of Protocols + conformed to */ +}; diff --git a/libobjc/objc/deprecated/struct_objc_ivar.h b/libobjc/objc/deprecated/struct_objc_ivar.h new file mode 100644 index 00000000000..57170ad1160 --- /dev/null +++ b/libobjc/objc/deprecated/struct_objc_ivar.h @@ -0,0 +1,15 @@ +/* +** The compiler generates one of these structures for a class that has +** instance variables defined in its specification. +*/ +typedef struct objc_ivar { + const char* ivar_name; /* Name of the instance + variable as entered in the + class definition. */ + const char* ivar_type; /* Description of the Ivar's + type. Useful for + debuggers. */ + int ivar_offset; /* Byte offset from the base + address of the instance + structure to the variable. */ +} *Ivar_t; diff --git a/libobjc/objc/deprecated/struct_objc_ivar_list.h b/libobjc/objc/deprecated/struct_objc_ivar_list.h new file mode 100644 index 00000000000..8f5051fb967 --- /dev/null +++ b/libobjc/objc/deprecated/struct_objc_ivar_list.h @@ -0,0 +1,10 @@ +typedef struct objc_ivar_list { + int ivar_count; /* Number of structures (Ivar) + contained in the list. One + structure per instance + variable defined in the + class. */ + struct objc_ivar ivar_list[1]; /* Variable length + structure. */ +} IvarList, *IvarList_t; + diff --git a/libobjc/objc/deprecated/struct_objc_method.h b/libobjc/objc/deprecated/struct_objc_method.h new file mode 100644 index 00000000000..af83c07b6ff --- /dev/null +++ b/libobjc/objc/deprecated/struct_objc_method.h @@ -0,0 +1,22 @@ +/* +** The compiler generates one (or more) of these structures for a class that +** has methods defined in its specification. +** +** The implementation of a class can be broken into separate pieces in a file +** and categories can break them across modules. To handle this problem is a +** singly linked list of methods. +*/ +struct objc_method { + SEL method_name; /* This variable is the method's + name. It is a char*. + The unique integer passed to + objc_msg_send is a char* too. + It is compared against + method_name using strcmp. */ + const char* method_types; /* Description of the method's + parameter list. Useful for + debuggers. */ + IMP method_imp; /* Address of the method in the + executable. */ +}; + diff --git a/libobjc/objc/deprecated/struct_objc_method_list.h b/libobjc/objc/deprecated/struct_objc_method_list.h new file mode 100644 index 00000000000..5156cabbf2d --- /dev/null +++ b/libobjc/objc/deprecated/struct_objc_method_list.h @@ -0,0 +1,9 @@ +typedef struct objc_method_list { + struct objc_method_list* method_next; /* This variable is used to link + a method list to another. It + is a singly linked list. */ + int method_count; /* Number of methods defined in + this structure. */ + Method method_list[1]; /* Variable length + structure. */ +} MethodList, *MethodList_t; diff --git a/libobjc/objc/deprecated/struct_objc_module.h b/libobjc/objc/deprecated/struct_objc_module.h new file mode 100644 index 00000000000..57950851fae --- /dev/null +++ b/libobjc/objc/deprecated/struct_objc_module.h @@ -0,0 +1,24 @@ +/* +** The compiler generates one of these structures for each module that +** composes the executable (eg main.m). +** +** This data structure is the root of the definition tree for the module. +** +** A collect program runs between ld stages and creates a ObjC ctor array. +** That array holds a pointer to each module structure of the executable. +*/ +typedef struct objc_module { + unsigned long version; /* Version of the Module data structure. */ + unsigned long size; /* sizeof(Module) according to the compiler - + only used to sanity check that it matches + sizeof(Module) according to the + runtime. */ + const char* name; /* Name of the file used to compile the + module - not set by modern compilers for + security reasons. */ + Symtab_t symtab; /* Pointer to the Symtab of the module. The + Symtab holds an array of pointers to the + classes and categories defined in the + module. */ +} Module, *Module_t; + diff --git a/libobjc/objc/deprecated/struct_objc_protocol_list.h b/libobjc/objc/deprecated/struct_objc_protocol_list.h new file mode 100644 index 00000000000..5e5788b5039 --- /dev/null +++ b/libobjc/objc/deprecated/struct_objc_protocol_list.h @@ -0,0 +1,5 @@ +struct objc_protocol_list { + struct objc_protocol_list *next; + size_t count; + Protocol *list[1]; +}; diff --git a/libobjc/objc/deprecated/struct_objc_static_instances.h b/libobjc/objc/deprecated/struct_objc_static_instances.h new file mode 100644 index 00000000000..9d889bfc08c --- /dev/null +++ b/libobjc/objc/deprecated/struct_objc_static_instances.h @@ -0,0 +1,14 @@ +/* For every class which happens to have statically allocated instances in + this module, one OBJC_STATIC_INSTANCES is allocated by the compiler. + INSTANCES is NULL terminated and points to all statically allocated + instances of this class. */ +struct objc_static_instances +{ + char *class_name; +#ifdef __cplusplus + id instances[1]; +#else + id instances[0]; +#endif +}; + diff --git a/libobjc/objc/deprecated/struct_objc_symtab.h b/libobjc/objc/deprecated/struct_objc_symtab.h new file mode 100644 index 00000000000..8e14d63ee34 --- /dev/null +++ b/libobjc/objc/deprecated/struct_objc_symtab.h @@ -0,0 +1,23 @@ +/* Whereas a Module (defined further down) is the root (typically) of a file, + a Symtab is the root of the class and category definitions within the + module. + + A Symtab contains a variable length array of pointers to classes and + categories defined in the module. */ +typedef struct objc_symtab { + unsigned long sel_ref_cnt; /* Unknown. */ + SEL refs; /* Unknown. */ + unsigned short cls_def_cnt; /* Number of classes compiled + (defined) in the module. */ + unsigned short cat_def_cnt; /* Number of categories + compiled (defined) in the + module. */ + + void *defs[1]; /* Variable array of pointers. + cls_def_cnt of type Class + followed by cat_def_cnt of + type Category_t, followed + by a NULL terminated array + of objc_static_instances. */ +} Symtab, *Symtab_t; + diff --git a/libobjc/objc/encoding.h b/libobjc/objc/encoding.h index 177ef726a00..523b129f328 100644 --- a/libobjc/objc/encoding.h +++ b/libobjc/objc/encoding.h @@ -28,6 +28,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #ifndef __encoding_INCLUDE_GNU #define __encoding_INCLUDE_GNU +/* This file is to be used with the "traditional" GNU Objective-C + Runtime API (the one declared in objc/objc-api.h). If you are + using the "modern" GNU Objective-C Runtime API, then the useful + functions from this file are declared in objc/runtime.h. +*/ + #include "objc-api.h" #include <ctype.h> @@ -35,6 +41,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see extern "C" { #endif /* __cplusplus */ +/* The following are used in encode strings to describe some + qualifiers of method and ivar types. */ #define _C_CONST 'r' #define _C_IN 'n' #define _C_INOUT 'N' @@ -44,6 +52,7 @@ extern "C" { #define _C_ONEWAY 'V' #define _C_GCINVISIBLE '|' +/* The same when used as flags. */ #define _F_CONST 0x01 #define _F_IN 0x01 #define _F_OUT 0x02 @@ -53,7 +62,6 @@ extern "C" { #define _F_ONEWAY 0x10 #define _F_GCINVISIBLE 0x20 -int objc_aligned_size (const char *type); int objc_sizeof_type (const char *type); int objc_alignof_type (const char *type); int objc_aligned_size (const char *type); diff --git a/libobjc/objc/message.h b/libobjc/objc/message.h index 6d476363c69..f0038e714ac 100644 --- a/libobjc/objc/message.h +++ b/libobjc/objc/message.h @@ -33,7 +33,16 @@ extern "C" { #include "objc.h" #include "objc-decls.h" -/* This file includes declarations of the messaging functions and types. */ +/* This file includes declarations of the messaging functions and + types. +*/ + +/* Compatibility note: the messaging function is one area where the + GNU runtime and the Apple/NeXT runtime differ significantly. If + you can, it is recommended that you use higher-level facilities + (provided by a Foundation library such as GNUstep Base) to perform + forwarding or other advanced messaging tricks. +*/ typedef void* retval_t; /* return value */ typedef void(*apply_t)(void); /* function pointer */ @@ -44,7 +53,37 @@ typedef union arglist { objc_EXPORT IMP objc_msg_lookup(id receiver, SEL op); -/* TODO: Add the remaining messaging declarations from objc-api.h. */ +/* + * Structure used when a message is send to a class's super class. + * The compiler generates one of these structures and passes it to + * objc_msg_lookup_super. + */ +typedef struct objc_super { + id self; /* Id of the object sending the message. */ +#ifdef __cplusplus + /* The new version of the API will always use 'super_class'. */ + Class super_class; +#else + Class class; /* Object's super class. */ +#endif +} Super, *Super_t; + +objc_EXPORT IMP objc_msg_lookup_super(Super_t super, SEL sel); + +objc_EXPORT retval_t objc_msg_sendv(id, SEL, arglist_t); + +/* + * Hooks for method forwarding. This makes it easy to substitute a + * library, such as ffcall, that implements closures, thereby avoiding + * gcc's __builtin_apply problems. __objc_msg_forward2's result will + * be preferred over that of __objc_msg_forward if both are set and + * return non-NULL. + * + * TODO: The API should define objc_set_msg_forward_handler () or + * similar instead of these hooks. + */ +objc_EXPORT IMP (*__objc_msg_forward)(SEL); +objc_EXPORT IMP (*__objc_msg_forward2)(id, SEL); #ifdef __cplusplus } diff --git a/libobjc/objc/objc-api.h b/libobjc/objc/objc-api.h index be433cb9a05..d31e13f6bf3 100644 --- a/libobjc/objc/objc-api.h +++ b/libobjc/objc/objc-api.h @@ -1,6 +1,6 @@ -/* GNU Objective-C Runtime API. +/* GNU Objective-C Runtime API - Traditional API Copyright (C) 1993, 1995, 1996, 1997, 2001, 2002, 2003, 2004, 2005, - 2007, 2009 Free Software Foundation, Inc. + 2007, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -23,10 +23,28 @@ a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ - #ifndef __objc_api_INCLUDE_GNU #define __objc_api_INCLUDE_GNU +/* + This file declares the "traditional" GNU Objective-C Runtime API. + It is the API supported by older versions of the GNU Objective-C + Runtime. Include this file to use it. + + This API is being replaced by the "modern" GNU Objective-C Runtime + API, which is declared in objc/runtime.h. The "modern" API is very + similar to the API used by the modern Apple/NeXT runtime. + + Because the two APIs have some conflicting definitions (in + particular, Method and Category are defined differently) you should + include either objc/objc-api.h (to use the traditional GNU + Objective-C Runtime API) or objc/runtime.h (to use the modern GNU + Objective-C Runtime API), but not both. +*/ +#ifdef __objc_runtime_INCLUDE_GNU +# error You can not include both objc/objc-api.h and objc/runtime.h. Include objc/objc-api.h for the traditional GNU Objective-C Runtime API and objc/runtime.h for the modern one. +#endif + #include "objc.h" #ifndef GNU_LIBOBJC_COMPILING_LIBOBJC_ITSELF # include "deprecated/hash.h" @@ -40,9 +58,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see extern "C" { #endif /* __cplusplus */ -/* For functions which return Method_t */ -#define METHOD_NULL (Method_t)0 - /* Boolean typedefs */ +#include "deprecated/METHOD_NULL.h" + /* Method descriptor returned by introspective Object methods. This is really just the first part of the more complete objc_method structure defined below and used internally by the runtime. */ @@ -52,7 +69,8 @@ struct objc_method_description char *types; /* type encoding */ }; -/* Filer types used to describe Ivars and Methods. */ +/* The following are used in encode strings to describe the type of + Ivars and Methods. */ #define _C_ID '@' #define _C_CLASS '#' #define _C_SEL ':' @@ -84,141 +102,22 @@ struct objc_method_description #define _C_VECTOR '!' #define _C_COMPLEX 'j' -/* The following one is never generated by the compiler. You can - treat it as equivalent to "*". -*/ +/* _C_ATOM is never generated by the compiler. You can treat it as + equivalent to "*". */ #define _C_ATOM '%' - #include "deprecated/objc_error.h" -/* For every class which happens to have statically allocated instances in - this module, one OBJC_STATIC_INSTANCES is allocated by the compiler. - INSTANCES is NULL terminated and points to all statically allocated - instances of this class. */ -struct objc_static_instances -{ - char *class_name; -#ifdef __cplusplus - id instances[1]; -#else - id instances[0]; -#endif -}; - -/* Whereas a Module (defined further down) is the root (typically) of a file, - a Symtab is the root of the class and category definitions within the - module. - - A Symtab contains a variable length array of pointers to classes and - categories defined in the module. */ -typedef struct objc_symtab { - unsigned long sel_ref_cnt; /* Unknown. */ - SEL refs; /* Unknown. */ - unsigned short cls_def_cnt; /* Number of classes compiled - (defined) in the module. */ - unsigned short cat_def_cnt; /* Number of categories - compiled (defined) in the - module. */ - - void *defs[1]; /* Variable array of pointers. - cls_def_cnt of type Class - followed by cat_def_cnt of - type Category_t, followed - by a NULL terminated array - of objc_static_instances. */ -} Symtab, *Symtab_t; - - -/* -** The compiler generates one of these structures for each module that -** composes the executable (eg main.m). -** -** This data structure is the root of the definition tree for the module. -** -** A collect program runs between ld stages and creates a ObjC ctor array. -** That array holds a pointer to each module structure of the executable. -*/ -typedef struct objc_module { - unsigned long version; /* Version of the Module data structure. */ - unsigned long size; /* sizeof(Module) according to the compiler - - only used to sanity check that it matches - sizeof(Module) according to the - runtime. */ - const char* name; /* Name of the file used to compile the - module - not set by modern compilers for - security reasons. */ - Symtab_t symtab; /* Pointer to the Symtab of the module. The - Symtab holds an array of pointers to the - classes and categories defined in the - module. */ -} Module, *Module_t; - - -/* -** The compiler generates one of these structures for a class that has -** instance variables defined in its specification. -*/ -typedef struct objc_ivar { - const char* ivar_name; /* Name of the instance - variable as entered in the - class definition. */ - const char* ivar_type; /* Description of the Ivar's - type. Useful for - debuggers. */ - int ivar_offset; /* Byte offset from the base - address of the instance - structure to the variable. */ -} *Ivar_t; - -typedef struct objc_ivar_list { - int ivar_count; /* Number of structures (Ivar) - contained in the list. One - structure per instance - variable defined in the - class. */ - struct objc_ivar ivar_list[1]; /* Variable length - structure. */ -} IvarList, *IvarList_t; +#include "deprecated/struct_objc_static_instances.h" +#include "deprecated/struct_objc_symtab.h" +#include "deprecated/struct_objc_module.h" +#include "deprecated/struct_objc_ivar.h" +#include "deprecated/struct_objc_ivar_list.h" +#include "deprecated/struct_objc_method.h" +typedef struct objc_method Method, *Method_t; - -/* -** The compiler generates one (or more) of these structures for a class that -** has methods defined in its specification. -** -** The implementation of a class can be broken into separate pieces in a file -** and categories can break them across modules. To handle this problem is a -** singly linked list of methods. -*/ -typedef struct objc_method { - SEL method_name; /* This variable is the method's - name. It is a char*. - The unique integer passed to - objc_msg_send is a char* too. - It is compared against - method_name using strcmp. */ - const char* method_types; /* Description of the method's - parameter list. Useful for - debuggers. */ - IMP method_imp; /* Address of the method in the - executable. */ -} Method, *Method_t; - -typedef struct objc_method_list { - struct objc_method_list* method_next; /* This variable is used to link - a method list to another. It - is a singly linked list. */ - int method_count; /* Number of methods defined in - this structure. */ - Method method_list[1]; /* Variable length - structure. */ -} MethodList, *MethodList_t; - -struct objc_protocol_list { - struct objc_protocol_list *next; - size_t count; - Protocol *list[1]; -}; +#include "deprecated/struct_objc_method_list.h" +#include "deprecated/struct_objc_protocol_list.h" /* ** This is used to assure consistent access to the info field of @@ -267,48 +166,16 @@ struct objc_protocol_list { (cls)->info >>= (HOST_BITS_PER_LONG/2); \ __CLS_SETINFO(cls, (((unsigned long)num) << (HOST_BITS_PER_LONG/2))); }) -/* -** The compiler generates one of these structures for each category. A class -** may have many categories and contain both instance and factory methods. -*/ -typedef struct objc_category { - const char* category_name; /* Name of the category. Name - contained in the () of the - category definition. */ - const char* class_name; /* Name of the class to which - the category belongs. */ - MethodList_t instance_methods; /* Linked list of instance - methods defined in the - category. NULL indicates no - instance methods defined. */ - MethodList_t class_methods; /* Linked list of factory - methods defined in the - category. NULL indicates no - class methods defined. */ - struct objc_protocol_list *protocols; /* List of Protocols - conformed to */ -} Category, *Category_t; - -/* -** Structure used when a message is send to a class's super class. The -** compiler generates one of these structures and passes it to -** objc_msg_super. -*/ -typedef struct objc_super { - id self; /* Id of the object sending - the message. */ -#ifdef __cplusplus - Class super_class; -#else - Class class; /* Object's super class. */ -#endif -} Super, *Super_t; - -objc_EXPORT IMP objc_msg_lookup_super(Super_t super, SEL sel); - -objc_EXPORT retval_t objc_msg_sendv(id, SEL, arglist_t); +#include "deprecated/struct_objc_category.h" +typedef struct objc_category Category, *Category_t; +/* We include message.h for compatibility with the old objc-api.h + which included the declarations currently in message.h. The + Apple/NeXT runtime does not do this and only includes message.h in + objc-runtime.h. It does not matter that much since most of the + definitions in message.h are runtime-specific. */ +#include "message.h" /* ** This is a hook which is called by objc_lookup_class and @@ -326,12 +193,7 @@ objc_EXPORT Class (*_objc_lookup_class)(const char *name); */ objc_EXPORT void (*_objc_load_callback)(Class _class, Category* category); -/* -** Hook functions for allocating, copying and disposing of instances -*/ -objc_EXPORT id (*_objc_object_alloc)(Class _class); -objc_EXPORT id (*_objc_object_copy)(id object); -objc_EXPORT id (*_objc_object_dispose)(id object); +#include "deprecated/objc_object_alloc.h" /* Standard functions for memory allocation and disposal. Users should @@ -359,16 +221,6 @@ objc_free(void *mem); #include "deprecated/objc_valloc.h" #include "deprecated/objc_malloc.h" -/* -** Hooks for method forwarding. This makes it easy to substitute a -** library, such as ffcall, that implements closures, thereby avoiding -** gcc's __builtin_apply problems. __objc_msg_forward2's result will -** be preferred over that of __objc_msg_forward if both are set and -** return non-NULL. -*/ -objc_EXPORT IMP (*__objc_msg_forward)(SEL); -objc_EXPORT IMP (*__objc_msg_forward2)(id, SEL); - #include "deprecated/objc_unexpected_exception.h" objc_EXPORT Method_t class_get_class_method(MetaClass _class, SEL aSel); @@ -465,15 +317,16 @@ extern void class_ivar_set_gcinvisible (Class _class, const char* ivarname, BOOL gcInvisible); -static inline IMP -method_get_imp(Method_t method) -{ - return (method!=METHOD_NULL)?method->method_imp:(IMP)0; -} +objc_EXPORT IMP method_get_imp(Method_t method); objc_EXPORT IMP get_imp (Class _class, SEL sel); -objc_EXPORT id object_copy(id object); +/* object_copy used to take a single argument in the traditional GNU + Objective-C Runtime API (the one declared here), but takes 2 in the + modern API (implemented in the actual runtime). Define the old + object_copy in terms of the new one. */ +objc_EXPORT id object_copy (id object, size_t size); +#define object_copy(X) (object_copy ((X), 0)) objc_EXPORT id object_dispose(id object); @@ -541,8 +394,7 @@ object_is_meta_class (id object) && !object_is_class (object)); } -objc_EXPORT struct sarray* -objc_get_uninstalled_dtable(void); +#include "deprecated/objc_get_uninstalled_dtable.h" #ifdef __cplusplus } diff --git a/libobjc/objc/objc-exception.h b/libobjc/objc/objc-exception.h index 2fb9ba6c7dd..d584014a28d 100644 --- a/libobjc/objc/objc-exception.h +++ b/libobjc/objc/objc-exception.h @@ -89,7 +89,7 @@ typedef int (*objc_exception_matcher)(Class catch_class, id exception); multi-threaded environment because other threads may be trying to invoke the exception matcher while you change it! */ objc_exception_matcher -objc_set_exception_matcher (objc_exception_matcher new_matcher); +objc_setExceptionMatcher (objc_exception_matcher new_matcher); /* An 'objc_uncaught_exception_handler' function is a function that @@ -103,12 +103,7 @@ typedef void (*objc_uncaught_exception_handler)(id exception); it. */ objc_uncaught_exception_handler -objc_set_uncaught_exception_handler (objc_uncaught_exception_handler new_handler); - - -/* For compatibility with the Apple/NeXT runtime. */ -#define objc_setExceptionMatcher objc_set_exception_matcher -#define objc_setUncaughtExceptionHandler objc_set_uncaught_exception_handler +objc_setUncaughtExceptionHandler (objc_uncaught_exception_handler new_handler); #ifdef __cplusplus } diff --git a/libobjc/objc/objc.h b/libobjc/objc/objc.h index 6c3214f5e08..7d382169dfb 100644 --- a/libobjc/objc/objc.h +++ b/libobjc/objc/objc.h @@ -88,22 +88,20 @@ typedef struct objc_class *Class; #include "deprecated/MetaClass.h" #include "deprecated/struct_objc_class.h" -/* An 'id' is an object of an unknown class. The struct objc_object - is private and what you see here is only the beginning of the - struct. In theory, the fact that 'class_pointer' is public means - that if you have any object 'object', you can immediately get its - class by using '((id)object)->class_pointer', but this is not - recommended; you should use object_get_class(object) instead. +/* An 'id' is an object of an unknown class. The way the object data + is stored inside the object is private and what you see here is + only the beginning of the actual struct. The first field is always + a pointer to the Class that the object belongs to. */ typedef struct objc_object { /* 'class_pointer' is the Class that the object belongs to. In case - of a Class object, this pointer points to the meta class. */ - /* Note that the Apple/NeXT runtime calls this variable 'isa'. - TODO: Decide if we want to call it 'isa' too. TODO: Why not - simply hide this pointer and force users to use the proper API to - get it ? - */ + of a Class object, this pointer points to the meta class. + + Compatibility Note: The Apple/NeXT runtime calls this field + 'isa'. To access this field in a portable way, use + object_getClass() from runtime.h, which is an inline function so + does not add any overhead. */ Class class_pointer; } *id; diff --git a/libobjc/objc/runtime.h b/libobjc/objc/runtime.h index 7b16f1b09ea..b15c522235d 100644 --- a/libobjc/objc/runtime.h +++ b/libobjc/objc/runtime.h @@ -1,4 +1,4 @@ -/* GNU Objective-C Runtime API. +/* GNU Objective-C Runtime API - Modern API Copyright (C) 2010 Free Software Foundation, Inc. Contributed by Nicola Pero <nicola.pero@meta-innovation.com> @@ -26,11 +26,340 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #ifndef __objc_runtime_INCLUDE_GNU #define __objc_runtime_INCLUDE_GNU +/* + This file declares the "modern" GNU Objective-C Runtime API. + Include this file to use it. + + This API is replacing the "traditional" GNU Objective-C Runtime API + (declared in objc/objc-api.h) which is the one supported by older + versions of the GNU Objective-C Runtime. The "modern" API is very + similar to the API used by the modern Apple/NeXT runtime. + + Because the two APIs have some conflicting definitions (in + particular, Method and Category are defined differently) you should + include either objc/objc-api.h (to use the traditional GNU + Objective-C Runtime API) or objc/runtime.h (to use the modern GNU + Objective-C Runtime API), but not both. +*/ +#ifdef __objc_api_INCLUDE_GNU +# error You can not include both objc/objc-api.h and objc/runtime.h. Include objc/objc-api.h for the traditional GNU Objective-C Runtime API and objc/runtime.h for the modern one. +#endif + +/* TODO: This file is incomplete. */ + #include "objc.h" -/* The following is temporary, until all code from objc-api.h has been - moved into this file and objc-api.h will include runtime.h. */ -#include "objc-api.h" +/* An 'Ivar' represents an instance variable. It holds information + about the name, type and offset of the instance variable. */ +typedef struct objc_ivar *Ivar; + +/* A 'Property' represents a property. It holds information about the + name of the property, and its attributes. + + Compatibility Note: the Apple/NeXT runtime defines this as + objc_property_t, so we define it that way as well, but obviously + Property is the right name. */ +typedef struct objc_property *Property; +typedef struct objc_property *objc_property_t; + +/* A 'Method' represents a method. It holds information about the + name, types and the IMP of the method. */ +typedef struct objc_method *Method; + +/* A 'Category' represents a category. It holds information about the + name of the category, the class it belongs to, and the methods, + protocols and such like provided by the category. */ +typedef struct objc_category *Category; + +/* 'Protocol' is defined in objc/objc.h (which is included by this + file). */ + +/* Method descriptor returned by introspective Object methods. At the + moment, this is really just the first part of the more complete + objc_method structure used internally by the runtime. (PS: In the + GNU Objective-C Runtime, selectors already include a type, so an + objc_method_description does not add much to a SEL. But in other + runtimes, that is not the case, which is why + objc_method_description exists). */ +struct objc_method_description +{ + SEL name; /* Selector (name and signature) */ + char *types; /* Type encoding */ +}; + +/* The following are used in encode strings to describe the type of + Ivars and Methods. */ +#define _C_ID '@' +#define _C_CLASS '#' +#define _C_SEL ':' +#define _C_CHR 'c' +#define _C_UCHR 'C' +#define _C_SHT 's' +#define _C_USHT 'S' +#define _C_INT 'i' +#define _C_UINT 'I' +#define _C_LNG 'l' +#define _C_ULNG 'L' +#define _C_LNG_LNG 'q' +#define _C_ULNG_LNG 'Q' +#define _C_FLT 'f' +#define _C_DBL 'd' +#define _C_LNG_DBL 'D' +#define _C_BFLD 'b' +#define _C_BOOL 'B' +#define _C_VOID 'v' +#define _C_UNDEF '?' +#define _C_PTR '^' +#define _C_CHARPTR '*' +#define _C_ARY_B '[' +#define _C_ARY_E ']' +#define _C_UNION_B '(' +#define _C_UNION_E ')' +#define _C_STRUCT_B '{' +#define _C_STRUCT_E '}' +#define _C_VECTOR '!' +#define _C_COMPLEX 'j' + +/* _C_ATOM is never generated by the compiler. You can treat it as + equivalent to "*". */ +#define _C_ATOM '%' + +/* The following are used in encode strings to describe some + qualifiers of method and ivar types. */ +#define _C_CONST 'r' +#define _C_IN 'n' +#define _C_INOUT 'N' +#define _C_OUT 'o' +#define _C_BYCOPY 'O' +#define _C_BYREF 'R' +#define _C_ONEWAY 'V' +#define _C_GCINVISIBLE '|' + +/* The same when used as flags. */ +#define _F_CONST 0x01 +#define _F_IN 0x01 +#define _F_OUT 0x02 +#define _F_INOUT 0x03 +#define _F_BYCOPY 0x04 +#define _F_BYREF 0x08 +#define _F_ONEWAY 0x10 +#define _F_GCINVISIBLE 0x20 + + +/** Implementation: the following functions are defined inline. */ + +/* Return the class of 'object', or Nil if the object is nil. If + 'object' is a class, the meta class is returned; if 'object' is a + meta class, the root meta class is returned (note that this is + different from the traditional GNU Objective-C Runtime API function + object_get_class(), which for a meta class would return the meta + class itself). This function is inline, so it is really fast and + should be used instead of accessing object->class_pointer + directly. */ +static inline Class +object_getClass (id object) +{ + if (object != nil) + return object->class_pointer; + else + return Nil; +} + + +/** Implementation: the following functions are in selector.c. */ + +/* Return the name of a given selector. */ +objc_EXPORT const char *sel_getName (SEL selector); + +/* Return the type of a given selector. + + Compatibility Note: the Apple/NeXT runtime has untyped selectors, + so it does not have this function, which is specific to the GNU + Runtime. */ +objc_EXPORT const char *sel_getType (SEL selector); + +/* This is the same as sel_registerName (). Please use + sel_registerName () instead. */ +objc_EXPORT SEL sel_getUid (const char *name); + +/* Register a selector with a given name (but unspecified types). If + you know the types, it is better to call sel_registerTypedName(). + If a selector with this name already exists, it is returned. */ +objc_EXPORT SEL sel_registerName (const char *name); + +/* Register a selector with a given name and types. If a selector + with this name and types already exists, it is returned. + + Compatibility Note: the Apple/NeXT runtime has untyped selectors, + so it does not have this function, which is specific to the GNU + Runtime. */ +objc_EXPORT SEL set_registerTypedName (const char *name, const char *type); + +/* Return YES if first_selector is the same as second_selector, and NO + if not. */ +objc_EXPORT BOOL sel_isEqual (SEL first_selector, SEL second_selector); + + +/** Implementation: the following functions are in objects.c. */ + +/* Create an instance of class 'class_', adding extraBytes to the size + of the returned object. This method allocates the appropriate + amount of memory for the instance, initializes it to zero, then + calls all the C++ constructors on appropriate C++ instance + variables of the instance (if any) (TODO: The C++ constructors bit + is not implemented yet). */ +objc_EXPORT id class_createInstance (Class class_, size_t extraBytes); + +/* Copy an object and return the copy. extraBytes should be identical + to the extraBytes parameter that was passed when creating the + original object. */ +objc_EXPORT id object_copy (id object, size_t extraBytes); + +/* Dispose of an object. This method calls the appropriate C++ + destructors on appropriate C++ instance variables of the instance + (if any) (TODO: This is not implemented yet), then frees the memory + for the instance. */ +objc_EXPORT id object_dispose (id object); + +/* Return the name of the class of 'object'. If 'object' is 'nil', + returns "Nil". */ +objc_EXPORT const char * object_getClassName (id object); + +/* Change the class of object to be class_. Return the previous class + of object. This is currently not really thread-safe. */ +objc_EXPORT Class object_setClass (id object, Class class_); + + +/** Implementation: the following functions are in ivars.c. */ + +/* Return an instance variable given the class and the instance + variable name. This is an expensive function to call, so try to + reuse the returned Ivar if you can. */ +objc_EXPORT Ivar class_getInstanceVariable (Class class_, const char *name); + +/* If the object was created in class_createInstance() with some + extraBytes, returns a pointer to them. If it was not, then the + returned pointer may make no sense. */ +objc_EXPORT void * object_getIndexedIvars (id object); + +/* Get the value of an instance variable of type 'id'. The function + returns the instance variable. To get the value of the instance + variable, you should pass as 'returnValue' a pointer to an 'id'; + the value will be copied there. Note that 'returnValue' is really + a 'void *', not a 'void **'. This function really works only with + instance variables of type 'id'; for other types of instance + variables, access directly the data at (char *)object + + ivar_getOffset (ivar). */ +objc_EXPORT Ivar object_getInstanceVariable (id object, const char *name, void **returnValue); + +/* Set the value of an instance variable. The value to set is passed + in 'newValue' (which really is an 'id', not a 'void *'). The + function returns the instance variable. This function really works + only with instance variables of type 'id'; for other types of + instance variables, access directly the data at (char *)object + + ivar_getOffset (ivar). */ +objc_EXPORT Ivar object_setInstanceVariable (id object, const char *name, void *newValue); + +/* Get the value of an instance variable of type 'id' of the object + 'object'. This is faster than object_getInstanceVariable if you + already have the instance variable because it avoids the expensive + call to class_getInstanceVariable that is done by + object_getInstanceVariable. */ +objc_EXPORT id object_getIvar (id object, Ivar variable); + +/* Set the value of an instance variable of type 'id' of the object + 'object'. This is faster than object_setInstanceVariable if you + already have the instance variable because it avoids the expensive + call to class_getInstanceVariable that is done by + object_setInstanceVariable. */ +objc_EXPORT void object_setIvar (id object, Ivar variable, id value); + +/* Return the name of the instance variable. */ +objc_EXPORT const char * ivar_getName (Ivar variable); + +/* Return the offset of the instance variable from the start of the + object data. */ +objc_EXPORT ptrdiff_t ivar_getOffset (Ivar variable); + +/* Return the type encoding of the variable. */ +objc_EXPORT const char * ivar_getTypeEncoding (Ivar variable); + + +/** Implementation: the following functions are in class.c. */ + +/* Compatibility Note: The Apple/NeXT runtime does not have + objc_get_unknown_class_handler and + objc_setGetUnknownClassHandler(). They provide functionality that + the traditional GNU Objective-C Runtime API used to provide via the + _objc_lookup_class hook. */ + +/* An 'objc_get_unknown_class_handler' function is used by + objc_getClass() to get a class that is currently unknown to the + compiler. You could use it for example to have the class loaded by + dynamically loading a library. 'class_name' is the name of the + class. The function should return the Class object if it manages to + load the class, and Nil if not. */ +typedef Class (*objc_get_unknown_class_handler)(const char *class_name); + +/* Sets a new handler function for getting unknown classes (to be used + by objc_getClass () and related), and returns the previous one. + This function is not safe to call in a multi-threaded environment + because other threads may be trying to use the get unknown class + handler while you change it! */ +objc_get_unknown_class_handler +objc_setGetUnknownClassHandler (objc_get_unknown_class_handler new_handler); + + +/* Return the class with name 'name', if it is already registered with + the runtime. If it is not registered, and + objc_setGetUnknownClassHandler() has been called to set a handler + for unknown classes, the handler is called to give it a chance to + load the class in some other way. If the class is not known to the + runtime and the handler is not set or returns Nil, objc_getClass() + returns Nil. */ +objc_EXPORT Class objc_getClass (const char *name); + +/* Return the class with name 'name', if it is already registered with + the runtime. Return Nil if not. This function does not call the + objc_get_unknown_class_handler function if the class is not + found. */ +objc_EXPORT Class objc_lookupClass (const char *name); + +/* Return the meta class associated to the class with name 'name', if + it is already registered with the runtime. First, it finds the + class using objc_getClass(). Then, it returns the associated meta + class. If the class could not be found using objc_getClass(), + returns Nil. */ +objc_EXPORT Class objc_getMetaClass (const char *name); + +/* This is identical to objc_getClass(), but if the class is not found, + it aborts the process instead of returning Nil. */ +objc_EXPORT Class objc_getRequiredClass (const char *name); + +/* If 'returnValue' is NULL, 'objc_getClassList' returns the number of + classes currently registered with the runtime. If 'returnValue' is + not NULL, it should be a (Class *) pointer to an area of memory + which can contain up to 'maxNumberOfClassesToReturn' Class records. + 'objc_getClassList' will fill the area pointed to by 'returnValue' + with all the Classes registered with the runtime (or up to + maxNumberOfClassesToReturn if there are more than + maxNumberOfClassesToReturn). The function return value is the + number of classes actually returned in 'returnValue'. */ +objc_EXPORT int objc_getClassList (Class *returnValue, int maxNumberOfClassesToReturn); + +/* Compatibility Note: The Apple/NeXT runtime also has + + Class objc_getFutureClass (const char *name); + void objc_setFutureClass (Class class_, const char *name); + + the documentation is unclear on what they are supposed to do, and + the GNU Objective-C Runtime currently does not provide them. */ + + +/* TODO: Add all the other functions in the API. */ + + +/** Implementation: the following functions are in objc-foreach.c. */ /* 'objc_enumerationMutation()' is called when a collection is mutated while being "fast enumerated". That is a hard error, and @@ -41,8 +370,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see is set. Then, it will abort the program. Compatibility note: the Apple runtime will not abort the program - after calling the mutation handler. - */ + after calling the mutation handler. */ objc_EXPORT void objc_enumerationMutation (id collection); /* 'objc_set_enumeration_mutation_handler' can be used to set a @@ -61,9 +389,8 @@ objc_EXPORT void objc_enumerationMutation (id collection); libraries; in the case of GNUstep, GNUstep Base may be using this function to improve the standard enumeration mutation handling. You probably shouldn't use this function unless you are writing - your own Foundation library. -*/ -objc_EXPORT void objc_set_enumeration_mutation_handler (void (*handler)(id)); + your own Foundation library. */ +objc_EXPORT void objc_setEnumerationMutationHandler (void (*handler)(id)); /* This structure (used during fast enumeration) is automatically defined by the compiler (it is as if this definition was always @@ -71,8 +398,7 @@ objc_EXPORT void objc_set_enumeration_mutation_handler (void (*handler)(id)); defined again with the name of NSFastEnumeration by "Foundation" libraries such as GNUstep Base. And if NSFastEnumeration is defined, the compiler will use it instead of - __objcFastEnumerationState when doing fast enumeration. -*/ + __objcFastEnumerationState when doing fast enumeration. */ /* struct __objcFastEnumerationState { @@ -82,7 +408,108 @@ struct __objcFastEnumerationState unsigned long extra[5]; }; */ -/* For compatibility with the Apple/NeXT runtime. */ -#define objc_setEnumerationMutationHandler objc_set_enumeration_mutation_handler + + +/** Implementation: the following functions are in encoding.c. */ + +/* Traditional GNU Objective-C Runtime functions that are currently + used to implement method forwarding. +*/ + +/* Return the size of a variable which has the specified 'type' + encoding. */ +int objc_sizeof_type (const char *type); + +/* Return the align of a variable which has the specified 'type' + encoding. */ +int objc_alignof_type (const char *type); + +/* Return the aligned size of a variable which has the specified + 'type' encoding. The aligned size is the size rounded up to the + nearest alignment. */ +int objc_aligned_size (const char *type); + +/* Return the promoted size of a variable which has the specified + 'type' encoding. This is the size rounded up to the nearest + integral of the wordsize, taken to be the size of a void *. */ +int objc_promoted_size (const char *type); + + +/* The following functions are used when parsing the type encoding of + methods, to skip over parts that are ignored. They take as + argument a pointer to a location inside the type encoding of a + method (which is a string) and return a new pointer, pointing to a + new location inside the string after having skipped the unwanted + information. */ + +/* Skip some type qualifiers (_C_CONST, _C_IN, etc). These may + eventually precede typespecs occurring in method prototype + encodings. */ +const char *objc_skip_type_qualifiers (const char *type); + +/* Skip one typespec element (_C_CLASS, _C_SEL, etc). If the typespec + is prepended by type qualifiers, these are skipped as well. */ +const char *objc_skip_typespec (const char *type); + +/* Skip an offset. */ +const char *objc_skip_offset (const char *type); + +/* Skip an argument specification (ie, skipping a typespec, which may + include qualifiers, and an offset too). */ +const char *objc_skip_argspec (const char *type); + +/* Read type qualifiers (_C_CONST, _C_IN, etc) from string 'type' + (stopping at the first non-type qualifier found) and return an + unsigned int which is the logical OR of all the corresponding flags + (_F_CONST, _F_IN etc). */ +unsigned objc_get_type_qualifiers (const char *type); + + +/* Note that the following functions work for very simple structures, + but get easily confused by more complicated ones (for example, + containing vectors). A better solution is required. +*/ + +/* The following three functions can be used to determine how a + structure is laid out by the compiler. For example: + + struct objc_struct_layout layout; + int i; + + objc_layout_structure (type, &layout); + while (objc_layout_structure_next_member (&layout)) + { + int position, align; + const char *type; + + objc_layout_structure_get_info (&layout, &position, &align, &type); + printf ("element %d has offset %d, alignment %d\n", + i++, position, align); + } + + These functions are used by objc_sizeof_type and objc_alignof_type + functions to compute the size and alignment of structures. The + previous method of computing the size and alignment of a structure + was not working on some architectures, particulary on AIX, and in + the presence of bitfields inside the structure. */ +struct objc_struct_layout +{ + const char *original_type; + const char *type; + const char *prev_type; + unsigned int record_size; + unsigned int record_align; +}; + +void objc_layout_structure (const char *type, + struct objc_struct_layout *layout); +BOOL objc_layout_structure_next_member (struct objc_struct_layout *layout); +void objc_layout_finish_structure (struct objc_struct_layout *layout, + unsigned int *size, + unsigned int *align); +void objc_layout_structure_get_info (struct objc_struct_layout *layout, + unsigned int *offset, + unsigned int *align, + const char **type); #endif diff --git a/libobjc/objects.c b/libobjc/objects.c index 9c237f49ea5..2562be55f24 100644 --- a/libobjc/objects.c +++ b/libobjc/objects.c @@ -23,51 +23,67 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ #include "objc-private/common.h" -#include <string.h> /* For memset */ -#include "tconfig.h" /* include defs of bzero for target */ #include "objc/objc.h" #include "objc/objc-api.h" #include "objc-private/runtime.h" /* the kitchen sink */ +#include <string.h> /* For memcpy() */ + #if OBJC_WITH_GC # include <gc.h> +# include <gc_typed.h> #endif -id __objc_object_alloc (Class); -id __objc_object_dispose (id); -id __objc_object_copy (id); - -id (*_objc_object_alloc) (Class) = __objc_object_alloc; /* !T:SINGLE */ -id (*_objc_object_dispose) (id) = __objc_object_dispose; /* !T:SINGLE */ -id (*_objc_object_copy) (id) = __objc_object_copy; /* !T:SINGLE */ - +/* FIXME: The semantics of extraBytes are not really clear. */ +inline id -class_create_instance (Class class) +class_createInstance (Class class, size_t extraBytes) { id new = nil; #if OBJC_WITH_GC if (CLS_ISCLASS (class)) - new = (id) GC_malloc_explicitly_typed (class->instance_size, - class->gc_object_type); + new = (id) GC_malloc_explicitly_typed (class->instance_size + extraBytes, + (GC_descr)class->gc_object_type); #else if (CLS_ISCLASS (class)) - new = (*_objc_object_alloc) (class); + new = (id) objc_calloc (class->instance_size + extraBytes, 1); #endif if (new != nil) { - memset (new, 0, class->instance_size); + /* There is no need to zero the memory, since both + GC_malloc_explicitly_typed and objc_calloc return zeroed + memory. */ new->class_pointer = class; } + + /* TODO: Invoke C++ constructors on all appropriate C++ instance + variables of the new object. */ + return new; } +/* Traditional GNU Objective-C Runtime API. */ +id +class_create_instance (Class class) +{ + return class_createInstance (class, 0); +} + +/* Temporary, while we are including objc-api.h instead of runtime.h. */ +#undef object_copy + id -object_copy (id object) +object_copy (id object, size_t extraBytes) { if ((object != nil) && CLS_ISCLASS (object->class_pointer)) - return (*_objc_object_copy) (object); + { + /* TODO: How should it work with C++ constructors ? */ + id copy = class_createInstance (object->class_pointer, extraBytes); + memcpy (copy, object, object->class_pointer->instance_size + extraBytes); + return copy; + } else return nil; } @@ -77,28 +93,43 @@ object_dispose (id object) { if ((object != nil) && CLS_ISCLASS (object->class_pointer)) { - if (_objc_object_dispose) - (*_objc_object_dispose) (object); - else - objc_free (object); + /* TODO: Invoke C++ destructors on all appropriate C++ instance + variables. But what happens with the garbage collector ? + Would object_dispose() be ever called in that case ? */ + + objc_free (object); } return nil; } -id __objc_object_alloc (Class class) +const char * +object_getClassName (id object) { - return (id) objc_malloc (class->instance_size); + if (object != nil) + return object->class_pointer->name; + else + return "Nil"; } -id __objc_object_dispose (id object) +Class +object_setClass (id object, Class class_) { - objc_free (object); - return 0; -} + if (object == nil) + return Nil; + else + { + Class old_class = object->class_pointer; -id __objc_object_copy (id object) -{ - id copy = class_create_instance (object->class_pointer); - memcpy (copy, object, object->class_pointer->instance_size); - return copy; + object->class_pointer = class_; + return old_class; + } } + +/* + Hook functions for memory allocation and disposal. Deprecated + and currently unused. +*/ + +id (*_objc_object_alloc) (Class) = 0; +id (*_objc_object_dispose) (id) = 0; +id (*_objc_object_copy) (id) = 0; diff --git a/libobjc/selector.c b/libobjc/selector.c index 10b7ab63dad..93952fd3834 100644 --- a/libobjc/selector.c +++ b/libobjc/selector.c @@ -287,16 +287,9 @@ sel_get_any_uid (const char *name) return (SEL) l->head; } -/* return selector representing name */ -SEL -sel_get_uid (const char *name) -{ - return sel_register_typed_name (name, 0); -} - /* Get name of selector. If selector is unknown, the empty string "" is returned */ -const char *sel_get_name (SEL selector) +const char *sel_getName (SEL selector) { const char *ret; @@ -310,6 +303,12 @@ const char *sel_get_name (SEL selector) return ret; } +/* Traditional GNU Objective-C Runtime API. */ +const char *sel_get_name (SEL selector) +{ + return sel_getName (selector); +} + BOOL sel_is_mapped (SEL selector) { @@ -317,8 +316,7 @@ sel_is_mapped (SEL selector) return ((idx > 0) && (idx <= __objc_selector_max_index)); } - -const char *sel_get_type (SEL selector) +const char *sel_getType (SEL selector) { if (selector) return selector->sel_types; @@ -326,6 +324,12 @@ const char *sel_get_type (SEL selector) return 0; } +/* Traditional GNU Objective-C Runtime API. */ +const char *sel_get_type (SEL selector) +{ + return sel_getType (selector); +} + /* The uninstalled dispatch table */ extern struct sarray *__objc_uninstalled_dtable; @@ -467,7 +471,7 @@ __sel_register_typed_name (const char *name, const char *types, } SEL -sel_register_name (const char *name) +sel_registerName (const char *name) { SEL ret; @@ -480,8 +484,15 @@ sel_register_name (const char *name) return ret; } +/* Traditional GNU Objective-C Runtime API. */ SEL -sel_register_typed_name (const char *name, const char *type) +sel_register_name (const char *name) +{ + return sel_registerName (name); +} + +SEL +sel_registerTypedName (const char *name, const char *type) { SEL ret; @@ -493,3 +504,23 @@ sel_register_typed_name (const char *name, const char *type) return ret; } + +SEL +sel_register_typed_name (const char *name, const char *type) +{ + return sel_registerTypedName (name, type); +} + +/* return selector representing name */ +SEL +sel_getUid (const char *name) +{ + return sel_registerTypedName (name, 0); +} + +/* Traditional GNU Objective-C Runtime API. */ +SEL +sel_get_uid (const char *name) +{ + return sel_getUid (name); +} diff --git a/libobjc/sendmsg.c b/libobjc/sendmsg.c index 621d5314d37..a822af4a31a 100644 --- a/libobjc/sendmsg.c +++ b/libobjc/sendmsg.c @@ -194,6 +194,13 @@ get_imp (Class class, SEL sel) return res; } +/* Given a method, return its implementation. */ +IMP +method_get_imp (Method_t method) +{ + return (method != (Method_t)0) ? method->method_imp : (IMP)0; +} + /* Query if an object can respond to a selector, returns YES if the object implements the selector otherwise NO. Does not check if the method can be forwarded. */ |