KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > classfile > io > ProgramClassReader


1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  * of Java bytecode.
4  *
5  * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21 package proguard.classfile.io;
22
23 import proguard.classfile.*;
24 import proguard.classfile.attribute.*;
25 import proguard.classfile.attribute.annotation.*;
26 import proguard.classfile.attribute.annotation.visitor.*;
27 import proguard.classfile.attribute.preverification.*;
28 import proguard.classfile.attribute.preverification.visitor.*;
29 import proguard.classfile.attribute.visitor.*;
30 import proguard.classfile.constant.*;
31 import proguard.classfile.constant.visitor.ConstantVisitor;
32 import proguard.classfile.util.*;
33 import proguard.classfile.visitor.*;
34
35 import java.io.DataInput JavaDoc;
36
37 /**
38  * This ClassVisitor fills out the ProgramClass objects that it visits with data
39  * from the given DataInput object.
40  *
41  * @author Eric Lafortune
42  */

43 public class ProgramClassReader
44 extends SimplifiedVisitor
45 implements ClassVisitor,
46              MemberVisitor,
47              ConstantVisitor,
48              AttributeVisitor,
49              InnerClassesInfoVisitor,
50              ExceptionInfoVisitor,
51              StackMapFrameVisitor,
52              VerificationTypeVisitor,
53              LineNumberInfoVisitor,
54              LocalVariableInfoVisitor,
55              LocalVariableTypeInfoVisitor,
56              AnnotationVisitor,
57              ElementValueVisitor
58 {
59     private RuntimeDataInput dataInput;
60
61
62     /**
63      * Creates a new ProgramClassReader for reading from the given DataInput.
64      */

65     public ProgramClassReader(DataInput JavaDoc dataInput)
66     {
67         this.dataInput = new RuntimeDataInput(dataInput);
68     }
69
70
71     // Implementations for ClassVisitor.
72

73     public void visitProgramClass(ProgramClass programClass)
74     {
75         // Read and check the magic number.
76
programClass.u4magic = dataInput.readInt();
77
78         ClassUtil.checkMagicNumber(programClass.u4magic);
79
80         // Read and check the version numbers.
81
int u2minorVersion = dataInput.readUnsignedShort();
82         int u2majorVersion = dataInput.readUnsignedShort();
83
84         programClass.u4version = ClassUtil.internalClassVersion(u2majorVersion,
85                                                                 u2minorVersion);
86
87         ClassUtil.checkVersionNumbers(programClass.u4version);
88
89         // Read the constant pool. Note that the first entry is not used.
90
programClass.u2constantPoolCount = dataInput.readUnsignedShort();
91
92         programClass.constantPool = new Constant[programClass.u2constantPoolCount];
93         for (int index = 1; index < programClass.u2constantPoolCount; index++)
94         {
95             Constant constant = createConstant();
96             constant.accept(programClass, this);
97             programClass.constantPool[index] = constant;
98
99             // Long constants and double constants take up two entries in the
100
// constant pool.
101
int tag = constant.getTag();
102             if (tag == ClassConstants.CONSTANT_Long ||
103                 tag == ClassConstants.CONSTANT_Double)
104             {
105                 programClass.constantPool[++index] = null;
106             }
107         }
108
109         // Read the general class information.
110
programClass.u2accessFlags = dataInput.readUnsignedShort();
111         programClass.u2thisClass = dataInput.readUnsignedShort();
112         programClass.u2superClass = dataInput.readUnsignedShort();
113
114         // Read the interfaces.
115
programClass.u2interfacesCount = dataInput.readUnsignedShort();
116
117         programClass.u2interfaces = new int[programClass.u2interfacesCount];
118         for (int index = 0; index < programClass.u2interfacesCount; index++)
119         {
120             programClass.u2interfaces[index] = dataInput.readUnsignedShort();
121         }
122
123         // Read the fields.
124
programClass.u2fieldsCount = dataInput.readUnsignedShort();
125
126         programClass.fields = new ProgramField[programClass.u2fieldsCount];
127         for (int index = 0; index < programClass.u2fieldsCount; index++)
128         {
129             ProgramField programField = new ProgramField();
130             this.visitProgramField(programClass, programField);
131             programClass.fields[index] = programField;
132         }
133
134         // Read the methods.
135
programClass.u2methodsCount = dataInput.readUnsignedShort();
136
137         programClass.methods = new ProgramMethod[programClass.u2methodsCount];
138         for (int index = 0; index < programClass.u2methodsCount; index++)
139         {
140             ProgramMethod programMethod = new ProgramMethod();
141             this.visitProgramMethod(programClass, programMethod);
142             programClass.methods[index] = programMethod;
143         }
144
145         // Read the class attributes.
146
programClass.u2attributesCount = dataInput.readUnsignedShort();
147
148         programClass.attributes = new Attribute[programClass.u2attributesCount];
149         for (int index = 0; index < programClass.u2attributesCount; index++)
150         {
151             Attribute attribute = createAttribute(programClass);
152             attribute.accept(programClass, this);
153             programClass.attributes[index] = attribute;
154         }
155     }
156
157
158     public void visitLibraryClass(LibraryClass libraryClass)
159     {
160     }
161
162
163     // Implementations for MemberVisitor.
164

165     public void visitProgramField(ProgramClass programClass, ProgramField programField)
166     {
167         // Read the general field information.
168
programField.u2accessFlags = dataInput.readUnsignedShort();
169         programField.u2nameIndex = dataInput.readUnsignedShort();
170         programField.u2descriptorIndex = dataInput.readUnsignedShort();
171
172         // Read the field attributes.
173
programField.u2attributesCount = dataInput.readUnsignedShort();
174
175         programField.attributes = new Attribute[programField.u2attributesCount];
176         for (int index = 0; index < programField.u2attributesCount; index++)
177         {
178             Attribute attribute = createAttribute(programClass);
179             attribute.accept(programClass, programField, this);
180             programField.attributes[index] = attribute;
181         }
182     }
183
184
185     public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
186     {
187         // Read the general method information.
188
programMethod.u2accessFlags = dataInput.readUnsignedShort();
189         programMethod.u2nameIndex = dataInput.readUnsignedShort();
190         programMethod.u2descriptorIndex = dataInput.readUnsignedShort();
191
192         // Read the method attributes.
193
programMethod.u2attributesCount = dataInput.readUnsignedShort();
194
195         programMethod.attributes = new Attribute[programMethod.u2attributesCount];
196         for (int index = 0; index < programMethod.u2attributesCount; index++)
197         {
198             Attribute attribute = createAttribute(programClass);
199             attribute.accept(programClass, programMethod, this);
200             programMethod.attributes[index] = attribute;
201         }
202     }
203
204
205     public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember)
206     {
207     }
208
209
210     // Implementations for ConstantVisitor.
211

212     public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
213     {
214         integerConstant.u4value = dataInput.readInt();
215     }
216
217
218     public void visitLongConstant(Clazz clazz, LongConstant longConstant)
219     {
220         longConstant.u8value = dataInput.readLong();
221     }
222
223
224     public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
225     {
226         floatConstant.f4value = dataInput.readFloat();
227     }
228
229
230     public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
231     {
232         doubleConstant.f8value = dataInput.readDouble();
233     }
234
235
236     public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
237     {
238         stringConstant.u2stringIndex = dataInput.readUnsignedShort();
239     }
240
241
242     public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
243     {
244         int u2length = dataInput.readUnsignedShort();
245
246         // Read the UTF-8 bytes.
247
byte[] bytes = new byte[u2length];
248         dataInput.readFully(bytes);
249         utf8Constant.setBytes(bytes);
250     }
251
252
253     public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
254     {
255         refConstant.u2classIndex = dataInput.readUnsignedShort();
256         refConstant.u2nameAndTypeIndex = dataInput.readUnsignedShort();
257     }
258
259
260     public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
261     {
262         classConstant.u2nameIndex = dataInput.readUnsignedShort();
263     }
264
265
266     public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
267     {
268         nameAndTypeConstant.u2nameIndex = dataInput.readUnsignedShort();
269         nameAndTypeConstant.u2descriptorIndex = dataInput.readUnsignedShort();
270     }
271
272
273     // Implementations for AttributeVisitor.
274

275     public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
276     {
277         // Read the unknown information.
278
byte[] info = new byte[unknownAttribute.u4attributeLength];
279         dataInput.readFully(info);
280         unknownAttribute.info = info;
281     }
282
283
284     public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
285     {
286         sourceFileAttribute.u2sourceFileIndex = dataInput.readUnsignedShort();
287     }
288
289
290     public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
291     {
292         sourceDirAttribute.u2sourceDirIndex = dataInput.readUnsignedShort();
293     }
294
295
296     public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
297     {
298         // Read the inner classes.
299
innerClassesAttribute.u2classesCount = dataInput.readUnsignedShort();
300
301         innerClassesAttribute.classes = new InnerClassesInfo[innerClassesAttribute.u2classesCount];
302         for (int index = 0; index < innerClassesAttribute.u2classesCount; index++)
303         {
304             InnerClassesInfo innerClassesInfo = new InnerClassesInfo();
305             this.visitInnerClassesInfo(clazz, innerClassesInfo);
306             innerClassesAttribute.classes[index] = innerClassesInfo;
307         }
308     }
309
310
311     public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
312     {
313         enclosingMethodAttribute.u2classIndex = dataInput.readUnsignedShort();
314         enclosingMethodAttribute.u2nameAndTypeIndex = dataInput.readUnsignedShort();
315     }
316
317
318     public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
319     {
320         // This attribute does not contain any additional information.
321
}
322
323
324     public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
325     {
326         // This attribute does not contain any additional information.
327
}
328
329
330     public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
331     {
332         signatureAttribute.u2signatureIndex = dataInput.readUnsignedShort();
333     }
334
335
336     public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
337     {
338         constantValueAttribute.u2constantValueIndex = dataInput.readUnsignedShort();
339     }
340
341
342     public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
343     {
344         // Read the exceptions.
345
exceptionsAttribute.u2exceptionIndexTableLength = dataInput.readUnsignedShort();
346
347         exceptionsAttribute.u2exceptionIndexTable = new int[exceptionsAttribute.u2exceptionIndexTableLength];
348         for (int index = 0; index < exceptionsAttribute.u2exceptionIndexTableLength; index++)
349         {
350             exceptionsAttribute.u2exceptionIndexTable[index] = dataInput.readUnsignedShort();
351         }
352     }
353
354
355     public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
356     {
357         // Read the stack size and local variable frame size.
358
codeAttribute.u2maxStack = dataInput.readUnsignedShort();
359         codeAttribute.u2maxLocals = dataInput.readUnsignedShort();
360
361         // Read the byte code.
362
codeAttribute.u4codeLength = dataInput.readInt();
363
364         byte[] code = new byte[codeAttribute.u4codeLength];
365         dataInput.readFully(code);
366         codeAttribute.code = code;
367
368         // Read the exceptions.
369
codeAttribute.u2exceptionTableLength = dataInput.readUnsignedShort();
370
371         codeAttribute.exceptionTable = new ExceptionInfo[codeAttribute.u2exceptionTableLength];
372         for (int index = 0; index < codeAttribute.u2exceptionTableLength; index++)
373         {
374             ExceptionInfo exceptionInfo = new ExceptionInfo();
375             this.visitExceptionInfo(clazz, method, codeAttribute, exceptionInfo);
376             codeAttribute.exceptionTable[index] = exceptionInfo;
377         }
378
379         // Read the code attributes.
380
codeAttribute.u2attributesCount = dataInput.readUnsignedShort();
381
382         codeAttribute.attributes = new Attribute[codeAttribute.u2attributesCount];
383         for (int index = 0; index < codeAttribute.u2attributesCount; index++)
384         {
385             Attribute attribute = createAttribute(clazz);
386             attribute.accept(clazz, method, codeAttribute, this);
387             codeAttribute.attributes[index] = attribute;
388         }
389     }
390
391
392     public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
393     {
394         // Read the stack map frames (only full frames, without tag).
395
stackMapAttribute.u2stackMapFramesCount = dataInput.readUnsignedShort();
396
397         stackMapAttribute.stackMapFrames = new FullFrame[stackMapAttribute.u2stackMapFramesCount];
398         for (int index = 0; index < stackMapAttribute.u2stackMapFramesCount; index++)
399         {
400             FullFrame stackMapFrame = new FullFrame();
401             this.visitFullFrame(clazz, method, codeAttribute, index, stackMapFrame);
402             stackMapAttribute.stackMapFrames[index] = stackMapFrame;
403         }
404     }
405
406
407     public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
408     {
409         // Read the stack map frames.
410
stackMapTableAttribute.u2stackMapFramesCount = dataInput.readUnsignedShort();
411
412         stackMapTableAttribute.stackMapFrames = new StackMapFrame[stackMapTableAttribute.u2stackMapFramesCount];
413         for (int index = 0; index < stackMapTableAttribute.u2stackMapFramesCount; index++)
414         {
415             StackMapFrame stackMapFrame = createStackMapFrame();
416             stackMapFrame.accept(clazz, method, codeAttribute, 0, this);
417             stackMapTableAttribute.stackMapFrames[index] = stackMapFrame;
418         }
419     }
420
421
422     public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
423     {
424         // Read the line numbers.
425
lineNumberTableAttribute.u2lineNumberTableLength = dataInput.readUnsignedShort();
426
427         lineNumberTableAttribute.lineNumberTable = new LineNumberInfo[lineNumberTableAttribute.u2lineNumberTableLength];
428         for (int index = 0; index < lineNumberTableAttribute.u2lineNumberTableLength; index++)
429         {
430             LineNumberInfo lineNumberInfo = new LineNumberInfo();
431             this.visitLineNumberInfo(clazz, method, codeAttribute, lineNumberInfo);
432             lineNumberTableAttribute.lineNumberTable[index] = lineNumberInfo;
433         }
434     }
435
436
437     public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
438     {
439         // Read the local variables.
440
localVariableTableAttribute.u2localVariableTableLength = dataInput.readUnsignedShort();
441
442         localVariableTableAttribute.localVariableTable = new LocalVariableInfo[localVariableTableAttribute.u2localVariableTableLength];
443         for (int index = 0; index < localVariableTableAttribute.u2localVariableTableLength; index++)
444         {
445             LocalVariableInfo localVariableInfo = new LocalVariableInfo();
446             this.visitLocalVariableInfo(clazz, method, codeAttribute, localVariableInfo);
447             localVariableTableAttribute.localVariableTable[index] = localVariableInfo;
448         }
449     }
450
451
452     public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
453     {
454         // Read the local variable types.
455
localVariableTypeTableAttribute.u2localVariableTypeTableLength = dataInput.readUnsignedShort();
456
457         localVariableTypeTableAttribute.localVariableTypeTable = new LocalVariableTypeInfo[localVariableTypeTableAttribute.u2localVariableTypeTableLength];
458         for (int index = 0; index < localVariableTypeTableAttribute.u2localVariableTypeTableLength; index++)
459         {
460             LocalVariableTypeInfo localVariableTypeInfo = new LocalVariableTypeInfo();
461             this.visitLocalVariableTypeInfo(clazz, method, codeAttribute, localVariableTypeInfo);
462             localVariableTypeTableAttribute.localVariableTypeTable[index] = localVariableTypeInfo;
463         }
464     }
465
466
467     public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
468     {
469         // Read the annotations.
470
annotationsAttribute.u2annotationsCount = dataInput.readUnsignedShort();
471
472         annotationsAttribute.annotations = new Annotation[annotationsAttribute.u2annotationsCount];
473         for (int index = 0; index < annotationsAttribute.u2annotationsCount; index++)
474         {
475             Annotation annotation = new Annotation();
476             this.visitAnnotation(clazz, annotation);
477             annotationsAttribute.annotations[index] = annotation;
478         }
479     }
480
481
482     public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
483     {
484         // Read the parameter annotations.
485
parameterAnnotationsAttribute.u2parametersCount = dataInput.readUnsignedByte();
486         parameterAnnotationsAttribute.u2parameterAnnotationsCount = new int[parameterAnnotationsAttribute.u2parametersCount];
487         parameterAnnotationsAttribute.parameterAnnotations = new Annotation[parameterAnnotationsAttribute.u2parametersCount][];
488
489         for (int parameterIndex = 0; parameterIndex < parameterAnnotationsAttribute.u2parametersCount; parameterIndex++)
490         {
491             // Read the parameter annotations of the given parameter.
492
int u2annotationsCount = dataInput.readUnsignedShort();
493
494             Annotation[] annotations = new Annotation[u2annotationsCount];
495
496             for (int index = 0; index < u2annotationsCount; index++)
497             {
498                 Annotation annotation = new Annotation();
499                 this.visitAnnotation(clazz, annotation);
500                 annotations[index] = annotation;
501             }
502
503             parameterAnnotationsAttribute.u2parameterAnnotationsCount[parameterIndex] = u2annotationsCount;
504             parameterAnnotationsAttribute.parameterAnnotations[parameterIndex] = annotations;
505         }
506     }
507
508
509     public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
510     {
511         // Read the default element value.
512
ElementValue elementValue = createElementValue();
513         elementValue.accept(clazz, null, this);
514         annotationDefaultAttribute.defaultValue = elementValue;
515     }
516
517
518     // Implementations for InnerClassesInfoVisitor.
519

520     public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
521     {
522         innerClassesInfo.u2innerClassIndex = dataInput.readUnsignedShort();
523         innerClassesInfo.u2outerClassIndex = dataInput.readUnsignedShort();
524         innerClassesInfo.u2innerNameIndex = dataInput.readUnsignedShort();
525         innerClassesInfo.u2innerClassAccessFlags = dataInput.readUnsignedShort();
526     }
527
528
529     // Implementations for ExceptionInfoVisitor.
530

531     public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
532     {
533         exceptionInfo.u2startPC = dataInput.readUnsignedShort();
534         exceptionInfo.u2endPC = dataInput.readUnsignedShort();
535         exceptionInfo.u2handlerPC = dataInput.readUnsignedShort();
536         exceptionInfo.u2catchType = dataInput.readUnsignedShort();
537     }
538
539
540     // Implementations for StackMapFrameVisitor.
541

542     public void visitSameZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameZeroFrame sameZeroFrame)
543     {
544         if (sameZeroFrame.getTag() == StackMapFrame.SAME_ZERO_FRAME_EXTENDED)
545         {
546             sameZeroFrame.u2offsetDelta = dataInput.readUnsignedShort();
547         }
548     }
549
550
551     public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)
552     {
553         if (sameOneFrame.getTag() == StackMapFrame.SAME_ONE_FRAME_EXTENDED)
554         {
555             sameOneFrame.u2offsetDelta = dataInput.readUnsignedShort();
556         }
557
558         // Read the verification type of the stack entry.
559
VerificationType verificationType = createVerificationType();
560         verificationType.accept(clazz, method, codeAttribute, offset, this);
561         sameOneFrame.stackItem = verificationType;
562     }
563
564
565     public void visitLessZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LessZeroFrame lessZeroFrame)
566     {
567         lessZeroFrame.u2offsetDelta = dataInput.readUnsignedShort();
568     }
569
570
571     public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)
572     {
573         moreZeroFrame.u2offsetDelta = dataInput.readUnsignedShort();
574
575         // Read the verification types of the additional local variables.
576
moreZeroFrame.additionalVariables = new VerificationType[moreZeroFrame.additionalVariablesCount];
577         for (int index = 0; index < moreZeroFrame.additionalVariablesCount; index++)
578         {
579             VerificationType verificationType = createVerificationType();
580             verificationType.accept(clazz, method, codeAttribute, offset, this);
581             moreZeroFrame.additionalVariables[index] = verificationType;
582         }
583     }
584
585
586     public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)
587     {
588         fullFrame.u2offsetDelta = dataInput.readUnsignedShort();
589
590         // Read the verification types of the local variables.
591
fullFrame.variablesCount = dataInput.readUnsignedShort();
592         fullFrame.variables = new VerificationType[fullFrame.variablesCount];
593         for (int index = 0; index < fullFrame.variablesCount; index++)
594         {
595             VerificationType verificationType = createVerificationType();
596             verificationType.variablesAccept(clazz, method, codeAttribute, offset, index, this);
597             fullFrame.variables[index] = verificationType;
598         }
599
600         // Read the verification types of the stack entries.
601
fullFrame.stackCount = dataInput.readUnsignedShort();
602         fullFrame.stack = new VerificationType[fullFrame.stackCount];
603         for (int index = 0; index < fullFrame.stackCount; index++)
604         {
605             VerificationType verificationType = createVerificationType();
606             verificationType.stackAccept(clazz, method, codeAttribute, offset, index, this);
607             fullFrame.stack[index] = verificationType;
608         }
609     }
610
611
612     // Implementations for VerificationTypeVisitor.
613

614     public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType)
615     {
616         // Most verification types don't contain any additional information.
617
}
618
619
620     public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType)
621     {
622         objectType.u2classIndex = dataInput.readUnsignedShort();
623     }
624
625
626     public void visitUninitializedType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedType uninitializedType)
627     {
628         uninitializedType.u2newInstructionOffset = dataInput.readUnsignedShort();
629     }
630
631
632     // Implementations for LineNumberInfoVisitor.
633

634     public void visitLineNumberInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfo lineNumberInfo)
635     {
636         lineNumberInfo.u2startPC = dataInput.readUnsignedShort();
637         lineNumberInfo.u2lineNumber = dataInput.readUnsignedShort();
638     }
639
640
641     // Implementations for LocalVariableInfoVisitor.
642

643     public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
644     {
645         localVariableInfo.u2startPC = dataInput.readUnsignedShort();
646         localVariableInfo.u2length = dataInput.readUnsignedShort();
647         localVariableInfo.u2nameIndex = dataInput.readUnsignedShort();
648         localVariableInfo.u2descriptorIndex = dataInput.readUnsignedShort();
649         localVariableInfo.u2index = dataInput.readUnsignedShort();
650     }
651
652
653     // Implementations for LocalVariableTypeInfoVisitor.
654

655     public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
656     {
657         localVariableTypeInfo.u2startPC = dataInput.readUnsignedShort();
658         localVariableTypeInfo.u2length = dataInput.readUnsignedShort();
659         localVariableTypeInfo.u2nameIndex = dataInput.readUnsignedShort();
660         localVariableTypeInfo.u2signatureIndex = dataInput.readUnsignedShort();
661         localVariableTypeInfo.u2index = dataInput.readUnsignedShort();
662     }
663
664
665     // Implementations for AnnotationVisitor.
666

667     public void visitAnnotation(Clazz clazz, Annotation annotation)
668     {
669         // Read the annotation type.
670
annotation.u2typeIndex = dataInput.readUnsignedShort();
671
672         // Read the element value pairs.
673
annotation.u2elementValuesCount = dataInput.readUnsignedShort();
674
675         annotation.elementValues = new ElementValue[annotation.u2elementValuesCount];
676         for (int index = 0; index < annotation.u2elementValuesCount; index++)
677         {
678             int u2elementNameIndex = dataInput.readUnsignedShort();
679             ElementValue elementValue = createElementValue();
680             elementValue.u2elementNameIndex = u2elementNameIndex;
681             elementValue.accept(clazz, annotation, this);
682             annotation.elementValues[index] = elementValue;
683         }
684     }
685
686
687     // Implementations for ElementValueVisitor.
688

689     public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
690     {
691         constantElementValue.u2constantValueIndex = dataInput.readUnsignedShort();
692     }
693
694
695     public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
696     {
697         enumConstantElementValue.u2typeNameIndex = dataInput.readUnsignedShort();
698         enumConstantElementValue.u2constantNameIndex = dataInput.readUnsignedShort();
699     }
700
701
702     public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
703     {
704         classElementValue.u2classInfoIndex = dataInput.readUnsignedShort();
705     }
706
707
708     public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
709     {
710         // Read the annotation.
711
Annotation annotationValue = new Annotation();
712         this.visitAnnotation(clazz, annotationValue);
713         annotationElementValue.annotationValue = annotationValue;
714     }
715
716
717     public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
718     {
719         // Read the element values.
720
arrayElementValue.u2elementValuesCount = dataInput.readUnsignedShort();
721
722         arrayElementValue.elementValues = new ElementValue[arrayElementValue.u2elementValuesCount];
723         for (int index = 0; index < arrayElementValue.u2elementValuesCount; index++)
724         {
725             ElementValue elementValue = createElementValue();
726             elementValue.accept(clazz, annotation, this);
727             arrayElementValue.elementValues[index] = elementValue;
728         }
729     }
730
731
732     // Small utility methods.
733

734     private Constant createConstant()
735     {
736         int u1tag = dataInput.readUnsignedByte();
737
738         switch (u1tag)
739         {
740             case ClassConstants.CONSTANT_Utf8: return new Utf8Constant();
741             case ClassConstants.CONSTANT_Integer: return new IntegerConstant();
742             case ClassConstants.CONSTANT_Float: return new FloatConstant();
743             case ClassConstants.CONSTANT_Long: return new LongConstant();
744             case ClassConstants.CONSTANT_Double: return new DoubleConstant();
745             case ClassConstants.CONSTANT_String: return new StringConstant();
746             case ClassConstants.CONSTANT_Fieldref: return new FieldrefConstant();
747             case ClassConstants.CONSTANT_Methodref: return new MethodrefConstant();
748             case ClassConstants.CONSTANT_InterfaceMethodref: return new InterfaceMethodrefConstant();
749             case ClassConstants.CONSTANT_Class: return new ClassConstant();
750             case ClassConstants.CONSTANT_NameAndType: return new NameAndTypeConstant();
751
752             default: throw new RuntimeException JavaDoc("Unknown constant type ["+u1tag+"] in constant pool");
753         }
754     }
755
756
757     private Attribute createAttribute(Clazz clazz)
758     {
759         int u2attributeNameIndex = dataInput.readUnsignedShort();
760         int u4attributeLength = dataInput.readInt();
761         String JavaDoc attributeName = clazz.getString(u2attributeNameIndex);
762         Attribute attribute =
763             attributeName.equals(ClassConstants.ATTR_SourceFile) ? (Attribute)new SourceFileAttribute():
764             attributeName.equals(ClassConstants.ATTR_SourceDir) ? (Attribute)new SourceDirAttribute():
765             attributeName.equals(ClassConstants.ATTR_InnerClasses) ? (Attribute)new InnerClassesAttribute():
766             attributeName.equals(ClassConstants.ATTR_EnclosingMethod) ? (Attribute)new EnclosingMethodAttribute():
767             attributeName.equals(ClassConstants.ATTR_Deprecated) ? (Attribute)new DeprecatedAttribute():
768             attributeName.equals(ClassConstants.ATTR_Synthetic) ? (Attribute)new SyntheticAttribute():
769             attributeName.equals(ClassConstants.ATTR_Signature) ? (Attribute)new SignatureAttribute():
770             attributeName.equals(ClassConstants.ATTR_ConstantValue) ? (Attribute)new ConstantValueAttribute():
771             attributeName.equals(ClassConstants.ATTR_Exceptions) ? (Attribute)new ExceptionsAttribute():
772             attributeName.equals(ClassConstants.ATTR_Code) ? (Attribute)new CodeAttribute():
773             attributeName.equals(ClassConstants.ATTR_StackMap) ? (Attribute)new StackMapAttribute():
774             attributeName.equals(ClassConstants.ATTR_StackMapTable) ? (Attribute)new StackMapTableAttribute():
775             attributeName.equals(ClassConstants.ATTR_LineNumberTable) ? (Attribute)new LineNumberTableAttribute():
776             attributeName.equals(ClassConstants.ATTR_LocalVariableTable) ? (Attribute)new LocalVariableTableAttribute():
777             attributeName.equals(ClassConstants.ATTR_LocalVariableTypeTable) ? (Attribute)new LocalVariableTypeTableAttribute():
778             attributeName.equals(ClassConstants.ATTR_RuntimeVisibleAnnotations) ? (Attribute)new RuntimeVisibleAnnotationsAttribute():
779             attributeName.equals(ClassConstants.ATTR_RuntimeInvisibleAnnotations) ? (Attribute)new RuntimeInvisibleAnnotationsAttribute():
780             attributeName.equals(ClassConstants.ATTR_RuntimeVisibleParameterAnnotations) ? (Attribute)new RuntimeVisibleParameterAnnotationsAttribute():
781             attributeName.equals(ClassConstants.ATTR_RuntimeInvisibleParameterAnnotations) ? (Attribute)new RuntimeInvisibleParameterAnnotationsAttribute():
782             attributeName.equals(ClassConstants.ATTR_AnnotationDefault) ? (Attribute)new AnnotationDefaultAttribute():
783                                                                                              (Attribute)new UnknownAttribute(u4attributeLength);
784         attribute.u2attributeNameIndex = u2attributeNameIndex;
785
786         return attribute;
787     }
788
789
790     private StackMapFrame createStackMapFrame()
791     {
792         int u1tag = dataInput.readUnsignedByte();
793
794         return
795             u1tag < StackMapFrame.SAME_ONE_FRAME ? (StackMapFrame)new SameZeroFrame(u1tag) :
796             u1tag < StackMapFrame.SAME_ONE_FRAME_EXTENDED ? (StackMapFrame)new SameOneFrame(u1tag) :
797             u1tag < StackMapFrame.LESS_ZERO_FRAME ? (StackMapFrame)new SameOneFrame(u1tag) :
798             u1tag < StackMapFrame.SAME_ZERO_FRAME_EXTENDED ? (StackMapFrame)new LessZeroFrame(u1tag) :
799             u1tag < StackMapFrame.MORE_ZERO_FRAME ? (StackMapFrame)new SameZeroFrame(u1tag) :
800             u1tag < StackMapFrame.FULL_FRAME ? (StackMapFrame)new MoreZeroFrame(u1tag) :
801                                                              (StackMapFrame)new FullFrame();
802     }
803
804
805     private VerificationType createVerificationType()
806     {
807         int u1tag = dataInput.readUnsignedByte();
808
809         switch (u1tag)
810         {
811             case VerificationType.INTEGER_TYPE: return new IntegerType();
812             case VerificationType.FLOAT_TYPE: return new FloatType();
813             case VerificationType.LONG_TYPE: return new LongType();
814             case VerificationType.DOUBLE_TYPE: return new DoubleType();
815             case VerificationType.TOP_TYPE: return new TopType();
816             case VerificationType.OBJECT_TYPE: return new ObjectType();
817             case VerificationType.NULL_TYPE: return new NullType();
818             case VerificationType.UNINITIALIZED_TYPE: return new UninitializedType();
819             case VerificationType.UNINITIALIZED_THIS_TYPE: return new UninitializedThisType();
820
821             default: throw new RuntimeException JavaDoc("Unknown verification type ["+u1tag+"] in stack map frame");
822         }
823     }
824
825
826     private ElementValue createElementValue()
827     {
828         int u1tag = dataInput.readUnsignedByte();
829
830         switch (u1tag)
831         {
832             case ClassConstants.INTERNAL_TYPE_BOOLEAN:
833             case ClassConstants.INTERNAL_TYPE_BYTE:
834             case ClassConstants.INTERNAL_TYPE_CHAR:
835             case ClassConstants.INTERNAL_TYPE_SHORT:
836             case ClassConstants.INTERNAL_TYPE_INT:
837             case ClassConstants.INTERNAL_TYPE_FLOAT:
838             case ClassConstants.INTERNAL_TYPE_LONG:
839             case ClassConstants.INTERNAL_TYPE_DOUBLE:
840             case ClassConstants.ELEMENT_VALUE_STRING_CONSTANT: return new ConstantElementValue(u1tag);
841
842             case ClassConstants.ELEMENT_VALUE_ENUM_CONSTANT: return new EnumConstantElementValue();
843             case ClassConstants.ELEMENT_VALUE_CLASS: return new ClassElementValue();
844             case ClassConstants.ELEMENT_VALUE_ANNOTATION: return new AnnotationElementValue();
845             case ClassConstants.ELEMENT_VALUE_ARRAY: return new ArrayElementValue();
846
847             default: throw new IllegalArgumentException JavaDoc("Unknown element value tag ["+u1tag+"]");
848         }
849     }
850 }
851
Popular Tags