This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

jcf-reader: support for JSR 292 classfile extensions


This adds support for the new (Version 51.0) class file format.  It
doesn't actually generate code for invokedynamic bcause we don't have
any runtime support yet, but it's a start.  jcf-dump prints all of the
new attributes.

Andrew.


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.

Index: java/jcf-dump.c
===================================================================
--- java/jcf-dump.c	(revision 186103)
+++ java/jcf-dump.c	(working copy)
@@ -430,7 +430,24 @@
   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); \
   fputc ('\n', out); JCF_SKIP (JCF, LENGTH); }
@@ -898,6 +915,53 @@
 	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: java/jcf-parse.c
===================================================================
--- java/jcf-parse.c	(revision 186103)
+++ java/jcf-parse.c	(working copy)
@@ -1113,8 +1113,8 @@
   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: java/javaop.def
===================================================================
--- java/javaop.def	(revision 186103)
+++ java/javaop.def	(working copy)
@@ -292,6 +292,7 @@
 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: java/jcf-reader.c
===================================================================
--- java/jcf-reader.c	(revision 186103)
+++ java/jcf-reader.c	(working copy)
@@ -36,6 +36,7 @@
 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,7 +294,16 @@
     }
   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);
 #else
@@ -382,6 +392,17 @@
 	  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 @@
   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: java/jcf.h
===================================================================
--- java/jcf.h	(revision 186103)
+++ java/jcf.h	(working copy)
@@ -88,6 +88,17 @@
 			   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 @@
   JCF_u2 this_class;
   JCF_u2 super_class;
   CPool cpool;
+  BootstrapMethods bootstrap_methods;
 } JCF;
 /*typedef JCF*  JCF_FILE;*/

@@ -245,6 +257,10 @@
   CONSTANT_NameAndType = 12,
   CONSTANT_Utf8 = 1,
   CONSTANT_Unicode = 2,
+  CONSTANT_MethodHandle = 15,
+  CONSTANT_MethodType = 16,
+  CONSTANT_InvokeDynamic = 18,
+
   CONSTANT_None = 0
 };

Index: java/jcf-io.c
===================================================================
--- java/jcf-io.c	(revision 186103)
+++ java/jcf-io.c	(working copy)
@@ -518,6 +518,26 @@
 	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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]