jcf.h (bootstrap_method): New.
authorAndrew Haley <aph@redhat.com>
Wed, 11 Apr 2012 10:47:43 +0000 (10:47 +0000)
committerAndrew Haley <aph@gcc.gnu.org>
Wed, 11 Apr 2012 10:47:43 +0000 (10:47 +0000)
2012-04-11  Andrew Haley  <aph@redhat.com>

* jcf.h (bootstrap_method): New.
(BootstrapMethods): New.
(JCF): Add BootstrapMethods.
(enum cpool_tag): Add MethodHandle, MethodType, and InvokeDynamic.
* jcf-reader.c (jcf_parse_bootstrap_methods): New.
(jcf_parse_constant_pool): Handlers for MethodHandle, MethodType,
and InvokeDynamic.
(jcf_parse_bootstrap_methods): New.
* javaop.def (invokedynamic): New opcode.
* jcf-parse.c (get_constant): An unknown constant type should not
be an internal error, but a fatal one.  Make it so.
* jcf-dump.c (HANDLE_BOOTSTRAP_METHODS_ATTRIBUTE): New.
(HANDLE_END_BOOTSTRAP_METHODS): New.
(print_constant): Handlers for MethodHandle, MethodType, and
InvokeDynamic.

From-SVN: r186307

gcc/java/ChangeLog
gcc/java/javaop.def
gcc/java/jcf-dump.c
gcc/java/jcf-io.c
gcc/java/jcf-parse.c
gcc/java/jcf-reader.c
gcc/java/jcf.h

index 3e6cb4d9dc9e9d09c2ffe49876df87db5407d0a6..49db1cb7bfb73b8c9152494f9ac252d4125ddfa1 100644 (file)
@@ -1,3 +1,21 @@
+2012-04-11  Andrew Haley  <aph@redhat.com>
+
+       * jcf.h (bootstrap_method): New.
+       (BootstrapMethods): New.
+       (JCF): Add BootstrapMethods.
+       (enum cpool_tag): Add MethodHandle, MethodType, and InvokeDynamic.
+       * jcf-reader.c (jcf_parse_bootstrap_methods): New.
+       (jcf_parse_constant_pool): Handlers for MethodHandle, MethodType,
+       and InvokeDynamic.
+       (jcf_parse_bootstrap_methods): New.
+       * javaop.def (invokedynamic): New opcode.
+       * jcf-parse.c (get_constant): An unknown constant type should not
+       be an internal error, but a fatal one.  Make it so.
+       * jcf-dump.c (HANDLE_BOOTSTRAP_METHODS_ATTRIBUTE): New.
+       (HANDLE_END_BOOTSTRAP_METHODS): New.
+       (print_constant): Handlers for MethodHandle, MethodType, and
+       InvokeDynamic.
+
 2012-04-02  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * class.c (emit_register_classes_in_jcr_section): Set DECL_USER_ALIGN.
index 653c77f72b8e583c8aa619e3d05a3d2887e46a47..6fe986d5d2d15dea0f3457bd8f7d87fafb9f9ceb 100644 (file)
@@ -292,6 +292,7 @@ JAVAOP (invokevirtual, 182, INVOKE,  VIRTUAL,0)
 JAVAOP (invokespecial, 183, INVOKE,  SPECIAL, 0)
 JAVAOP (invokestatic,  184, INVOKE,  STATIC, 0)
 JAVAOP (invokeinterface,185, INVOKE, INTERFACE, 1)
+JAVAOP (invokedynamic, 186, INVOKE,  DYNAMIC, 1)
 JAVAOP (new,           187, OBJECT,  PTR,    NEW)
 JAVAOP (newarray,      188, ARRAY,   NUM,    NEW)
 JAVAOP (anewarray,     189, ARRAY,   PTR,    NEW)
index 0c5878cc57969af18c76b478d1f2f2bfe538fa39..9173ea473cc52a02474b721648d8f44aa2b7c98c 100644 (file)
@@ -430,6 +430,23 @@ utf8_equal_string (JCF *jcf, int index, const char * value)
   print_element_value (out, jcf, 1);                                   \
 }
 
+#define HANDLE_BOOTSTRAP_METHODS_ATTRIBUTE()                           \
+{                                                                      \
+  COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length);      \
+  fputc ('\n', out); jcf_parse_bootstrap_methods (jcf, attribute_length); \
+}
+
+#define HANDLE_END_BOOTSTRAP_METHODS(NUM_METHODS)                      \
+  {                                                                    \
+    int i;                                                             \
+    for (i = 0; i < NUM_METHODS; i++)                                  \
+      {                                                                        \
+       bootstrap_method *m = &jcf->bootstrap_methods.methods[i];       \
+       fprintf (out, "  %d: ", i);                                     \
+       print_constant (out, jcf, m->method_ref, 1);                    \
+       fprintf (out, "\n");                                            \
+      }                                                                        \
+  }
 
 #define PROCESS_OTHER_ATTRIBUTE(JCF, INDEX, LENGTH) \
 { COMMON_HANDLE_ATTRIBUTE(JCF, INDEX, LENGTH); \
@@ -898,6 +915,53 @@ print_constant (FILE *out, JCF *jcf, int index, int verbosity)
        fputc ('\"', out);
       }
       break;
+    case CONSTANT_MethodHandle:
+      {
+       int kind = JPOOL_USHORT1 (jcf, index);
+       if (verbosity > 0)
+         fprintf (out, "MethodHandle kind: %d=", kind);
+       switch(kind) {
+       case 1:
+       case 2:
+       case 3:
+       case 4:
+         if (verbosity > 0)
+           fprintf (out, "Fieldref: %ld=", JPOOL_USHORT2 (jcf, index));
+         print_constant (out, jcf, JPOOL_USHORT2 (jcf, index), 0);
+       case 5:
+       case 6:
+       case 7:
+       case 8:
+         if (verbosity > 0)
+           fprintf (out, "Methodref: %ld=", JPOOL_USHORT2 (jcf, index));
+         print_constant (out, jcf, JPOOL_USHORT2 (jcf, index), 0);
+         break;
+       case 9:
+         if (verbosity > 0)
+           fprintf (out, "InterfaceMethodref: %ld=", JPOOL_USHORT2 (jcf, index));
+         print_constant (out, jcf, JPOOL_USHORT2 (jcf, index), 0);
+         break;
+       }
+       break;
+      }
+    case CONSTANT_MethodType:
+      if (verbosity > 0)
+       fprintf (out, "MethodType %ld: ", JPOOL_USHORT1 (jcf, index));
+      print_signature (out, jcf, JPOOL_USHORT1 (jcf, index), 0);
+      break;
+    case CONSTANT_InvokeDynamic:
+      {
+       uint16 name_and_type = JPOOL_USHORT2 (jcf, index);
+       if (verbosity > 0)
+         fprintf (out, "InvokeDynamic: ");
+       fprintf (out, "bootstrap_method: %ld ", JPOOL_USHORT1 (jcf, index));
+       if (verbosity == 2)
+         fprintf (out, " name_and_type: %d=<", name_and_type);
+       print_constant_terse (out, jcf, name_and_type, CONSTANT_NameAndType);
+       if (verbosity == 2)
+         fputc ('>', out);
+       break;
+      }
     default:
       fprintf (out, "(Unknown constant type %d)", kind);
     }
index 0dc761534c6132b6f068fa46075475349c03d6cc..c50ec49ccc5997732277d29de97ed933b2c3fac2 100644 (file)
@@ -518,6 +518,26 @@ verify_constant_pool (JCF *jcf)
        case CONSTANT_Utf8:
        case CONSTANT_Unicode:
          break;
+       case CONSTANT_MethodHandle:
+         n = JPOOL_USHORT1 (jcf, i);
+         if (n < 1 || n > 9)
+           return i;
+         n = JPOOL_USHORT2 (jcf, i);
+         if (n <= 0 || n >= JPOOL_SIZE(jcf))
+           return i;
+         break;
+       case CONSTANT_MethodType:
+         n = JPOOL_USHORT1 (jcf, i);
+         if (n <= 0 || n >= JPOOL_SIZE(jcf)
+             || JPOOL_TAG (jcf, n) != CONSTANT_Utf8)
+           return i;
+         break;
+       case CONSTANT_InvokeDynamic:
+         n = JPOOL_USHORT2 (jcf, i);
+         if (n <= 0 || n >= JPOOL_SIZE(jcf)
+             || JPOOL_TAG (jcf, n) != CONSTANT_NameAndType)
+           return i;
+         break;
        default:
          return i;
        }
index 04c04f575cf618e64edf34ccbfde6e4893974e1d..c799676074e72ce641d721f1e923cdf983f4647a 100644 (file)
@@ -1113,8 +1113,8 @@ get_constant (JCF *jcf, int index)
   jcf->cpool.data[index].t = value;
   return value;
  bad:
-  internal_error ("bad value constant type %d, index %d", 
-                 JPOOL_TAG (jcf, index), index);
+  fatal_error ("bad value constant type %d, index %d", 
+              JPOOL_TAG (jcf, index), index);
 }
 
 tree
index 315bd411a525160bf5929a8acf3c798dc5e4d71b..c47436a5b0f7d72306e330638b30429d284b53f9 100644 (file)
@@ -36,6 +36,7 @@ static int jcf_parse_fields (JCF *);
 static int jcf_parse_one_method (JCF *, int);
 static int jcf_parse_methods (JCF *);
 static int jcf_parse_final_attributes (JCF *);
+static int jcf_parse_bootstrap_methods (JCF *, int );
 #ifdef NEED_PEEK_ATTRIBUTE
 static int peek_attribute (JCF *, int, const char *, int);
 #endif
@@ -293,6 +294,15 @@ get_attribute (JCF *jcf, int index,
     }
   else
 #endif
+  if (MATCH_ATTRIBUTE ("BootstrapMethods"))
+    {
+#ifdef HANDLE_BOOTSTRAP_METHODS_ATTRIBUTE
+      HANDLE_BOOTSTRAP_METHODS_ATTRIBUTE();
+#else
+      JCF_SKIP (jcf, attribute_length);
+#endif
+    }
+   else
     {
 #ifdef PROCESS_OTHER_ATTRIBUTE
       PROCESS_OTHER_ATTRIBUTE(jcf, attribute_name, attribute_length);
@@ -382,6 +392,17 @@ jcf_parse_constant_pool (JCF* jcf)
          JCF_SKIP (jcf, n);
 #endif
          break;
+       case CONSTANT_MethodHandle:
+         jcf->cpool.data[i].w = JCF_readu (jcf);
+         jcf->cpool.data[i].w |= JCF_readu2 (jcf) << 16;
+         break;
+       case CONSTANT_MethodType:
+         jcf->cpool.data[i].w = JCF_readu2 (jcf);
+         break;
+       case CONSTANT_InvokeDynamic:
+         jcf->cpool.data[i].w = JCF_readu2 (jcf);
+         jcf->cpool.data[i].w |= JCF_readu2 (jcf) << 16;
+         break;
        default:
          return i;
        }
@@ -521,3 +542,39 @@ jcf_parse_final_attributes (JCF *jcf)
   return 0;
 }
 
+/* Read and handle the "BootstrapMethods" attribute.
+
+   Return 0 if OK.
+*/
+static int
+jcf_parse_bootstrap_methods (JCF* jcf, int attribute_length ATTRIBUTE_UNUSED)
+{
+  int i;
+  uint16 num_methods = JCF_readu2 (jcf);
+  jcf->bootstrap_methods.count = num_methods;
+  jcf->bootstrap_methods.methods
+    = (bootstrap_method *) ggc_alloc_atomic (num_methods
+                                             * sizeof (bootstrap_method));
+#ifdef HANDLE_START_BOOTSTRAP_METHODS
+  HANDLE_START_BOOTSTRAP_METHODS (jcf, num_methods);
+#endif
+
+  for (i = 0; i < num_methods; i++)
+    {
+      unsigned j;
+      bootstrap_method *m = &jcf->bootstrap_methods.methods[i];
+      m->method_ref = JCF_readu2 (jcf);
+      m->num_arguments = JCF_readu2 (jcf);
+      m->bootstrap_arguments
+       = (unsigned *) ggc_alloc_atomic (m->num_arguments
+                                        * sizeof (unsigned));
+      for (j = 0; j < m->num_arguments; j++)
+       m->bootstrap_arguments[j] = JCF_readu2 (jcf);
+    }
+
+#ifdef HANDLE_END_BOOTSTRAP_METHODS
+  HANDLE_END_BOOTSTRAP_METHODS (num_methods);
+#endif
+
+  return 0;
+}
index b066b2967c3791f7695d20f5b039fa0f917957d0..40b4ae2d27800084554d8bc8e063cccfa8d30872 100644 (file)
@@ -88,6 +88,17 @@ typedef struct GTY(()) CPool {
                           desc ("cpool_entry_is_tree (%1.tags%a)")))   data;
 } CPool;
 
+typedef struct GTY(()) bootstrap_method {
+  unsigned method_ref;
+  unsigned num_arguments;
+  unsigned* GTY((length ("%h.num_arguments"))) bootstrap_arguments;
+} bootstrap_method;
+
+typedef struct GTY(()) BootstrapMethods {
+  unsigned count;
+  bootstrap_method* GTY((length ("%h.count"))) methods;
+} BootstrapMethods;
+
 struct ZipDirectory;
 
 /* JCF encapsulates the state of reading a Java Class File. */
@@ -109,6 +120,7 @@ typedef struct GTY(()) JCF {
   JCF_u2 this_class;
   JCF_u2 super_class;
   CPool cpool;
+  BootstrapMethods bootstrap_methods;
 } JCF;
 /*typedef JCF*  JCF_FILE;*/
 
@@ -245,6 +257,10 @@ enum cpool_tag
   CONSTANT_NameAndType = 12,
   CONSTANT_Utf8 = 1,
   CONSTANT_Unicode = 2,
+  CONSTANT_MethodHandle = 15,
+  CONSTANT_MethodType = 16,
+  CONSTANT_InvokeDynamic = 18,
+
   CONSTANT_None = 0
 };