Commit cca4dd59 by Andrew Haley Committed by Andrew Haley

jcf.h (bootstrap_method): New.

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
parent ada37101
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> 2012-04-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* class.c (emit_register_classes_in_jcr_section): Set DECL_USER_ALIGN. * class.c (emit_register_classes_in_jcr_section): Set DECL_USER_ALIGN.
......
...@@ -292,6 +292,7 @@ JAVAOP (invokevirtual, 182, INVOKE, VIRTUAL,0) ...@@ -292,6 +292,7 @@ JAVAOP (invokevirtual, 182, INVOKE, VIRTUAL,0)
JAVAOP (invokespecial, 183, INVOKE, SPECIAL, 0) JAVAOP (invokespecial, 183, INVOKE, SPECIAL, 0)
JAVAOP (invokestatic, 184, INVOKE, STATIC, 0) JAVAOP (invokestatic, 184, INVOKE, STATIC, 0)
JAVAOP (invokeinterface,185, INVOKE, INTERFACE, 1) JAVAOP (invokeinterface,185, INVOKE, INTERFACE, 1)
JAVAOP (invokedynamic, 186, INVOKE, DYNAMIC, 1)
JAVAOP (new, 187, OBJECT, PTR, NEW) JAVAOP (new, 187, OBJECT, PTR, NEW)
JAVAOP (newarray, 188, ARRAY, NUM, NEW) JAVAOP (newarray, 188, ARRAY, NUM, NEW)
JAVAOP (anewarray, 189, ARRAY, PTR, NEW) JAVAOP (anewarray, 189, ARRAY, PTR, NEW)
......
...@@ -430,6 +430,23 @@ utf8_equal_string (JCF *jcf, int index, const char * value) ...@@ -430,6 +430,23 @@ utf8_equal_string (JCF *jcf, int index, const char * value)
print_element_value (out, jcf, 1); \ 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) \ #define PROCESS_OTHER_ATTRIBUTE(JCF, INDEX, LENGTH) \
{ COMMON_HANDLE_ATTRIBUTE(JCF, INDEX, LENGTH); \ { COMMON_HANDLE_ATTRIBUTE(JCF, INDEX, LENGTH); \
...@@ -898,6 +915,53 @@ print_constant (FILE *out, JCF *jcf, int index, int verbosity) ...@@ -898,6 +915,53 @@ print_constant (FILE *out, JCF *jcf, int index, int verbosity)
fputc ('\"', out); fputc ('\"', out);
} }
break; 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: default:
fprintf (out, "(Unknown constant type %d)", kind); fprintf (out, "(Unknown constant type %d)", kind);
} }
......
...@@ -518,6 +518,26 @@ verify_constant_pool (JCF *jcf) ...@@ -518,6 +518,26 @@ verify_constant_pool (JCF *jcf)
case CONSTANT_Utf8: case CONSTANT_Utf8:
case CONSTANT_Unicode: case CONSTANT_Unicode:
break; 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: default:
return i; return i;
} }
......
...@@ -1113,8 +1113,8 @@ get_constant (JCF *jcf, int index) ...@@ -1113,8 +1113,8 @@ get_constant (JCF *jcf, int index)
jcf->cpool.data[index].t = value; jcf->cpool.data[index].t = value;
return value; return value;
bad: bad:
internal_error ("bad value constant type %d, index %d", fatal_error ("bad value constant type %d, index %d",
JPOOL_TAG (jcf, index), index); JPOOL_TAG (jcf, index), index);
} }
tree tree
......
...@@ -36,6 +36,7 @@ static int jcf_parse_fields (JCF *); ...@@ -36,6 +36,7 @@ static int jcf_parse_fields (JCF *);
static int jcf_parse_one_method (JCF *, int); static int jcf_parse_one_method (JCF *, int);
static int jcf_parse_methods (JCF *); static int jcf_parse_methods (JCF *);
static int jcf_parse_final_attributes (JCF *); static int jcf_parse_final_attributes (JCF *);
static int jcf_parse_bootstrap_methods (JCF *, int );
#ifdef NEED_PEEK_ATTRIBUTE #ifdef NEED_PEEK_ATTRIBUTE
static int peek_attribute (JCF *, int, const char *, int); static int peek_attribute (JCF *, int, const char *, int);
#endif #endif
...@@ -293,6 +294,15 @@ get_attribute (JCF *jcf, int index, ...@@ -293,6 +294,15 @@ get_attribute (JCF *jcf, int index,
} }
else else
#endif #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 #ifdef PROCESS_OTHER_ATTRIBUTE
PROCESS_OTHER_ATTRIBUTE(jcf, attribute_name, attribute_length); PROCESS_OTHER_ATTRIBUTE(jcf, attribute_name, attribute_length);
...@@ -382,6 +392,17 @@ jcf_parse_constant_pool (JCF* jcf) ...@@ -382,6 +392,17 @@ jcf_parse_constant_pool (JCF* jcf)
JCF_SKIP (jcf, n); JCF_SKIP (jcf, n);
#endif #endif
break; 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: default:
return i; return i;
} }
...@@ -521,3 +542,39 @@ jcf_parse_final_attributes (JCF *jcf) ...@@ -521,3 +542,39 @@ jcf_parse_final_attributes (JCF *jcf)
return 0; 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;
}
...@@ -88,6 +88,17 @@ typedef struct GTY(()) CPool { ...@@ -88,6 +88,17 @@ typedef struct GTY(()) CPool {
desc ("cpool_entry_is_tree (%1.tags%a)"))) data; desc ("cpool_entry_is_tree (%1.tags%a)"))) data;
} CPool; } 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; struct ZipDirectory;
/* JCF encapsulates the state of reading a Java Class File. */ /* JCF encapsulates the state of reading a Java Class File. */
...@@ -109,6 +120,7 @@ typedef struct GTY(()) JCF { ...@@ -109,6 +120,7 @@ typedef struct GTY(()) JCF {
JCF_u2 this_class; JCF_u2 this_class;
JCF_u2 super_class; JCF_u2 super_class;
CPool cpool; CPool cpool;
BootstrapMethods bootstrap_methods;
} JCF; } JCF;
/*typedef JCF* JCF_FILE;*/ /*typedef JCF* JCF_FILE;*/
...@@ -245,6 +257,10 @@ enum cpool_tag ...@@ -245,6 +257,10 @@ enum cpool_tag
CONSTANT_NameAndType = 12, CONSTANT_NameAndType = 12,
CONSTANT_Utf8 = 1, CONSTANT_Utf8 = 1,
CONSTANT_Unicode = 2, CONSTANT_Unicode = 2,
CONSTANT_MethodHandle = 15,
CONSTANT_MethodType = 16,
CONSTANT_InvokeDynamic = 18,
CONSTANT_None = 0 CONSTANT_None = 0
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment