*** empty log message ***

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@43 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent f7064ccbaa
commit 5a804dd214
  1. 4
      jode/jode/bytecode/Opcodes.java
  2. 5
      jode/jode/decompiler/ClassAnalyzer.java
  3. 4
      jode/jode/expr/CompareBinaryOperator.java
  4. 19
      jode/jode/expr/ComplexExpression.java
  5. 17
      jode/jode/expr/Expression.java
  6. 23
      jode/jode/flow/CombineIfGotoExpressions.java
  7. 10
      jode/jode/flow/CreateExpression.java
  8. 20
      jode/jode/type/ClassRangeType.java

@ -360,9 +360,9 @@ public abstract class Opcodes implements RuntimeConstants {
} }
case opc_ireturn: case opc_lreturn: case opc_ireturn: case opc_lreturn:
case opc_freturn: case opc_dreturn: case opc_areturn: { case opc_freturn: case opc_dreturn: case opc_areturn: {
Type retType = MyType.intersection Type retType = MyType.tSubType(MyType.intersection
(ca.getMethod().mdef.getType().getReturnType(), (ca.getMethod().mdef.getType().getReturnType(),
types[0][opcode-opc_ireturn]); types[0][opcode-opc_ireturn]));
return createBlock return createBlock
(ca, addr, 1, new ReturnBlock(new NopOperator(retType))); (ca, addr, 1, new ReturnBlock(new NopOperator(retType)));
} }

@ -61,6 +61,11 @@ public class ClassAnalyzer implements Analyzer {
{ {
if (cdef.getSource() != null) if (cdef.getSource() != null)
writer.println("/* Original source: "+cdef.getSource()+" */"); writer.println("/* Original source: "+cdef.getSource()+" */");
writer.println("package " + cdef.getName().getQualifier() + ";");
/* XXX imports */
writer.println("");
String modif = Modifier.toString(cdef.getModifiers()); String modif = Modifier.toString(cdef.getModifiers());
if (modif.length() > 0) if (modif.length() > 0)
writer.print(modif + " "); writer.print(modif + " ");

@ -47,7 +47,9 @@ public class CompareBinaryOperator extends SimpleOperator {
public void setOperandType(Type[] inputTypes) { public void setOperandType(Type[] inputTypes) {
super.setOperandType(inputTypes); super.setOperandType(inputTypes);
Type operandType = Type operandType =
MyType.intersection(operandTypes[0],operandTypes[1]); MyType.tSubType(MyType.intersection
(MyType.tSuperType(operandTypes[0]),
MyType.tSuperType(operandTypes[1])));
operandTypes[0] = operandTypes[1] = operandType; operandTypes[0] = operandTypes[1] = operandType;
} }

@ -47,6 +47,16 @@ public class ComplexExpression extends Expression {
this.type = operator.getType(); this.type = operator.getType();
} }
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();
}
public Expression negate() { public Expression negate() {
if (operator.operator >= operator.COMPARE_OP && if (operator.operator >= operator.COMPARE_OP &&
operator.operator < operator.COMPARE_OP+6) { operator.operator < operator.COMPARE_OP+6) {
@ -182,9 +192,10 @@ public class ComplexExpression extends Expression {
} }
if (operator instanceof ConstructorOperator && if (operator instanceof ConstructorOperator &&
MyType.isOfType(operator.getType(), MyType.tStringBuffer)) { MyType.isOfType(operator.getType(), MyType.tStringBuffer)) {
if (operator.getOperandCount() == 1) /* subExpressions[0] is always a "new StringBuffer" */
if (subExpressions.length == 1)
return emptyString; return emptyString;
else if (operator.getOperandCount() == 2 && else if (subExpressions.length == 2 &&
MyType.isOfType(subExpressions[1].getType(), MyType.isOfType(subExpressions[1].getType(),
MyType.tString)) MyType.tString))
return (Expression) subExpressions[1].simplify(); return (Expression) subExpressions[1].simplify();
@ -281,7 +292,7 @@ public class ComplexExpression extends Expression {
!((InvokeOperator)operator).isStatic() && !((InvokeOperator)operator).isStatic() &&
((InvokeOperator)operator).getField(). ((InvokeOperator)operator).getField().
getClassDefinition().getType() == MyType.tStringBuffer && getClassDefinition().getType() == MyType.tStringBuffer &&
operator.getOperandCount() == 1) { subExpressions.length == 1) {
Instruction simple = subExpressions[0].simplifyStringBuffer(); Instruction simple = subExpressions[0].simplifyStringBuffer();
if (simple != null) if (simple != null)
return simple; return simple;
@ -292,7 +303,7 @@ public class ComplexExpression extends Expression {
((InvokeOperator)operator).isStatic() && ((InvokeOperator)operator).isStatic() &&
((InvokeOperator)operator).getField(). ((InvokeOperator)operator).getField().
getClassDefinition().getType() == MyType.tString && getClassDefinition().getType() == MyType.tString &&
operator.getOperandCount() == 1) { subExpressions.length == 1) {
if (subExpressions[0].getType() == MyType.tString) if (subExpressions[0].getType() == MyType.tString)
return subExpressions[0].simplify(); return subExpressions[0].simplify();
else { else {

@ -28,6 +28,12 @@ public abstract class Expression extends Instruction {
super (type); super (type);
} }
/**
* Get the number of operands.
* @return The number of stack entries this expression needs.
*/
public abstract int getOperandCount();
public Expression negate() { public Expression negate() {
Operator negop = Operator negop =
new UnaryOperator(Type.tBoolean, Operator.LOG_NOT_OP); new UnaryOperator(Type.tBoolean, Operator.LOG_NOT_OP);
@ -36,6 +42,17 @@ public abstract class Expression extends Instruction {
} }
public Expression tryToCombine(Expression 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(getOperator())
&& ce.subExpressions.length == 1) {
return new ComplexExpression
(new AssignOperator(store.getOperatorIndex(), store),
ce.subExpressions);
}
}
return null; return null;
} }

@ -39,6 +39,25 @@ public class CombineIfGotoExpressions implements Transformation{
// jode.Assert.assert(sequBlock.jump == null) // jode.Assert.assert(sequBlock.jump == null)
e = new Expression[2];
e[1] = (Expression)cb.getInstruction();
while (sequBlock.subBlocks[0] instanceof InstructionBlock) {
InstructionBlock ib =
(InstructionBlock) sequBlock.subBlocks[0];
Expression expr = (Expression) ib.getInstruction();
if (!expr.isVoid())
return false;
Expression combined = e[1].tryToCombine(expr);
if (combined == null)
return false;
cb.replace(sequBlock, cb);
cb.setInstruction(combined);
e[1] = combined;
sequBlock = (SequentialBlock) cb.outer;
}
ConditionalBlock cbprev = ConditionalBlock cbprev =
(ConditionalBlock) sequBlock.subBlocks[0]; (ConditionalBlock) sequBlock.subBlocks[0];
@ -48,15 +67,11 @@ public class CombineIfGotoExpressions implements Transformation{
prevJump = ((EmptyBlock) cbprev.trueBlock).jump; prevJump = ((EmptyBlock) cbprev.trueBlock).jump;
if (prevJump.destination == cb.jump.destination) { if (prevJump.destination == cb.jump.destination) {
e = new Expression[2];
operator = BinaryOperator.LOG_AND_OP; operator = BinaryOperator.LOG_AND_OP;
e[1] = (Expression)cb.getInstruction();
e[0] = ((Expression)cbprev.getInstruction()).negate(); e[0] = ((Expression)cbprev.getInstruction()).negate();
} else if (prevJump.destination } else if (prevJump.destination
== ((EmptyBlock) cb.trueBlock).jump.destination) { == ((EmptyBlock) cb.trueBlock).jump.destination) {
e = new Expression[2];
operator = BinaryOperator.LOG_OR_OP; operator = BinaryOperator.LOG_OR_OP;
e[1] = (Expression)cb.getInstruction();
e[0] = (Expression)cbprev.getInstruction(); e[0] = (Expression)cbprev.getInstruction();
} else } else
return false; return false;

@ -74,14 +74,20 @@ public class CreateExpression implements Transformation {
(InstructionBlock) sequBlock.getSubBlocks()[0]; (InstructionBlock) sequBlock.getSubBlocks()[0];
if (block.jump != null) if (block.jump != null)
return false; return false;
exprs[i] = exprs[i] = (Expression) block.getInstruction();
(Expression) block.getInstruction();
if (i > 0 && exprs[i].getOperandCount() > 0)
/* This is a not fully resolved expression in the
* middle, we must not touch it. */
return false;
if (exprs[i].isVoid()) { if (exprs[i].isVoid()) {
if (i == params-1) if (i == params-1)
return false; return false;
Expression e = exprs[i+1].tryToCombine(exprs[i]); Expression e = exprs[i+1].tryToCombine(exprs[i]);
if (e == null) if (e == null)
return false; return false;
i++; i++;
SequentialBlock subExprBlock = SequentialBlock subExprBlock =
(SequentialBlock) sequBlock.getSubBlocks()[1]; (SequentialBlock) sequBlock.getSubBlocks()[1];

@ -111,8 +111,9 @@ public class ClassRangeType extends MyType {
ClassDeclaration c2 = new ClassDeclaration(top.getClassName()); ClassDeclaration c2 = new ClassDeclaration(top.getClassName());
try { try {
if (c1.getClassDefinition(env).superClassOf(env, c2) || if (c2.getClassDefinition(env).isInterface()
c1.getClassDefinition(env).implementedBy(env, c2)) || c1.getClassDefinition(env).superClassOf(env, c2)
|| c1.getClassDefinition(env).implementedBy(env, c2))
return new ClassRangeType(bottom, top); return new ClassRangeType(bottom, top);
} catch (ClassNotFound ex) { } catch (ClassNotFound ex) {
} }
@ -183,20 +184,18 @@ public class ClassRangeType extends MyType {
* I currently only handle the simple case where one of the * I currently only handle the simple case where one of the
* two objects implements the other or is a child of it. * two objects implements the other or is a child of it.
* *
* Forget the following setences, java tells us if the local
* is an interface or an object.
*
* There are really complicated cases that are currently * There are really complicated cases that are currently
* ignored: imaging, c1 and c2 are both disjunct interfaces * ignored: imaging, c1 and c2 are both disjunct interfaces
* and there are some object which implements them both. * and there are some object which implements them both.
* There is no way for us to guess which. * There is no way for us to guess which.
* *
* Another possibility is that c1 is an interface and c2
* an Object that doesn't implement c1. This is not an error,
* because it may be a sub class of c1 and c2 that implements
* c1 and c2.
*
* What can we do about this? We probably need something more * What can we do about this? We probably need something more
* powerful than a simple class range. * powerful than a simple class range.
* But maybe this isn't needed at all. How should someone
* use an object which implements two interfaces in a local
* variable without casting? The information which object
* to use must be somewhere in the method.
* *
* But think of this code fragment: * But think of this code fragment:
* *
@ -337,9 +336,12 @@ public class ClassRangeType extends MyType {
Type newType = createRangeType(bottom,top); Type newType = createRangeType(bottom,top);
if (newType == tError) { if (newType == tError) {
boolean oldTypeDebugging = Decompiler.isTypeDebugging;
Decompiler.isTypeDebugging = true;
System.err.println("intersecting "+ this +" and "+ type + System.err.println("intersecting "+ this +" and "+ type +
" to <" + bottom + "-" + top + " to <" + bottom + "-" + top +
"> to <error>"); "> to <error>");
Decompiler.isTypeDebugging = oldTypeDebugging;
Thread.dumpStack(); Thread.dumpStack();
} else if (Decompiler.isTypeDebugging) { } else if (Decompiler.isTypeDebugging) {
System.err.println("intersecting "+ this +" and "+ type + System.err.println("intersecting "+ this +" and "+ type +

Loading…
Cancel
Save