KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > optimize > info > ExceptionInstructionChecker


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.optimize.info;
22
23 import proguard.classfile.util.SimplifiedVisitor;
24 import proguard.classfile.instruction.visitor.InstructionVisitor;
25 import proguard.classfile.instruction.*;
26 import proguard.classfile.constant.*;
27 import proguard.classfile.constant.visitor.ConstantVisitor;
28 import proguard.classfile.*;
29 import proguard.classfile.visitor.MemberVisitor;
30 import proguard.classfile.attribute.CodeAttribute;
31
32 /**
33  * This class can tell whether an instruction might throw exceptions.
34  *
35  * @author Eric Lafortune
36  */

37 public class ExceptionInstructionChecker
38 extends SimplifiedVisitor
39 implements InstructionVisitor,
40              ConstantVisitor,
41              MemberVisitor
42 {
43     // A return value for the visitor methods.
44
private boolean mayThrowExceptions;
45
46
47     /**
48      * Returns whether the given instruction may throw exceptions.
49      */

50     public boolean mayThrowExceptions(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
51     {
52         mayThrowExceptions = false;
53
54         instruction.accept(clazz, method, codeAttribute, offset, this);
55
56         return mayThrowExceptions;
57     }
58
59
60     // Implementations for InstructionVisitor.
61

62     public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
63
64
65     public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)
66     {
67         byte opcode = simpleInstruction.opcode;
68
69         // Check for instructions that may throw exceptions.
70
if (opcode == InstructionConstants.OP_IDIV ||
71             opcode == InstructionConstants.OP_LDIV ||
72             opcode == InstructionConstants.OP_IREM ||
73             opcode == InstructionConstants.OP_LREM ||
74             opcode == InstructionConstants.OP_IALOAD ||
75             opcode == InstructionConstants.OP_LALOAD ||
76             opcode == InstructionConstants.OP_FALOAD ||
77             opcode == InstructionConstants.OP_DALOAD ||
78             opcode == InstructionConstants.OP_AALOAD ||
79             opcode == InstructionConstants.OP_BALOAD ||
80             opcode == InstructionConstants.OP_CALOAD ||
81             opcode == InstructionConstants.OP_SALOAD ||
82             opcode == InstructionConstants.OP_IASTORE ||
83             opcode == InstructionConstants.OP_LASTORE ||
84             opcode == InstructionConstants.OP_FASTORE ||
85             opcode == InstructionConstants.OP_DASTORE ||
86             opcode == InstructionConstants.OP_AASTORE ||
87             opcode == InstructionConstants.OP_BASTORE ||
88             opcode == InstructionConstants.OP_CASTORE ||
89             opcode == InstructionConstants.OP_SASTORE ||
90             opcode == InstructionConstants.OP_NEWARRAY ||
91             opcode == InstructionConstants.OP_ARRAYLENGTH ||
92             opcode == InstructionConstants.OP_ATHROW ||
93             opcode == InstructionConstants.OP_MONITORENTER ||
94             opcode == InstructionConstants.OP_MONITOREXIT)
95         {
96             // These instructions may throw exceptions.
97
mayThrowExceptions = true;
98         }
99
100     }
101
102
103     public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
104     {
105         byte opcode = constantInstruction.opcode;
106
107         // Check for instructions that may throw exceptions.
108
if (opcode == InstructionConstants.OP_GETSTATIC ||
109             opcode == InstructionConstants.OP_PUTSTATIC ||
110             opcode == InstructionConstants.OP_GETFIELD ||
111             opcode == InstructionConstants.OP_PUTFIELD ||
112             opcode == InstructionConstants.OP_INVOKEVIRTUAL ||
113             opcode == InstructionConstants.OP_INVOKESPECIAL ||
114             opcode == InstructionConstants.OP_INVOKESTATIC ||
115             opcode == InstructionConstants.OP_INVOKEINTERFACE ||
116             opcode == InstructionConstants.OP_NEW ||
117             opcode == InstructionConstants.OP_ANEWARRAY ||
118             opcode == InstructionConstants.OP_CHECKCAST ||
119             opcode == InstructionConstants.OP_MULTIANEWARRAY)
120         {
121             // These instructions may throw exceptions.
122
mayThrowExceptions = true;
123         }
124 // else
125
// if (opcode == InstructionConstants.OP_INVOKEVIRTUAL ||
126
// opcode == InstructionConstants.OP_INVOKESPECIAL ||
127
// opcode == InstructionConstants.OP_INVOKESTATIC ||
128
// opcode == InstructionConstants.OP_INVOKEINTERFACE)
129
// {
130
// // Check if the invoking the method may throw an exception.
131
// clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
132
// }
133
}
134
135
136     // Implementations for ConstantVisitor.
137

138     public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant)
139     {
140         Member referencedMember = refConstant.referencedMember;
141
142         // Do we have a reference to the method?
143
if (referencedMember == null)
144         {
145             // We'll have to assume invoking the unknown method may throw an
146
// an exception.
147
mayThrowExceptions = true;
148         }
149         else
150         {
151             // First check the referenced method itself.
152
refConstant.referencedMemberAccept(this);
153
154             // If the result isn't conclusive, check down the hierarchy.
155
if (!mayThrowExceptions)
156             {
157                 Clazz referencedClass = refConstant.referencedClass;
158                 Method referencedMethod = (Method)referencedMember;
159
160                 // Check all other implementations of the method in the class
161
// hierarchy.
162
referencedClass.methodImplementationsAccept(referencedMethod,
163                                                             false,
164                                                             this);
165             }
166         }
167     }
168
169
170     // Implementations for MemberVisitor.
171

172     public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
173     {
174 // mayThrowExceptions = mayThrowExceptions ||
175
// ExceptionMethodMarker.mayThrowExceptions(programMethod);
176
}
177
178
179     public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
180     {
181 // mayThrowExceptions = mayThrowExceptions ||
182
// !NoExceptionMethodMarker.doesntThrowExceptions(libraryMethod);
183
}
184 }
185
Popular Tags