* src/net/sf/jode/jvm/SyntheticAnalyzer.java (checkGetClass):

Handle jdk1.4 class$ methods.

Fixed some javadocs.

Added changes (except obfuscator changes) from jode-1.1 tree up to
2001-07-08


git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1378 379699f6-c40d-0410-875b-85095c16579e
master
hoenicke 21 years ago
parent 2872b22195
commit 338feb1f61
  1. 36
      jode/src/net/sf/jode/bytecode/BasicBlockReader.java
  2. 27
      jode/src/net/sf/jode/bytecode/ClassInfo.java
  3. 1
      jode/src/net/sf/jode/expr/CompareToIntOperator.java
  4. 10
      jode/src/net/sf/jode/expr/StoreInstruction.java
  5. 25
      jode/src/net/sf/jode/flow/CatchBlock.java
  6. 6
      jode/src/net/sf/jode/flow/CompleteSynchronized.java
  7. 2
      jode/src/net/sf/jode/flow/CreateAssignExpression.java
  8. 1
      jode/src/net/sf/jode/flow/CreateExpression.java
  9. 2
      jode/src/net/sf/jode/flow/CreateIfThenElseOperator.java
  10. 3
      jode/src/net/sf/jode/flow/TransformConstructors.java
  11. 9
      jode/src/net/sf/jode/jvm/CodeVerifier.java
  12. 4
      jode/src/net/sf/jode/jvm/RuntimeEnvironment.java
  13. 16
      jode/src/net/sf/jode/jvm/SyntheticAnalyzer.java

@ -856,6 +856,13 @@ class BasicBlockReader implements Opcodes {
handlers[i].type = (index == 0) ? null
: cp.getClassName(index);
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_BYTECODE) != 0)
GlobalOptions.err.println("Handler "+handlers[i].start
+"-"+handlers[i].end
+" @"+handlers[i].catcher
+ ": "+handlers[i].type);
if (infos[handlers[i].catcher].instr.getOpcode() == opc_athrow) {
/* There is an obfuscator, which inserts bogus
* exception entries jumping directly to a throw
@ -864,6 +871,35 @@ class BasicBlockReader implements Opcodes {
handlersLength--;
i--;
}
if (handlers[i].start <= handlers[i].catcher
&& handlers[i].end > handlers[i].catcher)
{
/* Javac 1.4 is a bit paranoid with finally and
* synchronize blocks and even breaks the JLS.
* We fix it here. Hopefully this won't produce
* any other problems.
*/
if (handlers[i].start == handlers[i].catcher) {
handlersLength--;
i--;
} else {
handlers[i].end = handlers[i].catcher;
}
}
if (infos[handlers[i].end].instr.getOpcode() >= opc_ireturn
&& infos[handlers[i].end].instr.getOpcode() <= opc_return) {
/* JDK 1.4 sometimes doesn't put return instruction into try
* block, which breaks the decompiler later. The return
* instruction can't throw exceptions so it doesn't really
* matter.
*
* FIXME: This may break other things if the return
* instruction is reachable from outside the try block.
*/
handlers[i].end++;
}
}
if (handlersLength < handlers.length) {
HandlerEntry[] newHandlers = new HandlerEntry[handlersLength];

@ -240,6 +240,7 @@ public final class ClassInfo extends BinaryInfo implements Comparable {
private ClassPath classpath;
private int modifiers = -1;
private boolean deprecatedFlag;
private String name;
private String className;
private boolean methodScoped;
@ -560,6 +561,11 @@ public final class ClassInfo extends BinaryInfo implements Comparable {
} else if (howMuch >= ClassInfo.OUTERCLASS
&& name.equals("InnerClasses")) {
readInnerClassesAttribute(length, cp, input);
} else if (name.equals("Deprecated")) {
deprecatedFlag = true;
if (length != 0)
throw new ClassFormatException
("Deprecated attribute has wrong length");
} else
super.readAttribute(name, length, cp, input, howMuch);
}
@ -848,7 +854,9 @@ public final class ClassInfo extends BinaryInfo implements Comparable {
gcp.putUTF8(ci.className);
}
}
prepareAttributes(gcp);
if (deprecatedFlag)
gcp.putUTF8("Deprecated");
prepareAttributes(gcp);
}
/**
@ -911,6 +919,10 @@ public final class ClassInfo extends BinaryInfo implements Comparable {
output.writeShort(ci.modifiers);
}
}
if (deprecatedFlag) {
output.writeShort(gcp.putUTF8("Deprecated"));
output.writeInt(0);
}
}
@ -1191,6 +1203,15 @@ public final class ClassInfo extends BinaryInfo implements Comparable {
return Modifier.isInterface(getModifiers());
}
/**
* Checks whether this class was declared as deprecated. In bytecode
* this is represented by a special attribute.
* @return true if this class info represents a deprecated class.
*/
public boolean isDeprecated() {
return deprecatedFlag;
}
/**
* Searches for a field with given name and type signature.
* @param name the name of the field.
@ -1324,6 +1345,10 @@ public final class ClassInfo extends BinaryInfo implements Comparable {
modified = true;
}
public void setDeprecated(boolean flag) {
deprecatedFlag = flag;
}
public void setMethods(MethodInfo[] mi) {
methods = mi;
status = ALL;

@ -54,6 +54,7 @@ public class CompareToIntOperator extends Operator {
throws java.io.IOException
{
subExpressions[0].dumpExpression(writer, 550);
writer.breakOp();
writer.print(" <=>");
if (allowsNaN)
writer.print(greaterOnNaN ? "g" : "l");

@ -25,7 +25,7 @@ import net.sf.jode.decompiler.TabbedPrintWriter;
public class StoreInstruction extends Operator
implements CombineableOperator {
boolean isOpAssign = false;
boolean opAssign = false;
public StoreInstruction(LValueExpression lvalue) {
super(Type.tVoid, ASSIGN_OP);
@ -41,7 +41,11 @@ public class StoreInstruction extends Operator
setOperatorIndex(operatorIndex);
if (subExpressions[1] instanceof NopOperator)
subExpressions[1].type = Type.tUnknown;
isOpAssign = true;
opAssign = true;
}
public boolean isOpAssign() {
return opAssign;
}
/**
@ -72,7 +76,7 @@ public class StoreInstruction extends Operator
Type newType;
if (!isOpAssign) {
if (!opAssign) {
/* An opassign (+=, -=, etc.) doesn't merge rvalue type. */
Type lvalueType = subExpressions[0].getType();
Type rvalueType = subExpressions[1].getType();

@ -24,6 +24,7 @@ import net.sf.jode.decompiler.Declarable;
import net.sf.jode.expr.Expression;
import net.sf.jode.expr.LocalLoadOperator;
import net.sf.jode.expr.LocalStoreOperator;
import net.sf.jode.expr.NopOperator;
import net.sf.jode.expr.StoreInstruction;
import net.sf.jode.util.SimpleSet;
@ -220,17 +221,19 @@ public class CatchBlock extends StructuredBlock {
} else if (firstInstr instanceof InstructionBlock) {
Expression instr =
((InstructionBlock) firstInstr).getInstruction();
if (instr instanceof StoreInstruction
&& (((StoreInstruction)instr).getLValue()
instanceof LocalStoreOperator)) {
/* The exception is stored in a local variable */
exceptionLocal = ((LocalStoreOperator)
((StoreInstruction)instr).getLValue())
.getLocalInfo();
exceptionLocal.setType(exceptionType);
firstInstr.removeBlock();
return true;
}
if (instr instanceof StoreInstruction) {
StoreInstruction store = (StoreInstruction) instr;
if (store.getOperatorIndex() == store.OPASSIGN_OP
&& store.getSubExpressions()[1] instanceof NopOperator
&& store.getLValue() instanceof LocalStoreOperator) {
/* The exception is stored in a local variable */
exceptionLocal = ((LocalStoreOperator) store.getLValue())
.getLocalInfo();
exceptionLocal.setType(exceptionType);
firstInstr.removeBlock();
return true;
}
}
}
return false;
}

@ -24,8 +24,7 @@ import net.sf.jode.expr.*;
public class CompleteSynchronized {
/**
* This combines the monitorenter into a synchronized statement
* @param flow The FlowBlock that is transformed
* This combines the monitorenter into a synchronized statement.
*/
public static boolean enter(SynchronizedBlock synBlock,
StructuredBlock last) {
@ -63,8 +62,7 @@ public class CompleteSynchronized {
/**
* This combines the initial expression describing the object
* into a synchronized statement
* @param flow The FlowBlock that is transformed
* into a synchronized statement.
*/
public static boolean combineObject(SynchronizedBlock synBlock,
StructuredBlock last) {

@ -56,7 +56,7 @@ public class CreateAssignExpression {
SequentialBlock opBlock = (SequentialBlock) last.outer;
StoreInstruction store = (StoreInstruction) ic.getInstruction();
if (!store.isFreeOperator())
if (!store.isFreeOperator() || store.isOpAssign())
return false;
Expression lvalue = store.getSubExpressions()[0];
int lvalueCount = lvalue.getFreeOperandCount();

@ -35,7 +35,6 @@ public class CreateExpression {
/**
* This does the transformation.
* @param FlowBlock the flow block to transform.
* @return true if flow block was simplified.
*/
public static boolean transform(InstructionContainer ic,

@ -141,7 +141,6 @@ public class CreateIfThenElseOperator {
*
* Also note that the produced code is suboptimal: The push-0 could
* sometimes be better replaced with a correct jump.
* @param flow The FlowBlock that is transformed
*/
public static boolean createFunny(ConditionalBlock cb,
StructuredBlock last) {
@ -188,7 +187,6 @@ public class CreateIfThenElseOperator {
* -&gt;push cond ? e1 : e2
* </pre>
* The <code>-&gt;</code> points to the lastModified block.
* @param flow The FlowBlock that is transformed
*/
public static boolean create(InstructionContainer ic,
StructuredBlock last) {

@ -106,7 +106,8 @@ public class TransformConstructors {
this.clazzAnalyzer = clazzAnalyzer;
this.isStatic = isStatic;
this.cons = cons;
this.outerValues = clazzAnalyzer.getOuterValues();
if (!isStatic)
this.outerValues = clazzAnalyzer.getOuterValues();
lookForConstructorCall();
}

@ -1120,8 +1120,13 @@ public class CodeVerifier implements Opcodes {
if (!info.pop().isOfType(tType(type)))
throw new VerifyException(instr.getDescription());
Type classType = tType(ref.getClazz());
if (!info.pop().isOfType(classType))
throw new VerifyException(instr.getDescription());
Type classOnStack = info.pop();
if (!classOnStack.isOfType(classType)) {
/* Sometimes synthetic code writes to uninitialized classes. */
classType = tType("N" + ref.getClazz().substring(1));
if (!classOnStack.isOfType(classType))
throw new VerifyException(instr.getDescription());
}
break;
}
case opc_invokevirtual:

@ -109,13 +109,13 @@ public interface RuntimeEnvironment {
/**
* Enter a monitor.
* @param object the object whose monitor should be taken.
* @param obj the object whose monitor should be taken.
*/
public void enterMonitor(Object obj)
throws InterpreterException;
/**
* Exit a monitor.
* @param object the object whose monitor should be freed.
* @param obj the object whose monitor should be freed.
*/
public void exitMonitor(Object obj)
throws InterpreterException;

@ -111,7 +111,8 @@ public class SyntheticAnalyzer implements Opcodes {
Block startBlock = bb.getStartBlock();
Handler[] excHandlers = bb.getExceptionHandlers();
if (startBlock == null
|| startBlock.getInstructions().length != 3
|| startBlock.getInstructions().length < 2
|| startBlock.getInstructions().length > 3
|| excHandlers.length != 1
|| excHandlers[0].getStart() != startBlock
|| excHandlers[0].getEnd() != startBlock
@ -119,7 +120,7 @@ public class SyntheticAnalyzer implements Opcodes {
.equals(excHandlers[0].getType()))
return false;
for (int i=0; i< 3; i++) {
for (int i=0; i< 2; i++) {
Instruction instr = startBlock.getInstructions()[i];
if (instr.getOpcode() != getClassOpcodes[i])
return false;
@ -132,6 +133,17 @@ public class SyntheticAnalyzer implements Opcodes {
if (i == 0 && instr.getLocalSlot() != 0)
return false;
}
if (startBlock.getInstructions().length == 2) {
/* JDK 1.4: The return is outside of startBlock */
Block nextBlock = startBlock.getSuccs()[0];
Instruction[] instrs = nextBlock.getInstructions();
if (instrs[0].getOpcode() != opc_areturn)
return false;
} else {
/* JDK 1.3 */
if (startBlock.getInstructions()[2].getOpcode() != opc_areturn)
return false;
}
Block catchBlock = excHandlers[0].getCatcher();
if (catchBlock.getInstructions().length != 7)

Loading…
Cancel
Save