summaryrefslogtreecommitdiff
path: root/src/proguard/optimize/info/ExceptionInstructionChecker.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/proguard/optimize/info/ExceptionInstructionChecker.java')
-rw-r--r--src/proguard/optimize/info/ExceptionInstructionChecker.java101
1 files changed, 84 insertions, 17 deletions
diff --git a/src/proguard/optimize/info/ExceptionInstructionChecker.java b/src/proguard/optimize/info/ExceptionInstructionChecker.java
index 4bfa96f..a32a1d3 100644
--- a/src/proguard/optimize/info/ExceptionInstructionChecker.java
+++ b/src/proguard/optimize/info/ExceptionInstructionChecker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -22,12 +22,9 @@ package proguard.optimize.info;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
-import proguard.classfile.constant.RefConstant;
-import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
-import proguard.classfile.visitor.MemberVisitor;
/**
* This class can tell whether an instruction might throw exceptions.
@@ -45,15 +42,90 @@ implements InstructionVisitor
/**
- * Returns whether the given instruction may throw exceptions.
+ * Returns whether the specified method may throw exceptions.
*/
- public boolean mayThrowExceptions(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
+ public boolean mayThrowExceptions(Clazz clazz,
+ Method method,
+ CodeAttribute codeAttribute)
{
- mayThrowExceptions = false;
+ return mayThrowExceptions(clazz,
+ method,
+ codeAttribute,
+ 0,
+ codeAttribute.u4codeLength);
+ }
+
+
+ /**
+ * Returns whether the specified block of code may throw exceptions.
+ */
+ public boolean mayThrowExceptions(Clazz clazz,
+ Method method,
+ CodeAttribute codeAttribute,
+ int startOffset,
+ int endOffset)
+ {
+ byte[] code = codeAttribute.code;
+
+ // Go over all instructions.
+ int offset = startOffset;
+ while (offset < endOffset)
+ {
+ // Get the current instruction.
+ Instruction instruction = InstructionFactory.create(code, offset);
- instruction.accept(clazz, method, codeAttribute, offset, this);
+ // Check if it may be throwing exceptions.
+ if (mayThrowExceptions(clazz,
+ method,
+ codeAttribute,
+ offset,
+ instruction))
+ {
+ return true;
+ }
- return mayThrowExceptions;
+ // Go to the next instruction.
+ offset += instruction.length(offset);
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Returns whether the specified instruction may throw exceptions.
+ */
+ public boolean mayThrowExceptions(Clazz clazz,
+ Method method,
+ CodeAttribute codeAttribute,
+ int offset)
+ {
+ Instruction instruction = InstructionFactory.create(codeAttribute.code, offset);
+
+ return mayThrowExceptions(clazz,
+ method,
+ codeAttribute,
+ offset,
+ instruction);
+ }
+
+
+ /**
+ * Returns whether the given instruction may throw exceptions.
+ */
+ public boolean mayThrowExceptions(Clazz clazz,
+ Method method,
+ CodeAttribute codeAttribute,
+ int offset,
+ Instruction instruction)
+ {
+ return instruction.mayThrowExceptions();
+
+// mayThrowExceptions = false;
+//
+// instruction.accept(clazz, method, codeAttribute, offset, this);
+//
+// return mayThrowExceptions;
}
@@ -64,15 +136,13 @@ implements InstructionVisitor
public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)
{
- byte opcode = simpleInstruction.opcode;
-
// Check for instructions that may throw exceptions.
// Note that monitorexit can not sensibly throw exceptions, except the
// broken and deprecated asynchronous ThreadDeath. Removing the
// artificial infinite looping exception blocks that recent compilers
// add does not strictly follow the JVM specs, but it does have the
// additional benefit of avoiding a bug in the JVM in JDK 1.1.
- switch (opcode)
+ switch (simpleInstruction.opcode)
{
case InstructionConstants.OP_IDIV:
case InstructionConstants.OP_LDIV:
@@ -101,16 +171,13 @@ implements InstructionVisitor
// These instructions may throw exceptions.
mayThrowExceptions = true;
}
-
}
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
- byte opcode = constantInstruction.opcode;
-
// Check for instructions that may throw exceptions.
- switch (opcode)
+ switch (constantInstruction.opcode)
{
case InstructionConstants.OP_GETSTATIC:
case InstructionConstants.OP_PUTSTATIC:
@@ -128,7 +195,6 @@ implements InstructionVisitor
case InstructionConstants.OP_MULTIANEWARRAY:
// These instructions may throw exceptions.
mayThrowExceptions = true;
- }
// case InstructionConstants.OP_INVOKEVIRTUAL:
// case InstructionConstants.OP_INVOKESPECIAL:
@@ -136,6 +202,7 @@ implements InstructionVisitor
// case InstructionConstants.OP_INVOKEINTERFACE:
// // Check if the invoking the method may throw an exception.
// clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ }
}