++: check for 1 and 1.0

print type errors
setSubExpression enabled


git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@425 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent e32850d300
commit 981c5de033
  1. 153
      jode/jode/expr/ComplexExpression.java

@ -113,12 +113,19 @@ public class ComplexExpression extends Expression {
* is not a CombineableOperator. * is not a CombineableOperator.
*/ */
public int canCombine(Expression e) { public int canCombine(Expression e) {
// Decompiler.err.println("Try to combine "+e+" into "+this); // Decompiler.err.println("Try to combine "+e+" into "+this);
if (e.getOperator() instanceof LocalStoreOperator if (e.getOperator() instanceof LocalStoreOperator
&& e.getOperandCount() == 0) { && e.getOperandCount() == 0) {
// Special case for locals created on inlining methods, which may // Special case for locals created on inlining methods, which may
// combine everywhere // combine everywhere, as long as there are no side effects.
return containsMatchingLoad(e) ? 1 : 0;
for (int i=0; i < subExpressions.length; i++) {
int result = subExpressions[i].canCombine(e);
if (result != 0)
return result;
if (subExpressions[i].hasSideEffects(e))
return -1;
}
} }
if (e instanceof ComplexExpression) { if (e instanceof ComplexExpression) {
@ -216,18 +223,17 @@ public class ComplexExpression extends Expression {
return subExpressions; return subExpressions;
} }
// public void setSubExpressions(int i, Expression expr) { public void setSubExpressions(int i, Expression expr) {
// int diff = expr.getOperandCount() int diff = expr.getOperandCount()
// - subExpressions[i].getOperandCount(); - subExpressions[i].getOperandCount();
// subExpressions[i] = expr; subExpressions[i] = expr;
// for (ComplexExpression ce = this; ce != null; for (ComplexExpression ce = this; ce != null;
// ce = (ComplexExpression) ce.parent) ce = (ComplexExpression) ce.parent)
// ce.operandcount += diff; ce.operandcount += diff;
// updateType(); updateType();
// } }
void updateSubTypes() { void updateSubTypes() {
boolean changed = false;
for (int i=0; i < subExpressions.length; i++) { for (int i=0; i < subExpressions.length; i++) {
Type opType; Type opType;
if (operator instanceof CheckNullOperator if (operator instanceof CheckNullOperator
@ -240,53 +246,61 @@ public class ComplexExpression extends Expression {
opType = operator.getOperandType(i); opType = operator.getOperandType(i);
} else } else
opType = Type.tSubType(operator.getOperandType(i)); opType = Type.tSubType(operator.getOperandType(i));
Type exprType = subExpressions[i].getType(); if (opType != Type.tError) {
opType = opType.intersection(exprType); Type exprType = subExpressions[i].getType();
if (!opType.equals(exprType) && opType != Type.tError) { opType = opType.intersection(exprType);
if (Decompiler.isTypeDebugging) if (!opType.equals(exprType)) {
Decompiler.err.println("change in "+this+": " if (Decompiler.isTypeDebugging)
+exprType Decompiler.err.println("change in "+this+": "
+"->"+opType); +exprType+"->"+opType);
subExpressions[i].setType(opType); if (opType == Type.tError)
changed = true; Decompiler.err.println("Type error in "+this+": "
+exprType+"->"
+operator.getOperandType(i));
subExpressions[i].setType(opType);
}
} }
} }
} }
public void updateType() { public void updateType() {
if (subExpressions.length > 0) { while (true) {
while (true) { updateSubTypes();
updateSubTypes(); Type types[] = new Type[subExpressions.length];
Type types[] = new Type[subExpressions.length]; boolean changed = false;
boolean changed = false; for (int i=0; i < types.length; i++) {
for (int i=0; i < types.length; i++) { if (operator instanceof CheckNullOperator
if (operator instanceof CheckNullOperator || i == 0 && operator instanceof ArrayStoreOperator) {
|| i == 0 && operator instanceof ArrayStoreOperator) { /* No rule without exception:
/* No rule without exception: * We can always use tSuperType, except for the
* We can always use tSuperType, except for the * array operand of an array store instruction.
* array operand of an array store instruction. */
*/ types[i] = subExpressions[i].getType();
types[i] = subExpressions[i].getType(); } else
} else types[i] = Type.tSuperType
types[i] = Type.tSuperType (subExpressions[i].getType());
(subExpressions[i].getType()); Type opType = operator.getOperandType(i);
Type opType = operator.getOperandType(i); if (types[i] == Type.tError)
types[i] = types[i].intersection(opType); continue;
if (!types[i].equals(opType) types[i] = types[i].intersection(opType);
&& types[i] != Type.tError) { if (types[i].equals(opType))
if (Decompiler.isTypeDebugging) continue;
Decompiler.err.println("change in "+this+": "
+operator.getOperandType(i) if (Decompiler.isTypeDebugging)
+"->"+types[i]); Decompiler.err.println("change in "+this+" at "+i+": "
changed = true; +opType+"->"+types[i]);
} if (types[i] == Type.tError)
} Decompiler.err.println("Type error in "+this+" at "+i+": "
if (!changed) +subExpressions[i].getType()
break; +"->"+opType);
operator.setOperandType(types); else
} changed = true;
} }
Type newType = type.intersection(operator.getType()); if (!changed)
break;
operator.setOperandType(types);
}
Type newType = type.intersection(operator.getType());
if (!newType.equals(type)) { if (!newType.equals(type)) {
type = newType; type = newType;
if (parent != null) if (parent != null)
@ -344,6 +358,32 @@ public class ComplexExpression extends Expression {
return true; return true;
} }
/**
* This method should remove local variables that are only written
* and read one time directly after another. <br>
*
* In this case this is a non void LocalStoreOperator, whose local
* isn't used in other places.
* @return an expression where the locals are removed.
*/
public Expression removeOnetimeLocals() {
// System.err.println("removeOneTimeLocals: "+this);
if (operator instanceof LocalStoreOperator
&& operator.getType() != Type.tVoid) {
jode.decompiler.LocalInfo local = ((LocalStoreOperator)operator).getLocalInfo();
if ((local.getUseCount() == 2 /*XXX*/)) {
/* remove LocalInfo somehow XXX */
return subExpressions[0].removeOnetimeLocals();
} // else
// System.err.println("Can't remove local "+local);
}
for (int i=0; i< subExpressions.length; i++) {
subExpressions[i] = subExpressions[i].removeOnetimeLocals();
subExpressions[i].parent = this;
}
return this;
}
public Expression simplifyStringBuffer() { public Expression simplifyStringBuffer() {
if (operator instanceof InvokeOperator if (operator instanceof InvokeOperator
&& (((InvokeOperator)operator).getClassType() && (((InvokeOperator)operator).getClassType()
@ -459,7 +499,8 @@ public class ComplexExpression extends Expression {
operator.OPASSIGN_OP+operator.ADD_OP || operator.OPASSIGN_OP+operator.ADD_OP ||
operator.getOperatorIndex() == operator.getOperatorIndex() ==
operator.OPASSIGN_OP+operator.NEG_OP) && operator.OPASSIGN_OP+operator.NEG_OP) &&
(one.getValue().equals("1"))) { (one.getValue().equals("1")
|| one.getValue().equals("1.0"))) {
int op = (operator.getOperatorIndex() == int op = (operator.getOperatorIndex() ==
operator.OPASSIGN_OP+operator.ADD_OP) operator.OPASSIGN_OP+operator.ADD_OP)

Loading…
Cancel
Save