expr.c (build_field_ref): Pass NULL_TREE as SPECIAL arg to get_symbol_table_index().
authorAndrew Haley <aph@redhat.com>
Thu, 8 Jun 2006 14:01:40 +0000 (14:01 +0000)
committerAndrew Haley <aph@gcc.gnu.org>
Thu, 8 Jun 2006 14:01:40 +0000 (14:01 +0000)
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

gcc/java/ChangeLog
gcc/java/class.c
gcc/java/expr.c
gcc/java/java-tree.h
gcc/java/parse.y

index 90f275ce32c85fa34c7a461580c63d8e09074376..ae0e407fb36542dc8f1dbf86c84149f045c5486c 100644 (file)
@@ -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
index 403318aa6551f719dfe974c98510ba137703d307..44f435c134f2ea792b2ee482545b7c5d4881d3c6 100644 (file)
@@ -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++;
     }
index 4c0f1cd911b0df6f436fd697d72082494fc67844..cb3d506bad335459fe898d3faea12e7b6ab848a8 100644 (file)
@@ -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);
     }
index 1d322e795f755e5efa836aabdd44f955de97b55d..7f483d4d7e6887f18984d57318dfdc9e84c3e3d4 100644 (file)
@@ -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);
index a606d87869e52ced980e267cfa031aa4ae9f91ab..c93a93f94b0dbb1ee291347b3f20d531300f4ee1 100644 (file)
@@ -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;