some bugfixes

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@7 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 27 years ago
parent 1995b7a078
commit e579fa6d57
  1. 137
      jode/jode/decompiler/CodeAnalyzer.java
  2. 2
      jode/jode/decompiler/LocalInfo.java
  3. 7
      jode/jode/decompiler/LocalVariableAnalyzer.java
  4. 8
      jode/jode/expr/ArrayLoadOperator.java
  5. 2
      jode/jode/expr/ArrayStoreOperator.java
  6. 2
      jode/jode/expr/ConstOperator.java
  7. 4
      jode/jode/expr/ConstructorOperator.java
  8. 59
      jode/jode/expr/Expression.java
  9. 22
      jode/jode/expr/InstructionHeader.java
  10. 4
      jode/jode/expr/InvokeOperator.java
  11. 4
      jode/jode/expr/LocalLoadOperator.java
  12. 4
      jode/jode/expr/LocalStoreOperator.java
  13. 12
      jode/jode/expr/Operator.java
  14. 2
      jode/jode/expr/ReturnOperator.java
  15. 2
      jode/jode/expr/SwapOperator.java
  16. 75
      jode/jode/type/ClassRangeType.java
  17. 70
      jode/jode/type/MyType.java

@ -147,7 +147,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
Instruction pred; Instruction pred;
try { try {
NopOperator op = (NopOperator) ih.getInstruction(); NopOperator op = (NopOperator) ih.getInstruction();
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
pred = ih.getInstruction(); pred = ih.getInstruction();
if (pred == null) if (pred == null)
return null; return null;
@ -168,19 +168,19 @@ public class CodeAnalyzer implements Analyzer, Constants {
if (ih.getInstruction() instanceof DupOperator) if (ih.getInstruction() instanceof DupOperator)
/* this is not the end of the array assign */ /* this is not the end of the array assign */
return null; return null;
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
ArrayStoreOperator store = ArrayStoreOperator store =
(ArrayStoreOperator) ih.getInstruction(); (ArrayStoreOperator) ih.getInstruction();
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
Expression lastconst = (Expression) ih.getInstruction(); Expression lastconst = (Expression) ih.getInstruction();
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
Expression lastindexexpr = (Expression) ih.getInstruction(); Expression lastindexexpr = (Expression) ih.getInstruction();
ConstOperator lastindexop = ConstOperator lastindexop =
(ConstOperator) lastindexexpr.getOperator(); (ConstOperator) lastindexexpr.getOperator();
if (!MyType.isOfType(lastindexop.getType(), MyType.tUInt)) if (!MyType.isOfType(lastindexop.getType(), MyType.tInt))
return null; return null;
int lastindex = Integer.parseInt(lastindexop.getValue()); int lastindex = Integer.parseInt(lastindexop.getValue());
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
DupOperator dup = (DupOperator) ih.getInstruction(); DupOperator dup = (DupOperator) ih.getInstruction();
if (dup.getDepth() != 0 || if (dup.getDepth() != 0 ||
dup.getCount() != store.getLValueType().stackSize()) dup.getCount() != store.getLValueType().stackSize())
@ -189,12 +189,12 @@ public class CodeAnalyzer implements Analyzer, Constants {
consts[lastindex] = lastconst; consts[lastindex] = lastconst;
count = 1; count = 1;
while (lastindex-- > 0) { while (lastindex-- > 0) {
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
ArrayStoreOperator store2 = ArrayStoreOperator store2 =
(ArrayStoreOperator) ih.getInstruction(); (ArrayStoreOperator) ih.getInstruction();
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
lastconst = (Expression) ih.getInstruction(); lastconst = (Expression) ih.getInstruction();
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
Expression indexexpr = (Expression) ih.getInstruction(); Expression indexexpr = (Expression) ih.getInstruction();
ConstOperator indexop = ConstOperator indexop =
(ConstOperator) indexexpr.getOperator(); (ConstOperator) indexexpr.getOperator();
@ -210,14 +210,14 @@ public class CodeAnalyzer implements Analyzer, Constants {
lastindex--; lastindex--;
} }
consts[lastindex] = lastconst; consts[lastindex] = lastconst;
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
dup = (DupOperator) ih.getInstruction(); dup = (DupOperator) ih.getInstruction();
if (dup.getDepth() != 0 || if (dup.getDepth() != 0 ||
dup.getCount() != store.getLValueType().stackSize()) dup.getCount() != store.getLValueType().stackSize())
return null; return null;
count++; count++;
} }
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
Expression newArrayExpr = (Expression) ih.getInstruction(); Expression newArrayExpr = (Expression) ih.getInstruction();
NewArrayOperator newArrayOp = NewArrayOperator newArrayOp =
(NewArrayOperator) newArrayExpr.getOperator(); (NewArrayOperator) newArrayExpr.getOperator();
@ -245,15 +245,13 @@ public class CodeAnalyzer implements Analyzer, Constants {
public InstructionHeader createExpression(InstructionHeader ih) { public InstructionHeader createExpression(InstructionHeader ih) {
Operator op; Operator op;
Expression exprs[]; Expression exprs[];
int count; int params;
try { try {
op = (Operator) ih.getInstruction(); op = (Operator) ih.getInstruction();
int params = op.getOperandCount(); params = op.getOperandCount();
exprs = new Expression[params]; exprs = new Expression[params];
count = 1;
for (int i = params-1; i>=0; i--) { for (int i = params-1; i>=0; i--) {
count++; ih = ih.getSimpleUniquePredecessor();
ih = ih.getUniquePredecessor();
exprs[i] = (Expression) ih.getInstruction(); exprs[i] = (Expression) ih.getInstruction();
if (exprs[i].isVoid()) { if (exprs[i].isVoid()) {
if (i == params-1) if (i == params-1)
@ -263,6 +261,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
return null; return null;
i++; i++;
exprs[i] = e; exprs[i] = e;
ih.combine(2, e);
} }
} }
} catch (NullPointerException ex) { } catch (NullPointerException ex) {
@ -270,7 +269,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
} catch (ClassCastException ex) { } catch (ClassCastException ex) {
return null; return null;
} }
ih.combine(count, new Expression(op, exprs)); ih.combine(params+1, new Expression(op, exprs));
return ih; return ih;
} }
@ -303,7 +302,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
StoreInstruction store; StoreInstruction store;
try { try {
store = (StoreInstruction) ih.getInstruction(); store = (StoreInstruction) ih.getInstruction();
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
DupOperator dup = (DupOperator) ih.getInstruction(); DupOperator dup = (DupOperator) ih.getInstruction();
if (dup.getDepth() != store.getLValueOperandCount() && if (dup.getDepth() != store.getLValueOperandCount() &&
@ -337,7 +336,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
return null; return null;
if (iinc.getValue().equals("-1")) if (iinc.getValue().equals("-1"))
op ^= 1; op ^= 1;
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
Expression loadExpr = (Expression) ih.getInstruction(); Expression loadExpr = (Expression) ih.getInstruction();
LocalLoadOperator load = LocalLoadOperator load =
(LocalLoadOperator)loadExpr.getOperator(); (LocalLoadOperator)loadExpr.getOperator();
@ -363,7 +362,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
store = (StoreInstruction) ih.getInstruction(); store = (StoreInstruction) ih.getInstruction();
if (store.getLValueOperandCount() == 0) if (store.getLValueOperandCount() == 0)
return null; return null;
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
BinaryOperator binOp = (BinaryOperator) ih.getInstruction(); BinaryOperator binOp = (BinaryOperator) ih.getInstruction();
if (binOp.getOperator() == store.ADD_OP) if (binOp.getOperator() == store.ADD_OP)
op = Operator.INC_OP; op = Operator.INC_OP;
@ -371,7 +370,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
op = Operator.DEC_OP; op = Operator.DEC_OP;
else else
return null; return null;
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
Expression expr = (Expression) ih.getInstruction(); Expression expr = (Expression) ih.getInstruction();
ConstOperator constOp = (ConstOperator) expr.getOperator(); ConstOperator constOp = (ConstOperator) expr.getOperator();
if (!constOp.getValue().equals("1") && if (!constOp.getValue().equals("1") &&
@ -379,18 +378,18 @@ public class CodeAnalyzer implements Analyzer, Constants {
return null; return null;
if (constOp.getValue().equals("-1")) if (constOp.getValue().equals("-1"))
op ^= 1; op ^= 1;
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
DupOperator dup = (DupOperator) ih.getInstruction(); DupOperator dup = (DupOperator) ih.getInstruction();
if (dup.getCount() != store.getLValueType().stackSize() || if (dup.getCount() != store.getLValueType().stackSize() ||
dup.getDepth() != store.getLValueOperandCount()) dup.getDepth() != store.getLValueOperandCount())
return null; return null;
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
Operator load = (Operator) ih.getInstruction(); Operator load = (Operator) ih.getInstruction();
if (!store.matches(load)) if (!store.matches(load))
return null; return null;
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
DupOperator dup2 = (DupOperator) ih.getInstruction(); DupOperator dup2 = (DupOperator) ih.getInstruction();
if (dup2.getCount() != store.getLValueOperandCount() || if (dup2.getCount() != store.getLValueOperandCount() ||
dup2.getDepth() != 0) dup2.getDepth() != 0)
@ -413,20 +412,20 @@ public class CodeAnalyzer implements Analyzer, Constants {
BinaryOperator binop; BinaryOperator binop;
try { try {
store = (StoreInstruction) ih.getInstruction(); store = (StoreInstruction) ih.getInstruction();
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
binop = (BinaryOperator) ih.getInstruction(); binop = (BinaryOperator) ih.getInstruction();
if (binop.getOperator() < binop.ADD_OP || if (binop.getOperator() < binop.ADD_OP ||
binop.getOperator() >= binop.ASSIGN_OP) binop.getOperator() >= binop.ASSIGN_OP)
return null; return null;
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
rightHandSide = (Expression) ih.getInstruction(); rightHandSide = (Expression) ih.getInstruction();
if (rightHandSide.isVoid()) if (rightHandSide.isVoid())
return null; /* XXX */ return null; /* XXX */
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
Operator load = (Operator) ih.getInstruction(); Operator load = (Operator) ih.getInstruction();
if (!store.matches(load)) if (!store.matches(load))
return null; return null;
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
DupOperator dup = (DupOperator) ih.getInstruction(); DupOperator dup = (DupOperator) ih.getInstruction();
if (dup.getDepth() != 0 && if (dup.getDepth() != 0 &&
dup.getCount() != store.getLValueOperandCount()) dup.getCount() != store.getLValueOperandCount())
@ -455,16 +454,16 @@ public class CodeAnalyzer implements Analyzer, Constants {
int params = constrCall.getOperandCount(); int params = constrCall.getOperandCount();
exprs = new Expression[params]; exprs = new Expression[params];
for (int i = params-1; i>0; i--) { for (int i = params-1; i>0; i--) {
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
exprs[i] = (Expression) ih.getInstruction(); exprs[i] = (Expression) ih.getInstruction();
if (exprs[i].isVoid()) if (exprs[i].isVoid())
return null; /* XXX */ return null; /* XXX */
} }
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
DupOperator dup = (DupOperator) ih.getInstruction(); DupOperator dup = (DupOperator) ih.getInstruction();
if (dup.getCount() != 1 && dup.getDepth() != 0) if (dup.getCount() != 1 && dup.getDepth() != 0)
return null; return null;
ih = ih.getUniquePredecessor(); ih = ih.getSimpleUniquePredecessor();
exprs[0] = (Expression) ih.getInstruction(); exprs[0] = (Expression) ih.getInstruction();
if (exprs[0].isVoid()) if (exprs[0].isVoid())
return null; return null;
@ -493,7 +492,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
return null; return null;
InstructionHeader[] dests2 = ih2.getSuccessors(); InstructionHeader[] dests2 = ih2.getSuccessors();
/* if ih2.getUniquePredecessor.getOperator().isVoid() XXX */ /* if ih2.getSimpleUniquePredecessor.getOperator().isVoid() XXX */
Vector predec = ih2.getPredecessors(); Vector predec = ih2.getPredecessors();
if (predec.size() != 1) if (predec.size() != 1)
@ -510,12 +509,12 @@ public class CodeAnalyzer implements Analyzer, Constants {
e = new Expression[2]; e = new Expression[2];
operator = Operator.LOG_AND_OP; operator = Operator.LOG_AND_OP;
e[1] = (Expression)ih2.getInstruction(); e[1] = (Expression)ih2.getInstruction();
e[0] = ((Expression)ih2.getInstruction()).negate(); e[0] = ((Expression)ih1.getInstruction()).negate();
} else if (dests1[1] == dests2[1]) { } else if (dests1[1] == dests2[1]) {
e = new Expression[2]; e = new Expression[2];
operator = Operator.LOG_OR_OP; operator = Operator.LOG_OR_OP;
e[1] = (Expression)ih2.getInstruction(); e[1] = (Expression)ih2.getInstruction();
e[0] = (Expression)ih2.getInstruction(); e[0] = (Expression)ih1.getInstruction();
} else } else
return null; return null;
} catch (ClassCastException ex) { } catch (ClassCastException ex) {
@ -531,6 +530,64 @@ public class CodeAnalyzer implements Analyzer, Constants {
return ih1; return ih1;
} }
public InstructionHeader createFunnyIfThenElseOp(InstructionHeader ih) {
Expression cond = null;
try {
InstructionHeader ifHeader= ih;
if (ifHeader.switchType != MyType.tBoolean)
return null;
CompareUnaryOperator compare =
(CompareUnaryOperator) ifHeader.getInstruction();
if ((compare.getOperator() & ~1) != compare.EQUALS_OP)
return null;
Enumeration enum = ih.getPredecessors().elements();
while (enum.hasMoreElements()) {
try {
ih = (InstructionHeader) enum.nextElement();
Expression zeroExpr = (Expression) ih.getInstruction();
ConstOperator zero =
(ConstOperator) zeroExpr.getOperator();
if (!zero.getValue().equals("0"))
continue;
ih = ih.getUniquePredecessor();
if (ih.switchType != MyType.tBoolean)
continue;
if (compare.getOperator() == compare.EQUALS_OP &&
ih.getSuccessors()[1] != ifHeader.getSuccessors()[0]
|| compare.getOperator() == compare.NOTEQUALS_OP &&
ih.getSuccessors()[1] != ifHeader.getSuccessors()[1])
continue;
cond = (Expression) ih.getInstruction();
break;
} catch (ClassCastException ex) {
} catch (NullPointerException ex) {
}
}
if (cond == null)
return null;
} catch (ClassCastException ex) {
return null;
} catch (NullPointerException ex) {
return null;
}
InstructionHeader next = ih.nextInstruction;
ih.nextInstruction = next.nextInstruction;
ih.successors[1].predecessors.removeElement(ih);
ih.switchType = MyType.tVoid;
ih.successors = next.successors;
ih.successors[0].predecessors.removeElement(next);
ih.successors[0].predecessors.addElement(ih);
ih.succs = next.succs;
ih.length += next.length;
return ih;
}
public InstructionHeader createIfThenElseOperator(InstructionHeader ih) { public InstructionHeader createIfThenElseOperator(InstructionHeader ih) {
InstructionHeader ifHeader; InstructionHeader ifHeader;
Expression e[] = new Expression[3]; Expression e[] = new Expression[3];
@ -551,7 +608,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
succs[0].getSuccessors()[0] != succs[1].getSuccessors()[0]) succs[0].getSuccessors()[0] != succs[1].getSuccessors()[0])
return null; return null;
e[0] = (Expression) ifHeader.getInstruction(); e[0] = ((Expression) ifHeader.getInstruction()).negate();
e[1] = (Expression) succs[0].getInstruction(); e[1] = (Expression) succs[0].getInstruction();
e[2] = (Expression) succs[1].getInstruction(); e[2] = (Expression) succs[1].getInstruction();
} catch (ClassCastException ex) { } catch (ClassCastException ex) {
@ -563,11 +620,13 @@ public class CodeAnalyzer implements Analyzer, Constants {
(MyType.intersection(e[1].getType(),e[2].getType())); (MyType.intersection(e[1].getType(),e[2].getType()));
ifHeader.instr = new Expression(iteo, e); ifHeader.instr = new Expression(iteo, e);
ifHeader.nextInstruction = ih.nextInstruction; ifHeader.nextInstruction = ih.nextInstruction;
ifHeader.length = ih.addr + ih.length - ifHeader.addr;
ifHeader.succs = ih.succs;
ifHeader.successors = ih.successors; ifHeader.successors = ih.successors;
ifHeader.switchType = Type.tVoid; ifHeader.switchType = Type.tVoid;
ifHeader.nextInstruction.predecessors.removeElement(succs[0]); ifHeader.successors[0].predecessors.removeElement(succs[0]);
ifHeader.nextInstruction.predecessors.removeElement(succs[1]); ifHeader.successors[0].predecessors.removeElement(succs[1]);
ifHeader.nextInstruction.predecessors.addElement(ifHeader); ifHeader.successors[0].predecessors.addElement(ifHeader);
return ifHeader; return ifHeader;
} }
@ -578,6 +637,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
ih = next) { ih = next) {
if (env.isVerbose) if (env.isVerbose)
System.err.print("."); System.err.print(".");
// System.err.println(""+ih.getAddress());
if ((next = removeNop(ih)) != null) continue; if ((next = removeNop(ih)) != null) continue;
if ((next = createExpression(ih)) != null) continue; if ((next = createExpression(ih)) != null) continue;
if ((next = createPostIncExpression(ih)) != null) continue; if ((next = createPostIncExpression(ih)) != null) continue;
@ -585,6 +645,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
if ((next = createAssignOp(ih)) != null) continue; if ((next = createAssignOp(ih)) != null) continue;
if ((next = combineNewConstructor(ih)) != null) continue; if ((next = combineNewConstructor(ih)) != null) continue;
if ((next = combineIfGotoExpressions(ih)) != null) continue; if ((next = combineIfGotoExpressions(ih)) != null) continue;
if ((next = createFunnyIfThenElseOp(ih)) != null) continue;
if ((next = createIfThenElseOperator(ih)) != null) continue; if ((next = createIfThenElseOperator(ih)) != null) continue;
if ((next = createAssignExpression(ih)) != null) continue; if ((next = createAssignExpression(ih)) != null) continue;
if ((next = createConstantArray(ih)) != null) continue; if ((next = createConstantArray(ih)) != null) continue;

@ -92,7 +92,7 @@ public class LocalInfo {
*/ */
public Type setType(Type newType) { public Type setType(Type newType) {
if (shadow != null) if (shadow != null)
return shadow.setType(type); return shadow.setType(newType);
this.type = MyType.intersection(this.type, newType); this.type = MyType.intersection(this.type, newType);
if (this.type == MyType.tError) if (this.type == MyType.tError)
System.err.println("Type error in "+name.toString()); System.err.println("Type error in "+name.toString());

@ -196,11 +196,16 @@ public class LocalVariableAnalyzer {
throws java.io.IOException throws java.io.IOException
{ {
Enumeration enum = locals.elements(); Enumeration enum = locals.elements();
VAR:
while (enum.hasMoreElements()) { while (enum.hasMoreElements()) {
LocalInfo li = (LocalInfo) enum.nextElement(); LocalInfo li = (LocalInfo) enum.nextElement();
if (!li.isShadow()) if (!li.isShadow()) {
for (int i=0; i< argLocals.length; i++)
if (argLocals[i].getLocalInfo() == li)
continue VAR;
writer.println(env.getTypeString(li.getType(), writer.println(env.getTypeString(li.getType(),
li.getName())+";"); li.getName())+";");
} }
} }
} }
}

@ -34,10 +34,12 @@ public class ArrayLoadOperator extends SimpleOperator {
public void setOperandType(Type[] t) { public void setOperandType(Type[] t) {
super.setOperandType(t); super.setOperandType(t);
// if (operandTypes[0] instanceof ArrayType) try {
type = operandTypes[0].getElementType(); type = operandTypes[0].getElementType();
// else } catch (sun.tools.java.CompilerError err) {
// type = Type.tError; System.err.println("No Array type: "+operandTypes[0]);
type = Type.tError;
}
} }
public String toString(String[] operands) { public String toString(String[] operands) {

@ -36,7 +36,6 @@ public class ArrayStoreOperator extends StoreInstruction {
*/ */
public boolean setLValueType(Type type) { public boolean setLValueType(Type type) {
this.lvalueType = type; this.lvalueType = type;
System.err.println("Setting Lvalue type to "+lvalueType);
return true; return true;
} }
@ -54,6 +53,7 @@ public class ArrayStoreOperator extends StoreInstruction {
try { try {
lvalueType = arrayType.getElementType(); lvalueType = arrayType.getElementType();
} catch (sun.tools.java.CompilerError err) { } catch (sun.tools.java.CompilerError err) {
System.err.println("No Array type: "+arrayType);
lvalueType = Type.tError; lvalueType = Type.tError;
} }
} }

@ -46,7 +46,7 @@ public class ConstOperator extends NoArgOperator {
} }
public String toString(String[] operands) { public String toString(String[] operands) {
if (type == Type.tString) if (MyType.isOfType(type, Type.tString))
return quoted(value); return quoted(value);
if (type == Type.tBoolean) { if (type == Type.tBoolean) {
if (value.equals("0")) if (value.equals("0"))

@ -25,8 +25,8 @@ public class ConstructorOperator extends Operator {
public Type getOperandType(int i) { public Type getOperandType(int i) {
if (i == 0) if (i == 0)
return type; return MyType.tSubType(type);
return field.getType().getArgumentTypes()[i-1]; return MyType.tSubType(field.getType().getArgumentTypes()[i-1]);
} }
public void setOperandType(Type types[]) { public void setOperandType(Type types[]) {

@ -52,7 +52,7 @@ public class Expression extends Instruction {
if (e.operator instanceof StoreInstruction) { if (e.operator instanceof StoreInstruction) {
StoreInstruction store = (StoreInstruction) e.operator; StoreInstruction store = (StoreInstruction) e.operator;
Expression search = this; Expression search = this;
while (search.subExpressions.length > 0) { while (true) {
if (store.matches(search.operator)) { if (store.matches(search.operator)) {
int i; int i;
for (i=0; i < e.subExpressions.length-1; i++) { for (i=0; i < e.subExpressions.length-1; i++) {
@ -67,6 +67,14 @@ public class Expression extends Instruction {
return this; return this;
} }
} }
if (search.subExpressions.length == 0)
break;
if (search.getOperator() instanceof AssignOperator)
search = search.subExpressions[subExpressions.length-1];
else if (search.getOperator() instanceof StringAddOperator &&
search.subExpressions[1] == emptyString)
search = search.subExpressions[1];
else
search = search.subExpressions[0]; search = search.subExpressions[0];
} }
} }
@ -107,9 +115,8 @@ public class Expression extends Instruction {
if (operator.getPriority() < minPriority) { if (operator.getPriority() < minPriority) {
result = "("+result+")"; result = "("+result+")";
} }
if (operator.casts.indexOf("/*",0) >= 0 || if (operator.getType() == MyType.tError)
operator.casts.indexOf("<-",0) >= 0 && false) result = "(/*type error */" + result+")";
result = "<"+operator.casts+" "+result+">";
return result; return result;
} }
@ -134,12 +141,16 @@ public class Expression extends Instruction {
return toString(0); return toString(0);
} }
static Expression emptyString =
new Expression(new EmptyStringOperator(), new Expression[0]);
Expression simplifyStringBuffer() { Expression simplifyStringBuffer() {
FieldDefinition field; FieldDefinition field;
if (operator instanceof InvokeOperator && if (operator instanceof InvokeOperator &&
(field = ((InvokeOperator)operator).getField()) (field = ((InvokeOperator)operator).getField())
.getClassDefinition().getName() == .getClassDefinition().getName() ==
Constants.idJavaLangStringBuffer && Constants.idJavaLangStringBuffer &&
!((InvokeOperator)operator).isStatic() &&
field.getName() == Constants.idAppend && field.getName() == Constants.idAppend &&
field.getType().getArgumentTypes().length == 1) { field.getType().getArgumentTypes().length == 1) {
@ -148,20 +159,21 @@ public class Expression extends Instruction {
return null; return null;
if (e.operator instanceof EmptyStringOperator && if (e.operator instanceof EmptyStringOperator &&
subExpressions[1].getType() == Type.tString) MyType.isOfType(subExpressions[1].getType(), Type.tString))
return subExpressions[1]; return subExpressions[1];
Expression[] exprs = { e, subExpressions[1] }; Expression[] exprs = { e,
(Expression)subExpressions[1].simplify() };
return new Expression(new StringAddOperator(), exprs); return new Expression(new StringAddOperator(), exprs);
} }
if (operator instanceof ConstructorOperator && if (operator instanceof ConstructorOperator &&
operator.getType() == MyType.tStringBuffer) { MyType.isOfType(operator.getType(), MyType.tStringBuffer)) {
if (operator.getOperandCount() == 1) if (operator.getOperandCount() == 1)
return new Expression(new EmptyStringOperator(), return emptyString;
new Expression[0]);
else if (operator.getOperandCount() == 2 && else if (operator.getOperandCount() == 2 &&
subExpressions[1].getType() == MyType.tString) MyType.isOfType(subExpressions[1].getType(),
return subExpressions[1]; MyType.tString))
return (Expression) subExpressions[1].simplify();
} }
return null; return null;
} }
@ -210,14 +222,31 @@ public class Expression extends Instruction {
if (operator instanceof InvokeOperator && if (operator instanceof InvokeOperator &&
((InvokeOperator)operator).getField(). ((InvokeOperator)operator).getField().
getName() == Constants.idToString && getName() == Constants.idToString &&
!((InvokeOperator)operator).isStatic() &&
((InvokeOperator)operator).getField(). ((InvokeOperator)operator).getField().
getClassDefinition().getType() == MyType.tStringBuffer && getClassDefinition().getType() == MyType.tStringBuffer &&
operator.getOperandCount() == 1) { operator.getOperandCount() == 1) {
Expression e = subExpressions[0].simplifyStringBuffer(); Instruction simple = subExpressions[0].simplifyStringBuffer();
if (e != null) if (simple != null)
return e.simplify(); 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 Expression(new StringAddOperator(), exprs);
}
} }
for (int i=0; i< subExpressions.length; i++) for (int i=0; i< subExpressions.length; i++)
subExpressions[i] = (Expression) subExpressions[i].simplify(); subExpressions[i] = (Expression) subExpressions[i].simplify();

@ -160,10 +160,19 @@ public class InstructionHeader {
if (predecessors.size() != 1) if (predecessors.size() != 1)
return null; return null;
InstructionHeader pre = (InstructionHeader)predecessors.elementAt(0); InstructionHeader pre = (InstructionHeader)predecessors.elementAt(0);
return (pre.getNextInstruction() == this && return (pre.getNextInstruction() == this) ? pre : null;
pre.getSuccessors().length != 1) ? null : pre;
} }
/**
* Get the unique predecessor which mustn't be a (un)conditional jump
* @return the predecessor or null if there isn't a such a thing
*/
public InstructionHeader getSimpleUniquePredecessor() {
InstructionHeader pre = getUniquePredecessor();
return (pre.getSuccessors().length != 1) ? null : pre;
}
/** /**
* Get the predecessors of this instruction. This function mustn't * Get the predecessors of this instruction. This function mustn't
* be called before resolveSuccessors is executed for all * be called before resolveSuccessors is executed for all
@ -199,6 +208,15 @@ public class InstructionHeader {
writer.println("<"+addr + " - "+(addr+length-1)+">"); writer.println("<"+addr + " - "+(addr+length-1)+">");
writer.tab(); writer.tab();
} }
// writer.print("predecs: ");
// for (int i=0; i<predecessors.size(); i++) {
// if (i>0) writer.print(", ");
// writer.print(""+((InstructionHeader)predecessors.elementAt(i)).
// getAddress());
// }
// writer.println("");
if (!hasDirectPredecessor() && addr != 0) if (!hasDirectPredecessor() && addr != 0)
writer.print("addr_"+addr+": "); writer.print("addr_"+addr+": ");

@ -17,6 +17,10 @@ public class InvokeOperator extends Operator {
this.field = field; this.field = field;
} }
public boolean isStatic() {
return staticFlag;
}
public FieldDefinition getField() { public FieldDefinition getField() {
return field; return field;
} }

@ -29,12 +29,12 @@ implements LocalVarOperator {
} }
public Type getType() { public Type getType() {
System.err.println("LocalLoad.getType of "+local.getName()+": "+local.getType()); // System.err.println("LocalLoad.getType of "+local.getName()+": "+local.getType());
return local.getType(); return local.getType();
} }
public boolean setType(Type type) { public boolean setType(Type type) {
System.err.println("LocalLoad.setType of "+local.getName()+": "+local.getType()); // System.err.println("LocalLoad.setType of "+local.getName()+": "+local.getType());
return super.setType(local.setType(type)); return super.setType(local.setType(type));
} }

@ -29,12 +29,12 @@ implements LocalVarOperator {
} }
public Type getLValueType() { public Type getLValueType() {
System.err.println("LocalStore.getType of "+local.getName()+": "+local.getType()); // System.err.println("LocalStore.getType of "+local.getName()+": "+local.getType());
return local.getType(); return local.getType();
} }
public boolean setLValueType(Type type) { public boolean setLValueType(Type type) {
System.err.println("LocalStore.setType of "+local.getName()+": "+local.getType()); // System.err.println("LocalStore.setType of "+local.getName()+": "+local.getType());
return super.setLValueType return super.setLValueType
(local.setType(MyType.tSuperType(type))); (local.setType(MyType.tSuperType(type)));
} }

@ -11,6 +11,8 @@ public abstract class Operator extends Instruction {
public final static int INC_OP = 24; /* must be even! */ public final static int INC_OP = 24; /* must be even! */
public final static int DEC_OP = 25; public final static int DEC_OP = 25;
public final static int COMPARE_OP = 26; /* must be even! */ public final static int COMPARE_OP = 26; /* must be even! */
public final static int EQUALS_OP = 26;
public final static int NOTEQUALS_OP = 27;
public final static int LOG_AND_OP = 32; /* must be even! */ public final static int LOG_AND_OP = 32; /* must be even! */
public final static int LOG_OR_OP = 33; public final static int LOG_OR_OP = 33;
public final static int LOG_NOT_OP = 34; public final static int LOG_NOT_OP = 34;
@ -26,14 +28,11 @@ public abstract class Operator extends Instruction {
protected int operator; protected int operator;
String casts;
Operator (Type type, int op) { Operator (Type type, int op) {
super(type); super(type);
this.operator = op; this.operator = op;
if (type == null) if (type == null)
throw new AssertError("type == null"); throw new AssertError("type == null");
casts = type.toString();
} }
public int getOperator() { public int getOperator() {
@ -48,12 +47,7 @@ public abstract class Operator extends Instruction {
* @return true if the operand types changed * @return true if the operand types changed
*/ */
public boolean setType(Type type) { public boolean setType(Type type) {
// if (!MyType.isOfType(type, this.type)) { this.type = type;
// casts = type.toString()+"/*invalid*/ <- " + casts;
// } else if (type != this.type) {
// casts = type.toString()+" <- " + casts;
// }
// this.type = type;
return false; return false;
} }

@ -5,7 +5,7 @@ public class ReturnOperator extends SimpleOperator {
public ReturnOperator(Type type) { public ReturnOperator(Type type) {
super(Type.tVoid, 0, (type == Type.tVoid)?0:1); super(Type.tVoid, 0, (type == Type.tVoid)?0:1);
if (type != Type.tVoid) if (type != Type.tVoid)
operandTypes[0] = type; operandTypes[0] = MyType.tSubType(type);
} }
public int getPriority() { public int getPriority() {

@ -2,7 +2,7 @@ package jode;
public class SwapOperator extends Instruction { public class SwapOperator extends Instruction {
public SwapOperator() { public SwapOperator() {
super(MyType.tError); super(MyType.tVoid);
} }
public String toString() public String toString()

@ -36,6 +36,13 @@ public class ClassRangeType extends MyType {
// Fahrzeug, Fahrrad <Fahrzeug, Fahrrad> // Fahrzeug, Fahrrad <Fahrzeug, Fahrrad>
// int , Fahrrad error // int , Fahrrad error
if (bottom != null && bottom.getTypeCode() == 103) {
bottom = ((ClassRangeType)bottom).bottomType;
}
if (top != null && top.getTypeCode() == 103) {
top = ((ClassRangeType)top).topType;
}
/* First the trivial cases /* First the trivial cases
*/ */
if (top == tError || bottom == tError) if (top == tError || bottom == tError)
@ -49,13 +56,31 @@ public class ClassRangeType extends MyType {
/* <null, object> -> <tObject, object> /* <null, object> -> <tObject, object>
* if bottom is tObject, its okay. * if bottom is tObject, its okay.
*/ */
if (bottom == top)
return bottom;
if (top.getTypeCode() <= 4 && bottom == null)
return top;
if (bottom != null && bottom.getTypeCode() <= 4 &&
top.getTypeCode() <= bottom.getTypeCode())
return bottom;
if (top.getTypeCode() != 9 && top.getTypeCode() != 10)
return tError;
if (bottom == null || bottom == tObject) if (bottom == null || bottom == tObject)
return new ClassRangeType(tObject, top); return new ClassRangeType(tObject, top);
/* now bottom != null and top != null */ /* now bottom != null and top != null */
if (bottom.getTypeCode() == 9 && top.getTypeCode() == 9) if (bottom.getTypeCode() == 9 && top.getTypeCode() == 9) {
return tArray(createRangeType(bottom.getElementType(), Type type = createRangeType(bottom.getElementType(),
top.getElementType())); top.getElementType());
if (type == tError)
return tError;
return tArray(type);
}
if (bottom.getTypeCode() != 10 || top.getTypeCode() != 10) if (bottom.getTypeCode() != 10 || top.getTypeCode() != 10)
return tError; return tError;
@ -129,7 +154,7 @@ public class ClassRangeType extends MyType {
return tArray(getSpecializedType(t1.getElementType(), return tArray(getSpecializedType(t1.getElementType(),
t2.getElementType())); t2.getElementType()));
if (t1.getTypeCode() != 10 && t2.getTypeCode() != 10) if (t1.getTypeCode() != 10 || t2.getTypeCode() != 10)
return tError; return tError;
/* Now we have two classes or interfaces. The result should /* Now we have two classes or interfaces. The result should
@ -171,8 +196,8 @@ public class ClassRangeType extends MyType {
* Since the while condition is moved to the bottom of * Since the while condition is moved to the bottom of
* the loop, the type information of foo is only available * the loop, the type information of foo is only available
* <em>after</em> the two interface methods are called. * <em>after</em> the two interface methods are called.
* The current code would produce tError. */ * The current code would produce tError.
*/
ClassDeclaration c1 = new ClassDeclaration(t1.getClassName()); ClassDeclaration c1 = new ClassDeclaration(t1.getClassName());
ClassDeclaration c2 = new ClassDeclaration(t2.getClassName()); ClassDeclaration c2 = new ClassDeclaration(t2.getClassName());
@ -182,10 +207,10 @@ public class ClassRangeType extends MyType {
return t2; return t2;
if (c2.getClassDefinition(env).superClassOf(env, c1)) if (c2.getClassDefinition(env).superClassOf(env, c1))
return t1; return t1;
// if (c1.getClassDefinition(env).implementedBy(env, c2)) if (c1.getClassDefinition(env).implementedBy(env, c2))
// return t2; return t2;
// if (c2.getClassDefinition(env).implementedBy(env, c1)) if (c2.getClassDefinition(env).implementedBy(env, c1))
// return t1; return t1;
} catch (ClassNotFound ex) { } catch (ClassNotFound ex) {
} }
return tError; return tError;
@ -231,7 +256,7 @@ public class ClassRangeType extends MyType {
return tArray(getGeneralizedType(t1.getElementType(), return tArray(getGeneralizedType(t1.getElementType(),
t2.getElementType())); t2.getElementType()));
if (t1.getTypeCode() != 10 && t2.getTypeCode() != 10) if (t1.getTypeCode() != 10 || t2.getTypeCode() != 10)
return tError; return tError;
/* This code is not always correct: /* This code is not always correct:
@ -264,14 +289,14 @@ public class ClassRangeType extends MyType {
ClassDeclaration c2 = new ClassDeclaration(t2.getClassName()); ClassDeclaration c2 = new ClassDeclaration(t2.getClassName());
try { try {
// /* if one of the two types is an interface which /* if one of the two types is an interface which
// * is implemented by the other type the interface * is implemented by the other type the interface
// * is the result. * is the result.
// */ */
// if (c1.getClassDefinition(env).implementedBy(env, c2)) if (c1.getClassDefinition(env).implementedBy(env, c2))
// return t1; return t1;
// if (c2.getClassDefinition(env).implementedBy(env, c1)) if (c2.getClassDefinition(env).implementedBy(env, c1))
// return t2; return t2;
ClassDefinition c = c1.getClassDefinition(env); ClassDefinition c = c1.getClassDefinition(env);
while(c != null && !c.superClassOf(env, c2)) { while(c != null && !c.superClassOf(env, c2)) {
@ -289,14 +314,12 @@ public class ClassRangeType extends MyType {
Type bottom = getSpecializedType(bottomType, type.bottomType); Type bottom = getSpecializedType(bottomType, type.bottomType);
Type top = getGeneralizedType(topType, type.topType); Type top = getGeneralizedType(topType, type.topType);
Type newType = createRangeType(bottom,top);
if (newType == tError)
System.err.println("intersecting "+ this +" and "+ type + System.err.println("intersecting "+ this +" and "+ type +
" to <" + bottom + "-" + top + ">"); " to <" + bottom + "-" + top +
try { "> to <error>");
throw new AssertError("in:"); return newType;
} catch(AssertError error) {
error.printStackTrace();
}
return createRangeType(bottom,top);
} }
public boolean intersects(ClassRangeType type) public boolean intersects(ClassRangeType type)

@ -94,7 +94,7 @@ public class MyType extends Type {
* @return the intersection, or tError, if a type conflict happens. * @return the intersection, or tError, if a type conflict happens.
*/ */
public static Type intersection(Type t1, Type t2) { public static Type intersection(Type t1, Type t2) {
System.err.println("intersecting "+ t1 +" and "+ t2); // System.err.println("intersecting "+ t1 +" and "+ t2);
/* Trivial cases first. /* Trivial cases first.
*/ */
if (t1 == t2 || t2 == tUnknown) if (t1 == t2 || t2 == tUnknown)
@ -123,10 +123,11 @@ public class MyType extends Type {
/* Now it must be a class range type, or we have lost! /* Now it must be a class range type, or we have lost!
*/ */
if (t1.getTypeCode() != 103 || t2.getTypeCode() != 103) if (t1.getTypeCode() != 103 || t2.getTypeCode() != 103) {
throw new AssertError("Types incompatible: "+ System.err.println("intersecting "+ t1 +" and "+ t2 +
t1.toString()+","+ t2.toString()); " to <error>");
// return tError; return tError;
}
return ((ClassRangeType)t1).getIntersection((ClassRangeType)t2); return ((ClassRangeType)t1).getIntersection((ClassRangeType)t2);
} }
@ -140,60 +141,13 @@ public class MyType extends Type {
} }
/** /**
* Check if t1 is in &lt;unknown -- t2&rt;. * Check if t1 and &lt;unknown -- t2&rt; are not disjunct.
* @return true if t1 is a more specific type than t2, e.g. * @param t1 the type that should be checked
* if t2 is a superclass of t1 * @param t2 a simple type; this mustn't be a range type.
* @deprecated think about it, you don't need it! (I think) * @return true if this is the case.
* this code is probably broken so don't use it!
*/ */
public static boolean isOfType(Type t1, Type t2) { public static boolean isOfType(Type t1, Type t2) {
if ((t1 == t2 || t2 == tUnknown) && t1 != tError) return (ClassRangeType.getGeneralizedType(t1,t2) == t2 &&
return true; ClassRangeType.getSpecializedType(t1,t2) == t2);
switch (t1.getTypeCode()) {
case 0: /* boolean*/
case 1: /* byte */
case 2: /* char */
case 3: /* short */
case 4: /* int */
/* JavaC thinks, that this is okay. */
if (t2.getTypeCode() >= 0 && t2.getTypeCode() <=4)
return true;
// /* fallthrough */
// case 104: /* unknown index */
// if (t2 == tUInt)
// return true;
break;
case 5: /* long */
case 6: /* float */
case 7: /* double */
case 8: /* null? */
case 11: /* void */
case 12: /* method */
case 13: /* error */
// case 101: /* unknown int */
/* This are only to themself compatible */
break;
case 9: /* array */
case 10: /* class */
t1 = new ClassRangeType(t1, null);
/* fall through */
case 103: /* class range type */
if (t2.getTypeCode() == 103)
return ((ClassRangeType)t1).intersects((ClassRangeType)t2);
if (t2.getTypeCode() == 9 || t2.getTypeCode() == 10)
return ((ClassRangeType)t1).
intersects(new ClassRangeType(t2, null));
break;
default:
throw new AssertError("Wrong typeCode "+t1.getTypeCode());
}
return false;
} }
} }

Loading…
Cancel
Save