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:
parent
98d30e4fb5
commit
c994cc85bd
@ -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.
|
||||||
|
@ -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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user