Mirror of the JODE repository
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
jode/jode/CreateIfStatements.java

110 lines
4.1 KiB

/*
* CreateIfStatements (c) 1998 Jochen Hoenicke
*
* You may distribute under the terms of the GNU General Public License.
*
* IN NO EVENT SHALL JOCHEN HOENICKE BE LIABLE TO ANY PARTY FOR DIRECT,
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
* THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOCHEN HOENICKE
* HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* JOCHEN HOENICKE SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND JOCHEN HOENICKE HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* $Id$
*/
package jode;
public class CreateIfStatements extends FlowTransformation
implements Transformation {
public InstructionHeader transform(InstructionHeader ifgoto) {
if (ifgoto.getFlowType() != ifgoto.IFGOTO ||
ifgoto.nextInstruction == null ||
ifgoto.getSuccessors()[1].getAddress() <=
ifgoto.getSuccessors()[0].getAddress())
return null;
/* elseBlock points to the first instruction of the
* elseBlock or is null if the else block is empty.
* next points to the next instruction after this block
* or is null, if this if is the last instruction in
* this block.
*/
InstructionHeader elseBlock = null, next = null;
if (ifgoto.outer != ifgoto.successors[1].outer) {
if (ifgoto.outer.getEndBlock() != ifgoto.successors[1].getShadow())
/* This doesn't seem to be an if but a if-break
*/
return null;
/* This is an if without else that goes to the end
* of the current block. May be this was a continue,
* but who would know it?
*
* If you like breaks and continues more than ifs,
* simply do the break transformation before the
* if transformation.
*/
next = null;
} else {
/* This is a normal if, let us first assume, that there is
* no else part. Then end is successors[1], but that may
* be a while loop, so unoptimized it...
*/
next = UnoptimizeWhileLoops(ifgoto.successors[1]);
if (next != ifgoto.successors[1]) {
ifgoto.successors[1].predecessors.removeElement(ifgoto);
ifgoto.successors[1] = next;
ifgoto.successors[1].predecessors.addElement(ifgoto);
}
/* next.prevInstruction is the end of the `then' block.
* If this a goto statement that jumps downward, this is
* probably an `if-then-else'.
*/
InstructionHeader thenEnd = next.prevInstruction;
if (thenEnd.flowType == thenEnd.GOTO) {
if (thenEnd.successors[0].outer == next.outer &&
thenEnd.successors[0].addr >= next.addr) {
/* this is a normal if-then-else that is
* fully contained in this block.
*/
elseBlock = next;
next = UnoptimizeWhileLoops(thenEnd.successors[0]);
} else if (thenEnd.successors[0].getShadow() ==
ifgoto.outer.getEndBlock()) {
/* this is a normal if-then-else that goes
* to the end of the block.
*
* Again this may also be a continue/break statement,
* but again, who knows.
*/
elseBlock = next;
next = null;
}
}
}
/* This was all, the rest is done in the constructor of
* IfInstructionHeader.
*/
if(Decompiler.isVerbose)
System.err.print("i");
return new IfInstructionHeader
(ifgoto, elseBlock, next);
}
}