side effects

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@199 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent 3f815e4b70
commit 9edd43b624
  1. 54
      jode/jode/expr/ComplexExpression.java
  2. 29
      jode/jode/expr/ConstructorOperator.java
  3. 24
      jode/jode/expr/Expression.java
  4. 11
      jode/jode/expr/IIncOperator.java
  5. 39
      jode/jode/expr/InvokeOperator.java
  6. 10
      jode/jode/expr/StoreInstruction.java

@ -24,6 +24,7 @@ import jode.Type;
public class ComplexExpression extends Expression { public class ComplexExpression extends Expression {
Operator operator; Operator operator;
Expression[] subExpressions; Expression[] subExpressions;
int operandcount = 0;
public ComplexExpression(Operator op, Expression[] sub) { public ComplexExpression(Operator op, Expression[] sub) {
super(Type.tUnknown); super(Type.tUnknown);
@ -34,19 +35,15 @@ public class ComplexExpression extends Expression {
operator = op; operator = op;
operator.parent = this; operator.parent = this;
subExpressions = sub; subExpressions = sub;
for (int i=0; i< subExpressions.length; i++) for (int i=0; i< subExpressions.length; i++) {
subExpressions[i].parent = this; subExpressions[i].parent = this;
operandcount += subExpressions[i].getOperandCount();
}
updateType(); updateType();
} }
public int getOperandCount() { public int getOperandCount() {
if (subExpressions.length == 0) return operandcount;
return 0;
else
/* The only sub expression that may have non resolved
* operands may be the first.
*/
return subExpressions[0].getOperandCount();
} }
public Expression negate() { public Expression negate() {
@ -71,6 +68,22 @@ public class ComplexExpression extends Expression {
return new ComplexExpression(negop, new Expression[] { this }); return new ComplexExpression(negop, new Expression[] { this });
} }
/**
* Checks if the value of the given expression can change, due to
* side effects in this expression. If this returns false, the
* expression can safely be moved behind the current expresion.
* @param expr the expression that should not change.
*/
public boolean hasSideEffects(Expression expr) {
if (operator.hasSideEffects(expr))
return true;
for (int i=0; i < subExpressions.length; i++) {
if (subExpressions[i].hasSideEffects(expr))
return true;
}
return false;
}
/** /**
* Checks if the given Expression (which must be a CombineableOperator) * Checks if the given Expression (which must be a CombineableOperator)
* can be combined into this expression. * can be combined into this expression.
@ -103,7 +116,23 @@ public class ComplexExpression extends Expression {
} }
/** /**
* Checks if this expression contains a load, that matches the * Checks if this expression contains a conflicting load, that
* matches the given CombineableOperator. The sub expressions are
* not checked.
* @param op The combineable operator.
* @return if this expression contains a matching load. */
public boolean containsConflictingLoad(CombineableOperator op) {
if (op.matches(operator))
return true;
for (int i=0; i < subExpressions.length; i++) {
if (subExpressions[i].containsConflictingLoad(op))
return true;
}
return false;
}
/**
* Checks if this expression contains a conflicting load, that matches the
* given Expression (which must be a * given Expression (which must be a
* StoreInstruction/IIncOperator). * StoreInstruction/IIncOperator).
* @param e The store expression. * @param e The store expression.
@ -169,9 +198,15 @@ public class ComplexExpression extends Expression {
} }
public void setSubExpressions(int i, Expression expr) { public void setSubExpressions(int i, Expression expr) {
int diff = expr.getOperandCount()
- subExpressions[i].getOperandCount();
subExpressions[i] = expr; subExpressions[i] = expr;
for (ComplexExpression ce = this; ce != null;
ce = (ComplexExpression) ce.parent)
ce.operandcount += diff;
updateType(); updateType();
} }
void updateSubTypes() { void updateSubTypes() {
boolean changed = false; boolean changed = false;
for (int i=0; i < subExpressions.length; i++) { for (int i=0; i < subExpressions.length; i++) {
@ -456,5 +491,4 @@ public class ComplexExpression extends Expression {
return false; return false;
return true; return true;
} }
} }

@ -21,7 +21,8 @@ package jode.decompiler;
import jode.Type; import jode.Type;
import jode.MethodType; import jode.MethodType;
public class ConstructorOperator extends Operator { public class ConstructorOperator extends Operator
implements CombineableOperator {
MethodType methodType; MethodType methodType;
Type classType; Type classType;
@ -32,6 +33,32 @@ public class ConstructorOperator extends Operator {
this.methodType = methodType; this.methodType = methodType;
} }
/**
* Checks if the value of the given expression can change, due to
* side effects in this expression. If this returns false, the
* expression can safely be moved behind the current expresion.
* @param expr the expression that should not change.
*/
public boolean hasSideEffects(Expression expr) {
return expr.containsConflictingLoad(this);
}
/**
* Makes a non void expression out of this invoke instruction.
*/
public void makeNonVoid() {
throw new jode.AssertError("already non void");
}
/**
* Checks if the value of the operator can be changed by this expression.
*/
public boolean matches(Operator loadop) {
return (loadop instanceof InvokeOperator
|| loadop instanceof ConstructorOperator
|| loadop instanceof GetFieldOperator);
}
public int getPriority() { public int getPriority() {
return 950; return 950;
} }

@ -58,6 +58,17 @@ public abstract class Expression {
return new ComplexExpression(negop, new Expression[] { this }); return new ComplexExpression(negop, new Expression[] { this });
} }
/**
* Checks if the value of the given expression can change, due to
* side effects in this expression. If this returns false, the
* expression can safely be moved behind the current expresion.
* @param expr the expression that should not change.
*/
public boolean hasSideEffects(Expression expr) {
// Most expression don't have side effects.
return false;
}
/** /**
* Checks if the given Expression (which should be a CombineableOperator) * Checks if the given Expression (which should be a CombineableOperator)
* can be combined into this expression. * can be combined into this expression.
@ -82,6 +93,16 @@ public abstract class Expression {
return ((CombineableOperator)e.getOperator()).matches(getOperator()); return ((CombineableOperator)e.getOperator()).matches(getOperator());
} }
/**
* Checks if this expression contains a conflicting load, that
* matches the given CombineableOperator. The sub expressions are
* not checked.
* @param op The combineable operator.
* @return if this expression contains a matching load. */
public boolean containsConflictingLoad(CombineableOperator op) {
return op.matches(getOperator());
}
/** /**
* Combines the given Expression (which should be a StoreInstruction) * Combines the given Expression (which should be a StoreInstruction)
* into this expression. You must only call this if * into this expression. You must only call this if
@ -110,7 +131,8 @@ public abstract class Expression {
return this; return this;
} }
static Expression EMPTYSTRING = new ConstOperator(Type.tString, "\"\""); public static Expression EMPTYSTRING
= new ConstOperator(Type.tString, "\"\"");
public Expression simplifyStringBuffer() { public Expression simplifyStringBuffer() {
return null; return null;

@ -59,6 +59,17 @@ implements LocalVarOperator, CombineableOperator {
return 100; return 100;
} }
/**
* Checks if the value of the given expression can change, due to
* side effects in this expression. If this returns false, the
* expression can safely be moved behind the current expresion.
* @param expr the expression that should not change.
*/
public boolean hasSideEffects(Expression expr) {
return expr.containsConflictingLoad(this);
}
/** /**
* Makes a non void expression out of this store instruction. * Makes a non void expression out of this store instruction.
*/ */

@ -23,7 +23,8 @@ import jode.MethodType;
import jode.Type; import jode.Type;
import jode.bytecode.ClassInfo; import jode.bytecode.ClassInfo;
public final class InvokeOperator extends Operator { public final class InvokeOperator extends Operator
implements CombineableOperator {
CodeAnalyzer codeAnalyzer; CodeAnalyzer codeAnalyzer;
boolean specialFlag; boolean specialFlag;
MethodType methodType; MethodType methodType;
@ -44,6 +45,32 @@ public final class InvokeOperator extends Operator {
classType.useType(); classType.useType();
} }
/**
* Checks if the value of the given expression can change, due to
* side effects in this expression. If this returns false, the
* expression can safely be moved behind the current expresion.
* @param expr the expression that should not change.
*/
public boolean hasSideEffects(Expression expr) {
return expr.containsConflictingLoad(this);
}
/**
* Makes a non void expression out of this invoke instruction.
*/
public void makeNonVoid() {
throw new jode.AssertError("already non void");
}
/**
* Checks if the value of the operator can be changed by this expression.
*/
public boolean matches(Operator loadop) {
return (loadop instanceof InvokeOperator
|| loadop instanceof ConstructorOperator
|| loadop instanceof GetFieldOperator);
}
public boolean isStatic() { public boolean isStatic() {
return methodType.isStatic(); return methodType.isStatic();
} }
@ -135,11 +162,7 @@ public final class InvokeOperator extends Operator {
return method+"("+params+")"; return method+"("+params+")";
} }
public boolean equals(Object o) { /* Invokes never equals: they may return different values even if
return o instanceof InvokeOperator && * they have the same parameters.
((InvokeOperator)o).classType.equals(classType) && */
((InvokeOperator)o).methodName.equals(methodName) &&
((InvokeOperator)o).methodType.equals(methodType) &&
((InvokeOperator)o).specialFlag == specialFlag;
}
} }

@ -40,6 +40,16 @@ public abstract class StoreInstruction extends Operator
return lvalueType; return lvalueType;
} }
/**
* Checks if the value of the given expression can change, due to
* side effects in this expression. If this returns false, the
* expression can safely be moved behind the current expresion.
* @param expr the expression that should not change.
*/
public boolean hasSideEffects(Expression expr) {
return expr.containsConflictingLoad(this);
}
/** /**
* Makes a non void expression out of this store instruction. * Makes a non void expression out of this store instruction.
*/ */

Loading…
Cancel
Save