git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@12 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent 3360965bb1
commit 5c4d86e1cb
  1. 2
      jode/CreateConstantArray.java
  2. 29
      jode/CreateDoWhileStatements.java
  3. 1
      jode/jode/decompiler/CodeAnalyzer.java
  4. 3
      jode/jode/expr/CaseInstructionHeader.java
  5. 158
      jode/jode/expr/DoWhileInstructionHeader.java

@ -25,7 +25,7 @@ public class CreateConstantArray implements Transformation {
if (!MyType.isOfType(indexop.getType(), MyType.tUInt))
return null;
int index = Integer.parseInt(indexop.getValue());
if (index > 0 && consts == null) {
if (index >= 0 && consts == null) {
lastindex = index;
consts = new Expression[lastindex+1];
} else if (index < 0 || index > lastindex)

@ -0,0 +1,29 @@
package jode;
import java.util.Enumeration;
public class CreateDoWhileStatements extends FlowTransformation
implements Transformation {
public InstructionHeader transform(InstructionHeader head) {
if (head.predecessors.size() == 0 ||
head.flowType == head.DOWHILESTATEMENT)
return null;
InstructionHeader end = head;
Enumeration enum = head.predecessors.elements();
while (enum.hasMoreElements()) {
InstructionHeader pre = (InstructionHeader) enum.nextElement();
if (pre.outer == head.outer && pre.addr > end.addr)
end = pre;
}
if (end != head)
if (end.flowType == end.IFGOTO || end.flowType == end.GOTO) {
if(Decompiler.isVerbose)
System.err.print("d");
return new DoWhileInstructionHeader(head, end);
}
return null;
}
}

@ -72,6 +72,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
static Transformation[] simplifyTrafos = { new SimplifyExpression() };
static Transformation[] blockTrafos = {
new CreateDoWhileStatements(),
new CreateTryCatchStatements(),
new CreateIfStatements(),
new CreateBreakStatement(),

@ -35,6 +35,9 @@ public class CaseInstructionHeader extends InstructionHeader {
ih = ih.nextInstruction)
ih.dumpSource(writer);
writer.untab();
if (Decompiler.isDebugging)
writer.untab();
}
/**

@ -0,0 +1,158 @@
package jode;
/**
* This instruction header represents an if instruction. The
* linkage of the instructions is as follow:
* <pre>
* A: ....
* <p>
* prev = A, next = H or null, pred = normal, succ = {H,C}
* B: while ( instr ) {
* <p>
* prev = null, next = D, pred = {B}, succ = {D}
* C: first block-instr
* <p>
* prev = C, next = E, pred = normal succ = normal
* D: ...
* <p>
* prev = D, next = null, pred = normal succ = {B}
* E: last block-instr
* }
* <p>
* prev = B, ..., pred = (normal+{G}) \ {C..F}, succ = normal
* H: ...
* </pre>
*/
public class DoWhileInstructionHeader extends InstructionHeader {
InstructionHeader endHeader;
/**
* Creates a new while statement.
* @param head the first instruction of this do-while loop
* @param end the last instruction which contains the
* if-goto (or goto) statement.
*/
public DoWhileInstructionHeader(InstructionHeader head,
InstructionHeader end) {
super(DOWHILESTATEMENT,
head.addr, end.nextAddr,
new InstructionHeader[1], end.outer);
this.endHeader = end;
if (end.flowType == GOTO) {
/* This is a for(;;) loop
*/
this.instr = null;
end.successors[0].predecessors.removeElement(end);
} else {
this.instr = end.instr;
end.successors[0].predecessors.removeElement(end);
end.successors[1].predecessors.removeElement(end);
}
this.addPredecessors(head);
this.successors[0] = head;
head.predecessors.addElement(this);
this.prevInstruction = head.prevInstruction;
if (prevInstruction != null)
prevInstruction.nextInstruction = this;
this.nextInstruction = end.nextInstruction;
if (nextInstruction != null)
nextInstruction.prevInstruction = this;
if (successors[0] != this) {
successors[0].prevInstruction = null;
for (InstructionHeader ih = successors[0]; ih != null;
ih = ih.nextInstruction) {
if (ih.outer == outer)
ih.outer = this;
if (ih.nextInstruction == end)
ih.nextInstruction = null;
}
}
}
/**
* This should be implemented for those blocks, that is headers
* which are outer of other headers. This gives the instruction
* where the control flows after this block.
* @return the first instruction after this block.
*/
InstructionHeader getEndBlock() {
return getContinue();
}
public void dumpSource(TabbedPrintWriter writer)
throws java.io.IOException
{
if (Decompiler.isDebugging) {
dumpDebugging(writer);
writer.tab();
}
if (needsLabel()) {
writer.untab();
writer.println(getLabel()+": ");
writer.tab();
}
boolean braces = (successors[0].flowType != NORMAL ||
successors[0].nextInstruction != null);
writer.println((instr == null ? "for(;;)" : "do")+
(braces ? " {": ""));
writer.tab();
if (successors[0] != this) {
for (InstructionHeader ih = successors[0]; ih != null;
ih = ih.nextInstruction)
ih.dumpSource(writer);
} else
writer.println("/* empty */");
writer.untab();
if (instr != null)
writer.println((braces ? "} " : "") + "while ("+instr+");");
else if (braces)
writer.println("}");
if (Decompiler.isDebugging)
writer.untab();
}
/**
* Returns the InstructionHeader where a break of this instruction
* would jump to. Does only make sense for do/while/for-loops and
* switch instructions.
*/
public InstructionHeader getBreak() {
return super.getEndBlock();
}
public InstructionHeader getShadow() {
return successors[0];
}
/**
* Returns the InstructionHeader where a continue of this instruction
* would jump to. Does only make sense for do/while/for-loops.
*/
public InstructionHeader getContinue() {
return (instr == null)? this : endHeader;
}
public InstructionHeader doTransformations(Transformation[] trafo) {
InstructionHeader next;
if (successors[0] != this)
for (InstructionHeader ih = successors[0]; ih != null; ih = next) {
if ((next = ih.doTransformations(trafo)) == null)
next = ih.getNextInstruction();
}
return super.doTransformations(trafo);
}
}
Loading…
Cancel
Save