static void print_parameter_annotations (FILE *stream, JCF *jcf, int level) { uint8 nparams = JCF_readu (jcf); uint8 i; for (i = 0; i < nparams; ++i) { indent (stream, level); fprintf (stream, "Parameter annotations (%d):\n", (int) i); print_annotations (stream, jcf, level + 1); } }
/* Read and handle the constant pool. Return 0 if OK. Return -2 if a bad cross-reference (index of other constant) was seen. */ static int jcf_parse_constant_pool (JCF* jcf) { int i, n; JPOOL_SIZE (jcf) = (JCF_FILL (jcf, 2), JCF_readu2 (jcf)); jcf->cpool.tags = (uint8 *) ggc_alloc_atomic (JPOOL_SIZE (jcf)); jcf->cpool.data = ggc_alloc_cpool_entry (sizeof (jword) * JPOOL_SIZE (jcf)); jcf->cpool.tags[0] = 0; #ifdef HANDLE_START_CONSTANT_POOL HANDLE_START_CONSTANT_POOL (JPOOL_SIZE (jcf)); #endif for (i = 1; i < (int) JPOOL_SIZE (jcf); i++) { int constant_kind; /* Make sure at least 9 bytes are available. This is enough for all fixed-sized constant pool entries (so we don't need many more JCF_FILL calls below), but is is small enough that we are guaranteed to not hit EOF (in a valid .class file). */ JCF_FILL (jcf, 9); constant_kind = JCF_readu (jcf); jcf->cpool.tags[i] = constant_kind; switch (constant_kind) { case CONSTANT_String: case CONSTANT_Class: jcf->cpool.data[i].w = JCF_readu2 (jcf); break; case CONSTANT_Fieldref: case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref: case CONSTANT_NameAndType: jcf->cpool.data[i].w = JCF_readu2 (jcf); jcf->cpool.data[i].w |= JCF_readu2 (jcf) << 16; break; case CONSTANT_Integer: case CONSTANT_Float: jcf->cpool.data[i].w = JCF_readu4 (jcf); break; case CONSTANT_Long: case CONSTANT_Double: jcf->cpool.data[i].w = JCF_readu4 (jcf); i++; /* These take up two spots in the constant pool */ jcf->cpool.tags[i] = 0; jcf->cpool.data[i].w = JCF_readu4 (jcf); break; case CONSTANT_Utf8: n = JCF_readu2 (jcf); JCF_FILL (jcf, n); #ifdef HANDLE_CONSTANT_Utf8 HANDLE_CONSTANT_Utf8(jcf, i, n); #else jcf->cpool.data[i].w = JCF_TELL(jcf) - 2; 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; } } return 0; }
static void print_element_value (FILE *stream, JCF *jcf, int level) { uint8 tag = JCF_readu (jcf); indent (stream, level); switch (tag) { case 'B': case 'C': case 'S': case 'Z': case 'I': { uint16 cindex = JCF_readu2 (jcf); print_constant_terse_with_index (stream, jcf, cindex, CONSTANT_Integer); } break; case 'D': { uint16 cindex = JCF_readu2 (jcf); print_constant_terse_with_index (stream, jcf, cindex, CONSTANT_Double); } break; case 'F': { uint16 cindex = JCF_readu2 (jcf); print_constant_terse_with_index (stream, jcf, cindex, CONSTANT_Float); } break; case 'J': { uint16 cindex = JCF_readu2 (jcf); print_constant_terse_with_index (stream, jcf, cindex, CONSTANT_Long); } break; case 's': { uint16 cindex = JCF_readu2 (jcf); /* Despite what the JVM spec says, compilers generate a Utf8 constant here, not a String. */ print_constant_terse_with_index (stream, jcf, cindex, CONSTANT_Utf8); } break; case 'e': { uint16 type_name_index = JCF_readu2 (jcf); uint16 const_name_index = JCF_readu2 (jcf); fprintf (stream, "enum class: "); print_constant_terse_with_index (stream, jcf, type_name_index, CONSTANT_Utf8); fprintf (stream, "\n"); indent (stream, level); fprintf (stream, "Field: "); print_constant_terse_with_index (stream, jcf, const_name_index, CONSTANT_Utf8); } break; case 'c': { uint16 class_info_index = JCF_readu2 (jcf); print_constant_terse_with_index (stream, jcf, class_info_index, CONSTANT_Utf8); } break; case '@': { fprintf (stream, "Annotation:\n"); print_annotation (stream, jcf, level + 1); } break; case '[': { uint16 n_array_elts = JCF_readu2 (jcf); fprintf (stream, "array[%d]: [\n", (int) n_array_elts); while (n_array_elts--) print_element_value (stream, jcf, level + 1); indent (stream, level); fprintf (stream, "]"); } break; default: fprintf (stream, "Unexpected tag value: %d", (int) tag); break; } fputc ('\n', stream); }