diff --git a/jode/jode/flow/CaseBlock.java b/jode/jode/flow/CaseBlock.java new file mode 100644 index 0000000..9777539 --- /dev/null +++ b/jode/jode/flow/CaseBlock.java @@ -0,0 +1,108 @@ +/* CaseBlock Copyright (C) 1997-1998 Jochen Hoenicke. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + */ +package jode.flow; + +/** + * This block represents a case instruction. A case instruction is a + * part of a switch construction and may have a subpart or not (for + * multiple case directly after each other. + * + * @author Jochen Hoenicke */ +public class CaseBlock extends StructuredBlock { + /** + * The inner block that jumps to the subroutine, or null + * if this is a value only. + */ + StructuredBlock subBlock; + + /** + * The value of this case. + */ + int value; + + /** + * True, if this is the default case + */ + boolean isDefault = false; + + /** + * True, if this is the last case in a switch + */ + boolean isLastBlock; + + /** + * The type of the switch value. + */ + sun.tools.java.Type type; + + public CaseBlock(int value) { + this.value = value; + subBlock = null; + } + + public CaseBlock(int value, Jump dest) { + this.value = value; + subBlock = new EmptyBlock(dest); + subBlock.outer = this; + } + + /** + * Replaces the given sub block with a new block. + * @param oldBlock the old sub block. + * @param newBlock the new sub block. + * @return false, if oldBlock wasn't a direct sub block. + */ + public boolean replaceSubBlock(StructuredBlock oldBlock, + StructuredBlock newBlock) { + if (subBlock == oldBlock) + subBlock = newBlock; + else + return false; + return true; + } + + /** + * Returns all sub block of this structured block. + */ + public StructuredBlock[] getSubBlocks() { + if (subBlock != null) { + StructuredBlock[] result = { subBlock }; + return result; + } + return new StructuredBlock[0]; + } + + public void dumpInstruction(jode.TabbedPrintWriter writer) + throws java.io.IOException + { + if (isDefault) { + if (isLastBlock + && subBlock instanceof EmptyBlock + && subBlock.jump == null) + return; + writer.println("default:"); + } else + writer.println("case " + value /*XXX-type*/ + ":"); + if (subBlock != null) { + writer.tab(); + subBlock.dumpSource(writer); + writer.untab(); + } + } +} diff --git a/jode/jode/flow/CreateConstantArray.java b/jode/jode/flow/CreateConstantArray.java new file mode 100644 index 0000000..c8a01d2 --- /dev/null +++ b/jode/jode/flow/CreateConstantArray.java @@ -0,0 +1,134 @@ +/* CreateConstantArray Copyright (C) 1997-1998 Jochen Hoenicke. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + */ + +package jode.flow; +import jode.Expression; +import jode.DupOperator; +import jode.ArrayStoreOperator; +import jode.NewArrayOperator; +import jode.ConstantArrayOperator; +import jode.ConstOperator; +import jode.MyType; +import sun.tools.java.Type; + +public class CreateConstantArray implements Transformation { + + public boolean transform(FlowBlock flow) { + InstructionBlock lastBlock; + SequentialBlock sequBlock; + Expression[] consts = null; + int count = 0; + Type type; + try { + InstructionBlock ib = (InstructionBlock) flow.lastModified; + if (ib.getInstruction() instanceof DupOperator) + /* this is not the end of the array assign */ + return false; + + sequBlock = (SequentialBlock) ib.outer; + ib = (InstructionBlock) sequBlock.subBlocks[0]; + lastBlock = ib; + + int lastindex = -1; + while (ib.getInstruction() instanceof ArrayStoreOperator) { + ArrayStoreOperator store = + (ArrayStoreOperator) ib.getInstruction(); + + sequBlock = (SequentialBlock) sequBlock.outer; + ib = (InstructionBlock) sequBlock.subBlocks[0]; + Expression lastconst = (Expression) ib.getInstruction(); + + sequBlock = (SequentialBlock) sequBlock.outer; + ib = (InstructionBlock) sequBlock.subBlocks[0]; + Expression indexexpr = (Expression) ib.getInstruction(); + ConstOperator indexop = + (ConstOperator) indexexpr.getOperator(); + if (!MyType.isOfType(indexop.getType(), MyType.tUInt)) + return false; + int index = Integer.parseInt(indexop.getValue()); + if (index >= 0 && consts == null) { + lastindex = index; + consts = new Expression[lastindex+1]; + } else if (index < 0 || index > lastindex) + return false; + else { + while (index < lastindex) { + consts[lastindex--] = new Expression + (new ConstOperator(MyType.tUnknown, "0"), + new Expression[0]); + } + } + consts[lastindex--] = lastconst; + sequBlock = (SequentialBlock) sequBlock.outer; + ib = (InstructionBlock) sequBlock.subBlocks[0]; + DupOperator dup = (DupOperator) ib.getInstruction(); + if (dup.getDepth() != 0 || + dup.getCount() != store.getLValueType().stackSize()) + return false; + count++; + sequBlock = (SequentialBlock) sequBlock.outer; + ib = (InstructionBlock) sequBlock.subBlocks[0]; + } + if (count == 0) + return false; + while (lastindex >= 0) { + consts[lastindex--] = new Expression + (new ConstOperator(MyType.tUnknown, "0"), + new Expression[0]); + } + Expression newArrayExpr = (Expression) ib.getInstruction(); + NewArrayOperator newArrayOp = + (NewArrayOperator) newArrayExpr.getOperator(); + type = newArrayOp.getType(); + if (newArrayOp.getOperandCount() != 1) + return false; + Expression countexpr = + (Expression) newArrayExpr.getSubExpressions()[0]; + ConstOperator countop = + (ConstOperator) countexpr.getOperator(); + if (!MyType.isOfType(countop.getType(), MyType.tUInt)) + return false; + int arraylength = Integer.parseInt(countop.getValue()); + if (arraylength != consts.length) { + if (arraylength < consts.length) + return false; + Expression[] newConsts = new Expression[arraylength]; + System.arraycopy(consts, 0, newConsts, 0, consts.length); + for (int i=consts.length; i