Expression rework (ComplexExpression removed)

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@778 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent abf370c1d7
commit bd7b04902d
  1. 109
      jode/jode/flow/CreateAssignExpression.java
  2. 13
      jode/jode/flow/CreateCheckNull.java
  3. 50
      jode/jode/flow/CreateConstantArray.java
  4. 13
      jode/jode/flow/CreateExpression.java
  5. 6
      jode/jode/flow/CreateForInitializer.java
  6. 38
      jode/jode/flow/CreateIfThenElseOperator.java
  7. 149
      jode/jode/flow/CreateNewConstructor.java
  8. 56
      jode/jode/flow/CreatePrePostIncExpression.java
  9. 3
      jode/jode/flow/FlowBlock.java
  10. 2
      jode/jode/flow/ReturnBlock.java
  11. 55
      jode/jode/flow/SpecialBlock.java
  12. 2
      jode/jode/flow/SwitchBlock.java
  13. 84
      jode/jode/flow/TransformExceptionHandlers.java
  14. 39
      jode/jode/flow/TryBlock.java
  15. 3
      jode/jode/flow/VariableStack.java

@ -42,9 +42,9 @@ public class CreateAssignExpression {
* sequBlock: * sequBlock:
* dup (may be missing for static / local variables) * dup (may be missing for static / local variables)
* opBlock: * opBlock:
* (optional narrow) ((optional wide) load(stack) * rightHandSide) * PUSH (optional narrow)((optional wide) load(stack) * RHS)
* (optional dup_x) * (optional dup_x)
* store(stack) * store(POP)
* *
* We transform it to: * We transform it to:
* (push loadstoreOps) * (push loadstoreOps)
@ -53,15 +53,19 @@ public class CreateAssignExpression {
* store(stack) *= (stack) * store(stack) *= (stack)
* *
* If the optional dup is present the store*= becomes non void. */ * If the optional dup is present the store*= becomes non void. */
SequentialBlock opBlock = (SequentialBlock) last.outer; SequentialBlock opBlock = (SequentialBlock) last.outer;
StoreInstruction store = (StoreInstruction) ic.getInstruction(); StoreInstruction store = (StoreInstruction) ic.getInstruction();
if (!store.isFreeOperator())
return false;
int lvalueCount = store.getLValue().getFreeOperandCount();
boolean isAssignOp = false; boolean isAssignOp = false;
if (opBlock.subBlocks[0] instanceof SpecialBlock) { if (opBlock.subBlocks[0] instanceof SpecialBlock) {
SpecialBlock dup = (SpecialBlock) opBlock.subBlocks[0]; SpecialBlock dup = (SpecialBlock) opBlock.subBlocks[0];
if (dup.type != SpecialBlock.DUP if (dup.type != SpecialBlock.DUP
|| dup.depth != store.getLValueOperandCount() || dup.depth != lvalueCount
|| dup.count != store.getLValueType().stackSize() || dup.count != store.getLValue().getType().stackSize()
|| !(opBlock.outer instanceof SequentialBlock)) || !(opBlock.outer instanceof SequentialBlock))
return false; return false;
opBlock = (SequentialBlock) opBlock.outer; opBlock = (SequentialBlock) opBlock.outer;
@ -72,13 +76,15 @@ public class CreateAssignExpression {
return false; return false;
InstructionBlock ib = (InstructionBlock) opBlock.subBlocks[0]; InstructionBlock ib = (InstructionBlock) opBlock.subBlocks[0];
if (!(ib.getInstruction() instanceof ComplexExpression)) if (!(ib.getInstruction() instanceof Operator))
return false; return false;
Operator expr = (Operator) ib.getInstruction();
ComplexExpression expr = (ComplexExpression) ib.getInstruction(); if (expr.getFreeOperandCount() != lvalueCount)
return false;
SpecialBlock dup = null; SpecialBlock dup = null;
if (store.getLValueOperandCount() > 0) { if (lvalueCount > 0) {
if (!(opBlock.outer instanceof SequentialBlock) if (!(opBlock.outer instanceof SequentialBlock)
|| !(opBlock.outer.getSubBlocks()[0] instanceof SpecialBlock)) || !(opBlock.outer.getSubBlocks()[0] instanceof SpecialBlock))
return false; return false;
@ -87,48 +93,46 @@ public class CreateAssignExpression {
dup = (SpecialBlock) sequBlock.subBlocks[0]; dup = (SpecialBlock) sequBlock.subBlocks[0];
if (dup.type != SpecialBlock.DUP if (dup.type != SpecialBlock.DUP
|| dup.depth != 0 || dup.depth != 0 || dup.count != lvalueCount)
|| dup.count != store.getLValueOperandCount())
return false; return false;
} }
int opIndex; int opIndex;
Expression rightHandSide; Expression rightHandSide;
Type rhsType;
if (expr.getOperator() instanceof ConvertOperator if (expr instanceof ConvertOperator
&& expr.getSubExpressions()[0] instanceof ComplexExpression && expr.getSubExpressions()[0] instanceof Operator
&& expr.getOperator().getType().isOfType(store.getLValueType())) { && expr.getType().isOfType(store.getLValue().getType())) {
/* This gets tricky. We need to allow something like /* This gets tricky. We need to allow something like
* s = (short) (int) ((double) s / 0.1); * s = (short) (int) ((double) s / 0.1);
*/ */
expr = (ComplexExpression) expr.getSubExpressions()[0]; expr = (Operator) expr.getSubExpressions()[0];
while (expr.getOperator() instanceof ConvertOperator while (expr instanceof ConvertOperator
&& expr.getSubExpressions()[0] instanceof ComplexExpression) && expr.getSubExpressions()[0] instanceof Operator)
expr = (ComplexExpression) expr.getSubExpressions()[0]; expr = (Operator) expr.getSubExpressions()[0];
} }
if (expr.getOperator() instanceof BinaryOperator) { if (expr instanceof BinaryOperator) {
BinaryOperator binop = (BinaryOperator) expr.getOperator(); opIndex = expr.getOperatorIndex();
if (opIndex < expr.ADD_OP || opIndex >= expr.ASSIGN_OP)
opIndex = binop.getOperatorIndex(); return false;
if (opIndex < binop.ADD_OP || opIndex >= binop.ASSIGN_OP)
if (!(expr.getSubExpressions()[0] instanceof Operator))
return false; return false;
Expression loadExpr = expr.getSubExpressions()[0]; Operator loadExpr = (Operator) expr.getSubExpressions()[0];
while (loadExpr instanceof ComplexExpression while (loadExpr instanceof ConvertOperator
&& loadExpr.getOperator() instanceof ConvertOperator) && loadExpr.getSubExpressions()[0] instanceof Operator)
loadExpr = ((ComplexExpression)loadExpr) loadExpr = (Operator) loadExpr.getSubExpressions()[0];
.getSubExpressions()[0];
if (!(loadExpr instanceof Operator) if (!store.lvalueMatches((Operator) loadExpr)
|| !store.matches((Operator) loadExpr)) || !(loadExpr.isFreeOperator(lvalueCount)))
return false; return false;
if (store instanceof LocalStoreOperator) if (store.getLValue() instanceof LocalStoreOperator)
((LocalLoadOperator)loadExpr).getLocalInfo().combineWith ((LocalLoadOperator)loadExpr).getLocalInfo().combineWith
(((LocalStoreOperator)store).getLocalInfo()); (((LocalStoreOperator)store.getLValue()).getLocalInfo());
rightHandSide = expr.getSubExpressions()[1]; rightHandSide = expr.getSubExpressions()[1];
rhsType = binop.getOperandType(1);
} else { } else {
/* For String += the situation is more complex. /* For String += the situation is more complex.
* what is marked as load(stack) * rightHandSide above is * what is marked as load(stack) * rightHandSide above is
@ -139,31 +143,29 @@ public class CreateAssignExpression {
Expression simple = expr.simplifyString(); Expression simple = expr.simplifyString();
rightHandSide = simple; rightHandSide = simple;
/* Now search for the leftmost operand ... */ /* Now search for the leftmost operand ... */
ComplexExpression lastExpr = null; Operator lastExpr = null;
while (simple instanceof ComplexExpression Operator parent = null;
&& simple.getOperator() instanceof StringAddOperator) { while (simple instanceof StringAddOperator) {
lastExpr = (ComplexExpression) simple; parent = lastExpr;
lastExpr = (Operator) simple;
simple = lastExpr.getSubExpressions()[0]; simple = lastExpr.getSubExpressions()[0];
} }
/* ... check it ... */ /* ... check it ... */
if (lastExpr == null || !(simple instanceof Operator) if (lastExpr == null
|| !store.matches((Operator) simple)) || !(simple instanceof Operator)
|| !store.lvalueMatches((Operator) simple)
|| !(((Operator) simple).isFreeOperator(lvalueCount)))
return false; return false;
if (store instanceof LocalStoreOperator) if (store.getLValue() instanceof LocalStoreOperator)
((LocalLoadOperator)simple).getLocalInfo().combineWith ((LocalLoadOperator)simple).getLocalInfo().combineWith
(((LocalStoreOperator)store).getLocalInfo()); (((LocalStoreOperator)store.getLValue()).getLocalInfo());
/* ... and remove it. */ /* ... and remove it. */
if (lastExpr.getParent() != null) { if (parent != null) {
ComplexExpression ce = (ComplexExpression)lastExpr.getParent(); parent.setSubExpressions(0, lastExpr.getSubExpressions()[1]);
StringAddOperator addOp = (StringAddOperator) ce.getOperator();
addOp.clearFirstType();
ce.setSubExpressions(0,lastExpr.getSubExpressions()[1]);
rhsType = Type.tString;
} else { } else {
rhsType = lastExpr.getOperator().getOperandType(1);
rightHandSide = lastExpr.getSubExpressions()[1]; rightHandSide = lastExpr.getSubExpressions()[1];
} }
@ -174,7 +176,7 @@ public class CreateAssignExpression {
dup.removeBlock(); dup.removeBlock();
ib.setInstruction(rightHandSide); ib.setInstruction(rightHandSide);
store.makeOpAssign(store.OPASSIGN_OP+opIndex, rhsType); store.makeOpAssign(store.OPASSIGN_OP + opIndex);
if (isAssignOp) if (isAssignOp)
store.makeNonVoid(); store.makeNonVoid();
@ -187,17 +189,18 @@ public class CreateAssignExpression {
/* Situation: /* Situation:
* sequBlock: * sequBlock:
* dup_X(lvalue_count) * dup_X(lvalue_count)
* store instruction * store(POP) = POP
*/ */
SequentialBlock sequBlock = (SequentialBlock) last.outer; SequentialBlock sequBlock = (SequentialBlock) last.outer;
StoreInstruction store = (StoreInstruction) ic.getInstruction(); StoreInstruction store = (StoreInstruction) ic.getInstruction();
if (sequBlock.subBlocks[0] instanceof SpecialBlock) { if (sequBlock.subBlocks[0] instanceof SpecialBlock
&& store.isFreeOperator()) {
SpecialBlock dup = (SpecialBlock) sequBlock.subBlocks[0]; SpecialBlock dup = (SpecialBlock) sequBlock.subBlocks[0];
if (dup.type != SpecialBlock.DUP if (dup.type != SpecialBlock.DUP
|| dup.depth != store.getLValueOperandCount() || dup.depth != store.getLValue().getFreeOperandCount()
|| dup.count != store.getLValueType().stackSize()) || dup.count != store.getLValue().getType().stackSize())
return false; return false;
dup.removeBlock(); dup.removeBlock();

@ -39,7 +39,7 @@ public class CreateCheckNull {
public static boolean transformJavac(InstructionContainer ic, public static boolean transformJavac(InstructionContainer ic,
StructuredBlock last) { StructuredBlock last) {
if (!(last.outer instanceof SequentialBlock) if (!(last.outer instanceof SequentialBlock)
|| !(ic.getInstruction() instanceof ComplexExpression) || !(ic.getInstruction() instanceof Operator)
|| !(last.outer.getSubBlocks()[0] instanceof SpecialBlock)) || !(last.outer.getSubBlocks()[0] instanceof SpecialBlock))
return false; return false;
@ -48,7 +48,7 @@ public class CreateCheckNull {
|| dup.count != 1 || dup.depth != 0) || dup.count != 1 || dup.depth != 0)
return false; return false;
ComplexExpression ce = (ComplexExpression) ic.getInstruction(); Operator ce = (Operator) ic.getInstruction();
if (!(ce.getOperator() instanceof PopOperator) if (!(ce.getOperator() instanceof PopOperator)
|| !(ce.getSubExpressions()[0] instanceof InvokeOperator)) || !(ce.getSubExpressions()[0] instanceof InvokeOperator))
@ -83,9 +83,12 @@ public class CreateCheckNull {
/* negate the instruction back to its original state */ /* negate the instruction back to its original state */
Expression expr = ifBlock.cond.negate(); Expression expr = ifBlock.cond.negate();
if (!(expr instanceof CompareUnaryOperator) if (!(expr instanceof CompareUnaryOperator))
|| expr.getOperator().getOperatorIndex() != Operator.NOTEQUALS_OP return false;
|| !(expr.getOperator().getOperandType(0).isOfType(Type.tUObject)))
CompareUnaryOperator cmpOp = (CompareUnaryOperator) expr;
if (cmpOp.getOperatorIndex() != Operator.NOTEQUALS_OP
|| !(cmpOp.getCompareType().isOfType(Type.tUObject)))
return false; return false;
LocalInfo li = new LocalInfo(); LocalInfo li = new LocalInfo();

@ -29,62 +29,56 @@ public class CreateConstantArray {
/* Situation: /* Situation:
* PUSH new Array[] // or a constant array operator. * PUSH new Array[] // or a constant array operator.
* DUP // duplicate array reference * DUP // duplicate array reference
* PUSH index * POP[index] = value
* PUSH value
* stack_2[stack_1] = stack_0
* ... * ...
*/ */
if (last.outer instanceof SequentialBlock) { if (last.outer instanceof SequentialBlock) {
SequentialBlock sequBlock = (SequentialBlock) last.outer; SequentialBlock sequBlock = (SequentialBlock) last.outer;
Operator storeOp = ic.getInstruction().getOperator(); if (!(ic.getInstruction() instanceof StoreInstruction)
if (!(ic.getInstruction() instanceof ComplexExpression) || ic.getInstruction().getFreeOperandCount() != 1
|| !(ic.getInstruction().getOperator()
instanceof ArrayStoreOperator)
|| ic.getInstruction().getOperandCount() != 1
|| !(sequBlock.subBlocks[0] instanceof SpecialBlock) || !(sequBlock.subBlocks[0] instanceof SpecialBlock)
|| !(sequBlock.outer instanceof SequentialBlock)) || !(sequBlock.outer instanceof SequentialBlock))
return false; return false;
ComplexExpression storeExpr StoreInstruction store = (StoreInstruction) ic.getInstruction();
= (ComplexExpression) ic.getInstruction();
ArrayStoreOperator store
= (ArrayStoreOperator) storeExpr.getOperator();
Expression[] storeSub = storeExpr.getSubExpressions(); if (!(store.getLValue() instanceof ArrayStoreOperator))
if (!(storeSub[0] instanceof NopOperator)
|| !(storeSub[1] instanceof ConstOperator))
return false; return false;
Expression expr = storeSub[2]; ArrayStoreOperator lvalue = (ArrayStoreOperator) store.getLValue();
ConstOperator indexOp = (ConstOperator) storeSub[1];
if (!(lvalue.getSubExpressions()[0] instanceof NopOperator)
|| !(lvalue.getSubExpressions()[1] instanceof ConstOperator))
return false;
Expression expr = store.getSubExpressions()[1];
ConstOperator indexOp
= (ConstOperator) lvalue.getSubExpressions()[1];
SpecialBlock dup = (SpecialBlock) sequBlock.subBlocks[0]; SpecialBlock dup = (SpecialBlock) sequBlock.subBlocks[0];
sequBlock = (SequentialBlock) sequBlock.outer; sequBlock = (SequentialBlock) sequBlock.outer;
if (dup.type != SpecialBlock.DUP if (dup.type != SpecialBlock.DUP
|| dup.depth != 0 || dup.count != 1 || dup.depth != 0 || dup.count != 1
|| !(indexOp.getType().isOfType(Type.tUInt))
|| !(sequBlock.subBlocks[0] instanceof InstructionBlock)) || !(sequBlock.subBlocks[0] instanceof InstructionBlock))
return false; return false;
int index = Integer.parseInt(indexOp.getValue()); int index = Integer.parseInt(indexOp.getValue());
InstructionBlock ib = (InstructionBlock)sequBlock.subBlocks[0]; InstructionBlock ib = (InstructionBlock)sequBlock.subBlocks[0];
if (ib.getInstruction() instanceof ComplexExpression if (ib.getInstruction() instanceof NewArrayOperator) {
&& (ib.getInstruction().getOperator()
instanceof NewArrayOperator)) {
/* This is the first element */ /* This is the first element */
ComplexExpression newArrayExpr = NewArrayOperator newArray =
(ComplexExpression) ib.getInstruction(); (NewArrayOperator) ib.getInstruction();
NewArrayOperator newArrayOp = if (newArray.getDimensions() != 1
(NewArrayOperator) newArrayExpr.getOperator(); || !(newArray.getSubExpressions()[0]
if (newArrayOp.getOperandCount() != 1
|| !(newArrayExpr.getSubExpressions()[0]
instanceof ConstOperator)) instanceof ConstOperator))
return false; return false;
ConstOperator countop = ConstOperator countop =
(ConstOperator) newArrayExpr.getSubExpressions()[0]; (ConstOperator) newArray.getSubExpressions()[0];
if (!countop.getType().isOfType(Type.tUInt)) if (!countop.getType().isOfType(Type.tUInt))
return false; return false;
@ -96,7 +90,7 @@ public class CreateConstantArray {
GlobalOptions.err.print('a'); GlobalOptions.err.print('a');
ConstantArrayOperator cao ConstantArrayOperator cao
= new ConstantArrayOperator(newArrayOp.getType(), = new ConstantArrayOperator(newArray.getType(),
arraylength); arraylength);
cao.setValue(index, expr); cao.setValue(index, expr);
ic.setInstruction(cao); ic.setInstruction(cao);

@ -40,7 +40,7 @@ public class CreateExpression {
*/ */
public static boolean transform(InstructionContainer ic, public static boolean transform(InstructionContainer ic,
StructuredBlock last) { StructuredBlock last) {
int params = ic.getInstruction().getOperandCount(); int params = ic.getInstruction().getFreeOperandCount();
if (params == 0) if (params == 0)
return false; return false;
@ -61,9 +61,9 @@ public class CreateExpression {
if (!expr.isVoid()) if (!expr.isVoid())
break; break;
if (expr.getOperandCount() > 0 if (expr.getFreeOperandCount() > 0
|| !(expr.getOperator() instanceof CombineableOperator) || !(expr instanceof CombineableOperator)
|| lastExpression.canCombine(expr) <= 0) || lastExpression.canCombine((CombineableOperator) expr) <= 0)
return false; return false;
/* Hmm, we should really set lastExpression to /* Hmm, we should really set lastExpression to
@ -103,12 +103,13 @@ public class CreateExpression {
break; break;
} }
lastExpression = lastExpression.combine(expr); lastExpression = lastExpression.combine
((CombineableOperator) expr);
sequBlock = (SequentialBlock)sequBlock.outer; sequBlock = (SequentialBlock)sequBlock.outer;
} }
if (GlobalOptions.verboseLevel > 0 if (GlobalOptions.verboseLevel > 0
&& lastExpression.getOperandCount() == 0) && lastExpression.getFreeOperandCount() == 0)
GlobalOptions.err.print('x'); GlobalOptions.err.print('x');
ic.setInstruction(lastExpression); ic.setInstruction(lastExpression);

@ -41,9 +41,9 @@ public class CreateForInitializer {
InstructionBlock init = (InstructionBlock) sequBlock.subBlocks[0]; InstructionBlock init = (InstructionBlock) sequBlock.subBlocks[0];
if (!init.getInstruction().isVoid() if (!init.getInstruction().isVoid()
|| !(init.getInstruction().getOperator() || !(init.getInstruction() instanceof CombineableOperator)
instanceof CombineableOperator) || !forBlock.conditionMatches((CombineableOperator)
|| !forBlock.conditionMatches(init)) init.getInstruction()))
return false; return false;
if (GlobalOptions.verboseLevel > 0) if (GlobalOptions.verboseLevel > 0)

@ -59,6 +59,7 @@ public class CreateIfThenElseOperator {
if (ifBlock.elseBlock == null) if (ifBlock.elseBlock == null)
return false; return false;
/* Next is a non-shortcut "or": simplify both blocks! */
if (!createFunnyHelper(trueDest, falseDest, ifBlock.thenBlock) if (!createFunnyHelper(trueDest, falseDest, ifBlock.thenBlock)
| !createFunnyHelper(trueDest, falseDest, ifBlock.elseBlock)) | !createFunnyHelper(trueDest, falseDest, ifBlock.elseBlock))
return false; return false;
@ -66,14 +67,13 @@ public class CreateIfThenElseOperator {
if (GlobalOptions.verboseLevel > 0) if (GlobalOptions.verboseLevel > 0)
GlobalOptions.err.print('?'); GlobalOptions.err.print('?');
IfThenElseOperator iteo = new IfThenElseOperator(Type.tBoolean); Expression iteo = new IfThenElseOperator(Type.tBoolean)
((InstructionBlock)ifBlock.thenBlock).setInstruction .addOperand(((InstructionBlock) ifBlock.elseBlock)
(new ComplexExpression .getInstruction())
(iteo, new Expression[] { .addOperand(((InstructionBlock) ifBlock.thenBlock)
ifBlock.cond, .getInstruction())
((InstructionBlock) ifBlock.thenBlock).getInstruction(), .addOperand(ifBlock.cond);
((InstructionBlock) ifBlock.elseBlock).getInstruction() ((InstructionBlock)ifBlock.thenBlock).setInstruction(iteo);
}));
ifBlock.thenBlock.moveDefinitions(ifBlock, null); ifBlock.thenBlock.moveDefinitions(ifBlock, null);
ifBlock.thenBlock.replace(ifBlock); ifBlock.thenBlock.replace(ifBlock);
@ -192,7 +192,7 @@ public class CreateIfThenElseOperator {
*/ */
public static boolean create(InstructionContainer ic, public static boolean create(InstructionContainer ic,
StructuredBlock last) { StructuredBlock last) {
Expression e[] = new Expression[3]; Expression cond, thenExpr, elseExpr;
InstructionBlock thenBlock; InstructionBlock thenBlock;
if (ic.jump == null if (ic.jump == null
|| !(last.outer instanceof SequentialBlock)) || !(last.outer instanceof SequentialBlock))
@ -210,13 +210,13 @@ public class CreateIfThenElseOperator {
thenBlock = (InstructionBlock) ifBlock.thenBlock; thenBlock = (InstructionBlock) ifBlock.thenBlock;
e[1] = thenBlock.getInstruction(); thenExpr = thenBlock.getInstruction();
if (e[1].isVoid() || e[1].getOperandCount() > 0) if (thenExpr.isVoid() || thenExpr.getFreeOperandCount() > 0)
return false; return false;
e[2] = ic.getInstruction(); elseExpr = ic.getInstruction();
if (e[2].isVoid() || e[2].getOperandCount() > 0) if (elseExpr.isVoid() || elseExpr.getFreeOperandCount() > 0)
return false; return false;
e[0] = ifBlock.cond; cond = ifBlock.cond;
if (GlobalOptions.verboseLevel > 0) if (GlobalOptions.verboseLevel > 0)
GlobalOptions.err.print('?'); GlobalOptions.err.print('?');
@ -225,10 +225,12 @@ public class CreateIfThenElseOperator {
thenBlock.removeJump(); thenBlock.removeJump();
IfThenElseOperator iteo = new IfThenElseOperator IfThenElseOperator iteo = new IfThenElseOperator
(Type.tSuperType(e[1].getType()) (Type.tSuperType(thenExpr.getType())
.intersection(Type.tSuperType(e[2].getType()))); .intersection(Type.tSuperType(elseExpr.getType())));
iteo.addOperand(elseExpr);
ic.setInstruction(new ComplexExpression(iteo, e)); iteo.addOperand(thenExpr);
iteo.addOperand(cond);
ic.setInstruction(iteo);
ic.moveDefinitions(last.outer, last); ic.moveDefinitions(last.outer, last);
last.replace(last.outer); last.replace(last.outer);
return true; return true;

@ -19,35 +19,122 @@
package jode.flow; package jode.flow;
import jode.expr.*; import jode.expr.*;
import jode.bytecode.Reference;
import jode.decompiler.CodeAnalyzer;
import jode.type.Type;
public class CreateNewConstructor { public class CreateNewConstructor {
public static boolean transform(InstructionContainer ic, public static boolean transform(InstructionContainer ic,
StructuredBlock last) { StructuredBlock last) {
/* Situation: return transformNormal(ic, last) || transformJikesString(ic, last);
}
static boolean transformJikesString(InstructionContainer ic,
StructuredBlock last) {
/* special Situation for Jikes String +=:
*
* PUSH new StringBuffer()
* SWAP
* PUSH POP.append(POP)
*
* We transform it to javac String +=:
*
* PUSH new StringBuffer(String.valueOf(POP))
*/
if (!(last.outer instanceof SequentialBlock)
|| !(ic.getInstruction() instanceof InvokeOperator))
return false;
InvokeOperator appendCall = (InvokeOperator) ic.getInstruction();
if (!appendCall.getClassType().equals(Type.tStringBuffer)
|| !appendCall.isFreeOperator(2)
|| appendCall.isStatic()
|| !appendCall.getMethodName().equals("append")
|| appendCall.getMethodType().getParameterTypes().length != 1)
return false;
SequentialBlock sequBlock = (SequentialBlock) last.outer;
if (!(sequBlock.outer instanceof SequentialBlock)
|| !(sequBlock.subBlocks[0] instanceof SpecialBlock))
return false;
SpecialBlock swapBlock = (SpecialBlock) sequBlock.subBlocks[0];
sequBlock = (SequentialBlock) sequBlock.outer;
if (swapBlock.type != SpecialBlock.SWAP
|| !(sequBlock.subBlocks[0] instanceof InstructionBlock)
|| !(sequBlock.outer instanceof SequentialBlock))
return false;
InstructionBlock ib = (InstructionBlock) sequBlock.subBlocks[0];
sequBlock = (SequentialBlock) sequBlock.outer;
if (!(ib.getInstruction() instanceof ConstructorOperator)
|| !(sequBlock.subBlocks[0] instanceof InstructionBlock))
return false;
ConstructorOperator constr = (ConstructorOperator) ib.getInstruction();
ib = (InstructionBlock) sequBlock.subBlocks[0];
if (constr.getClassType() != Type.tStringBuffer
|| constr.isVoid()
|| constr.getMethodType().getParameterTypes().length != 0)
return false;
/* Okay everything checked. */
CodeAnalyzer codeAna = constr.getCodeAnalyzer();
Expression expr = ib.getInstruction();
Type appendType = appendCall.getMethodType().getParameterTypes()[0];
if (!appendType.equals(Type.tString)) {
InvokeOperator valueOf = new InvokeOperator
(codeAna, true, false,
Reference.getReference("Ljava/lang/String;", "valueOf",
"(" + appendType.getTypeSignature()
+ ")Ljava/lang/String;"));
expr = valueOf.addOperand(expr);
}
ConstructorOperator newConstr = new ConstructorOperator
(Reference.getReference("Ljava/lang/StringBuffer;", "<init>",
"(Ljava/lang/String;)V"), codeAna, false);
ic.setInstruction(newConstr.addOperand(expr));
last.replace(sequBlock);
return true;
}
static boolean transformNormal(InstructionContainer ic,
StructuredBlock last) {
/* Situation (normal):
*
* new <object>
* (optional DUP)
* (void resolved expressions)
* stack_n.<init>(resolved expressions)
* *
* transform it to
*
* (optional PUSH) new <object>((optional: stack_n),
* resolved expressions)
*
* special situation for string1 += string2:
*
* new <object> * new <object>
* (optional DUP) * (optional DUP)
* (void resolved expressions)
* PUSH load_ops * PUSH load_ops
* optionally: <= used for "string1 += string2" * DUP_X2/1 <= 2 if above DUP is present
* DUP_X2/1 <= 2 if above DUP is present * stack_n.<init>(stack_n, resolved expressions)
* stack_n.<init>((optional: stack_n), resolved expressions)
* *
* transform it to * transform it to
* *
* PUSH load_ops * PUSH load_ops
* optionally: * DUP <= remove the depth
* DUP <= remove the depth * (optional PUSH) new <object>(stack_n, resolved expressions)
* (optional PUSH) new <object>((optional: stack_n),
* resolved expressions)
*/ */
if (!(last.outer instanceof SequentialBlock)) if (!(last.outer instanceof SequentialBlock))
return false; return false;
if (!(ic.getInstruction().getOperator() instanceof InvokeOperator)) if (!(ic.getInstruction() instanceof InvokeOperator))
return false; return false;
Expression constrExpr = ic.getInstruction(); InvokeOperator constrCall = (InvokeOperator) ic.getInstruction();
InvokeOperator constrCall = (InvokeOperator) constrExpr.getOperator();
if (!constrCall.isConstructor()) if (!constrCall.isConstructor())
return false; return false;
@ -55,13 +142,12 @@ public class CreateNewConstructor {
SpecialBlock optDupX2 = null; SpecialBlock optDupX2 = null;
SequentialBlock sequBlock = (SequentialBlock) last.outer; SequentialBlock sequBlock = (SequentialBlock) last.outer;
Expression[] subs = constrCall.getSubExpressions();
if (constrExpr instanceof ComplexExpression) { int opcount = constrCall.getFreeOperandCount();
Expression[] subs = if (subs != null) {
((ComplexExpression) constrExpr).getSubExpressions();
if (!(subs[0] instanceof NopOperator)) if (!(subs[0] instanceof NopOperator))
return false; return false;
if (constrExpr.getOperandCount() > 1) { if (constrCall.getFreeOperandCount() > 1) {
if (!(sequBlock.outer instanceof SequentialBlock) if (!(sequBlock.outer instanceof SequentialBlock)
|| !(sequBlock.subBlocks[0] instanceof SpecialBlock)) || !(sequBlock.subBlocks[0] instanceof SpecialBlock))
return false; return false;
@ -71,7 +157,6 @@ public class CreateNewConstructor {
|| optDupX2.depth == 0) || optDupX2.depth == 0)
return false; return false;
int count = optDupX2.count; int count = optDupX2.count;
int opcount = constrExpr.getOperandCount() - 1;
do { do {
if (!(sequBlock.outer instanceof SequentialBlock) if (!(sequBlock.outer instanceof SequentialBlock)
|| !(sequBlock.subBlocks[0] || !(sequBlock.subBlocks[0]
@ -86,19 +171,22 @@ public class CreateNewConstructor {
continue; continue;
count -= expr.getType().stackSize(); count -= expr.getType().stackSize();
opcount--; opcount--;
} while (count > 0 && opcount > 0); } while (count > 0 && opcount > 1);
if (opcount != 0 || count != 0) if (count != 0)
return false; return false;
} else if (constrExpr.getOperandCount() != 1) }
return false; }
} else if (constrExpr.getOperandCount() != 1) if (opcount != 1)
return false; return false;
while (sequBlock.subBlocks[0] instanceof InstructionBlock while (sequBlock.subBlocks[0] instanceof InstructionBlock
&& ((InstructionBlock)sequBlock.subBlocks[0]) && sequBlock.outer instanceof SequentialBlock) {
.getInstruction().isVoid() Expression expr
&& sequBlock.outer instanceof SequentialBlock) = ((InstructionBlock)sequBlock.subBlocks[0]).getInstruction();
if (!expr.isVoid() || expr.getFreeOperandCount() > 0)
break;
sequBlock = (SequentialBlock) sequBlock.outer; sequBlock = (SequentialBlock) sequBlock.outer;
}
SpecialBlock dup = null; SpecialBlock dup = null;
if (sequBlock.outer instanceof SequentialBlock if (sequBlock.outer instanceof SequentialBlock
@ -133,14 +221,9 @@ public class CreateNewConstructor {
Expression newExpr = new ConstructorOperator Expression newExpr = new ConstructorOperator
(constrCall, dup == null); (constrCall, dup == null);
if (constrExpr instanceof ComplexExpression) { if (subs != null) {
Expression[] subs = for (int i=subs.length; i-- > 1; )
((ComplexExpression)constrExpr).getSubExpressions();
for (int i=subs.length - 1; i>=1; i--) {
if (subs[i] instanceof NopOperator)
break;
newExpr = newExpr.addOperand(subs[i]); newExpr = newExpr.addOperand(subs[i]);
}
} }
ic.setInstruction(newExpr); ic.setInstruction(newExpr);
return true; return true;

@ -77,12 +77,13 @@ public class CreatePrePostIncExpression {
else if (!iinc.getValue().equals("1")) else if (!iinc.getValue().equals("1"))
return false; return false;
if (!iinc.matches(load)) if (!iinc.lvalueMatches(load))
return false; return false;
Type type = load.getType().intersection(Type.tUInt); Type type = load.getType().intersection(Type.tUInt);
iinc.makeNonVoid();
Operator ppop = Operator ppop =
new LocalPrePostFixOperator(type, op, iinc, isPost); new PrePostFixOperator(type, op, iinc.getLValue(), isPost);
ic.setInstruction(ppop); ic.setInstruction(ppop);
ic.moveDefinitions(last.outer, last); ic.moveDefinitions(last.outer, last);
@ -103,41 +104,28 @@ public class CreatePrePostIncExpression {
* store(stack) = stack_0 +/- 1 * store(stack) = stack_0 +/- 1
*/ */
if (!(ic.getInstruction() instanceof ComplexExpression) if (!(ic.getInstruction() instanceof StoreInstruction))
|| !(ic.getInstruction().getOperator() instanceof StoreInstruction)
|| !(ic.getInstruction().isVoid()))
return false; return false;
ComplexExpression storeExpr = (ComplexExpression) ic.getInstruction(); StoreInstruction store = (StoreInstruction) ic.getInstruction();
StoreInstruction store =
(StoreInstruction) ic.getInstruction().getOperator();
/* Make sure that the lvalue part of the store is /* Make sure that the lvalue part of the store is
* not yet resolved (and not that the rvalue part * not yet resolved (and note that the rvalue part
* should also have 1 remaining operand) * should also have 1 remaining operand)
*/ */
int storeParams = store.getLValueOperandCount(); int lvalueCount = store.getLValue().getFreeOperandCount();
if (storeExpr.getOperandCount() != storeParams + 1 if (!store.getLValue().isFreeOperator()
|| !(storeExpr.getSubExpressions()[storeParams] || !store.isVoid()
instanceof ComplexExpression)) || !(store.getSubExpressions()[1] instanceof BinaryOperator))
return false; return false;
if (storeParams > 0) {
for (int i=0; i< storeParams; i++) {
if (!(storeExpr.getSubExpressions()[i] instanceof NopOperator))
return false;
}
}
ComplexExpression binExpr = (ComplexExpression) BinaryOperator binOp = (BinaryOperator) store.getSubExpressions()[1];
storeExpr.getSubExpressions()[storeParams]; if (binOp.getSubExpressions() == null
if (!(binExpr instanceof ComplexExpression) || !(binOp.getSubExpressions()[0] instanceof NopOperator)
|| !(binExpr.getOperator() instanceof BinaryOperator) || !(binOp.getSubExpressions()[1] instanceof ConstOperator))
|| !(binExpr.getSubExpressions()[0] instanceof NopOperator)
|| !(binExpr.getSubExpressions()[1] instanceof ConstOperator))
return false; return false;
BinaryOperator binOp = (BinaryOperator) binExpr.getOperator(); ConstOperator constOp = (ConstOperator) binOp.getSubExpressions()[1];
ConstOperator constOp = (ConstOperator) binExpr.getSubExpressions()[1];
int op; int op;
if (binOp.getOperatorIndex() == store.ADD_OP) if (binOp.getOperatorIndex() == store.ADD_OP)
op = Operator.INC_OP; op = Operator.INC_OP;
@ -161,8 +149,8 @@ public class CreatePrePostIncExpression {
SpecialBlock dup = (SpecialBlock) sb.subBlocks[0]; SpecialBlock dup = (SpecialBlock) sb.subBlocks[0];
if (dup.type != SpecialBlock.DUP if (dup.type != SpecialBlock.DUP
|| dup.count != store.getLValueType().stackSize() || dup.count != store.getLValue().getType().stackSize()
|| dup.depth != store.getLValueOperandCount()) || dup.depth != lvalueCount)
return false; return false;
if (!(sb.outer instanceof SequentialBlock)) if (!(sb.outer instanceof SequentialBlock))
@ -173,10 +161,10 @@ public class CreatePrePostIncExpression {
InstructionBlock ib = (InstructionBlock) sb.subBlocks[0]; InstructionBlock ib = (InstructionBlock) sb.subBlocks[0];
if (!(ib.getInstruction() instanceof Operator) if (!(ib.getInstruction() instanceof Operator)
|| !store.matches((Operator) ib.getInstruction())) || !store.lvalueMatches((Operator) ib.getInstruction()))
return false; return false;
if (store.getLValueOperandCount() > 0) { if (lvalueCount > 0) {
if (!(sb.outer instanceof SequentialBlock)) if (!(sb.outer instanceof SequentialBlock))
return false; return false;
sb = (SequentialBlock) sb.outer; sb = (SequentialBlock) sb.outer;
@ -184,14 +172,16 @@ public class CreatePrePostIncExpression {
return false; return false;
SpecialBlock dup2 = (SpecialBlock) sb.subBlocks[0]; SpecialBlock dup2 = (SpecialBlock) sb.subBlocks[0];
if (dup2.type != SpecialBlock.DUP if (dup2.type != SpecialBlock.DUP
|| dup2.count != store.getLValueOperandCount() || dup2.count != lvalueCount
|| dup2.depth != 0) || dup2.depth != 0)
return false; return false;
} }
ic.setInstruction ic.setInstruction
(new PrePostFixOperator(store.getLValueType(), op, store, true)); (new PrePostFixOperator(store.getLValue().getType(), op,
store.getLValue(), true));
ic.moveDefinitions(sb, last); ic.moveDefinitions(sb, last);
last.replace(sb); last.replace(sb);
return true; return true;
} }
} }

@ -965,8 +965,7 @@ public class FlowBlock {
} }
if (!createdForBlock if (!createdForBlock
&& (((InstructionBlock) && (((InstructionBlock) lastModified).getInstruction()
lastModified).getInstruction().getOperator()
instanceof CombineableOperator)) { instanceof CombineableOperator)) {
/* The only jump is the jump of the last /* The only jump is the jump of the last

@ -47,7 +47,7 @@ public class ReturnBlock extends InstructionContainer {
public VariableStack mapStackToLocal(VariableStack stack) { public VariableStack mapStackToLocal(VariableStack stack) {
VariableStack newStack = stack; VariableStack newStack = stack;
if (instr != null) { if (instr != null) {
int params = instr.getOperandCount(); int params = instr.getFreeOperandCount();
if (params > 0) { if (params > 0) {
this.stack = stack.peek(params); this.stack = stack.peek(params);
newStack = stack.pop(params); newStack = stack.pop(params);

@ -113,8 +113,8 @@ public class SpecialBlock extends StructuredBlock {
Expression expr2 = block2.getInstruction(); Expression expr2 = block2.getInstruction();
if (expr1.isVoid() || expr2.isVoid() if (expr1.isVoid() || expr2.isVoid()
|| expr1.getOperandCount() != 0 || expr1.getFreeOperandCount() != 0
|| expr2.getOperandCount() != 0 || expr2.getFreeOperandCount() != 0
|| expr1.hasSideEffects(expr2) || expr1.hasSideEffects(expr2)
|| expr2.hasSideEffects(expr1)) || expr2.hasSideEffects(expr1))
return false; return false;
@ -175,18 +175,16 @@ public class SpecialBlock extends StructuredBlock {
if (instr.getType().stackSize() == count) { if (instr.getType().stackSize() == count) {
StructuredBlock newBlock; StructuredBlock newBlock;
if (instr.getOperator() instanceof InvokeOperator if (instr instanceof InvokeOperator
|| instr.getOperator() instanceof ConstructorOperator) { || instr instanceof ConstructorOperator) {
ComplexExpression newExpr = new ComplexExpression Expression newExpr
(new PopOperator(instr.getType()), = new PopOperator(instr.getType()).addOperand(instr);
new Expression[] { instr });
prev.setInstruction(newExpr); prev.setInstruction(newExpr);
newBlock = prev; newBlock = prev;
} else { } else {
ComplexExpression newCond = new ComplexExpression Expression newCond = new CompareUnaryOperator
(new CompareUnaryOperator(instr.getType(), (instr.getType(), Operator.NOTEQUALS_OP)
Operator.NOTEQUALS_OP), .addOperand(instr);
new Expression[] { instr });
IfThenElseBlock newIfThen = new IfThenElseBlock(newCond); IfThenElseBlock newIfThen = new IfThenElseBlock(newCond);
newIfThen.setThenBlock(new EmptyBlock()); newIfThen.setThenBlock(new EmptyBlock());
newBlock = newIfThen; newBlock = newIfThen;
@ -204,41 +202,6 @@ public class SpecialBlock extends StructuredBlock {
} }
return true; return true;
} }
/* The following was another possibility to resolve pops,
* but it turned out to lead to stupid type errors, and
* it is obsolete due to the new stack analysis, now
*/
// } else if (last.outer.outer instanceof SequentialBlock
// && (last.outer.outer.getSubBlocks()[0]
// instanceof InstructionBlock)) {
// InstructionBlock prevprev
// = (InstructionBlock) last.outer.outer.getSubBlocks()[0];
// Expression previnstr = prevprev.getInstruction();
// if (previnstr.getType().stackSize() == 1
// && instr.getType().stackSize() == 1
// && count == 2
// && (previnstr.getType().getSuperType()
// .isOfType(instr.getType())
// || instr.getType().getSuperType()
// .isOfType(previnstr.getType()))) {
// /* compare two objects */
// ComplexExpression newCond = new ComplexExpression
// (new CompareBinaryOperator(instr.getType(),
// Operator.EQUALS_OP),
// new Expression[] { previnstr, instr });
// IfThenElseBlock newIfThen = new IfThenElseBlock(newCond);
// newIfThen.setThenBlock(new EmptyBlock());
// newIfThen.moveJump(jump);
// if (this == last) {
// newIfThen.replace(last.outer.outer);
// flowBlock.lastModified = newIfThen;
// } else {
// newIfThen.replace(this);
// last.replace(last.outer.outer);
// }
// return true;
// }
} }
return false; return false;
} }

@ -89,7 +89,7 @@ implements BreakableBlock {
*/ */
public VariableStack mapStackToLocal(VariableStack stack) { public VariableStack mapStackToLocal(VariableStack stack) {
VariableStack newStack; VariableStack newStack;
int params = instr.getOperandCount(); int params = instr.getFreeOperandCount();
if (params > 0) { if (params > 0) {
exprStack = stack.peek(params); exprStack = stack.peek(params);
newStack = stack.pop(params); newStack = stack.pop(params);

@ -189,18 +189,19 @@ public class TransformExceptionHandlers {
} else if (firstInstr instanceof InstructionBlock) { } else if (firstInstr instanceof InstructionBlock) {
Expression instr = Expression instr =
((InstructionBlock) firstInstr).getInstruction(); ((InstructionBlock) firstInstr).getInstruction();
if (instr instanceof LocalStoreOperator) { if (instr instanceof StoreInstruction
&& (((StoreInstruction)instr).getLValue()
instanceof LocalStoreOperator)) {
/* The exception is stored in a local variable */ /* The exception is stored in a local variable */
local = ((LocalStoreOperator) instr).getLocalInfo(); local = ((LocalStoreOperator)
((StoreInstruction)instr).getLValue()).getLocalInfo();
firstInstr.removeBlock(); firstInstr.removeBlock();
} }
} }
if (local == null) { if (local != null) {
local = new LocalInfo(); local.setType(type);
local.setName("ERROR!!!"); }
}
local.setType(type);
CatchBlock newBlock = new CatchBlock(type, local); CatchBlock newBlock = new CatchBlock(type, local);
((TryBlock)tryFlow.block).addCatchBlock(newBlock); ((TryBlock)tryFlow.block).addCatchBlock(newBlock);
@ -222,9 +223,12 @@ public class TransformExceptionHandlers {
SequentialBlock sequBlock = (SequentialBlock) subRoutine; SequentialBlock sequBlock = (SequentialBlock) subRoutine;
InstructionBlock instr = (InstructionBlock)sequBlock.subBlocks[0]; InstructionBlock instr = (InstructionBlock)sequBlock.subBlocks[0];
if (! (instr.getInstruction() instanceof LocalStoreOperator)) if (!(instr.getInstruction() instanceof StoreInstruction)
|| !(((StoreInstruction) instr.getInstruction()).getLValue()
instanceof LocalStoreOperator))
return false; return false;
LocalStoreOperator store = (LocalStoreOperator) instr.getInstruction(); LocalStoreOperator store = (LocalStoreOperator)
((StoreInstruction)instr.getInstruction()).getLValue();
while (sequBlock.subBlocks[1] instanceof SequentialBlock) while (sequBlock.subBlocks[1] instanceof SequentialBlock)
sequBlock = (SequentialBlock) sequBlock.subBlocks[1]; sequBlock = (SequentialBlock) sequBlock.subBlocks[1];
@ -297,18 +301,20 @@ public class TransformExceptionHandlers {
* in this case. * in this case.
*/ */
try { try {
ComplexExpression expr = (ComplexExpression) StoreInstruction store = (StoreInstruction)
((InstructionBlock) ((InstructionBlock)
ret.outer.getSubBlocks()[0]).instr; ret.outer.getSubBlocks()[0]).instr;
LocalStoreOperator store = LocalInfo local =
(LocalStoreOperator) expr.getOperator(); ((LocalStoreOperator) store.getLValue())
if (store.matches((LocalLoadOperator) .getLocalInfo();
ret.getInstruction())) { if (store.lvalueMatches
ret.setInstruction(expr. ((LocalLoadOperator)
getSubExpressions()[0]); ret.getInstruction())) {
Expression expr =
store.getSubExpressions()[1];
ret.setInstruction(expr);
ret.replace(ret.outer); ret.replace(ret.outer);
ret.used.removeElement ret.used.removeElement(local);
(store.getLocalInfo());
} }
} catch(ClassCastException ex) { } catch(ClassCastException ex) {
/* didn't succeed */ /* didn't succeed */
@ -387,11 +393,11 @@ public class TransformExceptionHandlers {
} }
static boolean isMonitorExit(Expression instr, LocalInfo local) { static boolean isMonitorExit(Expression instr, LocalInfo local) {
if (instr instanceof ComplexExpression) { if (instr instanceof MonitorExitOperator) {
ComplexExpression expr = (ComplexExpression)instr; MonitorExitOperator monExit = (MonitorExitOperator)instr;
if (expr.getOperator() instanceof MonitorExitOperator if (monExit.getFreeOperandCount() == 0
&& expr.getSubExpressions()[0] instanceof LocalLoadOperator && monExit.getSubExpressions()[0] instanceof LocalLoadOperator
&& (((LocalLoadOperator) expr.getSubExpressions()[0]) && (((LocalLoadOperator) monExit.getSubExpressions()[0])
.getLocalInfo().getSlot() == local.getSlot())) { .getLocalInfo().getSlot() == local.getSlot())) {
return true; return true;
} }
@ -451,16 +457,7 @@ public class TransformExceptionHandlers {
if (pred instanceof InstructionBlock) { if (pred instanceof InstructionBlock) {
Expression instr = Expression instr =
((InstructionBlock)pred).getInstruction(); ((InstructionBlock)pred).getInstruction();
if (instr instanceof ComplexExpression if (isMonitorExit(instr, local))
&& ((ComplexExpression)instr)
.getOperator() instanceof MonitorExitOperator
&& ((ComplexExpression)instr)
.getSubExpressions()[0]
instanceof LocalLoadOperator
&& (((LocalLoadOperator)
((ComplexExpression)instr)
.getSubExpressions()[0]).getLocalInfo()
.getSlot() == local.getSlot()))
continue; continue;
} }
} }
@ -522,14 +519,13 @@ public class TransformExceptionHandlers {
Expression instr = Expression instr =
((InstructionBlock)catchBlock.subBlocks[0]).getInstruction(); ((InstructionBlock)catchBlock.subBlocks[0]).getInstruction();
if (instr instanceof ComplexExpression if (instr instanceof MonitorExitOperator
&& ((ComplexExpression)instr).getOperator() && instr.getFreeOperandCount() == 0
instanceof MonitorExitOperator && (((MonitorExitOperator)instr).getSubExpressions()[0]
&& ((ComplexExpression)instr).getSubExpressions()[0] instanceof LocalLoadOperator)
instanceof LocalLoadOperator
&& catchBlock.subBlocks[1] instanceof ThrowBlock && catchBlock.subBlocks[1] instanceof ThrowBlock
&& ((ThrowBlock)catchBlock.subBlocks[1]).instr && (((ThrowBlock)catchBlock.subBlocks[1]).instr
instanceof NopOperator) { instanceof NopOperator)) {
/* This is a synchronized block: /* This is a synchronized block:
* *
@ -558,11 +554,11 @@ public class TransformExceptionHandlers {
*/ */
catchFlow.removeSuccessor(catchBlock.subBlocks[1].jump); catchFlow.removeSuccessor(catchBlock.subBlocks[1].jump);
ComplexExpression monexit = (ComplexExpression) MonitorExitOperator monexit = (MonitorExitOperator)
((InstructionBlock) catchBlock.subBlocks[0]).instr; ((InstructionBlock) catchBlock.subBlocks[0]).instr;
LocalInfo local = LocalInfo local =
((LocalLoadOperator)monexit.getSubExpressions()[0]) ((LocalLoadOperator)monexit.getSubExpressions()[0])
.getLocalInfo(); .getLocalInfo();
tryFlow.mergeAddr(catchFlow); tryFlow.mergeAddr(catchFlow);
checkAndRemoveMonitorExit checkAndRemoveMonitorExit
@ -639,11 +635,11 @@ public class TransformExceptionHandlers {
if (catchBlock instanceof SequentialBlock if (catchBlock instanceof SequentialBlock
&& catchBlock.getSubBlocks()[0] instanceof JsrBlock && catchBlock.getSubBlocks()[0] instanceof JsrBlock
&& instr instanceof LocalStoreOperator && instr instanceof StoreInstruction
&& catchBlock.getSubBlocks()[1] instanceof ThrowBlock && catchBlock.getSubBlocks()[1] instanceof ThrowBlock
&& (((ThrowBlock)catchBlock.getSubBlocks()[1]).instr && (((ThrowBlock)catchBlock.getSubBlocks()[1]).instr
instanceof LocalLoadOperator) instanceof LocalLoadOperator)
&& (((LocalStoreOperator) instr).matches && (((StoreInstruction) instr).lvalueMatches
((LocalLoadOperator) ((LocalLoadOperator)
((ThrowBlock)catchBlock.getSubBlocks()[1]).instr))) { ((ThrowBlock)catchBlock.getSubBlocks()[1]).instr))) {

@ -21,7 +21,6 @@ package jode.flow;
import jode.decompiler.TabbedPrintWriter; import jode.decompiler.TabbedPrintWriter;
import jode.type.*; import jode.type.*;
import jode.expr.Expression; import jode.expr.Expression;
import jode.expr.ComplexExpression;
import jode.expr.InvokeOperator; import jode.expr.InvokeOperator;
import jode.expr.ConstructorOperator; import jode.expr.ConstructorOperator;
import jode.expr.LocalLoadOperator; import jode.expr.LocalLoadOperator;
@ -64,7 +63,7 @@ public class TryBlock extends StructuredBlock {
tryFlow.checkConsistent(); tryFlow.checkConsistent();
} }
public void addCatchBlock(CatchBlock catchBlock) { public void addCatchBlock(StructuredBlock catchBlock) {
StructuredBlock[] newSubBlocks = StructuredBlock[] newSubBlocks =
new StructuredBlock[subBlocks.length+1]; new StructuredBlock[subBlocks.length+1];
System.arraycopy(subBlocks, 0, newSubBlocks, 0, subBlocks.length); System.arraycopy(subBlocks, 0, newSubBlocks, 0, subBlocks.length);
@ -164,49 +163,41 @@ public class TryBlock extends StructuredBlock {
((InstructionBlock)subBlocks[0]).getInstruction(); ((InstructionBlock)subBlocks[0]).getInstruction();
CatchBlock catchBlock = (CatchBlock) subBlocks[1]; CatchBlock catchBlock = (CatchBlock) subBlocks[1];
if (instr.isVoid() if (instr.isVoid() || instr.getFreeOperandCount() != 0
|| !(instr instanceof ComplexExpression) || !(instr instanceof InvokeOperator)
|| !(instr.getOperator() instanceof InvokeOperator)
|| !(catchBlock.catchBlock instanceof ThrowBlock) || !(catchBlock.catchBlock instanceof ThrowBlock)
|| !(catchBlock.exceptionType.equals || !(catchBlock.exceptionType.equals
(Type.tClass("java.lang.CloneNotSupportedException")))) (Type.tClass("java.lang.CloneNotSupportedException"))))
return false; return false;
InvokeOperator arrayClone = (InvokeOperator) instr;
InvokeOperator arrayClone =
(InvokeOperator) instr.getOperator();
if (!arrayClone.getMethodName().equals("clone") if (!arrayClone.getMethodName().equals("clone")
|| arrayClone.isStatic() || arrayClone.isStatic()
|| (arrayClone.getMethodType().getParameterTypes() || !(arrayClone.getMethodType().getTypeSignature()
.length != 0) .equals("()Ljava/lang/Object;"))
|| (arrayClone.getMethodType().getReturnType() || !(arrayClone.getSubExpressions()[0]
!= Type.tObject)
|| !(((ComplexExpression) instr).getSubExpressions()[0]
.getType().isOfType(Type.tArray(Type.tUnknown)))) .getType().isOfType(Type.tArray(Type.tUnknown))))
return false; return false;
Expression throwExpr = Expression throwExpr =
((ThrowBlock) catchBlock.catchBlock).getInstruction(); ((ThrowBlock) catchBlock.catchBlock).getInstruction();
if (!(throwExpr instanceof ComplexExpression) if (throwExpr.getFreeOperandCount() != 0
|| !(throwExpr.getOperator() instanceof ConstructorOperator)) || !(throwExpr instanceof ConstructorOperator))
return false; return false;
ConstructorOperator throwOp = ConstructorOperator throwOp = (ConstructorOperator) throwExpr;
(ConstructorOperator) throwExpr.getOperator();
if (!(throwOp.getClassType() if (!(throwOp.getClassType()
.equals(Type.tClass("java.lang.InternalError"))) .equals(Type.tClass("java.lang.InternalError")))
|| throwOp.getMethodType().getParameterTypes().length != 1) || throwOp.getMethodType().getParameterTypes().length != 1)
return false; return false;
Expression getMethodExpr = Expression getMethodExpr = throwOp.getSubExpressions()[0];
((ComplexExpression) throwExpr).getSubExpressions()[0]; if (!(getMethodExpr instanceof InvokeOperator))
if (!(getMethodExpr instanceof ComplexExpression)
|| !(getMethodExpr.getOperator() instanceof InvokeOperator))
return false; return false;
InvokeOperator invoke = (InvokeOperator) getMethodExpr.getOperator(); InvokeOperator invoke = (InvokeOperator) getMethodExpr;
if (!invoke.getMethodName().equals("getMessage") if (!invoke.getMethodName().equals("getMessage")
|| invoke.isStatic() || invoke.isStatic()
|| (invoke.getMethodType().getParameterTypes() || (invoke.getMethodType().getParameterTypes()
@ -215,12 +206,12 @@ public class TryBlock extends StructuredBlock {
!= Type.tString)) != Type.tString))
return false; return false;
Expression exceptExpr = Expression exceptExpr = invoke.getSubExpressions()[0];
((ComplexExpression) getMethodExpr).getSubExpressions()[0];
if (!(exceptExpr instanceof LocalLoadOperator) if (!(exceptExpr instanceof LocalLoadOperator)
|| !(((LocalLoadOperator) exceptExpr).getLocalInfo() || !(((LocalLoadOperator) exceptExpr).getLocalInfo()
.equals(catchBlock.exceptionLocal))) .equals(catchBlock.exceptionLocal)))
return false; return false;
subBlocks[0].replace(this); subBlocks[0].replace(this);
if (flowBlock.lastModified == this) if (flowBlock.lastModified == this)
flowBlock.lastModified = subBlocks[0]; flowBlock.lastModified = subBlocks[0];

@ -19,7 +19,6 @@
package jode.flow; package jode.flow;
import jode.decompiler.LocalInfo; import jode.decompiler.LocalInfo;
import jode.expr.ComplexExpression;
import jode.expr.Expression; import jode.expr.Expression;
import jode.expr.LocalLoadOperator; import jode.expr.LocalLoadOperator;
import jode.expr.Operator; import jode.expr.Operator;
@ -100,7 +99,7 @@ public class VariableStack {
} }
public Expression mergeIntoExpression(Expression expr, VariableSet used) { public Expression mergeIntoExpression(Expression expr, VariableSet used) {
/* assert expr.getOperandCount() == stackMap.length */ /* assert expr.getFreeOperandCount() == stackMap.length */
for (int i = stackMap.length-1; i >= 0; i--) { for (int i = stackMap.length-1; i >= 0; i--) {
if (!used.contains(stackMap[i])) if (!used.contains(stackMap[i]))

Loading…
Cancel
Save