git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@41 379699f6-c40d-0410-875b-85095c16579estable
parent
e353bf575c
commit
3714549529
@ -0,0 +1,311 @@ |
|||||||
|
/* |
||||||
|
* Expression (c) 1998 Jochen Hoenicke |
||||||
|
* |
||||||
|
* You may distribute under the terms of the GNU General Public License. |
||||||
|
* |
||||||
|
* IN NO EVENT SHALL JOCHEN HOENICKE BE LIABLE TO ANY PARTY FOR DIRECT, |
||||||
|
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF |
||||||
|
* THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOCHEN HOENICKE |
||||||
|
* HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
* JOCHEN HOENICKE SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
||||||
|
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" |
||||||
|
* BASIS, AND JOCHEN HOENICKE HAS NO OBLIGATION TO PROVIDE MAINTENANCE, |
||||||
|
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||||||
|
* |
||||||
|
* $Id$ |
||||||
|
*/ |
||||||
|
|
||||||
|
package jode; |
||||||
|
import sun.tools.java.Type; |
||||||
|
import sun.tools.java.Constants; |
||||||
|
import sun.tools.java.FieldDefinition; |
||||||
|
|
||||||
|
public class ComplexExpression extends Expression { |
||||||
|
Operator operator; |
||||||
|
Expression[] subExpressions; |
||||||
|
|
||||||
|
public ComplexExpression(Operator op, Expression[] sub) { |
||||||
|
super(MyType.tUnknown); |
||||||
|
operator = op; |
||||||
|
subExpressions = sub; |
||||||
|
operator.setExpression(this); |
||||||
|
if (subExpressions.length != op.getOperandCount()) |
||||||
|
throw new AssertError ("Operand count mismatch: "+ |
||||||
|
subExpressions.length + " != " + |
||||||
|
op.getOperandCount()); |
||||||
|
if (subExpressions.length > 0) { |
||||||
|
Type types[] = new Type[subExpressions.length]; |
||||||
|
for (int i=0; i < types.length; i++) { |
||||||
|
subExpressions[i].parent = this; |
||||||
|
types[i] = subExpressions[i].getType(); |
||||||
|
} |
||||||
|
operator.setOperandType(types); |
||||||
|
updateSubTypes(); |
||||||
|
} |
||||||
|
this.type = operator.getType(); |
||||||
|
} |
||||||
|
|
||||||
|
public Expression negate() { |
||||||
|
if (operator.operator >= operator.COMPARE_OP && |
||||||
|
operator.operator < operator.COMPARE_OP+6) { |
||||||
|
operator.setOperatorIndex(operator.getOperatorIndex() ^ 1); |
||||||
|
return this; |
||||||
|
} else if (operator.getOperatorIndex() == operator.LOG_AND_OP || |
||||||
|
operator.getOperatorIndex() == operator.LOG_OR_OP) { |
||||||
|
operator.setOperatorIndex(operator.getOperatorIndex() ^ 1); |
||||||
|
for (int i=0; i< subExpressions.length; i++) { |
||||||
|
subExpressions[i] = subExpressions[i].negate(); |
||||||
|
} |
||||||
|
return this; |
||||||
|
} else if (operator.operator == operator.LOG_NOT_OP) { |
||||||
|
return subExpressions[0]; |
||||||
|
} |
||||||
|
|
||||||
|
Operator negop = |
||||||
|
new UnaryOperator(Type.tBoolean, Operator.LOG_NOT_OP); |
||||||
|
Expression[] e = { this }; |
||||||
|
return new ComplexExpression(negop, e); |
||||||
|
} |
||||||
|
|
||||||
|
public Expression tryToCombine(Expression e) { |
||||||
|
if (e instanceof ComplexExpression |
||||||
|
&& e.getOperator() instanceof StoreInstruction) { |
||||||
|
ComplexExpression ce = (ComplexExpression) e; |
||||||
|
StoreInstruction store = (StoreInstruction) e.getOperator(); |
||||||
|
if (store.matches(operator)) { |
||||||
|
int i; |
||||||
|
for (i=0; i < ce.subExpressions.length-1; i++) { |
||||||
|
if (!ce.subExpressions[i].equals(subExpressions[i])) |
||||||
|
break; |
||||||
|
} |
||||||
|
if (i == ce.subExpressions.length-1) { |
||||||
|
operator = |
||||||
|
new AssignOperator(store.getOperatorIndex(), store); |
||||||
|
subExpressions = ce.subExpressions; |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
||||||
|
for (int i=0; i < subExpressions.length; i++) { |
||||||
|
Expression combined = subExpressions[i].tryToCombine(e); |
||||||
|
if (combined != null) { |
||||||
|
subExpressions[i] = combined; |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public Operator getOperator() { |
||||||
|
return operator; |
||||||
|
} |
||||||
|
|
||||||
|
public Expression[] getSubExpressions() { |
||||||
|
return subExpressions; |
||||||
|
} |
||||||
|
|
||||||
|
void updateSubTypes() { |
||||||
|
for (int i=0; i < subExpressions.length; i++) { |
||||||
|
subExpressions[i].setType(operator.getOperandType(i)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setType(Type newType) { |
||||||
|
newType = MyType.intersection(type, newType); |
||||||
|
if (newType != type) { |
||||||
|
type = newType; |
||||||
|
operator.setType(type); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isVoid() { |
||||||
|
return operator.getType() == Type.tVoid; |
||||||
|
} |
||||||
|
|
||||||
|
public String toString() { |
||||||
|
String[] expr = new String[subExpressions.length]; |
||||||
|
for (int i=0; i<subExpressions.length; i++) { |
||||||
|
expr[i] = subExpressions[i]. |
||||||
|
toString(operator.getOperandPriority(i)); |
||||||
|
} |
||||||
|
String result = operator.toString(expr); |
||||||
|
if (Decompiler.isTypeDebugging) |
||||||
|
result = "(("+operator.getType()+")"+result+")"; |
||||||
|
else if (operator.getType() == MyType.tError) |
||||||
|
result = "(/*type error */" + result+")"; |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean equals(Object o) { |
||||||
|
if (this == o) |
||||||
|
return true; |
||||||
|
if (!(o instanceof ComplexExpression)) |
||||||
|
return false; |
||||||
|
ComplexExpression expr = (ComplexExpression) o; |
||||||
|
if (!operator.equals(expr.operator) || |
||||||
|
subExpressions.length != expr.subExpressions.length) |
||||||
|
return false; |
||||||
|
|
||||||
|
for (int i=0; i<subExpressions.length; i++) { |
||||||
|
if (!subExpressions[i].equals(expr.subExpressions[i])) |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
static Expression emptyString = |
||||||
|
new EmptyStringOperator(); |
||||||
|
|
||||||
|
Expression simplifyStringBuffer() { |
||||||
|
FieldDefinition field; |
||||||
|
if (operator instanceof InvokeOperator && |
||||||
|
(field = ((InvokeOperator)operator).getField()) |
||||||
|
.getClassDefinition().getName() == |
||||||
|
Constants.idJavaLangStringBuffer && |
||||||
|
!((InvokeOperator)operator).isStatic() && |
||||||
|
field.getName() == Constants.idAppend && |
||||||
|
field.getType().getArgumentTypes().length == 1) { |
||||||
|
|
||||||
|
Expression e = subExpressions[0].simplifyStringBuffer(); |
||||||
|
if (e == null) |
||||||
|
return null; |
||||||
|
|
||||||
|
if (e.getOperator() instanceof EmptyStringOperator && |
||||||
|
MyType.isOfType(subExpressions[1].getType(), Type.tString)) |
||||||
|
return subExpressions[1]; |
||||||
|
|
||||||
|
Expression[] exprs = { e, |
||||||
|
(Expression)subExpressions[1].simplify() }; |
||||||
|
return new ComplexExpression(new StringAddOperator(), exprs); |
||||||
|
} |
||||||
|
if (operator instanceof ConstructorOperator && |
||||||
|
MyType.isOfType(operator.getType(), MyType.tStringBuffer)) { |
||||||
|
if (operator.getOperandCount() == 1) |
||||||
|
return emptyString; |
||||||
|
else if (operator.getOperandCount() == 2 && |
||||||
|
MyType.isOfType(subExpressions[1].getType(), |
||||||
|
MyType.tString)) |
||||||
|
return (Expression) subExpressions[1].simplify(); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public Instruction simplify() { |
||||||
|
if (operator instanceof IfThenElseOperator && |
||||||
|
operator.getType() == Type.tBoolean) { |
||||||
|
if (subExpressions[1].getOperator() instanceof ConstOperator && |
||||||
|
subExpressions[2].getOperator() instanceof ConstOperator) { |
||||||
|
ConstOperator c1 = |
||||||
|
(ConstOperator) subExpressions[1].getOperator(); |
||||||
|
ConstOperator c2 = |
||||||
|
(ConstOperator) subExpressions[2].getOperator(); |
||||||
|
if (c1.getValue().equals("true") && |
||||||
|
c2.getValue().equals("false")) |
||||||
|
return subExpressions[0].simplify(); |
||||||
|
if (c2.getValue().equals("true") && |
||||||
|
c1.getValue().equals("false")) |
||||||
|
return subExpressions[0].negate().simplify(); |
||||||
|
} |
||||||
|
} |
||||||
|
// if ((operator instanceof AssignOperator ||
|
||||||
|
// operator instanceof StoreInstruction) &&
|
||||||
|
// subExpressions[subExpressions.length-1]
|
||||||
|
// .operator instanceof ConstOperator) {
|
||||||
|
// StoreInstruction store;
|
||||||
|
// if (operator instanceof AssignOperator)
|
||||||
|
// store = ((AssignOperator)operator).getStore();
|
||||||
|
// else
|
||||||
|
// store = (StoreInstruction)operator;
|
||||||
|
|
||||||
|
// ConstOperator one = (ConstOperator)
|
||||||
|
// subExpressions[subExpressions.length-1].operator;
|
||||||
|
|
||||||
|
// if ((operator.getOperatorIndex() ==
|
||||||
|
// operator.OPASSIGN_OP+operator.ADD_OP ||
|
||||||
|
// operator.getOperatorIndex() ==
|
||||||
|
// operator.OPASSIGN_OP+operator.NEG_OP) &&
|
||||||
|
// (one.getValue().equals("1") ||
|
||||||
|
// one.getValue().equals("-1"))) {
|
||||||
|
|
||||||
|
// int op = ((operator.getOperatorIndex() ==
|
||||||
|
// operator.OPASSIGN_OP+operator.ADD_OP) ==
|
||||||
|
// one.getValue().equals("1"))?
|
||||||
|
// operator.INC_OP : operator.DEC_OP;
|
||||||
|
|
||||||
|
// return new PostFixOperator
|
||||||
|
// (store.getType(), op, store,
|
||||||
|
// operator instanceof StoreInstruction).simplify();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
if (operator instanceof CompareUnaryOperator && |
||||||
|
subExpressions[0].getOperator() instanceof CompareToIntOperator) { |
||||||
|
|
||||||
|
CompareBinaryOperator newOp = new CompareBinaryOperator |
||||||
|
(subExpressions[0].getOperator().getOperandType(0), |
||||||
|
operator.getOperatorIndex()); |
||||||
|
|
||||||
|
if (subExpressions[0] instanceof ComplexExpression) { |
||||||
|
return new ComplexExpression |
||||||
|
(newOp, |
||||||
|
((ComplexExpression)subExpressions[0]).subExpressions). |
||||||
|
simplify(); |
||||||
|
} else |
||||||
|
return newOp.simplify(); |
||||||
|
} |
||||||
|
if (operator instanceof CompareUnaryOperator && |
||||||
|
operator.getOperandType(0) != Type.tBoolean) { |
||||||
|
if (subExpressions[0].getOperator() instanceof ConstOperator) { |
||||||
|
ConstOperator c = |
||||||
|
(ConstOperator) subExpressions[0].getOperator(); |
||||||
|
if (c.getValue().equals("0") || c.getValue().equals("1")) { |
||||||
|
Type[] newType = {Type.tBoolean}; |
||||||
|
operator.setOperandType(newType); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (operator instanceof CompareUnaryOperator && |
||||||
|
operator.getOperandType(0) == Type.tBoolean) { |
||||||
|
/* xx == false */ |
||||||
|
if (operator.getOperatorIndex() == operator.EQUALS_OP) |
||||||
|
return subExpressions[0].negate().simplify(); |
||||||
|
/* xx != false */ |
||||||
|
if (operator.getOperatorIndex() == operator.NOTEQUALS_OP) |
||||||
|
return subExpressions[0].simplify(); |
||||||
|
} |
||||||
|
|
||||||
|
if (operator instanceof InvokeOperator && |
||||||
|
((InvokeOperator)operator).getField(). |
||||||
|
getName() == Constants.idToString && |
||||||
|
!((InvokeOperator)operator).isStatic() && |
||||||
|
((InvokeOperator)operator).getField(). |
||||||
|
getClassDefinition().getType() == MyType.tStringBuffer && |
||||||
|
operator.getOperandCount() == 1) { |
||||||
|
Instruction simple = subExpressions[0].simplifyStringBuffer(); |
||||||
|
if (simple != null) |
||||||
|
return simple; |
||||||
|
} |
||||||
|
if (operator instanceof InvokeOperator && |
||||||
|
((InvokeOperator)operator).getField(). |
||||||
|
getName() == Constants.idValueOf && |
||||||
|
((InvokeOperator)operator).isStatic() && |
||||||
|
((InvokeOperator)operator).getField(). |
||||||
|
getClassDefinition().getType() == MyType.tString && |
||||||
|
operator.getOperandCount() == 1) { |
||||||
|
if (subExpressions[0].getType() == MyType.tString) |
||||||
|
return subExpressions[0].simplify(); |
||||||
|
else { |
||||||
|
Expression[] exprs = { |
||||||
|
emptyString, |
||||||
|
(Expression) subExpressions[0].simplify() |
||||||
|
}; |
||||||
|
return new ComplexExpression(new StringAddOperator(), exprs); |
||||||
|
} |
||||||
|
} |
||||||
|
for (int i=0; i< subExpressions.length; i++) |
||||||
|
subExpressions[i] = (Expression) subExpressions[i].simplify(); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue