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 {
Operator operator;
Expression[] subExpressions;
int operandcount = 0;
public ComplexExpression(Operator op, Expression[] sub) {
super(Type.tUnknown);
@ -34,19 +35,15 @@ public class ComplexExpression extends Expression {
operator = op;
operator.parent = this;
subExpressions = sub;
for (int i=0; i< subExpressions.length; i++)
for (int i=0; i< subExpressions.length; i++) {
subExpressions[i].parent = this;
operandcount += subExpressions[i].getOperandCount();
}
updateType();
}
public int getOperandCount() {
if (subExpressions.length == 0)
return 0;
else
/* The only sub expression that may have non resolved
* operands may be the first.
*/
return subExpressions[0].getOperandCount();
return operandcount;
}
public Expression negate() {
@ -71,6 +68,22 @@ public class ComplexExpression extends Expression {
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)
* 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
* StoreInstruction/IIncOperator).
* @param e The store expression.
@ -169,9 +198,15 @@ public class ComplexExpression extends Expression {
}
public void setSubExpressions(int i, Expression expr) {
int diff = expr.getOperandCount()
- subExpressions[i].getOperandCount();
subExpressions[i] = expr;
for (ComplexExpression ce = this; ce != null;
ce = (ComplexExpression) ce.parent)
ce.operandcount += diff;
updateType();
}
void updateSubTypes() {
boolean changed = false;
for (int i=0; i < subExpressions.length; i++) {
@ -456,5 +491,4 @@ public class ComplexExpression extends Expression {
return false;
return true;
}
}

@ -21,7 +21,8 @@ package jode.decompiler;
import jode.Type;
import jode.MethodType;
public class ConstructorOperator extends Operator {
public class ConstructorOperator extends Operator
implements CombineableOperator {
MethodType methodType;
Type classType;
@ -32,6 +33,32 @@ public class ConstructorOperator extends Operator {
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() {
return 950;
}

@ -58,6 +58,17 @@ public abstract class Expression {
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)
* can be combined into this expression.
@ -82,6 +93,16 @@ public abstract class Expression {
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)
* into this expression. You must only call this if
@ -110,7 +131,8 @@ public abstract class Expression {
return this;
}
static Expression EMPTYSTRING = new ConstOperator(Type.tString, "\"\"");
public static Expression EMPTYSTRING
= new ConstOperator(Type.tString, "\"\"");
public Expression simplifyStringBuffer() {
return null;

@ -59,6 +59,17 @@ implements LocalVarOperator, CombineableOperator {
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.
*/

@ -23,7 +23,8 @@ import jode.MethodType;
import jode.Type;
import jode.bytecode.ClassInfo;
public final class InvokeOperator extends Operator {
public final class InvokeOperator extends Operator
implements CombineableOperator {
CodeAnalyzer codeAnalyzer;
boolean specialFlag;
MethodType methodType;
@ -44,6 +45,32 @@ public final class InvokeOperator extends Operator {
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() {
return methodType.isStatic();
}
@ -135,11 +162,7 @@ public final class InvokeOperator extends Operator {
return method+"("+params+")";
}
public boolean equals(Object o) {
return o instanceof InvokeOperator &&
((InvokeOperator)o).classType.equals(classType) &&
((InvokeOperator)o).methodName.equals(methodName) &&
((InvokeOperator)o).methodType.equals(methodType) &&
((InvokeOperator)o).specialFlag == specialFlag;
}
/* Invokes never equals: they may return different values even if
* they have the same parameters.
*/
}

@ -40,6 +40,16 @@ public abstract class StoreInstruction extends Operator
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.
*/

Loading…
Cancel
Save