VMCPStringBuilder.toString() relies on backdoor access to a private
constructor for String.  We can do this via a native method, but it's
easier and more efficient to add a compiler builtin.  This one performs
the transformation:

  gnu.java.lang.VMCPStringBuilder.toString(char[],int,int)
  --> java.lang.String.toString(char[],int,int)

I've also had to add a new field to the rewrite rules, that of the
destination class, but unless I've made a mistake this won't make
any difference to the existing rules.

Andrew.


2008-09-22  Andrew Haley  <[EMAIL PROTECTED]>

        * expr.c (rules): Add new rule for
        gnu.java.lang.VMCPStringBuilder.toString.
        (rewrite_rule.new_classname): New field.
        (maybe_rewrite_invocation): Use new_classname field instead of
        DECL_CONTEXT (*method_p).
        Allow rewrite_arglist to be NULL.

Index: gcc/java/expr.c
===================================================================
--- gcc/java/expr.c     (revision 140485)
+++ gcc/java/expr.c     (working copy)
@@ -2075,6 +2075,7 @@
   const char *classname;
   const char *method;
   const char *signature;
+  const char *new_classname;
   const char *new_signature;
   int flags;
   tree (*rewrite_arglist) (tree arglist);
@@ -2109,20 +2110,27 @@

 static rewrite_rule rules[] =
   {{"java.lang.Class", "getClassLoader", "()Ljava/lang/ClassLoader;",
-    "(Ljava/lang/Class;)Ljava/lang/ClassLoader;",
+    "java.lang.Class", "(Ljava/lang/Class;)Ljava/lang/ClassLoader;",
     ACC_FINAL|ACC_PRIVATE, rewrite_arglist_getclass},
+
    {"java.lang.Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;",
-    "(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
+    "java.lang.Class", 
"(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
     ACC_FINAL|ACC_PRIVATE|ACC_STATIC, rewrite_arglist_getclass},
+
    {"gnu.classpath.VMStackWalker", "getCallingClass", "()Ljava/lang/Class;",
-    "(Lgnu/gcj/RawData;)Ljava/lang/Class;",
+    "gnu.classpath.VMStackWalker", "(Lgnu/gcj/RawData;)Ljava/lang/Class;",
     ACC_FINAL|ACC_PRIVATE|ACC_STATIC, rewrite_arglist_getcaller},
+
    {"gnu.classpath.VMStackWalker", "getCallingClassLoader",
     "()Ljava/lang/ClassLoader;",
-    "(Lgnu/gcj/RawData;)Ljava/lang/ClassLoader;",
+    "gnu.classpath.VMStackWalker", 
"(Lgnu/gcj/RawData;)Ljava/lang/ClassLoader;",
     ACC_FINAL|ACC_PRIVATE|ACC_STATIC, rewrite_arglist_getcaller},

-   {NULL, NULL, NULL, NULL, 0, NULL}};
+   {"gnu.java.lang.VMCPStringBuilder", "toString", "([CII)Ljava/lang/String;",
+    "java.lang.String", "([CII)Ljava/lang/String;",
+    ACC_FINAL|ACC_PRIVATE|ACC_STATIC, NULL},
+
+   {NULL, NULL, NULL, NULL, NULL, 0, NULL}};

 /* True if this method is special, i.e. it's a private method that
    should be exported from a DSO.  */
@@ -2163,20 +2171,25 @@
          if (get_identifier (p->method) == method
              && get_identifier (p->signature) == *method_signature_p)
            {
-             tree maybe_method
-               = lookup_java_method (DECL_CONTEXT (*method_p),
+             tree maybe_method;
+             tree destination_class
+               = lookup_class (get_identifier (p->new_classname));
+             gcc_assert (destination_class);
+             maybe_method
+               = lookup_java_method (destination_class,
                                      method,
                                      get_identifier (p->new_signature));
              if (! maybe_method && ! flag_verify_invocations)
                {
                  maybe_method
-                   = add_method (DECL_CONTEXT (*method_p), p->flags,
+                   = add_method (destination_class, p->flags,
                                  method, get_identifier (p->new_signature));
                  DECL_EXTERNAL (maybe_method) = 1;
                }
              *method_p = maybe_method;
              gcc_assert (*method_p);
-             *arg_list_p = p->rewrite_arglist (*arg_list_p);
+             if (p->rewrite_arglist)
+               *arg_list_p = p->rewrite_arglist (*arg_list_p);
              *method_signature_p = get_identifier (p->new_signature);
              *special = integer_one_node;

Reply via email to