*** empty log message ***

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@102 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent af9ce24395
commit 90567a56b1
  1. 1
      jode/jode/decompiler/LocalVariableTable.java
  2. 41
      jode/jode/expr/ComplexExpression.java
  3. 22
      jode/jode/expr/ConstOperator.java
  4. 15
      jode/jode/expr/ConstructorOperator.java
  5. 27
      jode/jode/expr/Expression.java
  6. 16
      jode/jode/expr/GetFieldOperator.java
  7. 45
      jode/jode/expr/InvokeOperator.java
  8. 21
      jode/jode/expr/PutFieldOperator.java
  9. 9
      jode/jode/flow/CatchBlock.java
  10. 4
      jode/jode/flow/CombineIfGotoExpressions.java
  11. 7
      jode/jode/flow/CreateIfThenElseOperator.java
  12. 14
      jode/jode/flow/TryBlock.java

@ -19,7 +19,6 @@
package jode;
import java.util.Enumeration;
import gnu.bytecode.CpoolUtf8;
import gnu.bytecode.LocalVarsAttr;
import gnu.bytecode.Variable;
import gnu.bytecode.Spy;

@ -88,11 +88,12 @@ public class ComplexExpression extends Expression {
}
return 1;
}
for (int i=0; i < subExpressions.length; i++) {
int can = subExpressions[i].canCombine(e);
if (can != 0)
return can;
}
return subExpressions[0].canCombine(e);
// for (int i=0; i < subExpressions.length; i++) {
// int can = subExpressions[i].canCombine(e);
// if (can != 0)
// return can;
// }
}
return 0;
}
@ -120,7 +121,7 @@ public class ComplexExpression extends Expression {
return this;
}
}
throw new AssertError("combine didn't succeed");
return null;
}
public Operator getOperator() {
@ -235,37 +236,33 @@ public class ComplexExpression extends Expression {
return true;
}
static Expression emptyString =
new EmptyStringOperator();
public Expression simplifyStringBuffer() {
gnu.bytecode.CpoolRef field;
if (operator instanceof InvokeOperator
&& (((InvokeOperator)operator).getClassType()
.equals(Type.tStringBuffer))
&& !((InvokeOperator)operator).isStatic()
&& (((InvokeOperator)operator).getMethodName().equals("append"))
&& (((InvokeOperator)operator).getMethodType()
.getArgumentTypes().length == 1)) {
.getParameterTypes().length == 1)) {
Expression e = subExpressions[0].simplifyStringBuffer();
if (e == null)
return null;
if (e.getOperator() instanceof EmptyStringOperator &&
subExpressions[1].getType().isOfType(Type.tString))
if (e == EMPTYSTRING
&& subExpressions[1].getType().isOfType(Type.tString))
return subExpressions[1];
return new ComplexExpression
(new StringAddOperator(), new Expression[]
{ e, subExpressions[1] });
}
if (operator instanceof ConstructorOperator &&
operator.getType().isOfType(Type.tStringBuffer)) {
if (subExpressions.length == 0)
return emptyString;
else if (subExpressions.length == 1 &&
subExpressions[0].getType().isOfType(Type.tString))
if (operator instanceof ConstructorOperator
&& (((ConstructorOperator) operator).getClassType()
== Type.tStringBuffer)) {
if (subExpressions.length == 1 &&
subExpressions[0].getType().isOfType(Type.tString))
return subExpressions[0];
}
return null;
@ -276,7 +273,7 @@ public class ComplexExpression extends Expression {
InvokeOperator invoke = (InvokeOperator) operator;
if (invoke.getMethodName().equals("toString")
&& !invoke.isStatic()
&& (invoke.getClassType().equals(Type.tStringBuffer))
&& invoke.getClassType().equals(Type.tStringBuffer)
&& subExpressions.length == 1) {
Expression simple = subExpressions[0].simplifyStringBuffer();
if (simple != null)
@ -292,7 +289,7 @@ public class ComplexExpression extends Expression {
return new ComplexExpression
(new StringAddOperator(), new Expression[]
{ emptyString, subExpressions[0] });
{ EMPTYSTRING, subExpressions[0] });
}
/* The pizza way (pizza is the compiler of kaffe) */
else if (invoke.getMethodName().equals("concat")
@ -304,7 +301,7 @@ public class ComplexExpression extends Expression {
if (right instanceof ComplexExpression
&& right.getOperator() instanceof StringAddOperator
&& (((ComplexExpression) right).subExpressions[0]
== emptyString))
== EMPTYSTRING))
right = ((ComplexExpression)right).subExpressions[1];
return new ComplexExpression

@ -46,13 +46,17 @@ public class ConstOperator extends NoArgOperator {
return "false";
else if (value.equals("1"))
return "true";
} if (type == Type.tChar) {
char i = (char) Integer.parseInt(value);
switch (i) {
} if (type.getBottom() == Type.tChar) {
char c = (char) Integer.parseInt(value);
switch (c) {
case '\0':
return "\'\\0\'";
case '\t':
return "\'\\t\'";
case '\n':
return "\'\\n\'";
case '\r':
return "\'\\r\'";
case '\\':
return "\'\\\\\'";
case '\"':
@ -60,8 +64,16 @@ public class ConstOperator extends NoArgOperator {
case '\'':
return "\'\\\'\'";
}
if (i >= 32 && i <128)
return "\'"+i+"\'";
if (c < 32) {
String oct = Integer.toOctalString(c);
return "\'\\000".substring(0, 5-oct.length())+oct+"\'";
}
if (c >= 32 && c < 127)
return "\'"+c+"\'";
else {
String hex = Integer.toHexString(c);
return "\'\\u0000".substring(0, 7-hex.length())+hex+"\'";
}
} else if (parent != null) {
int opindex = parent.getOperator().getOperatorIndex();
if (opindex >= OPASSIGN_OP + ADD_OP

@ -35,24 +35,33 @@ public class ConstructorOperator extends Operator {
}
public int getOperandCount() {
return methodType.getArgumentTypes().length;
return methodType.getParameterTypes().length;
}
public int getOperandPriority(int i) {
return 0;
}
public Type getClassType() {
return classType;
}
public Type getOperandType(int i) {
return methodType.getArgumentTypes()[i];
return methodType.getParameterTypes()[i];
}
public void setOperandType(Type types[]) {
}
public Expression simplifyStringBuffer() {
return (getClassType() == Type.tStringBuffer)
? EMPTYSTRING : null;
}
public String toString(String[] operands) {
StringBuffer result =
new StringBuffer("new ").append(classType.toString()).append("(");
for (int i=0; i < methodType.getArgumentTypes().length; i++) {
for (int i=0; i < methodType.getParameterTypes().length; i++) {
if (i>0)
result.append(", ");
result.append(operands[i]);

@ -65,6 +65,8 @@ public abstract class Expression {
* conflict was found. You may wish to check for >0.
*/
public int canCombine(Expression e) {
if (!e.isVoid())
return 0;
if (e instanceof IIncOperator
&& ((IIncOperator)e.getOperator()).matches(getOperator()))
return 1;
@ -84,19 +86,30 @@ public abstract class Expression {
* @return The combined expression.
*/
public Expression combine(Expression e) {
if (e.getOperator() instanceof IIncOperator)
((IIncOperator)e.getOperator()).makeNonVoid();
else
((StoreInstruction)e.getOperator()).makeNonVoid();
/* Do not call setType, we don't want to intersect. */
e.type = e.getOperator().getType();
return e;
if (e.getOperator() instanceof IIncOperator) {
if (((IIncOperator)e.getOperator()).matches(getOperator())) {
((IIncOperator)e.getOperator()).makeNonVoid();
/* Do not call setType, we don't want to intersect. */
e.type = e.getOperator().getType();
return e;
}
} else {
if (((StoreInstruction)e.getOperator()).matches(getOperator())) {
((StoreInstruction)e.getOperator()).makeNonVoid();
/* Do not call setType, we don't want to intersect. */
e.type = e.getOperator().getType();
return e;
}
}
return null;
}
public Expression simplify() {
return this;
}
static Expression EMPTYSTRING = new ConstOperator(Type.tString, "\"\"");
public Expression simplifyStringBuffer() {
return null;
}

@ -22,17 +22,17 @@ import gnu.bytecode.CpoolRef;
public class GetFieldOperator extends Operator {
boolean staticFlag;
CpoolRef field;
CodeAnalyzer codeAnalyzer;
String fieldName;
Type classType;
public GetFieldOperator(CodeAnalyzer codeAnalyzer, boolean staticFlag,
CpoolRef field) {
super(Type.tType(field.getNameAndType().getType().getString()), 0);
Type classType, Type type, String fieldName) {
super(type, 0);
this.codeAnalyzer = codeAnalyzer;
this.staticFlag = staticFlag;
this.field = field;
classType = Type.tClass(field.getCpoolClass().getName().getString());
this.classType = classType;
this.fieldName = fieldName;
if (staticFlag)
classType.useType();
}
@ -57,7 +57,6 @@ public class GetFieldOperator extends Operator {
}
public String toString(String[] operands) {
String fieldName = field.getNameAndType().getName().getString();
return staticFlag
? (classType.equals(Type.tType(codeAnalyzer.getClazz()))
? fieldName
@ -68,7 +67,8 @@ public class GetFieldOperator extends Operator {
}
public boolean equals(Object o) {
return (o instanceof GetFieldOperator) &&
((GetFieldOperator)o).field == field;
return o instanceof GetFieldOperator
&& ((GetFieldOperator)o).classType.equals(classType)
&& ((GetFieldOperator)o).fieldName.equals(fieldName);
}
}

@ -22,36 +22,27 @@ import gnu.bytecode.CpoolRef;
public final class InvokeOperator extends Operator {
CodeAnalyzer codeAnalyzer;
boolean staticFlag;
boolean specialFlag;
MethodType methodType;
String methodName;
Type classType;
CpoolRef field;
public InvokeOperator(CodeAnalyzer codeAnalyzer,
boolean staticFlag, boolean specialFlag,
CpoolRef field) {
boolean specialFlag, Type classType,
MethodType methodType, String methodName) {
super(Type.tUnknown, 0);
methodType = new MethodType(field.getNameAndType().
getType().getString());
methodName = field.getNameAndType().getName().getString();
classType = Type.tClass(field.getCpoolClass().getName().getString());
this.methodType = methodType;
this.methodName = methodName;
this.classType = classType;
this.type = methodType.getReturnType();
this.codeAnalyzer = codeAnalyzer;
this.staticFlag = staticFlag;
this.specialFlag = specialFlag;
this.field = field;
if (staticFlag)
if (methodType.isStatic())
classType.useType();
}
public boolean isStatic() {
return staticFlag;
}
public CpoolRef getField() {
return field;
return methodType.isStatic();
}
public MethodType getMethodType() {
@ -71,22 +62,23 @@ public final class InvokeOperator extends Operator {
}
public int getOperandCount() {
return (staticFlag?0:1) + methodType.getArgumentTypes().length;
return (methodType.isStatic()?0:1)
+ methodType.getParameterTypes().length;
}
public int getOperandPriority(int i) {
if (!staticFlag && i == 0)
if (!methodType.isStatic() && i == 0)
return 950;
return 0;
}
public Type getOperandType(int i) {
if (!staticFlag) {
if (!methodType.isStatic()) {
if (i == 0)
return getClassType();
i--;
}
return methodType.getArgumentTypes()[i];
return methodType.getParameterTypes()[i];
}
public void setOperandType(Type types[]) {
@ -98,7 +90,7 @@ public final class InvokeOperator extends Operator {
public String toString(String[] operands) {
String object =
staticFlag
methodType.isStatic()
? (classType.equals(Type.tType(codeAnalyzer.getClazz()))
? ""
: classType.toString())
@ -110,7 +102,7 @@ public final class InvokeOperator extends Operator {
: "")
: operands[0]);
int arg = staticFlag ? 0 : 1;
int arg = methodType.isStatic() ? 0 : 1;
String method;
if (isConstructor())
method = (object.length() == 0 ? "this" : object);
@ -118,7 +110,7 @@ public final class InvokeOperator extends Operator {
method = (object.length() == 0 ? "" : object + ".") + methodName;
StringBuffer params = new StringBuffer();
for (int i=0; i < methodType.getArgumentTypes().length; i++) {
for (int i=0; i < methodType.getParameterTypes().length; i++) {
if (i>0)
params.append(", ");
params.append(operands[arg++]);
@ -127,9 +119,10 @@ public final class InvokeOperator extends Operator {
}
public boolean equals(Object o) {
return (o instanceof InvokeOperator) &&
((InvokeOperator)o).field == field &&
((InvokeOperator)o).staticFlag == staticFlag &&
return o instanceof InvokeOperator &&
((InvokeOperator)o).classType.equals(classType) &&
((InvokeOperator)o).methodName.equals(methodName) &&
((InvokeOperator)o).methodType.equals(methodType) &&
((InvokeOperator)o).specialFlag == specialFlag;
}
}

@ -23,23 +23,24 @@ import gnu.bytecode.CpoolRef;
public class PutFieldOperator extends StoreInstruction {
CodeAnalyzer codeAnalyzer;
boolean staticFlag;
CpoolRef field;
String fieldName;
Type classType;
public PutFieldOperator(CodeAnalyzer codeAnalyzer, boolean staticFlag,
CpoolRef field) {
super(Type.tType(field.getNameAndType().getType().getString()), ASSIGN_OP);
Type classType, Type type, String fieldName) {
super(type, ASSIGN_OP);
this.codeAnalyzer = codeAnalyzer;
this.staticFlag = staticFlag;
this.field = field;
classType = Type.tClass(field.getCpoolClass().getName().getString());
this.fieldName = fieldName;
this.classType = classType;
if (staticFlag)
classType.useType();
}
public boolean matches(Operator loadop) {
return loadop instanceof GetFieldOperator &&
((GetFieldOperator)loadop).field == field;
return loadop instanceof GetFieldOperator
&& ((GetFieldOperator)loadop).classType.equals(classType)
&& ((GetFieldOperator)loadop).fieldName.equals(fieldName);
}
public int getLValueOperandCount() {
@ -58,7 +59,6 @@ public class PutFieldOperator extends StoreInstruction {
}
public String getLValueString(String[] operands) {
String fieldName = field.getNameAndType().getName().getString();
return staticFlag
? (classType.equals(Type.tType(codeAnalyzer.getClazz()))
? fieldName
@ -69,7 +69,8 @@ public class PutFieldOperator extends StoreInstruction {
}
public boolean equals(Object o) {
return (o instanceof PutFieldOperator) &&
((PutFieldOperator)o).field == field;
return o instanceof PutFieldOperator
&& ((PutFieldOperator)o).classType.equals(classType)
&& ((PutFieldOperator)o).fieldName.equals(fieldName);
}
}

@ -110,4 +110,13 @@ public class CatchBlock extends StructuredBlock {
catchBlock.dumpSource(writer);
writer.untab();
}
/**
* Determines if there is a sub block, that flows through to the end
* of this block. If this returns true, you know that jump is null.
* @return true, if the jump may be safely changed.
*/
public boolean jumpMayBeChanged() {
return (catchBlock.jump != null || catchBlock.jumpMayBeChanged());
}
}

@ -67,9 +67,13 @@ public class CombineIfGotoExpressions implements Transformation{
if (prevJump.destination == cb.jump.destination) {
operator = BinaryOperator.LOG_AND_OP;
e[0] = cbprev.getInstruction().negate();
cb.jump.gen.unionExact(prevJump.gen);
cb.jump.kill.intersect(prevJump.kill);
} else if (prevJump.destination == cb.trueBlock.jump.destination) {
operator = BinaryOperator.LOG_OR_OP;
e[0] = cbprev.getInstruction();
cb.trueBlock.jump.gen.unionExact(prevJump.gen);
cb.trueBlock.jump.kill.intersect(prevJump.kill);
} else
return false;

@ -18,6 +18,7 @@
*/
package jode.flow;
import jode.Type;
import jode.Expression;
import jode.ComplexExpression;
import jode.IfThenElseOperator;
@ -149,7 +150,8 @@ public class CreateIfThenElseOperator implements Transformation {
System.err.print('?');
IfThenElseOperator iteo = new IfThenElseOperator
(e[1].getType().intersection(e[2].getType()));
(Type.tSuperType(e[1].getType())
.intersection(Type.tSuperType(e[2].getType())));
((InstructionBlock)ifBlock.thenBlock).
setInstruction(new ComplexExpression(iteo, e));
@ -214,7 +216,8 @@ public class CreateIfThenElseOperator implements Transformation {
thenBlock.removeJump();
IfThenElseOperator iteo = new IfThenElseOperator
(e[1].getType().intersection(e[2].getType()));
(Type.tSuperType(e[1].getType())
.intersection(Type.tSuperType(e[2].getType())));
((InstructionBlock)flow.lastModified).
setInstruction(new ComplexExpression(iteo, e));

@ -100,4 +100,18 @@ public class TryBlock extends StructuredBlock {
subBlocks[i].dumpSource(writer);
writer.println("}");
}
/**
* Determines if there is a sub block, that flows through to the end
* of this block. If this returns true, you know that jump is null.
* @return true, if the jump may be safely changed.
*/
public boolean jumpMayBeChanged() {
for (int i=0; i<subBlocks.length;i++) {
if (subBlocks[i].jump == null
&& !subBlocks[i].jumpMayBeChanged())
return false;
}
return true;
}
}

Loading…
Cancel
Save