Mercurial > hg > Members > kono > jpf-core
comparison src/main/gov/nasa/jpf/jvm/ClassFilePrinter.java @ 0:61d41facf527
initial v8 import (history reset)
author | Peter Mehlitz <Peter.C.Mehlitz@nasa.gov> |
---|---|
date | Fri, 23 Jan 2015 10:14:01 -0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:61d41facf527 |
---|---|
1 /* | |
2 * Copyright (C) 2014, United States Government, as represented by the | |
3 * Administrator of the National Aeronautics and Space Administration. | |
4 * All rights reserved. | |
5 * | |
6 * The Java Pathfinder core (jpf-core) platform is licensed under the | |
7 * Apache License, Version 2.0 (the "License"); you may not use this file except | |
8 * in compliance with the License. You may obtain a copy of the License at | |
9 * | |
10 * http://www.apache.org/licenses/LICENSE-2.0. | |
11 * | |
12 * Unless required by applicable law or agreed to in writing, software | |
13 * distributed under the License is distributed on an "AS IS" BASIS, | |
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
15 * See the License for the specific language governing permissions and | |
16 * limitations under the License. | |
17 */ | |
18 | |
19 package gov.nasa.jpf.jvm; | |
20 | |
21 import gov.nasa.jpf.jvm.JVMByteCodePrinter; | |
22 import gov.nasa.jpf.util.StructuredPrinter; | |
23 import gov.nasa.jpf.vm.ClassParseException; | |
24 import java.io.PrintWriter; | |
25 | |
26 /** | |
27 * simple tool to print contents of a classfile | |
28 * | |
29 * <2do> use indentation level variable and formated output | |
30 */ | |
31 public class ClassFilePrinter extends StructuredPrinter implements ClassFileReader { | |
32 | |
33 | |
34 public static void main(String[] args){ | |
35 ClassFilePrinter printer = new ClassFilePrinter(); | |
36 | |
37 try { | |
38 ClassFile cf = new ClassFile(args[0]); | |
39 cf.parse(printer); | |
40 | |
41 } catch (ClassParseException cfx){ | |
42 cfx.printStackTrace(); | |
43 } | |
44 } | |
45 | |
46 @Override | |
47 public void setClass(ClassFile cf, String clsName, String superClsName, int flags, int cpCount) { | |
48 printSectionHeader( "constpool"); | |
49 printCp(pw,cf); | |
50 | |
51 incIndent(); | |
52 printSectionHeader( "class"); | |
53 pw.printf("%sclass=%s\n", indent, clsName); | |
54 pw.printf("%ssuperclass=%s\n", indent, superClsName); | |
55 pw.printf("%sflags=0x%X\n", indent, flags); | |
56 } | |
57 | |
58 //--- interfaces | |
59 @Override | |
60 public void setInterfaceCount(ClassFile cf, int ifcCount) { | |
61 pw.printf("%sinterface count=%d\n", indent, ifcCount); | |
62 incIndent(); | |
63 } | |
64 | |
65 @Override | |
66 public void setInterface(ClassFile cf, int ifcIndex, String ifcName) { | |
67 pw.printf("%s[%d]: %s\n", indent, ifcIndex, ifcName); | |
68 } | |
69 | |
70 @Override | |
71 public void setInterfacesDone(ClassFile cf){ | |
72 decIndent(); | |
73 } | |
74 | |
75 //--- fields | |
76 @Override | |
77 public void setFieldCount(ClassFile cf, int fieldCount) { | |
78 printSectionHeader( "fields"); | |
79 pw.printf( "%sfield count=%d\n", indent, fieldCount); | |
80 } | |
81 | |
82 @Override | |
83 public void setField(ClassFile cf, int fieldIndex, int accessFlags, String name, String descriptor) { | |
84 pw.printf("%s[%d]: %s, type=%s,flags=0x%X", indent, fieldIndex, name, descriptor, accessFlags); | |
85 } | |
86 | |
87 @Override | |
88 public void setFieldAttributeCount(ClassFile cf, int fieldIndex, int attrCount) { | |
89 pw.printf(", attr count=%d\n", attrCount); | |
90 incIndent(); | |
91 } | |
92 | |
93 @Override | |
94 public void setFieldAttribute(ClassFile cf, int fieldIndex, int attrIndex, String name, int attrLength) { | |
95 pw.printf("%s[%d]: %s", indent, attrIndex, name); | |
96 | |
97 if (name == ClassFile.CONST_VALUE_ATTR) { | |
98 cf.parseConstValueAttr(this, null); | |
99 | |
100 } else if (name == ClassFile.RUNTIME_VISIBLE_ANNOTATIONS_ATTR){ | |
101 cf.parseAnnotationsAttr(this, null); | |
102 | |
103 } else if (name == ClassFile.RUNTIME_INVISIBLE_ANNOTATIONS_ATTR){ | |
104 cf.parseAnnotationsAttr(this, null); | |
105 | |
106 } else if (name == ClassFile.RUNTIME_VISIBLE_TYPE_ANNOTATIONS_ATTR){ | |
107 cf.parseTypeAnnotationsAttr(this, null); | |
108 | |
109 } else if (name == ClassFile.SIGNATURE_ATTR){ | |
110 cf.parseSignatureAttr(this, null); | |
111 | |
112 } else { | |
113 pw.printf(" ,length=%d,data=[",attrLength ); | |
114 printRawData(pw, cf, attrLength, 10); | |
115 pw.println(']'); | |
116 } | |
117 } | |
118 | |
119 @Override | |
120 public void setFieldAttributesDone(ClassFile cf, int fieldIndex){ | |
121 decIndent(); | |
122 } | |
123 | |
124 @Override | |
125 public void setFieldDone(ClassFile cf, int fieldIndex){ | |
126 pw.println(); | |
127 } | |
128 | |
129 @Override | |
130 public void setFieldsDone(ClassFile cf){ | |
131 } | |
132 | |
133 @Override | |
134 public void setConstantValue(ClassFile cf, Object tag, Object value) { | |
135 pw.printf(" value=%s\n", value); | |
136 } | |
137 | |
138 //--- methods | |
139 @Override | |
140 public void setMethodCount(ClassFile cf, int methodCount) { | |
141 printSectionHeader( "methods"); | |
142 pw.printf( "%smethod count=%d\n", indent, methodCount); | |
143 } | |
144 | |
145 @Override | |
146 public void setMethod(ClassFile cf, int methodIndex, int accessFlags, String name, String descriptor) { | |
147 pw.printf("%s[%d]: %s%s, flags=0x%X", indent, methodIndex, name, descriptor, accessFlags); | |
148 } | |
149 | |
150 @Override | |
151 public void setMethodAttributeCount(ClassFile cf, int methodIndex, int attrCount) { | |
152 pw.printf(", attr count=%d\n", attrCount); | |
153 incIndent(); | |
154 } | |
155 | |
156 @Override | |
157 public void setMethodAttribute(ClassFile cf, int methodIndex, int attrIndex, String name, int attrLength) { | |
158 pw.printf("%s[%d]: %s", indent, attrIndex, name); | |
159 | |
160 if (name == ClassFile.CODE_ATTR) { | |
161 cf.parseCodeAttr(this, null); | |
162 | |
163 } else if (name == ClassFile.EXCEPTIONS_ATTR){ | |
164 cf.parseExceptionAttr(this, null); | |
165 | |
166 } else if (name == ClassFile.RUNTIME_VISIBLE_ANNOTATIONS_ATTR){ | |
167 cf.parseAnnotationsAttr(this, null); | |
168 | |
169 } else if (name == ClassFile.RUNTIME_INVISIBLE_ANNOTATIONS_ATTR){ | |
170 cf.parseAnnotationsAttr(this, null); | |
171 | |
172 } else if (name == ClassFile.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS_ATTR){ | |
173 cf.parseParameterAnnotationsAttr(this, null); | |
174 | |
175 } else if (name == ClassFile.RUNTIME_VISIBLE_TYPE_ANNOTATIONS_ATTR){ | |
176 cf.parseTypeAnnotationsAttr(this, null); | |
177 | |
178 } else if (name == ClassFile.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS_ATTR){ | |
179 cf.parseParameterAnnotationsAttr(this, null); | |
180 | |
181 } else if (name == ClassFile.SIGNATURE_ATTR){ | |
182 cf.parseSignatureAttr(this, null); | |
183 | |
184 } else { | |
185 pw.printf(" ,length=%d,data=[", attrLength ); | |
186 printRawData(pw, cf, attrLength, 10); | |
187 pw.println(']'); | |
188 } | |
189 } | |
190 | |
191 @Override | |
192 public void setMethodAttributesDone(ClassFile cf, int methodIndex){ | |
193 decIndent(); | |
194 } | |
195 | |
196 @Override | |
197 public void setMethodDone(ClassFile cf, int methodIndex){ | |
198 pw.println(); | |
199 } | |
200 | |
201 @Override | |
202 public void setMethodsDone(ClassFile cf){ | |
203 } | |
204 | |
205 @Override | |
206 public void setExceptionCount(ClassFile cf, Object tag, int exceptionCount){ | |
207 pw.printf(", count=%d\n", exceptionCount); | |
208 incIndent(); | |
209 } | |
210 @Override | |
211 public void setException(ClassFile cf, Object tag, int exceptionIndex, String exceptionType){ | |
212 pw.printf("%s[%d]: %s\n", indent, exceptionIndex, exceptionType); | |
213 } | |
214 @Override | |
215 public void setExceptionsDone(ClassFile cf, Object tag){ | |
216 decIndent(); | |
217 } | |
218 | |
219 | |
220 @Override | |
221 public void setCode(ClassFile cf, Object tag, int maxStack, int maxLocals, int codeLength) { | |
222 pw.printf(", maxStack=%d,maxLocals=%d,length=%d\n", maxStack, maxLocals,codeLength); | |
223 incIndent(); | |
224 JVMByteCodePrinter bcPrinter = new JVMByteCodePrinter(pw, cf, indent); | |
225 cf.parseBytecode(bcPrinter, tag, codeLength); | |
226 decIndent(); | |
227 } | |
228 | |
229 @Override | |
230 public void setExceptionHandlerTableCount(ClassFile cf, Object tag, int exceptionTableCount) { | |
231 pw.printf("%sexception table count=%d\n", indent, exceptionTableCount); | |
232 incIndent(); | |
233 } | |
234 @Override | |
235 public void setExceptionHandler(ClassFile cf, Object tag, int exceptionIndex, | |
236 int startPc, int endPc, int handlerPc, String catchType) { | |
237 pw.printf("%s[%d]: type=%s, range=[%d..%d], handler=%d\n", indent, exceptionIndex, catchType, startPc, endPc, handlerPc); | |
238 } | |
239 @Override | |
240 public void setExceptionHandlerTableDone(ClassFile cf, Object tag){ | |
241 decIndent(); | |
242 } | |
243 | |
244 @Override | |
245 public void setCodeAttributeCount(ClassFile cf, Object tag, int attrCount) { | |
246 pw.printf("%scode attribute count=%d\n", indent, attrCount); | |
247 incIndent(); | |
248 } | |
249 @Override | |
250 public void setCodeAttribute(ClassFile cf, Object tag, int attrIndex, String name, int attrLength) { | |
251 pw.printf("%s[%d]: %s", indent, attrIndex, name); | |
252 | |
253 if (name == ClassFile.LINE_NUMBER_TABLE_ATTR) { | |
254 cf.parseLineNumberTableAttr(this, tag); | |
255 | |
256 } else if (name == ClassFile.LOCAL_VAR_TABLE_ATTR) { | |
257 cf.parseLocalVarTableAttr(this, tag); | |
258 | |
259 } else if (name == ClassFile.RUNTIME_VISIBLE_TYPE_ANNOTATIONS_ATTR){ | |
260 cf.parseTypeAnnotationsAttr(this, tag); | |
261 | |
262 } else { // generic | |
263 pw.printf(" ,length=%d,data=[", attrLength ); | |
264 printRawData(pw, cf, attrLength, 10); | |
265 pw.println(']'); | |
266 } | |
267 } | |
268 @Override | |
269 public void setCodeAttributesDone(ClassFile cf, Object tag){ | |
270 decIndent(); | |
271 } | |
272 | |
273 @Override | |
274 public void setLineNumberTableCount(ClassFile cf, Object tag, int lineNumberCount) { | |
275 pw.printf(", linenumber count=%d\n", lineNumberCount); | |
276 incIndent(); | |
277 } | |
278 @Override | |
279 public void setLineNumber(ClassFile cf, Object tag, int lineIndex, int lineNumber, int startPc) { | |
280 pw.printf("%s[%d]: line=%d, pc=%d\n", indent, lineIndex, lineNumber, startPc); | |
281 } | |
282 @Override | |
283 public void setLineNumberTableDone(ClassFile cf, Object tag){ | |
284 decIndent(); | |
285 } | |
286 | |
287 @Override | |
288 public void setLocalVarTableCount(ClassFile cf, Object tag, int localVarCount) { | |
289 pw.printf(", localVar count=%d\n", localVarCount); | |
290 incIndent(); | |
291 } | |
292 @Override | |
293 public void setLocalVar(ClassFile cf, Object tag, int localVarIndex, | |
294 String varName, String descriptor, int scopeStartPc, int scopeEndPc, int slotIndex) { | |
295 pw.printf("%s[%d]: %s, type=%s, scope=[%d..%d], slot=%d\n", indent, localVarIndex, varName, descriptor, | |
296 scopeStartPc, scopeEndPc, slotIndex); | |
297 } | |
298 @Override | |
299 public void setLocalVarTableDone(ClassFile cf, Object tag){ | |
300 decIndent(); | |
301 } | |
302 | |
303 //--- class attributes | |
304 @Override | |
305 public void setClassAttributeCount(ClassFile cf, int attrCount) { | |
306 printSectionHeader( "class attributes"); | |
307 pw.printf("%sclass attribute count=%d\n", indent, attrCount); | |
308 incIndent(); | |
309 } | |
310 @Override | |
311 public void setClassAttribute(ClassFile cf, int attrIndex, String name, int attrLength) { | |
312 pw.printf("%s[%d]: %s", indent, attrIndex, name); | |
313 | |
314 if (name == ClassFile.SOURCE_FILE_ATTR) { | |
315 cf.parseSourceFileAttr(this, null); | |
316 | |
317 } else if (name == ClassFile.DEPRECATED_ATTR) { | |
318 | |
319 } else if (name == ClassFile.INNER_CLASSES_ATTR) { | |
320 cf.parseInnerClassesAttr(this, null); | |
321 | |
322 } else if (name == ClassFile.RUNTIME_VISIBLE_ANNOTATIONS_ATTR){ | |
323 cf.parseAnnotationsAttr(this, null); | |
324 | |
325 } else if (name == ClassFile.RUNTIME_VISIBLE_TYPE_ANNOTATIONS_ATTR){ | |
326 cf.parseTypeAnnotationsAttr(this, null); | |
327 | |
328 } else if (name == ClassFile.RUNTIME_INVISIBLE_ANNOTATIONS_ATTR){ | |
329 cf.parseAnnotationsAttr(this, null); | |
330 | |
331 } else if (name == ClassFile.SIGNATURE_ATTR){ | |
332 cf.parseSignatureAttr(this, null); | |
333 | |
334 } else if (name == ClassFile.ENCLOSING_METHOD_ATTR){ | |
335 cf.parseEnclosingMethodAttr(this, null); | |
336 | |
337 } else if (name == ClassFile.BOOTSTRAP_METHOD_ATTR){ | |
338 cf.parseBootstrapMethodAttr(this, null); | |
339 | |
340 } else { | |
341 pw.printf(" ,length=%d,data=[", attrLength ); | |
342 printRawData(pw, cf, attrLength, 10); | |
343 pw.println(']'); | |
344 } | |
345 } | |
346 @Override | |
347 public void setClassAttributesDone(ClassFile cf){ | |
348 decIndent(); | |
349 } | |
350 | |
351 @Override | |
352 public void setEnclosingMethod(ClassFile cf, Object tag, String enclosingClass, String enclosingMethod, String descriptor) { | |
353 if (enclosingMethod != null){ | |
354 pw.printf(", enclosingClass=%s, method=%s%s\n", enclosingClass, enclosingMethod, descriptor); | |
355 } else { | |
356 pw.printf(", enclosingClass=%s\n", enclosingClass); | |
357 } | |
358 } | |
359 | |
360 | |
361 @Override | |
362 public void setSourceFile(ClassFile cf, Object tag, String pathName){ | |
363 pw.printf(", path=%s\n", pathName); | |
364 } | |
365 | |
366 @Override | |
367 public void setInnerClassCount(ClassFile cf, Object tag, int innerClsCount) { | |
368 pw.printf( ", inner class count=%d\n", innerClsCount); | |
369 incIndent(); | |
370 } | |
371 @Override | |
372 public void setInnerClass(ClassFile cf, Object tag, int innerClsIndex, | |
373 String outerName, String innerName, String innerSimpleName, int accessFlags) { | |
374 pw.printf("%s[%d]: %s, fullName=%s, outerClass=%s, flags=0x%X\n", indent, innerClsIndex, | |
375 innerSimpleName, innerName, outerName, accessFlags); | |
376 } | |
377 @Override | |
378 public void setInnerClassesDone(ClassFile cf, Object tag){ | |
379 decIndent(); | |
380 } | |
381 | |
382 @Override | |
383 public void setBootstrapMethodCount (ClassFile cf, Object tag, int count) { | |
384 pw.printf( ", bootstrap method count=%d\n", count); | |
385 incIndent(); | |
386 } | |
387 | |
388 @Override | |
389 public void setBootstrapMethod (ClassFile cf, Object tag, int idx, | |
390 int refKind, String cls, String mth, String descriptor, int[] cpArgs){ | |
391 String refTypeName = cf.getRefTypeName(refKind); | |
392 pw.printf("%s[%d]: %s %s.%s%s\n", indent, idx, refTypeName, cls, mth, descriptor); | |
393 incIndent(); | |
394 pw.printf("%smethod arg count: %d\n", indent, cpArgs.length); | |
395 incIndent(); | |
396 for (int i=0; i<cpArgs.length; i++){ | |
397 int cpIdx = cpArgs[i]; | |
398 String arg = getBootstrapMethodArgAsString(cf, cpIdx); | |
399 pw.printf("%s[%d]: %s\n", indent, i, arg); | |
400 } | |
401 decIndent(); | |
402 decIndent(); | |
403 } | |
404 | |
405 String getBootstrapMethodArgAsString (ClassFile cf, int cpIdx){ | |
406 StringBuilder sb = new StringBuilder(); | |
407 Object cpValue = cf.getCpValue(cpIdx); | |
408 sb.append('@'); | |
409 sb.append(cpIdx); | |
410 sb.append(" ("); | |
411 sb.append( cpValue); | |
412 sb.append("): "); | |
413 | |
414 if (cpValue instanceof ClassFile.CpInfo){ | |
415 switch ((ClassFile.CpInfo)cpValue){ | |
416 case MethodType: | |
417 sb.append( cf.methodTypeDescriptorAt(cpIdx)); | |
418 break; | |
419 case MethodHandle: | |
420 int methodRefIdx = cf.mhMethodRefIndexAt(cpIdx); | |
421 | |
422 sb.append( cf.getRefTypeName(cf.mhRefTypeAt(cpIdx))); | |
423 sb.append(' '); | |
424 sb.append( cf.methodClassNameAt(methodRefIdx)); | |
425 sb.append('.'); | |
426 sb.append( cf.methodNameAt(methodRefIdx)); | |
427 sb.append( cf.methodDescriptorAt(methodRefIdx)); | |
428 break; | |
429 default: | |
430 sb.append( cpValue.toString()); | |
431 } | |
432 } else { | |
433 sb.append( cpValue.toString()); | |
434 } | |
435 | |
436 return sb.toString(); | |
437 } | |
438 | |
439 @Override | |
440 public void setBootstrapMethodsDone (ClassFile cf, Object tag) { | |
441 decIndent(); | |
442 } | |
443 | |
444 @Override | |
445 public void setAnnotationCount(ClassFile cf, Object tag, int annotationCount){ | |
446 pw.printf( " count=%d\n", annotationCount); | |
447 incIndent(); | |
448 } | |
449 @Override | |
450 public void setAnnotation(ClassFile cf, Object tag, int annotationIndex, String annotationType){ | |
451 pw.printf("%s[%d]: %s", indent, annotationIndex, annotationType); | |
452 } | |
453 @Override | |
454 public void setAnnotationsDone(ClassFile cf, Object tag){ | |
455 decIndent(); | |
456 } | |
457 | |
458 // Java 8 type annotations | |
459 | |
460 @Override | |
461 public void setTypeAnnotationCount(ClassFile cf, Object tag, int annotationCount){ | |
462 pw.printf( " count=%d\n", annotationCount); | |
463 incIndent(); | |
464 } | |
465 | |
466 @Override | |
467 public void setTypeParameterAnnotation(ClassFile cf, Object tag, int annotationIndex, int targetType, | |
468 int typeIndex, short[] typePath, String annotationType){ | |
469 pw.printf("%s[%d]: %s (%s, type path=%s, type index=%d)", indent, annotationIndex, annotationType, | |
470 ClassFile.getTargetTypeName(targetType), ClassFile.getTypePathEncoding(typePath), typeIndex); | |
471 } | |
472 @Override | |
473 public void setSuperTypeAnnotation(ClassFile cf, Object tag, int annotationIndex, int targetType, | |
474 int superTypeIdx, short[] typePath, String annotationType){ | |
475 pw.printf("%s[%d]: %s (%s, type path=%s, super type index=%d)", indent, annotationIndex, annotationType, | |
476 ClassFile.getTargetTypeName(targetType), ClassFile.getTypePathEncoding(typePath), superTypeIdx); | |
477 } | |
478 @Override | |
479 public void setTypeParameterBoundAnnotation(ClassFile cf, Object tag, int annotationIndex, int targetType, | |
480 int typeParamIdx, int boundIdx, short[] typePath, String annotationType){ | |
481 pw.printf("%s[%d]: %s (%s, type path=%s, type index=%d, bound=%d)", indent, annotationIndex, annotationType, | |
482 ClassFile.getTargetTypeName(targetType), ClassFile.getTypePathEncoding(typePath), typeParamIdx, boundIdx); | |
483 } | |
484 @Override | |
485 public void setTypeAnnotation(ClassFile cf, Object tag, int annotationIndex, int targetType, | |
486 short[] typePath, String annotationType){ | |
487 pw.printf("%s[%d]: %s (%s, type path=%s)", indent, annotationIndex, annotationType, | |
488 ClassFile.getTargetTypeName(targetType), ClassFile.getTypePathEncoding(typePath)); | |
489 } | |
490 @Override | |
491 public void setFormalParameterAnnotation(ClassFile cf, Object tag, int annotationIndex, int targetType, | |
492 int formalParamIdx, short[] typePath, String annotationType){ | |
493 pw.printf("%s[%d]: %s (%s, type path=%s, formal param index=%d)", indent, annotationIndex, annotationType, | |
494 ClassFile.getTargetTypeName(targetType), ClassFile.getTypePathEncoding(typePath), formalParamIdx); | |
495 } | |
496 @Override | |
497 public void setThrowsAnnotation(ClassFile cf, Object tag, int annotationIndex, int targetType, | |
498 int throwsTypeIdx, short[] typePath, String annotationType){ | |
499 pw.printf("%s[%d]: %s (%s, type path=%s, throws index=%d)", indent, annotationIndex, annotationType, | |
500 ClassFile.getTargetTypeName(targetType), ClassFile.getTypePathEncoding(typePath), throwsTypeIdx); | |
501 } | |
502 @Override | |
503 public void setVariableAnnotation(ClassFile cf, Object tag, int annotationIndex, int targetType, | |
504 long[] scopeEntries, short[] typePath, String annotationType){ | |
505 pw.printf("%s[%d]: %s (%s, type path=%s, scope=%s)", indent, annotationIndex, annotationType, | |
506 ClassFile.getTargetTypeName(targetType), ClassFile.getTypePathEncoding(typePath), ClassFile.getScopeEncoding(scopeEntries)); | |
507 // 2do | |
508 } | |
509 @Override | |
510 public void setExceptionParameterAnnotation(ClassFile cf, Object tag, int annotationIndex, int targetType, | |
511 int exceptionIndex, short[] typePath, String annotationType){ | |
512 pw.printf("%s[%d]: %s (%s, type path=%s, catch type index=%d)", indent, annotationIndex, annotationType, | |
513 ClassFile.getTargetTypeName(targetType), ClassFile.getTypePathEncoding(typePath), exceptionIndex); | |
514 } | |
515 @Override | |
516 public void setBytecodeAnnotation(ClassFile cf, Object tag, int annotationIndex, int targetType, | |
517 int offset, short[] typePath, String annotationType){ | |
518 pw.printf("%s[%d]: %s (%s, type path=%s, bytecode offset=%d)", indent, annotationIndex, annotationType, | |
519 ClassFile.getTargetTypeName(targetType), ClassFile.getTypePathEncoding(typePath), offset); | |
520 } | |
521 @Override | |
522 public void setBytecodeTypeParameterAnnotation(ClassFile cf, Object tag, int annotationIndex, int targetType, | |
523 int offset, int typeArgIdx, short[] typePath, String annotationType){ | |
524 pw.printf("%s[%d]: %s (%s, type path=%s, bytecode offset=%d, type arg=%d)", indent, annotationIndex, annotationType, | |
525 ClassFile.getTargetTypeName(targetType), ClassFile.getTypePathEncoding(typePath), offset, typeArgIdx); | |
526 } | |
527 | |
528 @Override | |
529 public void setTypeAnnotationsDone(ClassFile cf, Object tag) { | |
530 decIndent(); | |
531 } | |
532 | |
533 @Override | |
534 public void setAnnotationValueCount(ClassFile cf, Object tag, int annotationIndex, int nValuePairs){ | |
535 pw.printf(" valueCount=%d\n", nValuePairs); | |
536 incIndent(); | |
537 } | |
538 | |
539 @Override | |
540 public void setPrimitiveAnnotationValue(ClassFile cf, Object tag, int annotationIndex, int valueIndex, | |
541 String elementName, int arrayIndex, Object val){ | |
542 if (arrayIndex < 0){ | |
543 pw.printf("%s[%d]: %s=%s\n", indent, annotationIndex, elementName, val); | |
544 } else { | |
545 if (arrayIndex==0) { | |
546 pw.printf("%s[%d]: %s={", indent, valueIndex, elementName); | |
547 } else { | |
548 pw.print(','); | |
549 } | |
550 pw.print(val); | |
551 } | |
552 } | |
553 | |
554 @Override | |
555 public void setStringAnnotationValue(ClassFile cf, Object tag, int annotationIndex, int valueIndex, | |
556 String elementName, int arrayIndex, String s){ | |
557 if (arrayIndex < 0){ | |
558 pw.printf("%s[%d]: %s=\"%s\"\n", indent, annotationIndex, elementName, s); | |
559 } else { | |
560 if (arrayIndex==0) { | |
561 pw.printf("%s[%d]: %s={", indent, valueIndex, elementName); | |
562 } else { | |
563 pw.print(','); | |
564 } | |
565 pw.printf("\"%s\"", s); | |
566 } | |
567 } | |
568 | |
569 @Override | |
570 public void setClassAnnotationValue(ClassFile cf, Object tag, int annotationIndex, int valueIndex, | |
571 String elementName, int arrayIndex, String typeName){ | |
572 if (arrayIndex < 0){ | |
573 pw.printf("%s[%d]: %s=class %s\n", indent, annotationIndex, elementName, typeName); | |
574 } else { | |
575 if (arrayIndex==0) { | |
576 pw.printf("%s[%d]: %s={", indent, valueIndex, elementName); | |
577 } else { | |
578 pw.print(','); | |
579 } | |
580 pw.printf("class %s", typeName); | |
581 } | |
582 } | |
583 | |
584 @Override | |
585 public void setEnumAnnotationValue(ClassFile cf, Object tag, int annotationIndex, int valueIndex, | |
586 String elementName, int arrayIndex, String enumType, String enumValue){ | |
587 if (arrayIndex < 0){ | |
588 pw.printf("%s[%d]: %s=%s.%s\n", indent, annotationIndex, elementName, enumType, enumValue); | |
589 } else { | |
590 if (arrayIndex==0) { | |
591 pw.printf("%s[%d]: %s={", indent, valueIndex, elementName); | |
592 } else { | |
593 pw.print(','); | |
594 } | |
595 pw.printf("%s.%s", enumType, enumValue); | |
596 } | |
597 } | |
598 | |
599 | |
600 @Override | |
601 public void setAnnotationValueElementCount(ClassFile cf, Object tag, int annotationIndex, int valueIndex, | |
602 String elementName, int elementCount){ | |
603 } | |
604 @Override | |
605 public void setAnnotationValueElementsDone(ClassFile cf, Object tag, int annotationIndex, int valueIndex, | |
606 String elementName){ | |
607 pw.println("}"); | |
608 } | |
609 | |
610 @Override | |
611 public void setAnnotationValuesDone(ClassFile cf, Object tag, int annotationIndex){ | |
612 decIndent(); | |
613 } | |
614 | |
615 @Override | |
616 public void setParameterCount(ClassFile cf, Object tag, int parameterCount){ | |
617 pw.printf(" parameterCount=%d\n", parameterCount); | |
618 incIndent(); | |
619 } | |
620 | |
621 @Override | |
622 public void setParameterAnnotationCount(ClassFile cf, Object tag, int paramIndex, int annotationCount){ | |
623 pw.printf("%s[%d] count: %d\n", indent, paramIndex, annotationCount); | |
624 incIndent(); | |
625 } | |
626 | |
627 @Override | |
628 public void setParameterAnnotation(ClassFile cf, Object tag, int annotationIndex, String annotationType){ | |
629 pw.printf("%s[%d]: %s", indent, annotationIndex, annotationType); | |
630 } | |
631 | |
632 @Override | |
633 public void setParameterAnnotationsDone(ClassFile cf, Object tag, int paramIndex){ | |
634 decIndent(); | |
635 } | |
636 | |
637 @Override | |
638 public void setParametersDone(ClassFile cf, Object tag){ | |
639 decIndent(); | |
640 } | |
641 | |
642 | |
643 @Override | |
644 public void setSignature(ClassFile cf, Object tag, String signature){ | |
645 pw.printf(" %s\n", signature); | |
646 } | |
647 | |
648 //--- internal stuff | |
649 | |
650 protected void printCp (PrintWriter pw, ClassFile cf){ | |
651 int nCpEntries = cf.getNumberOfCpEntries(); | |
652 | |
653 for (int i=1; i<nCpEntries; i++){ | |
654 | |
655 int j = cf.getDataPosOfCpEntry(i); | |
656 | |
657 pw.print(" ["); | |
658 pw.print(i); | |
659 pw.print("]: "); | |
660 | |
661 if (j < 0) { | |
662 pw.println("<unused>"); | |
663 continue; | |
664 } | |
665 | |
666 switch (cf.u1(j)){ | |
667 case ClassFile.CONSTANT_UTF8: | |
668 pw.print( "constant_utf8 {\""); | |
669 pw.print( cf.getCpValue(i)); | |
670 pw.println("\"}"); | |
671 break; | |
672 case ClassFile.CONSTANT_INTEGER: | |
673 pw.print( "constant_integer {"); | |
674 pw.print( cf.getCpValue(i)); | |
675 pw.println("}"); | |
676 break; | |
677 case ClassFile.CONSTANT_FLOAT: | |
678 pw.print( "constant_float {"); | |
679 pw.print( cf.getCpValue(i)); | |
680 pw.println("}"); | |
681 break; | |
682 case ClassFile.CONSTANT_LONG: | |
683 pw.print( "constant_long {"); | |
684 pw.print( cf.getCpValue(i)); | |
685 pw.println("}"); | |
686 break; | |
687 case ClassFile.CONSTANT_DOUBLE: | |
688 pw.print( "constant_double {"); | |
689 pw.print( cf.getCpValue(i)); | |
690 pw.println("}"); | |
691 break; | |
692 case ClassFile.CONSTANT_CLASS: | |
693 pw.print("constant_class {name=#"); | |
694 pw.print( cf.u2(j+1)); | |
695 pw.print("(\""); | |
696 pw.print( cf.classNameAt(i)); | |
697 pw.println("\")}"); | |
698 break; | |
699 case ClassFile.CONSTANT_STRING: | |
700 pw.print("constant_string {utf8=#"); | |
701 pw.print( cf.u2(j+1)); | |
702 pw.print("(\""); | |
703 pw.print( cf.stringAt(i)); | |
704 pw.println("\")}"); | |
705 break; | |
706 case ClassFile.FIELD_REF: | |
707 printRef(pw, cf, i, j, "fieldref"); | |
708 break; | |
709 case ClassFile.METHOD_REF: | |
710 printRef(pw, cf, i, j, "methodref"); | |
711 break; | |
712 case ClassFile.INTERFACE_METHOD_REF: | |
713 printRef(pw, cf, i, j, "interface_methodref"); | |
714 break; | |
715 case ClassFile.NAME_AND_TYPE: | |
716 pw.print("name_and_type {name=#"); | |
717 pw.print( cf.u2(j+1)); | |
718 pw.print("(\""); | |
719 pw.print(cf.utf8At(cf.u2(j+1))); | |
720 pw.print("\"),desciptor=#"); | |
721 pw.print( cf.u2(j+3)); | |
722 pw.print("(\""); | |
723 pw.print(cf.utf8At(cf.u2(j+3))); | |
724 pw.println("\")}"); | |
725 break; | |
726 | |
727 case ClassFile.METHOD_HANDLE: | |
728 pw.print("method_handle {"); | |
729 pw.print("(\""); | |
730 pw.println("\")}"); | |
731 break; | |
732 | |
733 case ClassFile.METHOD_TYPE: | |
734 pw.print("method_type {"); | |
735 pw.print("(\""); | |
736 pw.println("\")}"); | |
737 break; | |
738 | |
739 case ClassFile.INVOKE_DYNAMIC: | |
740 pw.print("invoke_dynamic {bootstrap=#"); | |
741 pw.print(cf.u2(j+1)); | |
742 pw.print("(\""); | |
743 pw.println("\")}"); | |
744 break; | |
745 | |
746 default: | |
747 pw.print("ERROR: illegal tag" + cf.u1(j)); | |
748 } | |
749 } | |
750 pw.println(); | |
751 } | |
752 | |
753 void printRef(PrintWriter pw, ClassFile cf, int cpIdx, int dataPos, String refType){ | |
754 pw.print(refType); | |
755 pw.print(" {class=#"); | |
756 pw.print(cf.u2(dataPos + 1)); | |
757 pw.print("(\""); | |
758 pw.print(cf.refClassNameAt(cpIdx)); | |
759 pw.print("\"),nameType=#"); | |
760 pw.print(cf.u2(dataPos + 3)); | |
761 pw.print("(\""); | |
762 pw.print(cf.refNameAt(cpIdx)); | |
763 pw.print("\",\""); | |
764 pw.print(cf.refDescriptorAt(cpIdx)); | |
765 pw.println("\")}"); | |
766 } | |
767 | |
768 void printRawData(PrintWriter pw, ClassFile cf, int dataLength, int maxBytes){ | |
769 int max = Math.min(dataLength, maxBytes); | |
770 int max1 = max-1; | |
771 for (int i=0; i<max1; i++){ | |
772 pw.printf("%02x ", cf.readUByte()); | |
773 } | |
774 pw.printf("%02x", cf.readUByte()); | |
775 | |
776 if (dataLength>maxBytes){ | |
777 pw.print(".."); | |
778 } | |
779 } | |
780 } |