aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicola Pero <nicola.pero@meta-innovation.com>2010-10-12 18:43:54 +0000
committerNicola Pero <nicola@gcc.gnu.org>2010-10-12 18:43:54 +0000
commitbe05b0f5991ef9d9cd7b99f2f8e042a24e5336b0 (patch)
treeb4d41623d7f15f6d47b2a7f3c02ac077462df0f9
parentce9555cb8273fc011d81d7bb2bb54da020b95b16 (diff)
In libobjc/: 2010-10-12 Nicola Pero <nicola.pero@meta-innovation.com>
In libobjc/: 2010-10-12 Nicola Pero <nicola.pero@meta-innovation.com> * class.c: Include objc/runtime.h and objc-private/module-abi-8.h instead of objc/objc-api.h. (objc_get_unknown_class_handler): Do not define. (class_isMetaClass): New. (class_getSuperclass): New. (class_getVersion): New. (class_setVersion): New. (class_getInstanceSize): New. * exceptions.c: Include objc/runtime.h instead of objc/objc-api.h. (is_kind_of_exception_matcher): Use objc_getSuperclass instead of objc_get_super_class. (get_ttype_entry): Use objc_getRequiredClass instead of objc_get_class. * ivars.c (class_getClassVariable): New. * objects.c: Include objc/runtime.h, objc/thr.h and objc-private/module-abi-8.h instead of objc/objc-api.h * objc/runtime.h (class_getClassVariable): New. (class_isMetaClass): New. (class_getSuperclass): New. (class_getVersion): New. (class_setVersion): New. (class_getInstanceSize): New. * objc-private/module-abi-8.h (HOST_BITS_PER_LONG): New (from objc/objc-api.h) (__CLS_INFO): Same. (__CLS_ISINFO): Same. (__CLS_SETINFO): Same. (CLS_ISMETA): Same. (CLS_ISCLASS): Same. (CLS_ISRESOLV): Same. (CLS_SETRESOLV): Same. (CLS_ISINITIALIZED): Same. (CLS_SETINITIALIZED): Same. (CLS_GETNUMBER): Same. (CLS_SETNUMBER): Same. From-SVN: r165392
-rw-r--r--libobjc/ChangeLog38
-rw-r--r--libobjc/class.c56
-rw-r--r--libobjc/exception.c15
-rw-r--r--libobjc/ivars.c19
-rw-r--r--libobjc/objc-private/module-abi-8.h41
-rw-r--r--libobjc/objc/runtime.h50
-rw-r--r--libobjc/objects.c8
7 files changed, 209 insertions, 18 deletions
diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog
index 78467d86d47..ec0a98f3790 100644
--- a/libobjc/ChangeLog
+++ b/libobjc/ChangeLog
@@ -1,5 +1,43 @@
2010-10-12 Nicola Pero <nicola.pero@meta-innovation.com>
+ * class.c: Include objc/runtime.h and objc-private/module-abi-8.h
+ instead of objc/objc-api.h.
+ (objc_get_unknown_class_handler): Do not define.
+ (class_isMetaClass): New.
+ (class_getSuperclass): New.
+ (class_getVersion): New.
+ (class_setVersion): New.
+ (class_getInstanceSize): New.
+ * exceptions.c: Include objc/runtime.h instead of objc/objc-api.h.
+ (is_kind_of_exception_matcher): Use objc_getSuperclass instead of
+ objc_get_super_class.
+ (get_ttype_entry): Use objc_getRequiredClass instead of
+ objc_get_class.
+ * ivars.c (class_getClassVariable): New.
+ * objects.c: Include objc/runtime.h, objc/thr.h and
+ objc-private/module-abi-8.h instead of objc/objc-api.h
+ * objc/runtime.h (class_getClassVariable): New.
+ (class_isMetaClass): New.
+ (class_getSuperclass): New.
+ (class_getVersion): New.
+ (class_setVersion): New.
+ (class_getInstanceSize): New.
+ * objc-private/module-abi-8.h (HOST_BITS_PER_LONG): New (from
+ objc/objc-api.h)
+ (__CLS_INFO): Same.
+ (__CLS_ISINFO): Same.
+ (__CLS_SETINFO): Same.
+ (CLS_ISMETA): Same.
+ (CLS_ISCLASS): Same.
+ (CLS_ISRESOLV): Same.
+ (CLS_SETRESOLV): Same.
+ (CLS_ISINITIALIZED): Same.
+ (CLS_SETINITIALIZED): Same.
+ (CLS_GETNUMBER): Same.
+ (CLS_SETNUMBER): Same.
+
+2010-10-12 Nicola Pero <nicola.pero@meta-innovation.com>
+
* archive.c: Do not include objc/objc.h.
* class.c: Do not include objc/objc.h.
* encoding.c: Include objc/runtime.h, ctype.h and
diff --git a/libobjc/class.c b/libobjc/class.c
index 75c933ba32f..4eb86761ee8 100644
--- a/libobjc/class.c
+++ b/libobjc/class.c
@@ -89,10 +89,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "objc-private/common.h"
#include "objc-private/error.h"
-#include "objc/objc-api.h"
+#include "objc/runtime.h"
#include "objc/thr.h"
-#include "objc-private/runtime.h" /* the kitchen sink */
-#include <string.h> /* For memset */
+#include "objc-private/module-abi-8.h" /* For CLS_ISCLASS and similar. */
+#include "objc-private/runtime.h" /* the kitchen sink */
+#include <string.h> /* For memset */
/* We use a table which maps a class name to the corresponding class
* pointer. The first part of this file defines this table, and
@@ -417,11 +418,6 @@ class_table_print_histogram (void)
*/
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. */
@@ -591,6 +587,7 @@ objc_lookup_class (const char *name)
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(). */
+/* Note that this is roughly equivalent to objc_getRequiredClass(). */
/* 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. */
@@ -739,6 +736,49 @@ class_getName (Class class_)
return class_->name;
}
+BOOL
+class_isMetaClass (Class class_)
+{
+ /* CLS_ISMETA includes the check for Nil class_. */
+ return CLS_ISMETA (class_);
+}
+
+Class
+class_getSuperclass (Class class_)
+{
+ if (class_ == Nil)
+ return Nil;
+
+ return class_->super_class;
+}
+
+int
+class_getVersion (Class class_)
+{
+ if (class_ == Nil)
+ return 0;
+
+ return (int)(class_->version);
+}
+
+void
+class_setVersion (Class class_, int version)
+{
+ if (class_ == Nil)
+ return;
+
+ class_->version = version;
+}
+
+size_t
+class_getInstanceSize (Class class_)
+{
+ if (class_ == Nil)
+ return 0;
+
+ return class_->instance_size;
+}
+
#define CLASSOF(c) ((c)->class_pointer)
Class
diff --git a/libobjc/exception.c b/libobjc/exception.c
index a221a3e77e3..4883448afad 100644
--- a/libobjc/exception.c
+++ b/libobjc/exception.c
@@ -25,7 +25,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "objc-private/common.h"
#include <stdlib.h>
#include "config.h"
-#include "objc/objc-api.h"
+#include "objc/runtime.h"
#include "objc/objc-exception.h"
#include "unwind.h"
#include "unwind-pe.h"
@@ -57,7 +57,7 @@ is_kind_of_exception_matcher (Class catch_class, id exception)
Class c;
for (c = exception->class_pointer; c != Nil;
- c = class_get_super_class (c))
+ c = class_getSuperclass (c))
if (c == catch_class)
return 1;
}
@@ -191,9 +191,11 @@ get_ttype_entry (struct lsda_header_info *info, _uleb128_t i)
ptr = (_Unwind_Ptr) (info->TType - (i * 4));
ptr = _Unwind_decode_target2 (ptr);
-
+
+ /* NULL ptr means catch-all. Note that if the class is not found,
+ this will abort the program. */
if (ptr)
- return objc_get_class ((const char *) ptr);
+ return objc_getRequiredClass ((const char *) ptr);
else
return 0;
}
@@ -209,9 +211,10 @@ get_ttype_entry (struct lsda_header_info *info, _Unwind_Word i)
read_encoded_value_with_base (info->ttype_encoding, info->ttype_base,
info->TType - i, &ptr);
- /* NULL ptr means catch-all. */
+ /* NULL ptr means catch-all. Note that if the class is not found,
+ this will abort the program. */
if (ptr)
- return objc_get_class ((const char *) ptr);
+ return objc_getRequiredClass ((const char *) ptr);
else
return 0;
}
diff --git a/libobjc/ivars.c b/libobjc/ivars.c
index 061fa211fa8..52b71af1124 100644
--- a/libobjc/ivars.c
+++ b/libobjc/ivars.c
@@ -60,6 +60,25 @@ class_getInstanceVariable (Class class_, const char *name)
return NULL;
}
+struct objc_ivar *
+class_getClassVariable (Class class_, const char *name)
+{
+ if (class_ == Nil)
+ return NULL;
+
+ /* Logically, since a class is an instance of its meta-class, and
+ since its class methods are the instance methods of the
+ meta-class, class variables should be instance variables of the
+ meta-class. That is different from the normal use of having
+ 'static' variables in the class implementation file, because
+ every class would have its own variables.
+
+ Anyway, it is all speculative at this stage, but if we get class
+ variables in Objective-C, it is conceivable that this
+ implementation should work. */
+ return class_getInstanceVariable (class_->class_pointer, name);
+}
+
void *
object_getIndexedIvars (id object)
{
diff --git a/libobjc/objc-private/module-abi-8.h b/libobjc/objc-private/module-abi-8.h
index 120f5139d04..414e5e354ec 100644
--- a/libobjc/objc-private/module-abi-8.h
+++ b/libobjc/objc-private/module-abi-8.h
@@ -183,7 +183,7 @@ struct objc_class {
const char* name; /* Name of the class. */
long version; /* Unknown. */
unsigned long info; /* Bit mask. See class masks
- defined above. */
+ defined below. */
long instance_size; /* Size in bytes of the class.
The sum of the class
definition and all super
@@ -218,6 +218,45 @@ struct objc_class {
};
#endif /* __objc_STRUCT_OBJC_CLASS_defined */
+/* This is used to assure consistent access to the info field of
+ classes. */
+#ifndef HOST_BITS_PER_LONG
+# define HOST_BITS_PER_LONG (sizeof(long)*8)
+#endif
+
+#define __CLS_INFO(cls) ((cls)->info)
+#define __CLS_ISINFO(cls, mask) ((__CLS_INFO(cls)&mask)==mask)
+#define __CLS_SETINFO(cls, mask) (__CLS_INFO(cls) |= mask)
+
+/* The structure is of type MetaClass */
+#define _CLS_META 0x2L
+#define CLS_ISMETA(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_META))
+
+/* The structure is of type Class */
+#define _CLS_CLASS 0x1L
+#define CLS_ISCLASS(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_CLASS))
+
+/* The class is initialized within the runtime. This means that it
+ has had correct super and sublinks assigned. */
+#define _CLS_RESOLV 0x8L
+#define CLS_ISRESOLV(cls) __CLS_ISINFO(cls, _CLS_RESOLV)
+#define CLS_SETRESOLV(cls) __CLS_SETINFO(cls, _CLS_RESOLV)
+
+/* The class has been send a +initialize message or a such is not
+ defined for this class. */
+#define _CLS_INITIALIZED 0x04L
+#define CLS_ISINITIALIZED(cls) __CLS_ISINFO(cls, _CLS_INITIALIZED)
+#define CLS_SETINITIALIZED(cls) __CLS_SETINFO(cls, _CLS_INITIALIZED)
+
+/* The class number of this class. This must be the same for both the
+ class and its meta class object. */
+#define CLS_GETNUMBER(cls) (__CLS_INFO(cls) >> (HOST_BITS_PER_LONG/2))
+#define CLS_SETNUMBER(cls, num) \
+ ({ (cls)->info <<= (HOST_BITS_PER_LONG/2); \
+ (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. */
diff --git a/libobjc/objc/runtime.h b/libobjc/objc/runtime.h
index 6efe78d6fce..a52c7611857 100644
--- a/libobjc/objc/runtime.h
+++ b/libobjc/objc/runtime.h
@@ -239,6 +239,14 @@ objc_EXPORT Class object_setClass (id object, Class class_);
reuse the returned Ivar if you can. */
objc_EXPORT Ivar class_getInstanceVariable (Class class_, const char *name);
+/* Return a class variable given the class and the class variable
+ name. This is an expensive function to call, so try to reuse the
+ returned Ivar if you can.
+
+ This function always returns NULL since class variables are
+ currently unavailable in Objective-C. */
+objc_EXPORT Ivar class_getClassVariable (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. */
@@ -361,6 +369,48 @@ objc_EXPORT int objc_getClassList (Class *returnValue, int maxNumberOfClassesToR
class_ is Nil. */
objc_EXPORT const char * class_getName (Class class_);
+/* Return YES if 'class_' is a meta class, and NO if not. If 'class_'
+ is Nil, return NO. */
+objc_EXPORT BOOL class_isMetaClass (Class class_);
+
+/* Return the superclass of 'class_'. If 'class_' is Nil, or it is a root
+ class, return Nil.
+
+ TODO: It may be worth to define this inline, since it is usually
+ used in loops when traversing the class hierarchy. */
+objc_EXPORT Class class_getSuperclass (Class class_);
+
+/* Return the 'version' number of the class, which is an integer that
+ can be used to track changes in the class API, methods and
+ variables. If class_ is Nil, return 0. If class_ is not Nil, the
+ version is 0 unless class_setVersion() has been called to set a
+ different one.
+
+ Please note that internally the version is a long, but the API only
+ allows you to set and retrieve int values. */
+objc_EXPORT int class_getVersion (Class class_);
+
+/* Set the 'version' number of the class, which is an integer that can
+ be used to track changes in the class API, methods and variables.
+ If 'class_' is Nil, does nothing.
+
+ This is typically used internally by "Foundation" libraries such as
+ GNUstep Base to support serialization / deserialization of objects
+ that work across changes in the classes. If you are using such a
+ library, you probably want to use their versioning API, which may
+ be based on this one, but is integrated with the rest of the
+ library.
+
+ Please note that internally the version is a long, but the API only
+ allows you to set and retrieve int values. */
+objc_EXPORT void class_setVersion (Class class_, int version);
+
+/* Return the size in bytes (a byte is the size of a char) of an
+ instance of the class. If class_ is Nil, return 0; else it return
+ a non-zero number (since the 'isa' instance variable is required
+ for all classes). */
+objc_EXPORT size_t class_getInstanceSize (Class class_);
+
/** Implementation: the following functions are in protocols.c. */
diff --git a/libobjc/objects.c b/libobjc/objects.c
index 7aaf9a3afa5..71b09afee56 100644
--- a/libobjc/objects.c
+++ b/libobjc/objects.c
@@ -23,10 +23,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#include "objc-private/common.h"
-#include "objc/objc-api.h"
-#include "objc-private/runtime.h" /* the kitchen sink */
+#include "objc/runtime.h"
+#include "objc/thr.h" /* Required by objc-private/runtime.h. */
+#include "objc-private/module-abi-8.h" /* For CLS_ISCLASS and similar. */
+#include "objc-private/runtime.h" /* the kitchen sink */
-#include <string.h> /* For memcpy() */
+#include <string.h> /* For memcpy() */
#if OBJC_WITH_GC
# include <gc.h>