PR c++/16115
[official-gcc.git] / gcc / java / jcf-dump.c
blob3d5f0c513d9896b031e611697bdb2d11625b29dd
1 /* Program to dump out a Java(TM) .class file.
2 Functionally similar to Sun's javap.
4 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
5 Free Software Foundation, Inc.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.
24 Java and all Java-based marks are trademarks or registered trademarks
25 of Sun Microsystems, Inc. in the United States and other countries.
26 The Free Software Foundation is independent of Sun Microsystems, Inc. */
28 /* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
31 jcf-dump is a program to print out the contents of class files.
32 Usage: jcf-dump [FLAGS] CLASS
33 Each CLASS is either:
34 + the name of a class in the CLASSPATH (e.g "java.lang.String"), or
35 + the name of a class *file* (e.g. "/home/me/work/package/Foo.class").
36 + The name of a .zip or .jar file (which prints all the classes in the
37 archive).
39 OPTIONS:
41 Dis-assemble each method.
42 -classpath PATH
43 Overrides $CLASSPATH.
44 --print-main
45 Print nothing if there is no valid "main" method;
46 otherwise, print only the class name.
47 --javap
48 Print output in the style of Sun's javap program. VERY UNFINISHED.
52 #include "config.h"
53 #include "system.h"
54 #include "coretypes.h"
55 #include "tm.h"
56 #include "ggc.h"
57 #include "intl.h"
59 #include "jcf.h"
60 #include "tree.h"
61 #include "java-tree.h"
63 #include "version.h"
65 #include <getopt.h>
66 #include <math.h>
68 /* Outout file. */
69 FILE *out;
70 /* Name of output file, if NULL if stdout. */
71 char *output_file = NULL;
73 int verbose = 0;
75 int flag_disassemble_methods = 0;
76 int flag_print_class_info = 1;
77 int flag_print_constant_pool = 0;
78 int flag_print_fields = 1;
79 int flag_print_methods = 1;
80 int flag_print_attributes = 1;
82 /* When nonzero, warn when source file is newer than matching class
83 file. */
84 int flag_newer = 1;
86 /* Print names of classes that have a "main" method. */
87 int flag_print_main = 0;
89 /* Index in constant pool of this class. */
90 int this_class_index = 0;
92 int class_access_flags = 0;
94 /* Print in format similar to javap. VERY IMCOMPLETE. */
95 int flag_javap_compatible = 0;
97 static void print_access_flags (FILE *, uint16, char);
98 static void print_constant_terse (FILE*, JCF*, int, int);
99 static void print_constant (FILE *, JCF *, int, int);
100 static void print_constant_ref (FILE *, JCF *, int);
101 static void disassemble_method (JCF*, const unsigned char *, int);
102 static void print_name (FILE*, JCF*, int);
103 static void print_signature (FILE*, JCF*, int, int);
104 static int utf8_equal_string (struct JCF*, int, const char *);
105 static void usage (void) ATTRIBUTE_NORETURN;
106 static void help (void) ATTRIBUTE_NORETURN;
107 static void version (void) ATTRIBUTE_NORETURN;
108 static void process_class (struct JCF *);
109 static void print_constant_pool (struct JCF *);
110 static void print_exception_table (struct JCF *, const unsigned char *entries,
111 int);
113 #define PRINT_SIGNATURE_RESULT_ONLY 1
114 #define PRINT_SIGNATURE_ARGS_ONLY 2
116 static int
117 utf8_equal_string (JCF *jcf, int index, const char * value)
119 if (CPOOL_INDEX_IN_RANGE (&jcf->cpool, index)
120 && JPOOL_TAG (jcf, index) == CONSTANT_Utf8)
122 int len = strlen (value);
123 if (JPOOL_UTF_LENGTH (jcf, index) == len
124 && memcmp (JPOOL_UTF_DATA (jcf, index), value, len) == 0)
125 return 1;
127 return 0;
130 #define HANDLE_MAGIC(MAGIC, MINOR, MAJOR) \
131 this_class_index = 0; \
132 if (flag_print_class_info) \
133 fprintf (out, \
134 "Magic number: 0x%0lx, minor_version: %ld, major_version: %ld.\n",\
135 (long) MAGIC, (long) MINOR, (long) MAJOR)
137 #define HANDLE_START_CONSTANT_POOL(COUNT) \
138 if (flag_print_constant_pool) \
139 fprintf (out, "\nConstant pool (count: %d):\n", COUNT)
141 #define HANDLE_SOURCEFILE(INDEX) \
142 { fprintf (out, "Attribute "); \
143 print_constant_terse (out, jcf, attribute_name, CONSTANT_Utf8); \
144 fprintf (out, ", length:%ld, #%d=", (long) attribute_length, INDEX); \
145 print_constant_terse (out, jcf, INDEX, CONSTANT_Utf8); fputc ('\n', out); }
147 #define HANDLE_CLASS_INFO(ACCESS_FLAGS, THIS, SUPER, INTERFACES_COUNT) \
148 this_class_index = THIS; \
149 class_access_flags = ACCESS_FLAGS; \
150 if (flag_print_class_info) \
151 { fprintf (out, "\nAccess flags: 0x%x", ACCESS_FLAGS); \
152 print_access_flags (out, ACCESS_FLAGS, 'c'); \
153 fputc ('\n', out); \
154 fprintf (out, "This class: "); \
155 print_constant_terse_with_index (out, jcf, THIS, CONSTANT_Class); \
156 if (flag_print_constant_pool || SUPER != 0) \
157 fprintf (out, ", super: "); \
158 if (flag_print_constant_pool) \
160 fprintf (out, "%d", SUPER); \
161 if (SUPER != 0) \
162 fputc ('=', out); \
164 if (SUPER != 0) \
165 print_constant_terse (out, jcf, SUPER, CONSTANT_Class); \
166 fprintf (out, "\nInterfaces (count: %d):\n", INTERFACES_COUNT); \
169 #define IGNORE_ATTRIBUTE(JCF, NAME, NAME_LENGTH) \
170 (flag_print_attributes <= 0)
172 #define HANDLE_CLASS_INTERFACE(INDEX) \
173 if (flag_print_class_info) \
174 { fprintf (out, "- Implements: "); \
175 print_constant_terse_with_index (out, jcf, INDEX, CONSTANT_Class); \
176 fputc ('\n', out); }
178 #define HANDLE_START_FIELDS(FIELDS_COUNT) \
179 if (flag_print_fields) \
180 fprintf (out, "\nFields (count: %d):\n", FIELDS_COUNT)
182 #define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
183 if (flag_print_fields) \
184 { fprintf (out, "Field name:"); \
185 print_constant_terse (out, jcf, NAME, CONSTANT_Utf8); \
186 print_access_flags (out, ACCESS_FLAGS, 'f'); \
187 fprintf (out, " Signature: "); \
188 if (flag_print_constant_pool) \
189 fprintf (out, "%d=", SIGNATURE); \
190 print_signature (out, jcf, SIGNATURE, 0); \
191 fputc ('\n', out); } \
192 else \
193 flag_print_attributes--;
195 #define HANDLE_END_FIELD() \
196 if (! flag_print_fields) \
197 flag_print_attributes++;
199 #define HANDLE_START_METHODS(METHODS_COUNT) \
200 if (flag_print_methods) \
201 fprintf (out, "\nMethods (count: %d):\n", METHODS_COUNT); \
202 else \
203 flag_print_attributes--;
206 #define HANDLE_END_METHODS() \
207 if (! flag_print_methods) \
208 flag_print_attributes++;
210 #define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
212 if (flag_print_methods) \
214 if (flag_javap_compatible) \
216 fprintf (out, " "); \
217 print_access_flags (out, ACCESS_FLAGS, 'm'); \
218 fputc (' ', out); \
219 print_signature (out, jcf, SIGNATURE, PRINT_SIGNATURE_RESULT_ONLY); \
220 fputc (' ', out); \
221 print_constant_terse (out, jcf, NAME, CONSTANT_Utf8); \
222 print_signature (out, jcf, SIGNATURE, PRINT_SIGNATURE_ARGS_ONLY); \
223 fputc ('\n', out); \
225 else \
227 fprintf (out, "\nMethod name:"); \
228 print_constant_terse (out, jcf, NAME, CONSTANT_Utf8); \
229 print_access_flags (out, ACCESS_FLAGS, 'm'); \
230 fprintf (out, " Signature: "); \
231 if (flag_print_constant_pool) \
232 fprintf (out, "%d=", SIGNATURE); \
233 print_signature (out, jcf, SIGNATURE, 0); \
234 fputc ('\n', out); \
237 if (flag_print_main && ACCESS_FLAGS == (ACC_STATIC|ACC_PUBLIC) \
238 && utf8_equal_string (jcf, NAME, "main") \
239 && utf8_equal_string (jcf, SIGNATURE, "([Ljava/lang/String;)V") \
240 && this_class_index > 0 \
241 && (class_access_flags & ACC_PUBLIC)) \
243 print_constant_terse(out, jcf, this_class_index, CONSTANT_Class); \
244 fputc ('\n', out); \
248 #define COMMON_HANDLE_ATTRIBUTE(JCF, INDEX, LENGTH) \
249 ( fprintf (out, "Attribute "), \
250 print_constant_terse (out, jcf, INDEX, CONSTANT_Utf8), \
251 fprintf (out, ", length:%ld", (long) LENGTH) )
253 #define HANDLE_CONSTANTVALUE(VALUE_INDEX) \
254 ( COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length), \
255 fprintf (out, ", value: "), \
256 print_constant_ref (out, jcf, VALUE_INDEX), \
257 fprintf (out, "\n") )
259 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
260 { COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length); \
261 fprintf (out, ", max_stack:%ld, max_locals:%ld, code_length:%ld\n", \
262 (long) MAX_STACK, (long) MAX_LOCALS, (long) CODE_LENGTH); \
263 disassemble_method (jcf, jcf->read_ptr, CODE_LENGTH); }
265 #define HANDLE_EXCEPTION_TABLE(ENTRIES, COUNT) \
266 print_exception_table (jcf, ENTRIES, COUNT)
268 #define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
269 { int n = (COUNT); int i; \
270 COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length); \
271 fprintf (out, ", count: %d\n", n); \
272 for (i = 0; i < n; i++) {\
273 int ex_index = JCF_readu2 (jcf); \
274 fprintf (out, "%3d: ", i); \
275 print_constant_ref (out, jcf, ex_index); \
276 fputc ('\n', out); } }
278 #define HANDLE_LOCALVARIABLETABLE_ATTRIBUTE(COUNT) \
279 { int n = (COUNT); int i; \
280 COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length); \
281 fprintf (out, ", count: %d\n", n); \
282 for (i = 0; i < n; i++) {\
283 int start_pc = JCF_readu2 (jcf); \
284 int length = JCF_readu2 (jcf); \
285 int name_index = JCF_readu2 (jcf); \
286 int signature_index = JCF_readu2 (jcf); \
287 int slot = JCF_readu2 (jcf); \
288 fprintf (out, " slot#%d: name: ", slot); \
289 if (flag_print_constant_pool) \
290 fprintf (out, "%d=", name_index); \
291 print_name (out, jcf, name_index); \
292 fprintf (out, ", type: "); \
293 if (flag_print_constant_pool) \
294 fprintf (out, "%d=", signature_index); \
295 print_signature (out, jcf, signature_index, 0); \
296 fprintf (out, " (pc: %d length: %d)\n", start_pc, length); }}
298 #define HANDLE_LINENUMBERTABLE_ATTRIBUTE(COUNT) \
299 { int n = (COUNT); int i; \
300 COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length); \
301 fprintf (out, ", count: %d\n", n); \
302 if (flag_disassemble_methods) \
303 for (i = 0; i < n; i++) {\
304 int start_pc = JCF_readu2 (jcf); \
305 int line_number = JCF_readu2 (jcf); \
306 fprintf (out, " line: %d at pc: %d\n", line_number, start_pc); }\
307 else \
308 JCF_SKIP (jcf, 4 * n); }
310 #define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \
311 { int n = (COUNT); \
312 COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length); \
313 while (n--) \
315 uint16 inner_class_info_index = JCF_readu2 (jcf); \
316 uint16 outer_class_info_index = JCF_readu2 (jcf); \
317 uint16 inner_name_index = JCF_readu2 (jcf); \
318 uint16 inner_class_access_flags = JCF_readu2 (jcf); \
320 if (flag_print_class_info) \
322 fprintf (out, "\n inner: "); \
323 print_constant_terse_with_index (out, jcf, \
324 inner_class_info_index, CONSTANT_Class); \
325 if (inner_name_index == 0) \
326 fprintf (out, " (anonymous)"); \
327 else if (verbose || flag_print_constant_pool) \
329 fprintf (out, " ("); \
330 print_constant_terse_with_index (out, jcf, inner_name_index, \
331 CONSTANT_Utf8); \
332 fputc (')', out); \
334 fprintf (out, ", access flags: 0x%x", inner_class_access_flags); \
335 print_access_flags (out, inner_class_access_flags, 'c'); \
336 fprintf (out, ", outer class: "); \
337 print_constant_terse_with_index (out, jcf, \
338 outer_class_info_index, CONSTANT_Class); \
341 if (flag_print_class_info) \
342 fputc ('\n', out); \
345 #define PROCESS_OTHER_ATTRIBUTE(JCF, INDEX, LENGTH) \
346 { COMMON_HANDLE_ATTRIBUTE(JCF, INDEX, LENGTH); \
347 fputc ('\n', out); JCF_SKIP (JCF, LENGTH); }
349 #define START_FINAL_ATTRIBUTES(ATTRIBUTES_COUNT) \
350 if (flag_print_attributes > 0) \
351 fprintf (out, "\nAttributes (count: %d):\n", attributes_count);
353 #include "javaop.h"
355 static void
356 print_constant_ref (FILE *stream, JCF *jcf, int index)
358 if (index <= 0 || index >= JPOOL_SIZE(jcf))
359 fprintf (stream, "<out of range>");
360 else
362 if (flag_print_constant_pool)
363 fprintf (stream, "#%d=", index);
364 fputc ('<', stream);
365 print_constant (stream, jcf, index, 1);
366 fputc ('>', stream);
370 /* Print the access flags given by FLAGS.
371 The CONTEXT is one of 'c' (class flags), 'f' (field flags),
372 or 'm' (method flags). */
374 static void
375 print_access_flags (FILE *stream, uint16 flags, char context)
377 if (flags & ACC_PUBLIC) fprintf (stream, " public");
378 if (flags & ACC_PRIVATE) fprintf (stream, " private");
379 if (flags & ACC_PROTECTED) fprintf (stream, " protected");
380 if (flags & ACC_ABSTRACT) fprintf (stream, " abstract");
381 if (flags & ACC_STATIC) fprintf (stream, " static");
382 if (flags & ACC_FINAL) fprintf (stream, " final");
383 if (flags & ACC_TRANSIENT) fprintf (stream, " transient");
384 if (flags & ACC_VOLATILE) fprintf (stream, " volatile");
385 if (flags & ACC_NATIVE) fprintf (stream, " native");
386 if (flags & ACC_SYNCHRONIZED)
388 if (context == 'c')
389 fprintf (stream, " super");
390 else
391 fprintf (stream, " synchronized");
393 if (flags & ACC_INTERFACE) fprintf (stream, " interface");
394 if (flags & ACC_STRICT) fprintf (stream, " strictfp");
398 static void
399 print_name (FILE* stream, JCF* jcf, int name_index)
401 if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
402 fprintf (stream, "<not a UTF8 constant>");
403 else
404 jcf_print_utf8 (stream, JPOOL_UTF_DATA (jcf,name_index),
405 JPOOL_UTF_LENGTH (jcf, name_index));
408 /* If the type of the constant at INDEX matches EXPECTED,
409 print it tersely, otherwise more verbosely. */
411 static void
412 print_constant_terse (FILE *out, JCF *jcf, int index, int expected)
414 if (! CPOOL_INDEX_IN_RANGE (&jcf->cpool, index))
415 fprintf (out, "<constant pool index %d not in range>", index);
416 else if (JPOOL_TAG (jcf, index) != expected)
418 fprintf (out, "<Unexpected constant type ");
419 print_constant (out, jcf, index, 1);
420 fprintf (out, ">");
422 else
423 print_constant (out, jcf, index, 0);
426 static void
427 print_constant_terse_with_index (FILE *out, JCF *jcf, int index, int expected)
429 if (flag_print_constant_pool)
430 fprintf (out, "%d=", index);
431 print_constant_terse (out, jcf, index, expected);
434 /* Print the constant at INDEX in JCF's constant pool.
435 If verbosity==0, print very tersely (no extraneous text).
436 If verbosity==1, prefix the type of the constant.
437 If verbosity==2, add more descriptive text. */
439 static void
440 print_constant (FILE *out, JCF *jcf, int index, int verbosity)
442 int j, n;
443 jlong num;
444 const char *str;
445 int kind = JPOOL_TAG (jcf, index);
446 switch (kind)
448 case CONSTANT_Class:
449 n = JPOOL_USHORT1 (jcf, index);
450 if (verbosity > 0)
452 if (verbosity > 1)
453 fprintf (out, "Class name: %d=", n);
454 else
455 fprintf (out, "Class ");
457 if (! CPOOL_INDEX_IN_RANGE (&jcf->cpool, n))
458 fprintf (out, "<out of range>");
459 else if (verbosity < 2 && JPOOL_TAG (jcf, n) == CONSTANT_Utf8)
461 int len = JPOOL_UTF_LENGTH (jcf, n);
462 jcf_print_utf8_replace (out, JPOOL_UTF_DATA(jcf,n), len, '/', '.');
464 else
465 print_constant_terse (out, jcf, n, CONSTANT_Utf8);
466 break;
467 case CONSTANT_Fieldref:
468 str = "Field"; goto field_or_method;
469 case CONSTANT_Methodref:
470 str = "Method"; goto field_or_method;
471 case CONSTANT_InterfaceMethodref:
472 str = "InterfaceMethod"; goto field_or_method;
473 field_or_method:
475 uint16 tclass = JPOOL_USHORT1 (jcf, index);
476 uint16 name_and_type = JPOOL_USHORT2 (jcf, index);
477 if (verbosity == 2)
478 fprintf (out, "%sref class: %d=", str, tclass);
479 else if (verbosity > 0)
480 fprintf (out, "%s ", str);
481 print_constant_terse (out, jcf, tclass, CONSTANT_Class);
482 if (verbosity < 2)
483 fprintf (out, ".");
484 else
485 fprintf (out, " name_and_type: %d=<", name_and_type);
486 print_constant_terse (out, jcf, name_and_type, CONSTANT_NameAndType);
487 if (verbosity == 2)
488 fputc ('>', out);
490 break;
491 case CONSTANT_String:
492 j = JPOOL_USHORT1 (jcf, index);
493 if (verbosity > 0)
495 if (verbosity > 1)
496 fprintf (out, "String %d=", j);
497 else
498 fprintf (out, "String ");
500 print_constant_terse (out, jcf, j, CONSTANT_Utf8);
501 break;
502 case CONSTANT_Integer:
503 if (verbosity > 0)
504 fprintf (out, "Integer ");
505 num = JPOOL_INT (jcf, index);
506 goto integer;
507 case CONSTANT_Long:
508 if (verbosity > 0)
509 fprintf (out, "Long ");
510 num = JPOOL_LONG (jcf, index);
511 goto integer;
512 integer:
514 char buffer[25];
515 format_int (buffer, num, 10);
516 fprintf (out, "%s", buffer);
517 if (verbosity > 1)
519 format_uint (buffer, (uint64)num, 16);
520 fprintf (out, "=0x%s", buffer);
523 break;
524 case CONSTANT_Float:
526 jfloat fnum = JPOOL_FLOAT (jcf, index);
528 if (verbosity > 0)
529 fputs ("Float ", out);
531 if (fnum.negative)
532 putc ('-', out);
534 if (JFLOAT_FINITE (fnum))
536 int dummy;
537 int exponent = fnum.exponent - JFLOAT_EXP_BIAS;
538 double f;
539 uint32 mantissa = fnum.mantissa;
540 if (fnum.exponent == 0)
541 /* Denormal. */
542 exponent++;
543 else
544 /* Normal; add the implicit bit. */
545 mantissa |= ((uint32)1 << 23);
547 f = frexp (mantissa, &dummy);
548 f = ldexp (f, exponent + 1);
549 fprintf (out, "%.10g", f);
551 else
553 if (fnum.mantissa == 0)
554 fputs ("Inf", out);
555 else if (fnum.mantissa & JFLOAT_QNAN_MASK)
556 fprintf (out, "QNaN(%u)", (fnum.mantissa & ~JFLOAT_QNAN_MASK));
557 else
558 fprintf (out, "SNaN(%u)", (fnum.mantissa & ~JFLOAT_QNAN_MASK));
561 if (verbosity > 1)
562 fprintf (out, ", bits = 0x%08lx", JPOOL_UINT (jcf, index));
564 break;
566 case CONSTANT_Double:
568 jdouble dnum = JPOOL_DOUBLE (jcf, index);
570 if (verbosity > 0)
571 fputs ("Double ", out);
573 if (dnum.negative)
574 putc ('-', out);
576 if (JDOUBLE_FINITE (dnum))
578 int dummy;
579 int exponent = dnum.exponent - JDOUBLE_EXP_BIAS;
580 double d;
581 uint64 mantissa = ((((uint64) dnum.mantissa0) << 32)
582 + dnum.mantissa1);
583 if (dnum.exponent == 0)
584 /* Denormal. */
585 exponent++;
586 else
587 /* Normal; add the implicit bit. */
588 mantissa |= ((uint64)1 << 52);
590 d = frexp (mantissa, &dummy);
591 d = ldexp (d, exponent + 1);
592 fprintf (out, "%.20g", d);
594 else
596 uint64 mantissa = dnum.mantissa0 & ~JDOUBLE_QNAN_MASK;
597 mantissa = (mantissa << 32) + dnum.mantissa1;
599 if (dnum.mantissa0 == 0 && dnum.mantissa1 == 0)
600 fputs ("Inf", out);
601 else if (dnum.mantissa0 & JDOUBLE_QNAN_MASK)
602 fprintf (out, "QNaN(%llu)", (unsigned long long)mantissa);
603 else
604 fprintf (out, "SNaN(%llu)", (unsigned long long)mantissa);
606 if (verbosity > 1)
608 int32 hi, lo;
609 hi = JPOOL_UINT (jcf, index);
610 lo = JPOOL_UINT (jcf, index + 1);
611 fprintf (out, ", bits = 0x%08lx%08lx", (long) hi, (long) lo);
613 break;
615 case CONSTANT_NameAndType:
617 uint16 name = JPOOL_USHORT1 (jcf, index);
618 uint16 sig = JPOOL_USHORT2 (jcf, index);
619 if (verbosity > 0)
621 if (verbosity > 1)
622 fprintf (out, "NameAndType name: %d=", name);
623 else
624 fprintf (out, "NameAndType ");
626 print_name (out, jcf, name);
627 if (verbosity <= 1)
628 fputc (' ', out);
629 else
630 fprintf (out, ", signature: %d=", sig);
631 print_signature (out, jcf, sig, 0);
633 break;
634 case CONSTANT_Utf8:
636 const unsigned char *str = JPOOL_UTF_DATA (jcf, index);
637 int length = JPOOL_UTF_LENGTH (jcf, index);
638 if (verbosity > 0)
639 { /* Print as 8-bit bytes. */
640 fputs ("Utf8: \"", out);
641 while (--length >= 0)
642 jcf_print_char (out, *str++);
644 else
645 { /* Print as Unicode. */
646 fputc ('\"', out);
647 jcf_print_utf8 (out, str, length);
649 fputc ('\"', out);
651 break;
652 default:
653 fprintf (out, "(Unknown constant type %d)", kind);
657 static void
658 print_constant_pool (JCF *jcf)
660 int i;
661 for (i = 1; i < JPOOL_SIZE(jcf); i++)
663 int kind = JPOOL_TAG (jcf, i);
664 fprintf (out, "#%d: ", i);
665 print_constant (out, jcf, i, 2);
666 fprintf (out, "\n");
667 if (kind == CONSTANT_Double || kind == CONSTANT_Long)
668 i++; /* These take up two slots in the constant table */
672 static void
673 print_signature_type (FILE* stream, const unsigned char **ptr,
674 const unsigned char *limit)
676 int array_size;
677 if ((*ptr) >= limit)
678 return;
679 switch (*(*ptr))
681 case '[':
682 array_size = -1;
683 for ((*ptr)++; (*ptr) < limit && ISDIGIT (**ptr); (*ptr)++)
685 array_size = (array_size < 0 ? 0 : 10 * array_size) + *(*ptr) - '0';
687 print_signature_type (stream, ptr, limit);
688 if (array_size == -1)
689 fprintf (stream, "[]");
690 else
691 fprintf (stream, "[%d]", array_size);
692 break;
693 case '(':
695 int nargs = 0;
696 fputc (*(*ptr)++, stream);
697 for (; **ptr != ')' && *ptr < limit; nargs++)
699 if (nargs > 0)
700 fputc (',', stream);
701 print_signature_type (stream, ptr, limit);
703 if (*ptr < limit)
705 fputc (*(*ptr)++, stream);
706 print_signature_type (stream, ptr, limit);
708 else
709 fprintf (stream, "???");
711 break;
713 case 'B': fprintf (stream, "byte"); (*ptr)++; break;
714 case 'C': fprintf (stream, "char"); (*ptr)++; break;
715 case 'D': fprintf (stream, "double"); (*ptr)++; break;
716 case 'F': fprintf (stream, "float"); (*ptr)++; break;
717 case 'S': fprintf (stream, "short"); (*ptr)++; break;
718 case 'I': fprintf (stream, "int"); (*ptr)++; break;
719 case 'J': fprintf (stream, "long"); (*ptr)++; break;
720 case 'Z': fprintf (stream, "boolean"); (*ptr)++; break;
721 case 'V': fprintf (stream, "void"); (*ptr)++; break;
723 case 'L':
724 for ((*ptr)++; (*ptr)<limit && *(*ptr) != ';'; (*ptr)++)
725 jcf_print_char (stream, *(*ptr) == '/' ? '.' : *(*ptr));
726 if (*(*ptr) == ';')
727 (*ptr)++;
728 break;
729 default:
730 jcf_print_char (stream, *(*ptr)++);
734 static void
735 print_signature (FILE* stream, JCF *jcf, int signature_index, int options)
737 if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
738 print_constant_terse (out, jcf, signature_index, CONSTANT_Utf8);
739 else
741 const unsigned char *str = JPOOL_UTF_DATA (jcf, signature_index);
742 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
743 const unsigned char *limit;
744 limit = str + length;
745 if (str >= limit)
746 fprintf (stream, "<empty signature string>");
747 else
749 if (options & PRINT_SIGNATURE_RESULT_ONLY)
751 while (str < limit && *str++ != ')') ;
753 if (options & PRINT_SIGNATURE_ARGS_ONLY)
755 str++;
756 fputc ('(', stream);
757 while (str < limit && *str != ')')
759 print_signature_type (stream, &str, limit);
760 if (*str != ')')
761 fputs (", ", stream);
763 fputc (')', stream);
765 else
767 print_signature_type (stream, &str, limit);
768 if (str < limit)
770 fprintf (stream, "<junk:");
771 jcf_print_utf8 (stream, str, limit - str);
772 fputc ('>', stream);
780 static void
781 print_exception_table (JCF *jcf, const unsigned char *entries, int count)
783 /* Print exception table. */
784 int i = count;
785 if (i > 0)
787 const unsigned char *ptr = entries;
788 fprintf (out, "Exceptions (count: %d):\n", i);
789 for (; --i >= 0; ptr+= 8)
791 int start_pc = GET_u2 (ptr);
792 int end_pc = GET_u2 (ptr+2);
793 int handler_pc = GET_u2 (ptr+4);
794 int catch_type = GET_u2 (ptr+6);
795 fprintf (out, " start: %d, end: %d, handler: %d, type: ",
796 start_pc, end_pc, handler_pc);
797 if (catch_type == 0)
798 fputs ("0 /* finally */", out);
799 else
800 print_constant_terse_with_index (out, jcf,
801 catch_type, CONSTANT_Class);
802 fputc ('\n', out);
807 #include "jcf-reader.c"
809 static void
810 process_class (JCF *jcf)
812 int code;
813 if (jcf_parse_preamble (jcf) != 0)
814 fprintf (stderr, _("Not a valid Java .class file.\n"));
816 /* Parse and possibly print constant pool */
817 code = jcf_parse_constant_pool (jcf);
818 if (code != 0)
820 fprintf (stderr, _("error while parsing constant pool\n"));
821 exit (FATAL_EXIT_CODE);
823 code = verify_constant_pool (jcf);
824 if (code > 0)
826 fprintf (stderr, _("error in constant pool entry #%d\n"), code);
827 exit (FATAL_EXIT_CODE);
829 if (flag_print_constant_pool)
830 print_constant_pool (jcf);
832 jcf_parse_class (jcf);
833 code = jcf_parse_fields (jcf);
834 if (code != 0)
836 fprintf (stderr, _("error while parsing fields\n"));
837 exit (FATAL_EXIT_CODE);
839 code = jcf_parse_methods (jcf);
840 if (code != 0)
842 fprintf (stderr, _("error while parsing methods\n"));
843 exit (FATAL_EXIT_CODE);
845 code = jcf_parse_final_attributes (jcf);
846 if (code != 0)
848 fprintf (stderr, _("error while parsing final attributes\n"));
849 exit (FATAL_EXIT_CODE);
851 jcf->filename = NULL;
856 /* This is used to mark options with no short value. */
857 #define LONG_OPT(Num) ((Num) + 128)
859 #define OPT_classpath LONG_OPT (0)
860 #define OPT_CLASSPATH OPT_classpath
861 #define OPT_bootclasspath LONG_OPT (1)
862 #define OPT_extdirs LONG_OPT (2)
863 #define OPT_HELP LONG_OPT (3)
864 #define OPT_VERSION LONG_OPT (4)
865 #define OPT_JAVAP LONG_OPT (5)
867 static const struct option options[] =
869 { "classpath", required_argument, NULL, OPT_classpath },
870 { "bootclasspath", required_argument, NULL, OPT_bootclasspath },
871 { "extdirs", required_argument, NULL, OPT_extdirs },
872 { "CLASSPATH", required_argument, NULL, OPT_CLASSPATH },
873 { "help", no_argument, NULL, OPT_HELP },
874 { "verbose", no_argument, NULL, 'v' },
875 { "version", no_argument, NULL, OPT_VERSION },
876 { "javap", no_argument, NULL, OPT_JAVAP },
877 { "print-main", no_argument, &flag_print_main, 1 },
878 { "print-constants", no_argument, &flag_print_constant_pool, 1 },
879 { NULL, no_argument, NULL, 0 }
882 static void
883 usage (void)
885 fprintf (stderr, _("Try `jcf-dump --help' for more information.\n"));
886 exit (1);
889 static void
890 help (void)
892 printf (_("Usage: jcf-dump [OPTION]... CLASS...\n\n"));
893 printf (_("Display contents of a class file in readable form.\n\n"));
894 printf (_(" -c Disassemble method bodies\n"));
895 printf (_(" --javap Generate output in `javap' format\n"));
896 printf ("\n");
897 printf (_(" --classpath PATH Set path to find .class files\n"));
898 printf (_(" -IDIR Append directory to class path\n"));
899 printf (_(" --bootclasspath PATH Override built-in class path\n"));
900 printf (_(" --extdirs PATH Set extensions directory path\n"));
901 printf (_(" -o FILE Set output file name\n"));
902 printf ("\n");
903 printf (_(" --help Print this help, then exit\n"));
904 printf (_(" --version Print version number, then exit\n"));
905 printf (_(" -v, --verbose Print extra information while running\n"));
906 printf ("\n");
907 printf (_("For bug reporting instructions, please see:\n"
908 "%s.\n"), bug_report_url);
909 exit (0);
912 static void
913 version (void)
915 printf ("jcf-dump (GCC) %s\n\n", version_string);
916 printf ("Copyright %s 2004 Free Software Foundation, Inc.\n", _("(C)"));
917 printf (_("This is free software; see the source for copying conditions. There is NO\n"
918 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
919 exit (0);
923 main (int argc, char** argv)
925 JCF jcf[1];
926 int argi, opt;
928 gcc_init_libintl ();
930 if (argc <= 1)
932 fprintf (stderr, _("jcf-dump: no classes specified\n"));
933 usage ();
936 jcf_path_init ();
938 /* We use getopt_long_only to allow single `-' long options. For
939 some of our options this is more natural. */
940 while ((opt = getopt_long_only (argc, argv, "o:I:vc", options, NULL)) != -1)
942 switch (opt)
944 case 0:
945 /* Already handled. */
946 break;
948 case 'o':
949 output_file = optarg;
950 break;
952 case 'I':
953 jcf_path_include_arg (optarg);
954 break;
956 case 'v':
957 verbose++;
958 break;
960 case 'c':
961 flag_disassemble_methods = 1;
962 break;
964 case OPT_classpath:
965 jcf_path_classpath_arg (optarg);
966 break;
968 case OPT_bootclasspath:
969 jcf_path_bootclasspath_arg (optarg);
970 break;
972 case OPT_extdirs:
973 jcf_path_extdirs_arg (optarg);
974 break;
976 case OPT_HELP:
977 help ();
978 break;
980 case OPT_VERSION:
981 version ();
982 break;
984 case OPT_JAVAP:
985 flag_javap_compatible++;
986 flag_print_constant_pool = 0;
987 flag_print_attributes = 0;
988 break;
990 default:
991 usage ();
995 if (verbose && ! flag_javap_compatible)
996 flag_print_constant_pool = 1;
998 if (optind == argc)
1000 fprintf (stderr, _("jcf-dump: no classes specified\n"));
1001 usage ();
1004 jcf_path_seal (verbose);
1006 if (flag_print_main)
1008 flag_print_fields = 0;
1009 flag_print_methods = 0;
1010 flag_print_constant_pool = 0;
1011 flag_print_attributes = 0;
1012 flag_print_class_info = 0;
1015 if (output_file)
1017 out = fopen (output_file, "w");
1018 if (! out)
1020 fprintf (stderr, _("Cannot open '%s' for output.\n"), output_file);
1021 return FATAL_EXIT_CODE;
1024 else
1025 out = stdout;
1027 if (optind >= argc)
1029 fprintf (out, "Reading .class from <standard input>.\n");
1030 open_class ("<stdio>", jcf, 0, NULL);
1031 process_class (jcf);
1033 else
1035 for (argi = optind; argi < argc; argi++)
1037 char *arg = argv[argi];
1038 const char *class_filename = find_class (arg, strlen (arg), jcf, 0);
1039 if (class_filename == NULL)
1040 class_filename = find_classfile (arg, jcf, NULL);
1041 if (class_filename == NULL)
1043 perror ("Could not find class");
1044 return FATAL_EXIT_CODE;
1046 JCF_FILL (jcf, 4);
1047 if (GET_u4 (jcf->read_ptr) == ZIPMAGIC)
1049 long compressed_size, member_size;
1050 int compression_method, filename_length, extra_length;
1051 int general_purpose_bits;
1052 const char *filename;
1053 int total_length;
1054 if (flag_print_class_info)
1055 fprintf (out, "Reading classes from archive %s.\n",
1056 class_filename);
1057 for (;;)
1059 int skip = 0;
1060 jcf_filbuf_t save_filbuf = jcf->filbuf;
1061 long magic = JCF_readu4_le (jcf);
1062 if (magic == 0x02014b50 || magic == 0x06054b50)
1063 break; /* got to central directory */
1064 if (magic != 0x04034b50) /* ZIPMAGIC (little-endian) */
1066 fprintf (stderr, _("bad format of .zip/.jar archive\n"));
1067 return FATAL_EXIT_CODE;
1069 JCF_FILL (jcf, 26);
1070 JCF_SKIP (jcf, 2);
1071 general_purpose_bits = JCF_readu2_le (jcf);
1072 compression_method = JCF_readu2_le (jcf);
1073 JCF_SKIP (jcf, 8);
1074 compressed_size = JCF_readu4_le (jcf);
1075 member_size = JCF_readu4_le (jcf);
1076 filename_length = JCF_readu2_le (jcf);
1077 extra_length = JCF_readu2_le (jcf);
1078 total_length = filename_length + extra_length
1079 + compressed_size;
1080 if (jcf->read_end - jcf->read_ptr < total_length)
1081 jcf_trim_old_input (jcf);
1082 JCF_FILL (jcf, total_length);
1083 filename = jcf->read_ptr;
1084 JCF_SKIP (jcf, filename_length);
1085 JCF_SKIP (jcf, extra_length);
1086 if (filename_length > 0
1087 && filename[filename_length-1] == '/')
1089 if (flag_print_class_info)
1090 fprintf (out, "[Skipping directory %.*s]\n",
1091 filename_length, filename);
1092 skip = 1;
1094 else if (compression_method != 0)
1096 if (flag_print_class_info)
1097 fprintf (out, "[Skipping compressed file %.*s]\n",
1098 filename_length, filename);
1099 skip = 1;
1101 else if (member_size < 4
1102 || GET_u4 (jcf->read_ptr) != 0xcafebabe)
1104 if (flag_print_class_info)
1105 fprintf (out, "[Skipping non-.class member %.*s]\n",
1106 filename_length, filename);
1107 skip = 1;
1109 else
1111 if (flag_print_class_info)
1112 fprintf (out, "Reading class member: %.*s.\n",
1113 filename_length, filename);
1115 if (skip)
1117 JCF_SKIP (jcf, compressed_size);
1119 else
1121 unsigned char *save_end;
1122 jcf->filbuf = jcf_unexpected_eof;
1123 save_end = jcf->read_end;
1124 jcf->read_end = jcf->read_ptr + compressed_size;
1125 process_class (jcf);
1126 jcf->filbuf = save_filbuf;
1127 jcf->read_end = save_end;
1131 else
1133 if (flag_print_class_info)
1134 fprintf (out, "Reading .class from %s.\n", class_filename);
1135 process_class (jcf);
1137 JCF_FINISH(jcf);
1141 return SUCCESS_EXIT_CODE;
1146 static void
1147 disassemble_method (JCF* jcf, const unsigned char *byte_ops, int len)
1149 #undef PTR
1150 int PC;
1151 int i;
1152 int saw_wide = 0;
1153 if (flag_disassemble_methods == 0)
1154 return;
1155 #define BCODE byte_ops
1156 for (PC = 0; PC < len;)
1158 int oldpc = PC;
1159 int saw_index;
1160 jint INT_temp;
1161 switch (byte_ops[PC++])
1164 /* This is the actual code emitted for each of opcodes in javaops.def.
1165 The actual opcode-specific stuff is handled by the OPKIND macro.
1166 I.e. for an opcode whose OPKIND is BINOP, the BINOP will be called.
1167 Those macros are defined below. The OPKINDs that do not have any
1168 inline parameters (such as BINOP) and therefore do mot need anything
1169 else to me printed out just use an empty body. */
1171 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
1172 case OPCODE: \
1173 fprintf (out, "%3d: %s", oldpc, #OPNAME); \
1174 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
1175 fputc ('\n', out); \
1176 break;
1178 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
1179 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
1180 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
1181 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
1183 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > len ? \
1184 (fprintf(stderr, _("Bad byte codes.\n")), exit(-1)) : 1)
1186 /* Print out operand (if not implied by the opcode) for PUSCH opcodes.
1187 These all push a constant onto the opcode stack. */
1188 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
1189 saw_index = 0, i = (OPERAND_VALUE); \
1190 if (oldpc+1 == PC) /* nothing */; \
1191 else if (saw_index) fprintf (out, " "), print_constant_ref (out, jcf, i); \
1192 else fprintf (out, " %d", i);
1194 /* Print out operand (a local variable index) for LOAD opcodes.
1195 These all push local variable onto the opcode stack. */
1196 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
1197 INT_temp = saw_wide ? IMMEDIATE_u2 : (OPERAND_VALUE); goto load_store;
1199 /* Handle STORE opcodes same as LOAD opcodes.
1200 These all store a value from the opcode stack in a local variable. */
1201 #define STORE LOAD
1203 /* Handle more kind of opcodes. */
1204 #define STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1205 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1206 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1207 #define CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1208 #define CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1209 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1210 #define UNKNOWN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1212 /* Handle putfield and getfield opcodes, with static versions. */
1213 #define FIELD(MAYBE_STATIC, PUT_OR_GET) \
1214 fputc (' ', out); print_constant_ref (out, jcf, IMMEDIATE_u2)
1216 /* Print operand for invoke opcodes. */
1217 #define INVOKE(OPERAND_TYPE, OPERAND_VALUE) \
1218 fputc (' ', out); print_constant_ref (out, jcf, IMMEDIATE_u2);\
1219 if (OPERAND_VALUE) /* for invokeinterface */ \
1220 { int nargs = IMMEDIATE_u1; PC++; \
1221 fprintf (out, " nargs:%d", nargs); }
1223 #define OBJECT(OPERAND_TYPE, OPERAND_VALUE) \
1224 fputc (' ', out); print_constant_ref (out, jcf, IMMEDIATE_u2);
1226 #define ARRAY(OPERAND_TYPE, SUBOP) \
1227 ARRAY_##SUBOP(OPERAND_TYPE)
1228 /* Handle sub-categories of ARRAY opcodes. */
1229 #define ARRAY_LOAD(TYPE) /* nothing */
1230 #define ARRAY_STORE(TYPE) /* nothing */
1231 #define ARRAY_LENGTH(TYPE) /* nothing */
1232 #define ARRAY_NEW(TYPE) ARRAY_NEW_##TYPE
1233 #define ARRAY_NEW_NUM \
1234 INT_temp = IMMEDIATE_u1; \
1235 { switch ((int) INT_temp) { \
1236 case 4: fputs (" boolean", out); break; \
1237 case 5: fputs (" char", out); break; \
1238 case 6: fputs (" float", out); break; \
1239 case 7: fputs (" double", out); break; \
1240 case 8: fputs (" byte", out); break; \
1241 case 9: fputs (" short", out); break; \
1242 case 10: fputs (" int", out); break; \
1243 case 11: fputs (" long", out); break; \
1244 default: fprintf (out, " <unknown type code %ld>", (long)INT_temp); break;\
1247 #define ARRAY_NEW_PTR \
1248 fputc (' ', out); print_constant_ref (out, jcf, IMMEDIATE_u2);
1250 #define ARRAY_NEW_MULTI \
1251 fputc (' ', out); print_constant_ref (out, jcf, IMMEDIATE_u2); \
1252 fprintf (out, " %d", IMMEDIATE_u1); /* number of dimensions */
1254 #define TEST(OPERAND_TYPE, OPERAND_VALUE) \
1255 fprintf (out, " %d", oldpc + IMMEDIATE_s2)
1257 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
1258 saw_index = 0, INT_temp = (OPERAND_VALUE); \
1259 fprintf (out, " %ld", (long) (saw_index ? INT_temp : oldpc + INT_temp))
1261 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
1262 saw_index = 0, INT_temp = (OPERAND_VALUE); \
1263 fprintf (out, " %ld", (long) (saw_index ? INT_temp : oldpc + INT_temp))
1265 #undef RET /* Defined by config/i386/i386.h */
1266 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
1267 INT_temp = saw_wide ? IMMEDIATE_u2 : (OPERAND_VALUE); \
1268 saw_wide = 0; \
1269 fprintf (out, " %ld", (long) INT_temp);
1271 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
1272 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
1274 #define LOOKUP_SWITCH \
1275 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
1276 fprintf (out, " npairs=%ld, default=%ld", (long) npairs, (long) default_offset+oldpc); \
1277 while (--npairs >= 0) { \
1278 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
1279 fprintf (out, "\n%10ld: %ld", (long)match, (long)(offset+oldpc)); } \
1282 #define TABLE_SWITCH \
1283 { jint default_offset = IMMEDIATE_s4; \
1284 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
1285 fprintf (out, " low=%ld, high=%ld, default=%ld", \
1286 (long) low, (long) high, (long) default_offset+oldpc); \
1287 for (; low <= high; low++) { \
1288 jint offset = IMMEDIATE_s4; \
1289 fprintf (out, "\n%10ld: %ld", (long)low, (long)(offset+oldpc)); } \
1292 #define SPECIAL(OPERAND_TYPE, OPERAND_VALUE) \
1293 SPECIAL_##OPERAND_VALUE(OPERAND_TYPE)
1295 #define SPECIAL_IINC(OPERAND_TYPE) \
1296 i = saw_wide ? IMMEDIATE_u2 : IMMEDIATE_u1; \
1297 fprintf (out, " %d", i); \
1298 i = saw_wide ? IMMEDIATE_s2 : IMMEDIATE_s1; \
1299 saw_wide = 0; \
1300 fprintf (out, " %d", i)
1302 #define SPECIAL_WIDE(OPERAND_TYPE) \
1303 saw_wide = 1;
1305 #define SPECIAL_EXIT(OPERAND_TYPE) /* nothing */
1306 #define SPECIAL_ENTER(OPERAND_TYPE) /* nothing */
1307 #define SPECIAL_BREAK(OPERAND_TYPE) /* nothing */
1308 #define SPECIAL_THROW(OPERAND_TYPE) /* nothing */
1310 #define IMPL(OPERAND_TYPE, OPERAND_VALUE) \
1311 fprintf (out, " %d", IMMEDIATE_u##OPERAND_VALUE)
1313 #define COND(OPERAND_TYPE, OPERAND_VALUE) \
1314 TEST(OPERAND_TYPE, OPERAND_VALUE)
1316 #include "javaop.def"
1318 load_store:
1319 if (oldpc+1 == PC) /* nothing - local index implied by opcode */;
1320 else
1322 saw_wide = 0;
1323 fprintf (out, " %ld", (long) INT_temp);
1325 fputc ('\n', out);
1326 break;
1328 default:
1329 fprintf (out, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);