Expression rework (ComplexExpression removed)

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

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

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

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

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

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

@ -19,35 +19,122 @@
package jode.flow;
import jode.expr.*;
import jode.bytecode.Reference;
import jode.decompiler.CodeAnalyzer;
import jode.type.Type;
public class CreateNewConstructor {
public static boolean transform(InstructionContainer ic,
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>
* (optional DUP)
* (void resolved expressions)
* PUSH load_ops
* optionally: <= used for "string1 += string2"
* DUP_X2/1 <= 2 if above DUP is present
* stack_n.<init>((optional: stack_n), resolved expressions)
* DUP_X2/1 <= 2 if above DUP is present
* stack_n.<init>(stack_n, resolved expressions)
*
* transform it to
*
* PUSH load_ops
* optionally:
* DUP <= remove the depth
* (optional PUSH) new <object>((optional: stack_n),
* resolved expressions)
* DUP <= remove the depth
* (optional PUSH) new <object>(stack_n, resolved expressions)
*/
if (!(last.outer instanceof SequentialBlock))
return false;
if (!(ic.getInstruction().getOperator() instanceof InvokeOperator))
if (!(ic.getInstruction() instanceof InvokeOperator))
return false;
Expression constrExpr = ic.getInstruction();
InvokeOperator constrCall = (InvokeOperator) constrExpr.getOperator();
InvokeOperator constrCall = (InvokeOperator) ic.getInstruction();
if (!constrCall.isConstructor())
return false;
@ -55,13 +142,12 @@ public class CreateNewConstructor {
SpecialBlock optDupX2 = null;
SequentialBlock sequBlock = (SequentialBlock) last.outer;
if (constrExpr instanceof ComplexExpression) {
Expression[] subs =
((ComplexExpression) constrExpr).getSubExpressions();
Expression[] subs = constrCall.getSubExpressions();
int opcount = constrCall.getFreeOperandCount();
if (subs != null) {
if (!(subs[0] instanceof NopOperator))
return false;
if (constrExpr.getOperandCount() > 1) {
if (constrCall.getFreeOperandCount() > 1) {
if (!(sequBlock.outer instanceof SequentialBlock)
|| !(sequBlock.subBlocks[0] instanceof SpecialBlock))
return false;
@ -71,7 +157,6 @@ public class CreateNewConstructor {
|| optDupX2.depth == 0)
return false;
int count = optDupX2.count;
int opcount = constrExpr.getOperandCount() - 1;
do {
if (!(sequBlock.outer instanceof SequentialBlock)
|| !(sequBlock.subBlocks[0]
@ -86,19 +171,22 @@ public class CreateNewConstructor {
continue;
count -= expr.getType().stackSize();
opcount--;
} while (count > 0 && opcount > 0);
if (opcount != 0 || count != 0)
} while (count > 0 && opcount > 1);
if (count != 0)
return false;
} else if (constrExpr.getOperandCount() != 1)
return false;
} else if (constrExpr.getOperandCount() != 1)
}
}
if (opcount != 1)
return false;
while (sequBlock.subBlocks[0] instanceof InstructionBlock
&& ((InstructionBlock)sequBlock.subBlocks[0])
.getInstruction().isVoid()
&& sequBlock.outer instanceof SequentialBlock)
while (sequBlock.subBlocks[0] instanceof InstructionBlock
&& sequBlock.outer instanceof SequentialBlock) {
Expression expr
= ((InstructionBlock)sequBlock.subBlocks[0]).getInstruction();
if (!expr.isVoid() || expr.getFreeOperandCount() > 0)
break;
sequBlock = (SequentialBlock) sequBlock.outer;
}
SpecialBlock dup = null;
if (sequBlock.outer instanceof SequentialBlock
@ -133,14 +221,9 @@ public class CreateNewConstructor {
Expression newExpr = new ConstructorOperator
(constrCall, dup == null);
if (constrExpr instanceof ComplexExpression) {
Expression[] subs =
((ComplexExpression)constrExpr).getSubExpressions();
for (int i=subs.length - 1; i>=1; i--) {
if (subs[i] instanceof NopOperator)
break;
if (subs != null) {
for (int i=subs.length; i-- > 1; )
newExpr = newExpr.addOperand(subs[i]);
}
}
ic.setInstruction(newExpr);
return true;

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

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

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

@ -113,8 +113,8 @@ public class SpecialBlock extends StructuredBlock {
Expression expr2 = block2.getInstruction();
if (expr1.isVoid() || expr2.isVoid()
|| expr1.getOperandCount() != 0
|| expr2.getOperandCount() != 0
|| expr1.getFreeOperandCount() != 0
|| expr2.getFreeOperandCount() != 0
|| expr1.hasSideEffects(expr2)
|| expr2.hasSideEffects(expr1))
return false;
@ -175,18 +175,16 @@ public class SpecialBlock extends StructuredBlock {
if (instr.getType().stackSize() == count) {
StructuredBlock newBlock;
if (instr.getOperator() instanceof InvokeOperator
|| instr.getOperator() instanceof ConstructorOperator) {
ComplexExpression newExpr = new ComplexExpression
(new PopOperator(instr.getType()),
new Expression[] { instr });
if (instr instanceof InvokeOperator
|| instr instanceof ConstructorOperator) {
Expression newExpr
= new PopOperator(instr.getType()).addOperand(instr);
prev.setInstruction(newExpr);
newBlock = prev;
} else {
ComplexExpression newCond = new ComplexExpression
(new CompareUnaryOperator(instr.getType(),
Operator.NOTEQUALS_OP),
new Expression[] { instr });
Expression newCond = new CompareUnaryOperator
(instr.getType(), Operator.NOTEQUALS_OP)
.addOperand(instr);
IfThenElseBlock newIfThen = new IfThenElseBlock(newCond);
newIfThen.setThenBlock(new EmptyBlock());
newBlock = newIfThen;
@ -204,41 +202,6 @@ public class SpecialBlock extends StructuredBlock {
}
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;
}

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

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

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

@ -19,7 +19,6 @@
package jode.flow;
import jode.decompiler.LocalInfo;
import jode.expr.ComplexExpression;
import jode.expr.Expression;
import jode.expr.LocalLoadOperator;
import jode.expr.Operator;
@ -100,7 +99,7 @@ public class VariableStack {
}
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--) {
if (!used.contains(stackMap[i]))

Loading…
Cancel
Save