libobjc: fix class_addIvar()'s alignment
Nicola Pero
nicola.pero@meta-innovation.com
Fri Dec 24 21:27:00 GMT 2010
This patch changes class_addIvar() to be compatible with the Apple
runtime and
understand the alignment argument in the same way as the Apple runtime
understands it: as the log2 of the alignment, as opposed to the actual
alignment.
Committed to trunk.
Thanks
Index: ChangeLog
===================================================================
--- ChangeLog (revision 168229)
+++ ChangeLog (working copy)
@@ -1,5 +1,12 @@
2010-12-24 Nicola Pero <nicola.pero@meta-innovation.com>
+ * objc/runtime.h (class_addIvar): Updated documentation. The
+ alignment is actually the log_2 of the alignment in bytes.
+ * ivars.c (class_addIvar): Corresponding change to the
+ implementation.
+
+2010-12-24 Nicola Pero <nicola.pero@meta-innovation.com>
+
* objc/runtime.h (sel_getType): Renamed to
sel_getTypeEncoding to
be consistent with method_getTypeEncoding and
ivar_getTypeEncoding.
Index: ivars.c
===================================================================
--- ivars.c (revision 168228)
+++ ivars.c (working copy)
@@ -212,7 +212,7 @@
BOOL
class_addIvar (Class class_, const char * ivar_name, size_t size,
- unsigned char alignment, const char *type)
+ unsigned char log_2_of_alignment, const char *type)
{
struct objc_ivar_list *ivars;
@@ -270,6 +270,7 @@
size. */
{
struct objc_ivar *ivar = &(ivars->ivar_list[ivars->ivar_count -
1]);
+ unsigned int alignment = 1 << log_2_of_alignment;
int misalignment;
ivar->ivar_name = objc_malloc (strlen (ivar_name) + 1);
Index: objc/runtime.h
===================================================================
--- objc/runtime.h (revision 168229)
+++ objc/runtime.h (working copy)
@@ -352,14 +352,16 @@
using objc_allocateClassPair() and has not been registered with the
runtime using objc_registerClassPair() yet. You can not add
instance variables to classes already registered with the runtime.
- 'size' is the size of the instance variable, 'alignment' the
- alignment, and 'type' the type encoding of the variable type. You
- can use sizeof(), __alignof__() and @encode() to determine the
- right 'size', 'alignment' and 'type' for your instance variable.
- For example, to add an instance variable name "my_variable" and of
- type 'id', you can use:
+ 'size' is the size of the instance variable, 'log_2_of_alignment'
+ the alignment as a power of 2 (so 0 means alignment to a 1 byte
+ boundary, 1 means alignment to a 2 byte boundary, 2 means alignment
+ to a 4 byte boundary, etc), and 'type' the type encoding of the
+ variable type. You can use sizeof(), log2(__alignof__()) and
+ @encode() to determine the right 'size', 'alignment' and 'type' for
+ your instance variable. For example, to add an instance variable
+ name "my_variable" and of type 'id', you can use:
- class_addIvar (class, "my_variable", sizeof (id), __alignof__ (id),
+ class_addIvar (class, "my_variable", sizeof (id), log2
( __alignof__ (id)),
@encode (id));
Return YES if the variable was added, and NO if not. In
@@ -368,7 +370,7 @@
'type' is NULL, or 'size' is 0.
*/
objc_EXPORT BOOL class_addIvar (Class class_, const char *
ivar_name, size_t size,
- unsigned char alignment, const char
*type);
+ unsigned char log_2_of_alignment,
const char *type);
/* Return the name of the property. Return NULL if 'property' is
NULL. */
Index: ChangeLog
===================================================================
--- ChangeLog (revision 168229)
+++ ChangeLog (working copy)
@@ -1,5 +1,11 @@
2010-12-24 Nicola Pero <nicola.pero@meta-innovation.com>
+ * objc.dg/gnu-api-2-class.m: Updated test to pass log_2 of the
+ alignment to class_addIvar, instead of the alignment itself.
+ * obj-c++.dg/gnu-api-2-class.mm: Same change.
+
+2010-12-24 Nicola Pero <nicola.pero@meta-innovation.com>
+
* objc.dg/gnu-api-2-sel.m: Updated for renaming of
sel_getType to
sel_getTypeEncoding. Test that sel_getTypeEncoding returns
NULL
when called with a NULL argument. Added test for
Index: objc.dg/gnu-api-2-class.m
===================================================================
--- objc.dg/gnu-api-2-class.m (revision 168229)
+++ objc.dg/gnu-api-2-class.m (working copy)
@@ -62,6 +62,24 @@
- (id) mySelf;
@end
+/* Hack to calculate the log2 of a byte alignment. */
+unsigned char
+log_2_of (unsigned int x)
+{
+ unsigned char result = 0;
+
+ /* We count how many times we need to divide by 2 before we reach 1.
+ This algorithm is good enough for the small numbers (such as 8,
+ 16 or 64) that we have to deal with. */
+ while (x > 1)
+ {
+ x = x / 2;
+ result++;
+ }
+
+ return result;
+}
+
int main(int argc, void **args)
{
/* Functions are tested in alphabetical order. */
@@ -74,15 +92,15 @@
abort ();
if (! class_addIvar (new_class, "variable2_ivar", sizeof (id),
- __alignof__ (id), @encode (id)))
+ log_2_of (__alignof__ (id)), @encode (id)))
abort ();
if (! class_addIvar (new_class, "variable3_ivar", sizeof
(unsigned char),
- __alignof__ (unsigned char), @encode
(unsigned char)))
+ log_2_of (__alignof__ (unsigned char)),
@encode (unsigned char)))
abort ();
if (! class_addIvar (new_class, "variable4_ivar", sizeof
(unsigned long),
- __alignof__ (unsigned long), @encode
(unsigned long)))
+ log_2_of (__alignof__ (unsigned long)),
@encode (unsigned long)))
abort ();
objc_registerClassPair (new_class);
@@ -135,7 +153,7 @@
abort ();
if (! class_addIvar (new_class, "variable_ivar", sizeof (id),
- __alignof__ (id), @encode (id)))
+ log_2_of (__alignof__ (id)), @encode (id)))
abort ();
if (! class_addMethod (new_class, @selector (setVariable:),
method_getImplementation (method1),
Index: obj-c++.dg/gnu-api-2-class.mm
===================================================================
--- obj-c++.dg/gnu-api-2-class.mm (revision 168228)
+++ obj-c++.dg/gnu-api-2-class.mm (working copy)
@@ -62,6 +62,24 @@
- (id) mySelf;
@end
+/* Hack to calculate the log2 of a byte alignment. */
+unsigned char
+log_2_of (unsigned int x)
+{
+ unsigned char result = 0;
+
+ /* We count how many times we need to divide by 2 before we reach 1.
+ This algorithm is good enough for the small numbers (such as 8,
+ 16 or 64) that we have to deal with. */
+ while (x > 1)
+ {
+ x = x / 2;
+ result++;
+ }
+
+ return result;
+}
+
int main ()
{
/* Functions are tested in alphabetical order. */
@@ -74,15 +92,15 @@
abort ();
if (! class_addIvar (new_class, "variable2_ivar", sizeof (id),
- __alignof__ (id), @encode (id)))
+ log_2_of (__alignof__ (id)), @encode (id)))
abort ();
if (! class_addIvar (new_class, "variable3_ivar", sizeof
(unsigned char),
- __alignof__ (unsigned char), @encode
(unsigned char)))
+ log_2_of (__alignof__ (unsigned char)),
@encode (unsigned char)))
abort ();
if (! class_addIvar (new_class, "variable4_ivar", sizeof
(unsigned long),
- __alignof__ (unsigned long), @encode
(unsigned long)))
+ log_2_of (__alignof__ (unsigned long)),
@encode (unsigned long)))
abort ();
objc_registerClassPair (new_class);
@@ -135,7 +153,7 @@
abort ();
if (! class_addIvar (new_class, "variable_ivar", sizeof (id),
- __alignof__ (id), @encode (id)))
+ log_2_of (__alignof__ (id)), @encode (id)))
abort ();
if (! class_addMethod (new_class, @selector (setVariable:),
method_getImplementation (method1),
More information about the Gcc-patches
mailing list