On Wed, Apr 11, 2012 at 12:22 PM, Andrew Haley <a...@redhat.com> wrote: > 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.
This breaks bootstrap for me: In file included from /space/rguenther/src/svn/trunk/gcc/java/jcf-parse.c:1009:0: /space/rguenther/src/svn/trunk/gcc/java/jcf-reader.c:550:1: error: 'int jcf_parse_bootstrap_methods(JCF*, int)' defined but not used [-Werror=unused-function] jcf_parse_bootstrap_methods (JCF* jcf, int attribute_length ATTRIBUTE_UNUSED) ^ cc1plus: all warnings being treated as errors make[3]: *** [java/jcf-parse.o] Error 1 make[3]: *** Waiting for unfinished jobs.... > Andrew. > > > 2012-04-11 Andrew Haley <a...@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; > }