From 3d203535dfdd2f10c778354292ce6ea04ed8042b Mon Sep 17 00:00:00 2001 From: aph Date: Thu, 8 Jun 2006 14:01:40 +0000 Subject: [PATCH] 2006-06-08 Andrew Haley * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114487 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/java/ChangeLog | 22 ++++++++++++++++++++++ gcc/java/class.c | 13 ++++++++++--- gcc/java/expr.c | 46 +++++++++++++++++++++++++++++----------------- gcc/java/java-tree.h | 8 ++++---- gcc/java/parse.y | 15 +++++++++++---- 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 + + * 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 * 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; -- 2.7.4