You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
358 lines
14 KiB
358 lines
14 KiB
package net.sf.jode.flow;
|
|
import net.sf.jode.decompiler.LocalInfo;
|
|
import junit.framework.*;
|
|
import net.sf.jode.expr.*;
|
|
import net.sf.jode.type.Type;
|
|
import net.sf.jode.decompiler.TabbedPrintWriter;
|
|
import net.sf.jode.GlobalOptions;
|
|
|
|
public class TrExcTest extends TestCase {
|
|
private static final boolean VERBOSE = false;
|
|
|
|
public TrExcTest(String name) {
|
|
super (name);
|
|
}
|
|
|
|
public void setUp() {
|
|
GlobalOptions.debuggingFlags |= GlobalOptions.DEBUG_CHECK;
|
|
if (VERBOSE)
|
|
GlobalOptions.debuggingFlags
|
|
|= GlobalOptions.DEBUG_ANALYZE | GlobalOptions.DEBUG_FLOW;
|
|
}
|
|
|
|
FlowBlock[] createFlowBlocks(int n) {
|
|
FlowBlock[] flows = new FlowBlock[n];
|
|
for (int i = 0; i < n; i++)
|
|
flows[i] = new FlowBlock(null, i, i > 0 ? flows[i-1] : null);
|
|
return flows;
|
|
}
|
|
|
|
public void testSynchronized11() throws java.io.IOException {
|
|
FlowBlock[] flows = createFlowBlocks(5);
|
|
LocalInfo thisLocal = new LocalInfo(null, 0);
|
|
LocalInfo tmpLocal = new LocalInfo(null, 1);
|
|
LocalInfo tmp2Local = new LocalInfo(null, 2);
|
|
|
|
/* Monitorenter */
|
|
flows[0].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, thisLocal)), thisLocal);
|
|
flows[0].appendBlock
|
|
(new InstructionBlock(new MonitorEnterOperator()));
|
|
flows[0].setSuccessors(new FlowBlock[] { flows[1] });
|
|
|
|
/* Synchronized Blocks */
|
|
flows[1].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, thisLocal)), thisLocal);
|
|
flows[1].appendWriteBlock
|
|
(new InstructionBlock
|
|
(new StoreInstruction
|
|
(new LocalStoreOperator(Type.tUObject, tmpLocal))), tmpLocal);
|
|
flows[1].appendBlock(new JsrBlock());
|
|
flows[1].setSuccessors(new FlowBlock[] { flows[4], flows[2] });
|
|
|
|
flows[2].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, tmpLocal)), tmpLocal);
|
|
flows[2].appendBlock
|
|
(new ReturnBlock(new NopOperator(Type.tUObject)));
|
|
flows[2].setSuccessors(new FlowBlock[] { FlowBlock.END_OF_METHOD });
|
|
|
|
/* Catch Exception Blocks */
|
|
flows[3].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, thisLocal)), thisLocal);
|
|
flows[3].appendBlock
|
|
(new InstructionBlock(new MonitorExitOperator()));
|
|
flows[3].appendBlock
|
|
(new ThrowBlock(new NopOperator(Type.tUObject)));
|
|
flows[3].setSuccessors(new FlowBlock[0]);
|
|
|
|
/* monitorexit subroutine */
|
|
flows[4].appendWriteBlock
|
|
(new InstructionBlock
|
|
(new StoreInstruction
|
|
(new LocalStoreOperator(Type.tUObject, tmp2Local))), tmp2Local);
|
|
flows[4].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, thisLocal)), thisLocal);
|
|
flows[4].appendBlock
|
|
(new InstructionBlock(new MonitorExitOperator()));
|
|
flows[4].appendReadBlock
|
|
(new RetBlock(tmp2Local), tmp2Local);
|
|
flows[4].setSuccessors(new FlowBlock[0]);
|
|
|
|
flows[0].addStartPred();
|
|
TransformExceptionHandlers exc = new TransformExceptionHandlers(flows);
|
|
exc.addHandler(flows[1],flows[2],flows[3], null);
|
|
exc.analyze();
|
|
flows[0].analyze();
|
|
flows[0].removeStartPred();
|
|
if (VERBOSE)
|
|
flows[0].dumpSource(new TabbedPrintWriter(GlobalOptions.err));
|
|
assertTrue(flows[0].getBlock() instanceof SynchronizedBlock);
|
|
assertTrue(flows[0].getBlock().getSubBlocks()[0]
|
|
instanceof ReturnBlock);
|
|
}
|
|
|
|
public void testSynchronized13() throws java.io.IOException {
|
|
FlowBlock[] flows = createFlowBlocks(5);
|
|
LocalInfo thisLocal = new LocalInfo(null, 0);
|
|
LocalInfo tmpLocal = new LocalInfo(null, 1);
|
|
LocalInfo tmp2Local = new LocalInfo(null, 2);
|
|
|
|
/* Monitorenter */
|
|
flows[0].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, thisLocal)), thisLocal);
|
|
flows[0].appendBlock
|
|
(new InstructionBlock(new MonitorEnterOperator()));
|
|
flows[0].setSuccessors(new FlowBlock[] { flows[1] });
|
|
|
|
/* Synchronized Blocks */
|
|
flows[1].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, thisLocal)), thisLocal);
|
|
flows[1].appendWriteBlock
|
|
(new InstructionBlock
|
|
(new StoreInstruction
|
|
(new LocalStoreOperator(Type.tUObject, tmpLocal))), tmpLocal);
|
|
flows[1].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, thisLocal)), thisLocal);
|
|
flows[1].appendBlock
|
|
(new InstructionBlock(new MonitorExitOperator()));
|
|
flows[1].setSuccessors(new FlowBlock[] { flows[2] });
|
|
|
|
flows[2].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, tmpLocal)), tmpLocal);
|
|
flows[2].appendBlock
|
|
(new ReturnBlock(new NopOperator(Type.tUObject)));
|
|
flows[2].setSuccessors(new FlowBlock[] { FlowBlock.END_OF_METHOD });
|
|
|
|
/* Catch Exception Blocks */
|
|
flows[3].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, thisLocal)), thisLocal);
|
|
flows[3].appendBlock
|
|
(new InstructionBlock(new MonitorExitOperator()));
|
|
flows[3].appendBlock
|
|
(new ThrowBlock(new NopOperator(Type.tUObject)));
|
|
flows[3].setSuccessors(new FlowBlock[0]);
|
|
|
|
/* monitorexit subroutine */
|
|
flows[4].appendWriteBlock
|
|
(new InstructionBlock
|
|
(new StoreInstruction
|
|
(new LocalStoreOperator(Type.tUObject, tmp2Local))), tmp2Local);
|
|
flows[4].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, thisLocal)), thisLocal);
|
|
flows[4].appendBlock
|
|
(new InstructionBlock(new MonitorExitOperator()));
|
|
flows[4].appendReadBlock
|
|
(new RetBlock(tmp2Local), tmp2Local);
|
|
flows[4].setSuccessors(new FlowBlock[0]);
|
|
|
|
flows[0].addStartPred();
|
|
TransformExceptionHandlers exc = new TransformExceptionHandlers(flows);
|
|
exc.addHandler(flows[1],flows[2],flows[3], null);
|
|
exc.analyze();
|
|
flows[0].analyze();
|
|
flows[0].removeStartPred();
|
|
if (VERBOSE)
|
|
flows[0].dumpSource(new TabbedPrintWriter(GlobalOptions.err));
|
|
assertTrue(flows[0].getBlock() instanceof SynchronizedBlock);
|
|
assertTrue(flows[0].getBlock().getSubBlocks()[0]
|
|
instanceof ReturnBlock);
|
|
}
|
|
|
|
public void testSpecialFin() throws java.io.IOException {
|
|
FlowBlock[] flows = createFlowBlocks(3);
|
|
LocalInfo thisLocal = new LocalInfo(null, 0);
|
|
LocalInfo tmpLocal = new LocalInfo(null, 1);
|
|
LocalInfo tmp2Local = new LocalInfo(null, 2);
|
|
|
|
/* Try Blocks */
|
|
flows[0].setSuccessors(new FlowBlock[] { flows[2] });
|
|
|
|
/* Catch Exception Blocks */
|
|
flows[1].appendBlock(new SpecialBlock(SpecialBlock.POP, 1, 0));
|
|
flows[1].setSuccessors(new FlowBlock[] { flows[2] });
|
|
|
|
/* subroutine */
|
|
flows[2].appendBlock(new DescriptionBlock("/*FINALLY*/"));
|
|
flows[2].setSuccessors(new FlowBlock[] { FlowBlock.END_OF_METHOD });
|
|
|
|
flows[0].addStartPred();
|
|
TransformExceptionHandlers exc = new TransformExceptionHandlers(flows);
|
|
exc.addHandler(flows[0],flows[0],flows[1], null);
|
|
exc.analyze();
|
|
flows[0].analyze();
|
|
flows[0].removeStartPred();
|
|
if (VERBOSE)
|
|
flows[0].dumpSource(new TabbedPrintWriter(GlobalOptions.err));
|
|
assertTrue("Try", flows[0].getBlock() instanceof TryBlock);
|
|
assertTrue("Empty", flows[0].getBlock().getSubBlocks()[0] instanceof EmptyBlock);
|
|
assertTrue("Finally", flows[0].getBlock().getSubBlocks()[1] instanceof FinallyBlock);
|
|
assertTrue("Descr", flows[0].getBlock().getSubBlocks()[1].getSubBlocks()[0] instanceof DescriptionBlock);
|
|
}
|
|
|
|
public void testSpecialFinTryLoops() throws java.io.IOException {
|
|
FlowBlock[] flows = createFlowBlocks(3);
|
|
LocalInfo thisLocal = new LocalInfo(null, 0);
|
|
LocalInfo tmpLocal = new LocalInfo(null, 1);
|
|
LocalInfo tmp2Local = new LocalInfo(null, 2);
|
|
|
|
/* Try Blocks */
|
|
flows[0].setSuccessors(new FlowBlock[] { flows[0] });
|
|
|
|
/* Catch Exception Blocks */
|
|
flows[1].appendBlock(new SpecialBlock(SpecialBlock.POP, 1, 0));
|
|
flows[1].setSuccessors(new FlowBlock[] { flows[2] });
|
|
|
|
/* subroutine */
|
|
flows[2].appendBlock(new DescriptionBlock("/*FINALLY*/"));
|
|
flows[2].setSuccessors(new FlowBlock[] { FlowBlock.END_OF_METHOD });
|
|
|
|
flows[0].addStartPred();
|
|
TransformExceptionHandlers exc = new TransformExceptionHandlers(flows);
|
|
exc.addHandler(flows[0],flows[0],flows[1], null);
|
|
exc.analyze();
|
|
flows[0].analyze();
|
|
flows[0].removeStartPred();
|
|
if (VERBOSE)
|
|
flows[0].dumpSource(new TabbedPrintWriter(GlobalOptions.err));
|
|
assertTrue("Try", flows[0].getBlock() instanceof TryBlock);
|
|
assertTrue("Loop", flows[0].getBlock().getSubBlocks()[0] instanceof LoopBlock);
|
|
assertTrue("Empty", flows[0].getBlock().getSubBlocks()[0].getSubBlocks()[0] instanceof EmptyBlock);
|
|
assertTrue("Finally", flows[0].getBlock().getSubBlocks()[1] instanceof FinallyBlock);
|
|
assertTrue("Descr", flows[0].getBlock().getSubBlocks()[1].getSubBlocks()[0] instanceof DescriptionBlock);
|
|
}
|
|
|
|
public void testFinBreaksJikes() throws java.io.IOException {
|
|
FlowBlock[] flows = createFlowBlocks(5);
|
|
LocalInfo thisLocal = new LocalInfo(null, 0);
|
|
LocalInfo tmpLocal = new LocalInfo(null, 1);
|
|
LocalInfo tmp2Local = new LocalInfo(null, 2);
|
|
|
|
/* Try Blocks */
|
|
flows[0].appendBlock(new JsrBlock());
|
|
flows[0].setSuccessors(new FlowBlock[] { flows[3], flows[4] });
|
|
|
|
/* Catch Exception Blocks */
|
|
flows[1].appendWriteBlock
|
|
(new InstructionBlock
|
|
(new StoreInstruction
|
|
(new LocalStoreOperator(Type.tUObject, tmpLocal))), tmpLocal);
|
|
flows[1].appendBlock(new JsrBlock());
|
|
flows[1].setSuccessors(new FlowBlock[] { flows[3], flows[2] });
|
|
|
|
flows[2].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, tmpLocal)), tmpLocal);
|
|
flows[2].appendBlock
|
|
(new ThrowBlock(new NopOperator(Type.tUObject)));
|
|
flows[2].setSuccessors(new FlowBlock[0]);
|
|
|
|
/* subroutine */
|
|
flows[3].appendBlock(new SpecialBlock(SpecialBlock.POP, 1, 0));
|
|
flows[3].setSuccessors(new FlowBlock[] { flows[4] });
|
|
|
|
flows[4].appendBlock(new DescriptionBlock("/*HERE*/"));
|
|
flows[4].setSuccessors(new FlowBlock[] { FlowBlock.END_OF_METHOD });
|
|
|
|
flows[0].addStartPred();
|
|
TransformExceptionHandlers exc = new TransformExceptionHandlers(flows);
|
|
exc.addHandler(flows[0],flows[0],flows[1], null);
|
|
exc.analyze();
|
|
flows[0].analyze();
|
|
flows[0].removeStartPred();
|
|
if (VERBOSE)
|
|
flows[0].dumpSource(new TabbedPrintWriter(GlobalOptions.err));
|
|
assertTrue("Sequ", flows[0].getBlock() instanceof SequentialBlock);
|
|
assertTrue("Loop", flows[0].getBlock().getSubBlocks()[0] instanceof LoopBlock);
|
|
assertTrue("Try", flows[0].getBlock().getSubBlocks()[0].getSubBlocks()[0] instanceof TryBlock);
|
|
assertTrue("Empty", flows[0].getBlock().getSubBlocks()[0].getSubBlocks()[0].getSubBlocks()[0] instanceof EmptyBlock);
|
|
assertTrue("Finally", flows[0].getBlock().getSubBlocks()[0].getSubBlocks()[0].getSubBlocks()[1] instanceof FinallyBlock);
|
|
assertTrue("Break", flows[0].getBlock().getSubBlocks()[0].getSubBlocks()[0].getSubBlocks()[1].getSubBlocks()[0] instanceof BreakBlock);
|
|
assertTrue("Descr", flows[0].getBlock().getSubBlocks()[1]
|
|
instanceof DescriptionBlock);
|
|
}
|
|
|
|
public void testFinCondBreaks() throws java.io.IOException {
|
|
FlowBlock[] flows = createFlowBlocks(6);
|
|
LocalInfo thisLocal = new LocalInfo(null, 0);
|
|
LocalInfo tmpLocal = new LocalInfo(null, 1);
|
|
LocalInfo tmp2Local = new LocalInfo(null, 2);
|
|
|
|
/* Try Blocks */
|
|
flows[0].appendBlock(new JsrBlock());
|
|
flows[0].setSuccessors(new FlowBlock[] { flows[3], flows[5] });
|
|
|
|
/* Catch Exception Blocks */
|
|
flows[1].appendWriteBlock
|
|
(new InstructionBlock
|
|
(new StoreInstruction
|
|
(new LocalStoreOperator(Type.tUObject, tmpLocal))), tmpLocal);
|
|
flows[1].appendBlock(new JsrBlock());
|
|
flows[1].setSuccessors(new FlowBlock[] { flows[3], flows[2] });
|
|
|
|
flows[2].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, tmpLocal)), tmpLocal);
|
|
flows[2].appendBlock
|
|
(new ThrowBlock(new NopOperator(Type.tUObject)));
|
|
flows[2].setSuccessors(new FlowBlock[0]);
|
|
|
|
/* subroutine */
|
|
flows[3].appendWriteBlock
|
|
(new InstructionBlock
|
|
(new StoreInstruction
|
|
(new LocalStoreOperator(Type.tUObject, tmp2Local))), tmp2Local);
|
|
flows[3].appendReadBlock
|
|
(new InstructionBlock
|
|
(new LocalLoadOperator(Type.tUObject, null, thisLocal)), thisLocal);
|
|
flows[3].appendBlock(new ConditionalBlock
|
|
(new CompareUnaryOperator
|
|
(Type.tUObject, Operator.EQUALS_OP)));
|
|
flows[3].setSuccessors(new FlowBlock[] { flows[4], flows[5] });
|
|
flows[4].appendReadBlock
|
|
(new RetBlock(tmp2Local), tmp2Local);
|
|
flows[4].setSuccessors(new FlowBlock[0]);
|
|
|
|
flows[5].appendBlock(new DescriptionBlock("/*HERE*/"));
|
|
flows[5].setSuccessors(new FlowBlock[] { FlowBlock.END_OF_METHOD });
|
|
|
|
flows[0].addStartPred();
|
|
TransformExceptionHandlers exc = new TransformExceptionHandlers(flows);
|
|
exc.addHandler(flows[0],flows[0],flows[1], null);
|
|
exc.analyze();
|
|
flows[0].analyze();
|
|
flows[0].removeStartPred();
|
|
if (VERBOSE)
|
|
flows[0].dumpSource(new TabbedPrintWriter(GlobalOptions.err));
|
|
assertTrue("Sequ", flows[0].getBlock() instanceof SequentialBlock);
|
|
assertTrue("Loop", flows[0].getBlock().getSubBlocks()[0] instanceof LoopBlock);
|
|
assertTrue("Try", flows[0].getBlock().getSubBlocks()[0].getSubBlocks()[0] instanceof TryBlock);
|
|
assertTrue("Empty", flows[0].getBlock().getSubBlocks()[0].getSubBlocks()[0].getSubBlocks()[0] instanceof EmptyBlock);
|
|
assertTrue("Finally", flows[0].getBlock().getSubBlocks()[0].getSubBlocks()[0].getSubBlocks()[1] instanceof FinallyBlock);
|
|
assertTrue("If", flows[0].getBlock().getSubBlocks()[0].getSubBlocks()[0].getSubBlocks()[1].getSubBlocks()[0] instanceof IfThenElseBlock);
|
|
assertTrue("Break", flows[0].getBlock().getSubBlocks()[0].getSubBlocks()[0].getSubBlocks()[1].getSubBlocks()[0].getSubBlocks()[0] instanceof BreakBlock);
|
|
assertTrue("Descr", flows[0].getBlock().getSubBlocks()[1]
|
|
instanceof DescriptionBlock);
|
|
}
|
|
|
|
public static Test suite() {
|
|
TestSuite suite = new TestSuite();
|
|
suite.addTest(new TrExcTest("testSynchronized11"));
|
|
suite.addTest(new TrExcTest("testSynchronized13"));
|
|
suite.addTest(new TrExcTest("testSpecialFin"));
|
|
suite.addTest(new TrExcTest("testSpecialFinTryLoops"));
|
|
suite.addTest(new TrExcTest("testFinBreaksJikes"));
|
|
suite.addTest(new TrExcTest("testFinCondBreaks"));
|
|
return suite;
|
|
}
|
|
}
|
|
|