some bugfixes

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@7 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 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. 63
      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. 4
      jode/jode/expr/ReturnOperator.java
  15. 2
      jode/jode/expr/SwapOperator.java
  16. 79
      jode/jode/type/ClassRangeType.java
  17. 70
      jode/jode/type/MyType.java

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

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

@ -196,11 +196,16 @@ public class LocalVariableAnalyzer {
throws java.io.IOException
{
Enumeration enum = locals.elements();
VAR:
while (enum.hasMoreElements()) {
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(),
li.getName())+";");
}
}
}
}

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

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

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

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

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

@ -160,9 +160,18 @@ public class InstructionHeader {
if (predecessors.size() != 1)
return null;
InstructionHeader pre = (InstructionHeader)predecessors.elementAt(0);
return (pre.getNextInstruction() == this &&
pre.getSuccessors().length != 1) ? null : pre;
return (pre.getNextInstruction() == this) ? pre : null;
}
/**
* 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
@ -199,6 +208,15 @@ public class InstructionHeader {
writer.println("<"+addr + " - "+(addr+length-1)+">");
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)
writer.print("addr_"+addr+": ");

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

@ -29,12 +29,12 @@ implements LocalVarOperator {
}
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();
}
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));
}

@ -29,12 +29,12 @@ implements LocalVarOperator {
}
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();
}
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
(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 DEC_OP = 25;
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_OR_OP = 33;
public final static int LOG_NOT_OP = 34;
@ -26,14 +28,11 @@ public abstract class Operator extends Instruction {
protected int operator;
String casts;
Operator (Type type, int op) {
super(type);
this.operator = op;
if (type == null)
throw new AssertError("type == null");
casts = type.toString();
}
public int getOperator() {
@ -48,12 +47,7 @@ public abstract class Operator extends Instruction {
* @return true if the operand types changed
*/
public boolean setType(Type type) {
// if (!MyType.isOfType(type, this.type)) {
// casts = type.toString()+"/*invalid*/ <- " + casts;
// } else if (type != this.type) {
// casts = type.toString()+" <- " + casts;
// }
// this.type = type;
this.type = type;
return false;
}

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

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

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

@ -94,7 +94,7 @@ public class MyType extends Type {
* @return the intersection, or tError, if a type conflict happens.
*/
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.
*/
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!
*/
if (t1.getTypeCode() != 103 || t2.getTypeCode() != 103)
throw new AssertError("Types incompatible: "+
t1.toString()+","+ t2.toString());
// return tError;
if (t1.getTypeCode() != 103 || t2.getTypeCode() != 103) {
System.err.println("intersecting "+ t1 +" and "+ t2 +
" to <error>");
return tError;
}
return ((ClassRangeType)t1).getIntersection((ClassRangeType)t2);
}
@ -140,60 +141,13 @@ public class MyType extends Type {
}
/**
* Check if t1 is in &lt;unknown -- t2&rt;.
* @return true if t1 is a more specific type than t2, e.g.
* if t2 is a superclass of t1
* @deprecated think about it, you don't need it! (I think)
* this code is probably broken so don't use it!
* Check if t1 and &lt;unknown -- t2&rt; are not disjunct.
* @param t1 the type that should be checked
* @param t2 a simple type; this mustn't be a range type.
* @return true if this is the case.
*/
public static boolean isOfType(Type t1, Type t2) {
if ((t1 == t2 || t2 == tUnknown) && t1 != tError)
return true;
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;
return (ClassRangeType.getGeneralizedType(t1,t2) == t2 &&
ClassRangeType.getSpecializedType(t1,t2) == t2);
}
}

Loading…
Cancel
Save