In libobjc/: 2010-10-12 Nicola Pero <nicola.pero@meta-innovation.com>

In libobjc/:
2010-10-12  Nicola Pero  <nicola.pero@meta-innovation.com>

        * encoding.c: Tidied up comments.
        (objc_skip_variable_name): New static inline function.
        (objc_sizeof_type): Use objc_skip_variable_name instead of copying
        the same code over and over.
        (objc_alignof_type): Same.
        (objc_aligned_size): Same.
        (objc_promoted_size): Same.
        (objc_skip_typespec): Same.
        (objc_layout_structure_next_member): Same.
        (objc_skip_offset): Skip a '-' before the digits (if any).  Fixed
        historical bug where objc_skip_offset would skip one byte even if
        there is no offset: check that the first offset digit is actually
        a digit before skipping it.
        (objc_skip_type_qualifiers): Mark as inline.
        (objc_skip_typespec): Mark as inline.

From-SVN: r165403
This commit is contained in:
Nicola Pero 2010-10-12 22:57:57 +00:00 committed by Nicola Pero
parent 98d30e4fb5
commit c994cc85bd
2 changed files with 83 additions and 110 deletions

View File

@ -1,3 +1,21 @@
2010-10-12 Nicola Pero <nicola.pero@meta-innovation.com>
* encoding.c: Tidied up comments.
(objc_skip_variable_name): New static inline function.
(objc_sizeof_type): Use objc_skip_variable_name instead of copying
the same code over and over.
(objc_alignof_type): Same.
(objc_aligned_size): Same.
(objc_promoted_size): Same.
(objc_skip_typespec): Same.
(objc_layout_structure_next_member): Same.
(objc_skip_offset): Skip a '-' before the digits (if any). Fixed
historical bug where objc_skip_offset would skip one byte even if
there is no offset: check that the first offset digit is actually
a digit before skipping it.
(objc_skip_type_qualifiers): Mark as inline.
(objc_skip_typespec): Mark as inline.
2010-10-12 Nicola Pero <nicola.pero@meta-innovation.com> 2010-10-12 Nicola Pero <nicola.pero@meta-innovation.com>
* Makefile.in (C_SOURCE_FILES): Added methods.c. * Makefile.in (C_SOURCE_FILES): Added methods.c.

View File

@ -28,8 +28,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
/* FIXME: This file has no business including tm.h. */ /* FIXME: This file has no business including tm.h. */
/* FIXME: This file contains functions that will abort the entire /* FIXME: This file contains functions that will abort the entire
program if they fail. Is that really needed ? program if they fail. Is that really needed ? */
*/
#include "objc-private/common.h" #include "objc-private/common.h"
#include "objc-private/error.h" #include "objc-private/error.h"
@ -139,22 +138,34 @@ static int __attribute__ ((__unused__)) not_target_flags = 0;
#define darwin_rs6000_special_round_type_align(S,C,S2) \ #define darwin_rs6000_special_round_type_align(S,C,S2) \
rs6000_special_round_type_align(S,C,S2) rs6000_special_round_type_align(S,C,S2)
/*
return the size of an object specified by type
*/
int /* Skip a variable name, enclosed in quotes ("). */
objc_sizeof_type (const char *type) static inline
const char *
objc_skip_variable_name (const char *type)
{ {
/* Skip the variable name if any */ /* Skip the variable name if any. */
if (*type == '"') if (*type == '"')
{ {
/* FIXME: How do we know we won't read beyond the end of the /* FIXME: How do we know we won't read beyond the end of the
string. Here and in the rest of the file! */ string. Here and in the rest of the file! */
for (type++; *type++ != '"';) /* Skip '"'. */
/* do nothing */; type++;
/* Skip to the next '"'. */
while (*type != '"')
type++;
/* Skip '"'. */
type++;
} }
return type;
}
int
objc_sizeof_type (const char *type)
{
type = objc_skip_variable_name (type);
switch (*type) { switch (*type) {
case _C_BOOL: case _C_BOOL:
return sizeof (_Bool); return sizeof (_Bool);
@ -258,7 +269,8 @@ objc_sizeof_type (const char *type)
case _C_BFLD: case _C_BFLD:
{ {
/* The new encoding of bitfields is: b 'position' 'type' 'size' */ /* The GNU encoding of bitfields is: b 'position' 'type'
'size'. */
int position, size; int position, size;
int startByte, endByte; int startByte, endByte;
@ -363,20 +375,11 @@ objc_sizeof_type (const char *type)
} }
} }
/*
Return the alignment of an object specified by type
*/
int int
objc_alignof_type (const char *type) objc_alignof_type (const char *type)
{ {
/* Skip the variable name if any */ type = objc_skip_variable_name (type);
if (*type == '"')
{
for (type++; *type++ != '"';)
/* do nothing */;
}
switch (*type) { switch (*type) {
case _C_BOOL: case _C_BOOL:
return __alignof__ (_Bool); return __alignof__ (_Bool);
@ -562,56 +565,31 @@ objc_alignof_type (const char *type)
} }
} }
/*
The aligned size if the size rounded up to the nearest alignment.
*/
int int
objc_aligned_size (const char *type) objc_aligned_size (const char *type)
{ {
int size, align; int size, align;
/* Skip the variable name */ type = objc_skip_variable_name (type);
if (*type == '"')
{
for (type++; *type++ != '"';)
/* do nothing */;
}
size = objc_sizeof_type (type); size = objc_sizeof_type (type);
align = objc_alignof_type (type); align = objc_alignof_type (type);
return ROUND (size, align); return ROUND (size, align);
} }
/*
The size rounded up to the nearest integral of the wordsize, taken
to be the size of a void *.
*/
int int
objc_promoted_size (const char *type) objc_promoted_size (const char *type)
{ {
int size, wordsize; int size, wordsize;
/* Skip the variable name */ type = objc_skip_variable_name (type);
if (*type == '"')
{
for (type++; *type++ != '"';)
/* do nothing */;
}
size = objc_sizeof_type (type); size = objc_sizeof_type (type);
wordsize = sizeof (void *); wordsize = sizeof (void *);
return ROUND (size, wordsize); return ROUND (size, wordsize);
} }
/* inline
Skip type qualifiers. These may eventually precede typespecs
occurring in method prototype encodings.
*/
const char * const char *
objc_skip_type_qualifiers (const char *type) objc_skip_type_qualifiers (const char *type)
{ {
@ -629,22 +607,11 @@ objc_skip_type_qualifiers (const char *type)
return type; return type;
} }
inline
/*
Skip one typespec element. If the typespec is prepended by type
qualifiers, these are skipped as well.
*/
const char * const char *
objc_skip_typespec (const char *type) objc_skip_typespec (const char *type)
{ {
/* Skip the variable name if any */ type = objc_skip_variable_name (type);
if (*type == '"')
{
for (type++; *type++ != '"';)
/* do nothing */;
}
type = objc_skip_type_qualifiers (type); type = objc_skip_type_qualifiers (type);
switch (*type) { switch (*type) {
@ -728,7 +695,8 @@ objc_skip_typespec (const char *type)
} }
case _C_BFLD: case _C_BFLD:
/* The new encoding of bitfields is: b 'position' 'type' 'size' */ /* The GNU encoding of bitfields is: b 'position' 'type'
'size'. */
while (isdigit ((unsigned char)*++type)) while (isdigit ((unsigned char)*++type))
; /* skip position */ ; /* skip position */
while (isdigit ((unsigned char)*++type)) while (isdigit ((unsigned char)*++type))
@ -770,25 +738,29 @@ objc_skip_typespec (const char *type)
} }
} }
/* inline
Skip an offset as part of a method encoding. This is prepended by a
'+' if the argument is passed in registers.
FIXME: The compiler never generates '+'.
*/
const char * const char *
objc_skip_offset (const char *type) objc_skip_offset (const char *type)
{ {
/* The offset is prepended by a '+' if the argument is passed in
registers. PS: The compiler stopped generating this '+' in
version 3.4. */
if (*type == '+') if (*type == '+')
type++; type++;
while (isdigit ((unsigned char) *++type))
; /* Some people claim that on some platforms, where the stack grows
backwards, the compiler generates negative offsets (??). Skip a
'-' for such a negative offset. */
if (*type == '-')
type++;
/* Skip the digits that represent the offset. */
while (isdigit ((unsigned char) *type))
type++;
return type; return type;
} }
/*
Skip an argument specification of a method encoding.
*/
const char * const char *
objc_skip_argspec (const char *type) objc_skip_argspec (const char *type)
{ {
@ -832,12 +804,9 @@ method_get_number_of_arguments (struct objc_method *mth)
return method_getNumberOfArguments (mth); return method_getNumberOfArguments (mth);
} }
/* /* Return the size of the argument block needed on the stack to invoke
Return the size of the argument block needed on the stack to invoke the method MTH. This may be zero, if all arguments are passed in
the method MTH. This may be zero, if all arguments are passed in registers. */
registers.
*/
int int
method_get_sizeof_arguments (struct objc_method *mth) method_get_sizeof_arguments (struct objc_method *mth)
{ {
@ -884,12 +853,10 @@ method_get_next_argument (arglist_t argframe, const char **type)
return argframe->arg_ptr + atoi (t); return argframe->arg_ptr + atoi (t);
} }
/* /* Return a pointer to the value of the first argument of the method
Return a pointer to the value of the first argument of the method described in M with the given argumentframe ARGFRAME. The type
described in M with the given argumentframe ARGFRAME. The type is returned in TYPE. type must be passed to successive calls of
is returned in TYPE. type must be passed to successive calls of method_get_next_argument. */
method_get_next_argument.
*/
char * char *
method_get_first_argument (struct objc_method *m, method_get_first_argument (struct objc_method *m,
arglist_t argframe, arglist_t argframe,
@ -899,12 +866,9 @@ method_get_first_argument (struct objc_method *m,
return method_get_next_argument (argframe, type); return method_get_next_argument (argframe, type);
} }
/* /* Return a pointer to the ARGth argument of the method
Return a pointer to the ARGth argument of the method
M from the frame ARGFRAME. The type of the argument M from the frame ARGFRAME. The type of the argument
is returned in the value-result argument TYPE is returned in the value-result argument TYPE. */
*/
char * char *
method_get_nth_argument (struct objc_method *m, method_get_nth_argument (struct objc_method *m,
arglist_t argframe, int arg, arglist_t argframe, int arg,
@ -936,13 +900,13 @@ objc_get_type_qualifiers (const char *type)
while (flag) while (flag)
switch (*type++) switch (*type++)
{ {
case _C_CONST: res |= _F_CONST; break; case _C_CONST: res |= _F_CONST; break;
case _C_IN: res |= _F_IN; break; case _C_IN: res |= _F_IN; break;
case _C_INOUT: res |= _F_INOUT; break; case _C_INOUT: res |= _F_INOUT; break;
case _C_OUT: res |= _F_OUT; break; case _C_OUT: res |= _F_OUT; break;
case _C_BYCOPY: res |= _F_BYCOPY; break; case _C_BYCOPY: res |= _F_BYCOPY; break;
case _C_BYREF: res |= _F_BYREF; break; case _C_BYREF: res |= _F_BYREF; break;
case _C_ONEWAY: res |= _F_ONEWAY; break; case _C_ONEWAY: res |= _F_ONEWAY; break;
case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break; case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
default: flag = NO; default: flag = NO;
} }
@ -950,7 +914,6 @@ objc_get_type_qualifiers (const char *type)
return res; return res;
} }
/* The following three functions can be used to determine how a /* The following three functions can be used to determine how a
structure is laid out by the compiler. For example: structure is laid out by the compiler. For example:
@ -972,7 +935,7 @@ objc_get_type_qualifiers (const char *type)
functions to compute the size and alignment of structures. The functions to compute the size and alignment of structures. The
previous method of computing the size and alignment of a structure previous method of computing the size and alignment of a structure
was not working on some architectures, particulary on AIX, and in was not working on some architectures, particulary on AIX, and in
the presence of bitfields inside the structure. */ the presence of bitfields inside the structure. */
void void
objc_layout_structure (const char *type, objc_layout_structure (const char *type,
struct objc_struct_layout *layout) struct objc_struct_layout *layout)
@ -1006,7 +969,6 @@ objc_layout_structure (const char *type,
layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY); layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
} }
BOOL BOOL
objc_layout_structure_next_member (struct objc_struct_layout *layout) objc_layout_structure_next_member (struct objc_struct_layout *layout)
{ {
@ -1048,12 +1010,7 @@ objc_layout_structure_next_member (struct objc_struct_layout *layout)
return NO; return NO;
/* Skip the variable name if any */ /* Skip the variable name if any */
if (*layout->type == '"') layout->type = objc_skip_variable_name (layout->type);
{
for (layout->type++; *layout->type++ != '"';)
/* do nothing */;
}
type = objc_skip_type_qualifiers (layout->type); type = objc_skip_type_qualifiers (layout->type);
if (*type != _C_BFLD) if (*type != _C_BFLD)
@ -1139,7 +1096,6 @@ objc_layout_structure_next_member (struct objc_struct_layout *layout)
return YES; return YES;
} }
void objc_layout_finish_structure (struct objc_struct_layout *layout, void objc_layout_finish_structure (struct objc_struct_layout *layout,
unsigned int *size, unsigned int *size,
unsigned int *align) unsigned int *align)
@ -1177,7 +1133,6 @@ void objc_layout_finish_structure (struct objc_struct_layout *layout,
*align = layout->record_align / BITS_PER_UNIT; *align = layout->record_align / BITS_PER_UNIT;
} }
void objc_layout_structure_get_info (struct objc_struct_layout *layout, void objc_layout_structure_get_info (struct objc_struct_layout *layout,
unsigned int *offset, unsigned int *offset,
unsigned int *align, unsigned int *align,