|
|
@ -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; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|