summaryrefslogtreecommitdiff
path: root/gcc/java/jcf-reader.c
diff options
context:
space:
mode:
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2012-04-11 10:47:43 +0000
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2012-04-11 10:47:43 +0000
commit39101666a2b9ca7c4c35cada9be85a4ebe12e0b4 (patch)
tree22431b761201f7586d181a8501e813148ae881b4 /gcc/java/jcf-reader.c
parent669b0b523ebfe2537057b3111917d6c776df9a43 (diff)
downloadgcc-39101666a2b9ca7c4c35cada9be85a4ebe12e0b4.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186307 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java/jcf-reader.c')
-rw-r--r--gcc/java/jcf-reader.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/gcc/java/jcf-reader.c b/gcc/java/jcf-reader.c
index 315bd411a52..c47436a5b0f 100644
--- a/gcc/java/jcf-reader.c
+++ b/gcc/java/jcf-reader.c
@@ -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;
+}