Commit 30c0e2df by Kresten Krab Thorup

(offset_is_register): New variable

(offset_is_register): New variable
        (forwarding_offset): Use apply_args_register_offset to get
        register offset.
        (encode_method_def, encode_method_prototype): Prepend argument
        offset by '+' if passed in register.
        (apply_args_register_offset): Added declaration.
(generate_method_descriptors, generate_ivar_lists,
        generate_dispatch_tables): Reorganized use of constructors.
        (build_descriptor_table_initializer, build_ivar_list_initializer,
        build_dispatch_table_initializer): Removed argument `int *size'.

From-SVN: r5199
parent fb2ca25a
...@@ -174,6 +174,9 @@ static tree init_selector PROTO((int)); ...@@ -174,6 +174,9 @@ static tree init_selector PROTO((int));
static tree build_keyword_selector PROTO((tree)); static tree build_keyword_selector PROTO((tree));
static tree synth_id_with_class_suffix PROTO((char *, tree)); static tree synth_id_with_class_suffix PROTO((char *, tree));
/* from expr.c */
extern int apply_args_register_offset PROTO((int));
/* misc. bookkeeping */ /* misc. bookkeeping */
typedef struct hashed_entry *hash; typedef struct hashed_entry *hash;
...@@ -265,7 +268,7 @@ static tree build_class_reference_decl PROTO((tree)); ...@@ -265,7 +268,7 @@ static tree build_class_reference_decl PROTO((tree));
static void add_class_reference PROTO((tree)); static void add_class_reference PROTO((tree));
static tree objc_copy_list PROTO((tree, tree *)); static tree objc_copy_list PROTO((tree, tree *));
static tree build_protocol_template PROTO((void)); static tree build_protocol_template PROTO((void));
static tree build_descriptor_table_initializer PROTO((tree, tree, int *)); static tree build_descriptor_table_initializer PROTO((tree, tree));
static tree build_method_prototype_list_template PROTO((tree, int)); static tree build_method_prototype_list_template PROTO((tree, int));
static tree build_method_prototype_template PROTO((void)); static tree build_method_prototype_template PROTO((void));
static int forwarding_offset PROTO((tree)); static int forwarding_offset PROTO((tree));
...@@ -279,9 +282,9 @@ static void generate_protocols PROTO((void)); ...@@ -279,9 +282,9 @@ static void generate_protocols PROTO((void));
static void check_ivars PROTO((tree, tree)); static void check_ivars PROTO((tree, tree));
static tree build_ivar_list_template PROTO((tree, int)); static tree build_ivar_list_template PROTO((tree, int));
static tree build_method_list_template PROTO((tree, int)); static tree build_method_list_template PROTO((tree, int));
static tree build_ivar_list_initializer PROTO((tree, tree, int *)); static tree build_ivar_list_initializer PROTO((tree, tree));
static tree generate_ivars_list PROTO((tree, char *, int, tree)); static tree generate_ivars_list PROTO((tree, char *, int, tree));
static tree build_dispatch_table_initializer PROTO((tree, tree, int *)); static tree build_dispatch_table_initializer PROTO((tree, tree));
static tree generate_dispatch_table PROTO((tree, char *, int, tree)); static tree generate_dispatch_table PROTO((tree, char *, int, tree));
static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree, tree, int, tree, tree, tree)); static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree, tree, int, tree, tree, tree));
static void generate_category PROTO((tree)); static void generate_category PROTO((tree));
...@@ -2218,25 +2221,26 @@ build_protocol_template () ...@@ -2218,25 +2221,26 @@ build_protocol_template ()
} }
static tree static tree
build_descriptor_table_initializer (type, entries, size) build_descriptor_table_initializer (type, entries)
tree type; tree type;
tree entries; tree entries;
int *size;
{ {
tree initlist = NULLT; tree initlist = NULLT;
do do
{ {
initlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)), initlist); tree eltlist = NULLT;
eltlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)), NULLT);
eltlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries), meth_var_types), eltlist);
initlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries), meth_var_types), initlist); initlist = tree_cons (NULLT, build_constructor (type, nreverse (eltlist)), initlist);
(*size)++;
entries = TREE_CHAIN (entries); entries = TREE_CHAIN (entries);
} }
while (entries); while (entries);
return build_constructor (type, nreverse (initlist)); return build_constructor (build_array_type (type, 0), nreverse (initlist));
} }
/* struct objc_method_prototype_list { /* struct objc_method_prototype_list {
...@@ -2314,6 +2318,9 @@ build_method_prototype_template () ...@@ -2314,6 +2318,9 @@ build_method_prototype_template ()
return proto_record; return proto_record;
} }
/* True if last call to forwarding_offset yielded a register offset */
static int offset_is_register;
static int static int
forwarding_offset (parm) forwarding_offset (parm)
tree parm; tree parm;
...@@ -2335,16 +2342,14 @@ forwarding_offset (parm) ...@@ -2335,16 +2342,14 @@ forwarding_offset (parm)
offset_in_bytes = 0; offset_in_bytes = 0;
offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET; offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
offset_is_register = 0;
} }
#ifdef OBJC_FORWARDING_REG_OFFSET
else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG) else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
{ {
int regno = REGNO (DECL_INCOMING_RTL (parm)); int regno = REGNO (DECL_INCOMING_RTL (parm));
offset_in_bytes = apply_args_register_offset (regno);
offset_in_bytes = 4 * (regno - OBJC_FORWARDING_FIRST_REG) offset_is_register = 1;
+ OBJC_FORWARDING_REG_OFFSET;
} }
#endif /* OBJC_FORWARDING_REG_OFFSET */
else else
return 0; return 0;
...@@ -2391,7 +2396,7 @@ encode_method_prototype (method_decl, func_decl) ...@@ -2391,7 +2396,7 @@ encode_method_prototype (method_decl, func_decl)
+ (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms))) + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
/ BITS_PER_UNIT)); / BITS_PER_UNIT));
if (parm_end > max_parm_end) if (!offset_is_register && max_parm_end < parm_end)
max_parm_end = parm_end; max_parm_end = parm_end;
} }
...@@ -2420,6 +2425,11 @@ encode_method_prototype (method_decl, func_decl) ...@@ -2420,6 +2425,11 @@ encode_method_prototype (method_decl, func_decl)
/* compute offset */ /* compute offset */
sprintf (buf, "%d", forwarding_offset (parms)); sprintf (buf, "%d", forwarding_offset (parms));
/* indicate register */
if (offset_is_register)
obstack_1grow (&util_obstack, '+');
obstack_grow (&util_obstack, buf, strlen (buf)); obstack_grow (&util_obstack, buf, strlen (buf));
} }
...@@ -2474,17 +2484,15 @@ generate_method_descriptors (protocol) /* generate_dispatch_tables */ ...@@ -2474,17 +2484,15 @@ generate_method_descriptors (protocol) /* generate_dispatch_tables */
chain = PROTOCOL_CLS_METHODS (protocol); chain = PROTOCOL_CLS_METHODS (protocol);
if (chain) if (chain)
{ {
tree field; size = list_length (chain);
size = 0;
method_list_template method_list_template
= build_method_prototype_list_template (objc_method_prototype_template, = build_method_prototype_list_template (objc_method_prototype_template,
size); size);
field = TREE_CHAIN (TYPE_FIELDS (method_list_template)); initlist
initlist = build_descriptor_table_initializer (TREE_TYPE (field), = build_descriptor_table_initializer (objc_method_prototype_template,
chain, &size); chain);
UOBJC_CLASS_METHODS_decl UOBJC_CLASS_METHODS_decl
= generate_descriptor_table (method_list_template, = generate_descriptor_table (method_list_template,
...@@ -2499,16 +2507,14 @@ generate_method_descriptors (protocol) /* generate_dispatch_tables */ ...@@ -2499,16 +2507,14 @@ generate_method_descriptors (protocol) /* generate_dispatch_tables */
chain = PROTOCOL_NST_METHODS (protocol); chain = PROTOCOL_NST_METHODS (protocol);
if (chain) if (chain)
{ {
tree field; size = list_length (chain);
size = 0;
method_list_template method_list_template
= build_method_prototype_list_template (objc_method_prototype_template, = build_method_prototype_list_template (objc_method_prototype_template,
size); size);
field = TREE_CHAIN (TYPE_FIELDS (method_list_template)); initlist
initlist = build_descriptor_table_initializer (TREE_TYPE (field), = build_descriptor_table_initializer (objc_method_prototype_template,
chain, &size); chain);
UOBJC_INSTANCE_METHODS_decl UOBJC_INSTANCE_METHODS_decl
= generate_descriptor_table (method_list_template, = generate_descriptor_table (method_list_template,
...@@ -3218,52 +3224,57 @@ build_method_list_template (list_type, size) ...@@ -3218,52 +3224,57 @@ build_method_list_template (list_type, size)
} }
static tree static tree
build_ivar_list_initializer (type, field_decl, size) build_ivar_list_initializer (type, field_decl)
tree type; tree type;
tree field_decl; tree field_decl;
int *size;
{ {
tree initlist = NULLT; tree initlist = NULLT;
do do
{ {
tree ivar = NULLT;
/* set name */ /* set name */
if (DECL_NAME (field_decl)) if (DECL_NAME (field_decl))
initlist = tree_cons (NULLT, ivar = tree_cons (NULLT,
add_objc_string (DECL_NAME (field_decl), add_objc_string (DECL_NAME (field_decl),
meth_var_names), meth_var_names),
initlist); ivar);
else else
/* unnamed bit-field ivar (yuck). */ /* unnamed bit-field ivar (yuck). */
initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); ivar = tree_cons (NULLT, build_int_2 (0, 0), ivar);
/* set type */ /* set type */
encode_field_decl (field_decl, encode_field_decl (field_decl,
obstack_object_size (&util_obstack), obstack_object_size (&util_obstack),
OBJC_ENCODE_DONT_INLINE_DEFS); OBJC_ENCODE_DONT_INLINE_DEFS);
obstack_1grow (&util_obstack, 0); /* null terminate string */ obstack_1grow (&util_obstack, 0); /* null terminate string */
initlist ivar
= tree_cons = tree_cons
(NULLT, (NULLT,
add_objc_string (get_identifier (obstack_finish (&util_obstack)), add_objc_string (get_identifier (obstack_finish (&util_obstack)),
meth_var_types), meth_var_types),
initlist); ivar);
obstack_free (&util_obstack, util_firstobj); obstack_free (&util_obstack, util_firstobj);
/* set offset */ /* set offset */
initlist ivar
= tree_cons = tree_cons
(NULLT, (NULLT,
build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl)) build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
/ BITS_PER_UNIT), / BITS_PER_UNIT),
0), 0),
initlist); ivar);
(*size)++;
initlist = tree_cons (NULLT,
build_constructor (type, nreverse (ivar)),
initlist);
field_decl = TREE_CHAIN (field_decl); field_decl = TREE_CHAIN (field_decl);
} }
while (field_decl); while (field_decl);
return build_constructor (type, nreverse (initlist)); return build_constructor (build_array_type (type, 0), nreverse (initlist));
} }
static tree static tree
...@@ -3317,10 +3328,10 @@ generate_ivar_lists () ...@@ -3317,10 +3328,10 @@ generate_ivar_lists ()
if (CLASS_SUPER_NAME (implementation_template) == NULLT if (CLASS_SUPER_NAME (implementation_template) == NULLT
&& (chain = TYPE_FIELDS (objc_class_template))) && (chain = TYPE_FIELDS (objc_class_template)))
{ {
size = 0; size = list_length (chain);
ivar_list_template = build_ivar_list_template (objc_ivar_template, size); ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
initlist = build_ivar_list_initializer (ivar_list_template, initlist = build_ivar_list_initializer (objc_ivar_template, chain);
chain, &size);
UOBJC_CLASS_VARIABLES_decl UOBJC_CLASS_VARIABLES_decl
= generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES", = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
...@@ -3334,10 +3345,9 @@ generate_ivar_lists () ...@@ -3334,10 +3345,9 @@ generate_ivar_lists ()
chain = CLASS_IVARS (implementation_template); chain = CLASS_IVARS (implementation_template);
if (chain) if (chain)
{ {
size = 0; size = list_length (chain);
ivar_list_template = build_ivar_list_template (objc_ivar_template, size); ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
initlist = build_ivar_list_initializer (ivar_list_template, initlist = build_ivar_list_initializer (objc_ivar_template, chain);
chain, &size);
UOBJC_INSTANCE_VARIABLES_decl UOBJC_INSTANCE_VARIABLES_decl
= generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES", = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
...@@ -3352,39 +3362,45 @@ generate_ivar_lists () ...@@ -3352,39 +3362,45 @@ generate_ivar_lists ()
} }
static tree static tree
build_dispatch_table_initializer (type, entries, size) build_dispatch_table_initializer (type, entries)
tree type; tree type;
tree entries; tree entries;
int *size;
{ {
tree initlist = NULLT; tree initlist = NULLT;
do do
{ {
initlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)), tree elemlist = NULLT;
initlist);
elemlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)),
NULLT);
initlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries), elemlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries),
meth_var_types), meth_var_types),
initlist); elemlist);
initlist = tree_cons (NULLT, METHOD_DEFINITION (entries), initlist); elemlist = tree_cons (NULLT,
build_unary_op (ADDR_EXPR, METHOD_DEFINITION (entries), 1),
elemlist);
initlist = tree_cons (NULLT,
build_constructor (type, nreverse (elemlist)),
initlist);
(*size)++;
entries = TREE_CHAIN (entries); entries = TREE_CHAIN (entries);
} }
while (entries); while (entries);
return build_constructor (type, nreverse (initlist)); return build_constructor (build_array_type (type, 0), nreverse (initlist));
} }
/* To accomplish method prototyping without generating all kinds of /* To accomplish method prototyping without generating all kinds of
inane warnings, the definition of the dispatch table entries were inane warnings, the definition of the dispatch table entries were
changed from: changed from:
struct objc_method { SEL _cmd; id (*_imp)(); }; struct objc_method { SEL _cmd; ...; id (*_imp)(); };
to: to:
struct objc_method { SEL _cmd; void *_imp; }; */ struct objc_method { SEL _cmd; ...; void *_imp; }; */
static tree static tree
build_method_template () build_method_template ()
...@@ -3476,12 +3492,10 @@ generate_dispatch_tables () ...@@ -3476,12 +3492,10 @@ generate_dispatch_tables ()
chain = CLASS_CLS_METHODS (implementation_context); chain = CLASS_CLS_METHODS (implementation_context);
if (chain) if (chain)
{ {
size = 0; size = list_length (chain);
method_list_template = build_method_list_template (objc_method_template, method_list_template = build_method_list_template (objc_method_template, size);
size); initlist = build_dispatch_table_initializer (objc_method_template, chain);
initlist = build_dispatch_table_initializer (method_list_template,
chain, &size);
UOBJC_CLASS_METHODS_decl UOBJC_CLASS_METHODS_decl
= generate_dispatch_table (method_list_template, = generate_dispatch_table (method_list_template,
...@@ -3499,12 +3513,11 @@ generate_dispatch_tables () ...@@ -3499,12 +3513,11 @@ generate_dispatch_tables ()
chain = CLASS_NST_METHODS (implementation_context); chain = CLASS_NST_METHODS (implementation_context);
if (chain) if (chain)
{ {
size = 0; size = list_length (chain);
method_list_template = build_method_list_template (objc_method_template, size);
initlist = build_dispatch_table_initializer (objc_method_template, chain);
method_list_template = build_method_list_template (objc_method_template,
size);
initlist = build_dispatch_table_initializer (method_list_template,
chain, &size);
if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE) if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
UOBJC_INSTANCE_METHODS_decl UOBJC_INSTANCE_METHODS_decl
= generate_dispatch_table (method_list_template, = generate_dispatch_table (method_list_template,
...@@ -6598,7 +6611,7 @@ encode_method_def (func_decl) ...@@ -6598,7 +6611,7 @@ encode_method_def (func_decl)
+ (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms))) + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
/ BITS_PER_UNIT)); / BITS_PER_UNIT));
if (parm_end > max_parm_end) if (!offset_is_register && parm_end > max_parm_end)
max_parm_end = parm_end; max_parm_end = parm_end;
} }
...@@ -6618,6 +6631,11 @@ encode_method_def (func_decl) ...@@ -6618,6 +6631,11 @@ encode_method_def (func_decl)
/* compute offset */ /* compute offset */
sprintf (buffer, "%d", forwarding_offset (parms)); sprintf (buffer, "%d", forwarding_offset (parms));
/* indicate register */
if (offset_is_register)
obstack_1grow (&util_obstack, '+');
obstack_grow (&util_obstack, buffer, strlen (buffer)); obstack_grow (&util_obstack, buffer, strlen (buffer));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment