aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2006-06-08 14:01:40 +0000
committerAndrew Haley <aph@gcc.gnu.org>2006-06-08 14:01:40 +0000
commit313ab5ee9c2616aa6c3058cf992d2f69b52fc2db (patch)
tree06de34fc6cdfcf4bb3efea134a03b6b617bab797 /gcc
parent297750da0393e5542752140f9ad5abb924f6305e (diff)
downloadgcc-313ab5ee9c2616aa6c3058cf992d2f69b52fc2db.zip
gcc-313ab5ee9c2616aa6c3058cf992d2f69b52fc2db.tar.gz
gcc-313ab5ee9c2616aa6c3058cf992d2f69b52fc2db.tar.bz2
expr.c (build_field_ref): Pass NULL_TREE as SPECIAL arg to get_symbol_table_index().
2006-06-08 Andrew Haley <aph@redhat.com> * expr.c (build_field_ref): Pass NULL_TREE as SPECIAL arg to get_symbol_table_index(). (maybe_rewrite_invocation): Set SPECIAL if we need to access a private method. (build_known_method_ref): New arg: special. Pass it to get_symbol_table_index. (get_symbol_table_index): Put SPECIAL in the TREE_PURPOSE field of the method list. (build_invokevirtual): New arg: special. Pass it to get_symbol_table_index. (expand_invoke): New variable: special. Pass it to maybe_rewrite_invocation(). Pass it to build_known_method_ref(). * class.c (build_symbol_entry): Add new arg: special. Use it to build the symbol table conbstructor. (emit_symbol_table): Extract SPECIAL from the method list and pass it to build_symbol_entry(). * parse.y (patch_invoke): Call maybe_rewrite_invocation() and set special accordingly. From-SVN: r114487
Diffstat (limited to 'gcc')
-rw-r--r--gcc/java/ChangeLog22
-rw-r--r--gcc/java/class.c13
-rw-r--r--gcc/java/expr.c46
-rw-r--r--gcc/java/java-tree.h8
-rw-r--r--gcc/java/parse.y15
5 files changed, 76 insertions, 28 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 90f275c..ae0e407 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,25 @@
+2006-06-08 Andrew Haley <aph@redhat.com>
+
+ * expr.c (build_field_ref): Pass NULL_TREE as SPECIAL arg to
+ get_symbol_table_index().
+ (maybe_rewrite_invocation): Set SPECIAL if we need to access a
+ private method.
+ (build_known_method_ref): New arg: special. Pass it to
+ get_symbol_table_index.
+ (get_symbol_table_index): Put SPECIAL in the TREE_PURPOSE field of
+ the method list.
+ (build_invokevirtual): New arg: special. Pass it to
+ get_symbol_table_index.
+ (expand_invoke): New variable: special.
+ Pass it to maybe_rewrite_invocation().
+ Pass it to build_known_method_ref().
+ * class.c (build_symbol_entry): Add new arg: special. Use it to
+ build the symbol table conbstructor.
+ (emit_symbol_table): Extract SPECIAL from the method list and pass
+ it to build_symbol_entry().
+ * parse.y (patch_invoke): Call maybe_rewrite_invocation() and set
+ special accordingly.
+
2006-06-06 David Daney <ddaney@avtrex.com>
* gcj.texi (libgcj Runtime Properties): Document
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 403318a..44f435c 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -62,7 +62,7 @@ static int supers_all_compiled (tree type);
static tree maybe_layout_super_class (tree, tree);
static void add_miranda_methods (tree, tree);
static int assume_compiled (const char *);
-static tree build_symbol_entry (tree);
+static tree build_symbol_entry (tree, tree);
static tree emit_assertion_table (tree);
static void register_class (void);
@@ -2651,7 +2651,7 @@ emit_register_classes (tree *list_p)
/* Make a symbol_type (_Jv_MethodSymbol) node for DECL. */
static tree
-build_symbol_entry (tree decl)
+build_symbol_entry (tree decl, tree special)
{
tree clname, name, signature, sym;
clname = build_utf8_ref (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl))));
@@ -2667,6 +2667,12 @@ build_symbol_entry (tree decl)
signature = build_utf8_ref (unmangle_classname
(IDENTIFIER_POINTER (signature),
IDENTIFIER_LENGTH (signature)));
+ /* SPECIAL is either NULL_TREE or integer_one_node. We emit
+ signature addr+1 if SPECIAL, and this indicates to the runtime
+ system that this is a "special" symbol, i.e. one that should
+ bypass access controls. */
+ if (special != NULL_TREE)
+ signature = build2 (PLUS_EXPR, TREE_TYPE (signature), signature, special);
START_RECORD_CONSTRUCTOR (sym, symbol_type);
PUSH_FIELD_VALUE (sym, "clname", clname);
@@ -2701,8 +2707,9 @@ emit_symbol_table (tree name, tree the_table, tree decl_list,
list = NULL_TREE;
while (method_list != NULL_TREE)
{
+ tree special = TREE_PURPOSE (method_list);
method = TREE_VALUE (method_list);
- list = tree_cons (NULL_TREE, build_symbol_entry (method), list);
+ list = tree_cons (NULL_TREE, build_symbol_entry (method, special), list);
method_list = TREE_CHAIN (method_list);
index++;
}
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 4c0f1cd..cb3d506 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -1711,7 +1711,8 @@ build_field_ref (tree self_value, tree self_class, tree name)
{
tree otable_index
= build_int_cst (NULL_TREE, get_symbol_table_index
- (field_decl, &TYPE_OTABLE_METHODS (output_class)));
+ (field_decl, NULL_TREE,
+ &TYPE_OTABLE_METHODS (output_class)));
tree field_offset
= build4 (ARRAY_REF, integer_type_node,
TYPE_OTABLE_DECL (output_class), otable_index,
@@ -2060,14 +2061,17 @@ static rewrite_rule rules[] =
{NULL, NULL, NULL, NULL, 0, NULL}};
/* Scan the rules list for replacements for *METHOD_P and replace the
- args accordingly. */
+ args accordingly. If the rewrite results in an access to a private
+ method, update SPECIAL.*/
void
maybe_rewrite_invocation (tree *method_p, tree *arg_list_p,
- tree *method_signature_p)
+ tree *method_signature_p, tree *special)
{
tree context = DECL_NAME (TYPE_NAME (DECL_CONTEXT (*method_p)));
rewrite_rule *p;
+ *special = NULL_TREE;
+
for (p = rules; p->classname; p++)
{
if (get_identifier (p->classname) == context)
@@ -2091,6 +2095,7 @@ maybe_rewrite_invocation (tree *method_p, tree *arg_list_p,
gcc_assert (*method_p);
*arg_list_p = p->rewrite_arglist (*arg_list_p);
*method_signature_p = get_identifier (p->new_signature);
+ *special = integer_one_node;
break;
}
@@ -2103,7 +2108,7 @@ maybe_rewrite_invocation (tree *method_p, tree *arg_list_p,
tree
build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
tree self_type, tree method_signature ATTRIBUTE_UNUSED,
- tree arg_list ATTRIBUTE_UNUSED)
+ tree arg_list ATTRIBUTE_UNUSED, tree special)
{
tree func;
if (is_compiled_class (self_type))
@@ -2121,8 +2126,10 @@ build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
else
{
tree table_index
- = build_int_cst (NULL_TREE, get_symbol_table_index
- (method, &TYPE_ATABLE_METHODS (output_class)));
+ = build_int_cst (NULL_TREE,
+ (get_symbol_table_index
+ (method, special,
+ &TYPE_ATABLE_METHODS (output_class))));
func
= build4 (ARRAY_REF,
TREE_TYPE (TREE_TYPE (TYPE_ATABLE_DECL (output_class))),
@@ -2207,14 +2214,14 @@ invoke_build_dtable (int is_invoke_interface, tree arg_list)
reused. */
int
-get_symbol_table_index (tree t, tree *symbol_table)
+get_symbol_table_index (tree t, tree special, tree *symbol_table)
{
int i = 1;
tree method_list;
if (*symbol_table == NULL_TREE)
{
- *symbol_table = build_tree_list (t, t);
+ *symbol_table = build_tree_list (special, t);
return 1;
}
@@ -2223,7 +2230,8 @@ get_symbol_table_index (tree t, tree *symbol_table)
while (1)
{
tree value = TREE_VALUE (method_list);
- if (value == t)
+ tree purpose = TREE_PURPOSE (method_list);
+ if (value == t && purpose == special)
return i;
i++;
if (TREE_CHAIN (method_list) == NULL_TREE)
@@ -2232,12 +2240,12 @@ get_symbol_table_index (tree t, tree *symbol_table)
method_list = TREE_CHAIN (method_list);
}
- TREE_CHAIN (method_list) = build_tree_list (t, t);
+ TREE_CHAIN (method_list) = build_tree_list (special, t);
return i;
}
tree
-build_invokevirtual (tree dtable, tree method)
+build_invokevirtual (tree dtable, tree method, tree special)
{
tree func;
tree nativecode_ptr_ptr_type_node
@@ -2251,7 +2259,8 @@ build_invokevirtual (tree dtable, tree method)
otable_index
= build_int_cst (NULL_TREE, get_symbol_table_index
- (method, &TYPE_OTABLE_METHODS (output_class)));
+ (method, special,
+ &TYPE_OTABLE_METHODS (output_class)));
method_index = build4 (ARRAY_REF, integer_type_node,
TYPE_OTABLE_DECL (output_class),
otable_index, NULL_TREE, NULL_TREE);
@@ -2307,7 +2316,7 @@ build_invokeinterface (tree dtable, tree method)
{
int itable_index
= 2 * (get_symbol_table_index
- (method, &TYPE_ITABLE_METHODS (output_class)));
+ (method, NULL_TREE, &TYPE_ITABLE_METHODS (output_class)));
interface
= build4 (ARRAY_REF,
TREE_TYPE (TREE_TYPE (TYPE_ITABLE_DECL (output_class))),
@@ -2360,6 +2369,8 @@ expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
tree call, func, method, arg_list, method_type;
tree check = NULL_TREE;
+ tree special = NULL_TREE;
+
if (! CLASS_LOADED_P (self_type))
{
load_class (self_type, 1);
@@ -2474,12 +2485,13 @@ expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
flush_quick_stack ();
- maybe_rewrite_invocation (&method, &arg_list, &method_signature);
+ maybe_rewrite_invocation (&method, &arg_list, &method_signature,
+ &special);
func = NULL_TREE;
if (opcode == OPCODE_invokestatic)
func = build_known_method_ref (method, method_type, self_type,
- method_signature, arg_list);
+ method_signature, arg_list, special);
else if (opcode == OPCODE_invokespecial
|| (opcode == OPCODE_invokevirtual
&& (METHOD_PRIVATE (method)
@@ -2499,14 +2511,14 @@ expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
TREE_VALUE (arg_list) = save_arg;
check = java_check_reference (save_arg, ! DECL_INIT_P (method));
func = build_known_method_ref (method, method_type, self_type,
- method_signature, arg_list);
+ method_signature, arg_list, special);
}
else
{
tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
arg_list);
if (opcode == OPCODE_invokevirtual)
- func = build_invokevirtual (dtable, method);
+ func = build_invokevirtual (dtable, method, special);
else
func = build_invokeinterface (dtable, method);
}
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 1d322e7..7f483d4 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -1241,11 +1241,11 @@ extern tree check_for_builtin (tree, tree);
extern void initialize_builtins (void);
extern tree lookup_name (tree);
-extern void maybe_rewrite_invocation (tree *, tree *, tree *);
-extern tree build_known_method_ref (tree, tree, tree, tree, tree);
+extern void maybe_rewrite_invocation (tree *, tree *, tree *, tree *);
+extern tree build_known_method_ref (tree, tree, tree, tree, tree, tree);
extern tree build_class_init (tree, tree);
extern int attach_init_test_initialization_flags (void **, void *);
-extern tree build_invokevirtual (tree, tree);
+extern tree build_invokevirtual (tree, tree, tree);
extern tree build_invokeinterface (tree, tree);
extern tree build_jni_stub (tree);
extern tree invoke_build_dtable (int, tree);
@@ -1393,7 +1393,7 @@ extern void register_exception_range(struct eh_range *, int, int);
extern void finish_method (tree);
extern void java_expand_body (tree);
-extern int get_symbol_table_index (tree, tree *);
+extern int get_symbol_table_index (tree, tree, tree *);
extern tree make_catch_class_record (tree, tree);
extern tree emit_catch_table (tree);
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index a606d87..c93a93f 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -11043,8 +11043,14 @@ patch_invoke (tree patch, tree method, tree args)
switch (invocation_mode (method, CALL_USING_SUPER (patch)))
{
case INVOKE_VIRTUAL:
- dtable = invoke_build_dtable (0, args);
- func = build_invokevirtual (dtable, method);
+ {
+ tree signature = build_java_signature (TREE_TYPE (method));
+ tree special;
+ maybe_rewrite_invocation (&method, &args, &signature, &special);
+
+ dtable = invoke_build_dtable (0, args);
+ func = build_invokevirtual (dtable, method, special);
+ }
break;
case INVOKE_NONVIRTUAL:
@@ -11066,10 +11072,11 @@ patch_invoke (tree patch, tree method, tree args)
case INVOKE_STATIC:
{
tree signature = build_java_signature (TREE_TYPE (method));
- maybe_rewrite_invocation (&method, &args, &signature);
+ tree special;
+ maybe_rewrite_invocation (&method, &args, &signature, &special);
func = build_known_method_ref (method, TREE_TYPE (method),
DECL_CONTEXT (method),
- signature, args);
+ signature, args, special);
}
break;