From 671bd91c6f4ac744456eb386ba4201a5deab5d63 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 22 Oct 1998 11:00:38 +0000 Subject: [PATCH] for implementiert, imports git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@57 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/expr/AssignOperator.java | 9 + jode/jode/expr/Expression.java | 2 +- jode/jode/expr/IIncOperator.java | 11 ++ jode/jode/expr/LocalPrePostFixOperator.java | 43 +++++ jode/jode/expr/PrePostFixOperator.java | 67 +++++++ jode/jode/flow/CreateForInitializer.java | 58 +++++++ .../jode/flow/CreatePrePostIncExpression.java | 164 ++++++++++++++++++ jode/jode/type/ArrayType.java | 7 + jode/jode/type/RangeType.java | 8 + 9 files changed, 368 insertions(+), 1 deletion(-) create mode 100644 jode/jode/expr/LocalPrePostFixOperator.java create mode 100644 jode/jode/expr/PrePostFixOperator.java create mode 100644 jode/jode/flow/CreateForInitializer.java create mode 100644 jode/jode/flow/CreatePrePostIncExpression.java diff --git a/jode/jode/expr/AssignOperator.java b/jode/jode/expr/AssignOperator.java index e223beb..acfec78 100644 --- a/jode/jode/expr/AssignOperator.java +++ b/jode/jode/expr/AssignOperator.java @@ -19,6 +19,15 @@ package jode; +/** + * This class represents an assign expression, i.e. an assignment, + * whose return value is used further. + * + * It contains the underlying store instruction, which you can get + * with getStore + * + * @author Jochen Hoenicke + */ public class AssignOperator extends Operator { StoreInstruction store; diff --git a/jode/jode/expr/Expression.java b/jode/jode/expr/Expression.java index 1c577be..67ec520 100644 --- a/jode/jode/expr/Expression.java +++ b/jode/jode/expr/Expression.java @@ -56,7 +56,7 @@ public abstract class Expression extends Instruction { } Expression simplifyStringBuffer() { - return this; + return null; } public abstract Operator getOperator(); diff --git a/jode/jode/expr/IIncOperator.java b/jode/jode/expr/IIncOperator.java index 88ac98d..ac0ae3b 100644 --- a/jode/jode/expr/IIncOperator.java +++ b/jode/jode/expr/IIncOperator.java @@ -62,6 +62,17 @@ implements LocalVarOperator { == local.getLocalInfo(); } + public Instruction simplify() { + if (value.equals("1")) { + int op = (getOperatorIndex() == OPASSIGN_OP+ADD_OP) + ? INC_OP : DEC_OP; + + return new LocalPrePostFixOperator + (local.getType(), op, this, true).simplify(); + } + return super.simplify(); + } + public String toString(String[] operands) { return local.getName().toString() + getOperatorString() + value; diff --git a/jode/jode/expr/LocalPrePostFixOperator.java b/jode/jode/expr/LocalPrePostFixOperator.java new file mode 100644 index 0000000..b2c31f2 --- /dev/null +++ b/jode/jode/expr/LocalPrePostFixOperator.java @@ -0,0 +1,43 @@ +/* + * LocalPrePostFixOperator (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 LocalPrePostFixOperator extends NoArgOperator { + IIncOperator iinc; + boolean postfix; + + public LocalPrePostFixOperator(Type type, int op, + IIncOperator iinc, boolean postfix) { + super(type, op); + this.iinc = iinc; + this.postfix = postfix; + } + + public int getPriority() { + return postfix ? 800 : 700; + } + + public String toString(String[] operands) { + if (postfix) + return iinc.getLocalInfo().getName() + getOperatorString(); + else + return getOperatorString() + iinc.getLocalInfo().getName(); + } +} diff --git a/jode/jode/expr/PrePostFixOperator.java b/jode/jode/expr/PrePostFixOperator.java new file mode 100644 index 0000000..3664256 --- /dev/null +++ b/jode/jode/expr/PrePostFixOperator.java @@ -0,0 +1,67 @@ +/* + * PrePostFixOperator (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 PrePostFixOperator extends Operator { + StoreInstruction store; + boolean postfix; + + public PrePostFixOperator(Type type, int op, + StoreInstruction store, boolean postfix) { + super(type, op); + this.store = store; + this.postfix = postfix; + } + + public int getPriority() { + return postfix ? 800 : 700; + } + + public int getOperandPriority(int i) { + return getPriority(); + } + + public Type getOperandType(int i) { + return store.getLValueOperandType(i); + } + + public int getOperandCount() { + return store.getLValueOperandCount(); + } + + /** + * Sets the return type of this operator. + */ + public void setType(Type type) { + store.setLValueType(type); + super.setType(store.getLValueType()); + } + + public void setOperandType(Type[] inputTypes) { + store.setLValueOperandType(inputTypes); + } + + public String toString(String[] operands) { + if (postfix) + return store.getLValueString(operands) + getOperatorString(); + else + return getOperatorString() + store.getLValueString(operands); + } +} diff --git a/jode/jode/flow/CreateForInitializer.java b/jode/jode/flow/CreateForInitializer.java new file mode 100644 index 0000000..b2e10b4 --- /dev/null +++ b/jode/jode/flow/CreateForInitializer.java @@ -0,0 +1,58 @@ +/* + * CreateForInitializer (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.flow; +import jode.Instruction; + +public class CreateForInitializer implements Transformation { + + /** + * This combines an variable initializer into a for statement + * @param flow The FlowBlock that is transformed + */ + public boolean transform(FlowBlock flow) { + + LoopBlock forBlock; + Instruction initializer; + try { + forBlock = (LoopBlock) flow.lastModified; + + if (forBlock.type != forBlock.FOR || forBlock.init != null) + return false; + + SequentialBlock sequBlock = + (SequentialBlock) forBlock.outer; + + initializer = + ((InstructionBlock) sequBlock.subBlocks[0]).getInstruction(); + + } catch (ClassCastException ex) { + return false; + } catch (NullPointerException ex) { + return false; + } + + if (jode.Decompiler.isVerbose) + System.err.print("f"); + + forBlock.init = initializer; + forBlock.replace(forBlock.outer, forBlock); + return true; + } +} diff --git a/jode/jode/flow/CreatePrePostIncExpression.java b/jode/jode/flow/CreatePrePostIncExpression.java new file mode 100644 index 0000000..7096665 --- /dev/null +++ b/jode/jode/flow/CreatePrePostIncExpression.java @@ -0,0 +1,164 @@ +/* + * CreatePrePostIncExpression (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.flow; +import jode.*; + +public class CreatePrePostIncExpression implements Transformation { + + public boolean transform(FlowBlock flow) + { + return (createLocalPrePostInc(flow) || createPostInc(flow)); + } + + public boolean createLocalPrePostInc(FlowBlock flow) { + IIncOperator iinc; + boolean isPost; + int op; + InstructionContainer lastBlock; + Type type; + try { + lastBlock = (InstructionContainer) flow.lastModified; + + Instruction instr2 = lastBlock.getInstruction(); + SequentialBlock sequBlock = (SequentialBlock)lastBlock.outer; + if (sequBlock.subBlocks[1] != lastBlock) + return false; + InstructionBlock ib = (InstructionBlock) sequBlock.subBlocks[0]; + Instruction instr1 = ib.getInstruction(); + + LocalLoadOperator load; + if (instr1 instanceof IIncOperator + && instr2 instanceof LocalLoadOperator) { + iinc = (IIncOperator) instr1; + load = (LocalLoadOperator) instr2; + isPost = false; + } else if (instr1 instanceof LocalLoadOperator + && instr2 instanceof IIncOperator) { + load = (LocalLoadOperator) instr1; + iinc = (IIncOperator) instr2; + isPost = true; + } else + return false; + + if (iinc.getOperatorIndex() == iinc.ADD_OP + iinc.OPASSIGN_OP) + op = Operator.INC_OP; + else if (iinc.getOperatorIndex() == iinc.NEG_OP + iinc.OPASSIGN_OP) + op = Operator.DEC_OP; + else + return false; + + if (iinc.getValue().equals("-1")) + op ^= 1; + else if (!iinc.getValue().equals("1")) + return false; + + if (!iinc.matches(load)) + return false; + + type = load.getType().intersection(Type.tUInt); + } catch (NullPointerException ex) { + return false; + } catch (ClassCastException ex) { + return false; + } + Operator ppop = new LocalPrePostFixOperator(type, op, iinc, isPost); + lastBlock.setInstruction(ppop); + lastBlock.replace(lastBlock.outer, lastBlock); + return true; + } + + public boolean createPostInc(FlowBlock flow) { + StoreInstruction store; + int op; + Type type; + InstructionBlock lastBlock; + SequentialBlock sequBlock; + try { + lastBlock = (InstructionBlock) flow.lastModified; + + Expression storeExpr = (Expression) lastBlock.getInstruction(); + store = (StoreInstruction) storeExpr.getOperator(); + + sequBlock = (SequentialBlock) lastBlock.outer; + if (sequBlock.subBlocks[1] != lastBlock) + return false; + + BinaryOperator binOp; + InstructionBlock ib; + if (store.getLValueOperandCount() > 0) { + ib = (InstructionBlock) sequBlock.subBlocks[0]; + binOp = (BinaryOperator) ib.getInstruction(); + sequBlock = (SequentialBlock) sequBlock.outer; + } else + binOp = (BinaryOperator) + ((ComplexExpression) storeExpr).getSubExpressions()[0]; + + if (binOp.getOperatorIndex() == store.ADD_OP) + op = Operator.INC_OP; + else if (store.getOperatorIndex() == store.NEG_OP) + op = Operator.DEC_OP; + else + return false; + + ib = (InstructionBlock) sequBlock.subBlocks[0]; + + ConstOperator constOp = (ConstOperator) ib.getInstruction(); + if (!constOp.getValue().equals("1") && + !constOp.getValue().equals("-1")) + return false; + if (constOp.getValue().equals("-1")) + op ^= 1; + + sequBlock = (SequentialBlock) sequBlock.outer; + ib = (InstructionBlock) sequBlock.subBlocks[0]; + + DupOperator dup = (DupOperator) ib.getInstruction(); + if (dup.getCount() != store.getLValueType().stackSize() || + dup.getDepth() != store.getLValueOperandCount()) + return false; + + sequBlock = (SequentialBlock) sequBlock.outer; + ib = (InstructionBlock) sequBlock.subBlocks[0]; + + Operator load = (Operator) ib.getInstruction(); + if (!store.matches(load)) + return false; + + if (store.getLValueOperandCount() > 0) { + sequBlock = (SequentialBlock) sequBlock.outer; + ib = (InstructionBlock) sequBlock.subBlocks[0]; + + DupOperator dup2 = (DupOperator) ib.getInstruction(); + if (dup2.getCount() != store.getLValueOperandCount() || + dup2.getDepth() != 0) + return false; + } + type = load.getType().intersection(store.getLValueType()); + } catch (NullPointerException ex) { + return false; + } catch (ClassCastException ex) { + return false; + } + Operator postop = new PrePostFixOperator(type, op, store, true); + lastBlock.setInstruction(postop); + lastBlock.replace(sequBlock, lastBlock); + return true; + } +} diff --git a/jode/jode/type/ArrayType.java b/jode/jode/type/ArrayType.java index 8ecda82..b35c12a 100644 --- a/jode/jode/type/ArrayType.java +++ b/jode/jode/type/ArrayType.java @@ -101,6 +101,13 @@ public class ArrayType extends Type { : tError; } + /** + * Marks this type as used, so that the class is imported. + */ + public void useType() { + elementType.useType(); + } + public String toString() { return elementType.toString()+"[]"; } diff --git a/jode/jode/type/RangeType.java b/jode/jode/type/RangeType.java index 58fb18e..b99adda 100644 --- a/jode/jode/type/RangeType.java +++ b/jode/jode/type/RangeType.java @@ -77,6 +77,14 @@ public class RangeType extends Type { throw new AssertError("getGeneralizedType called on RangeType"); } + /** + * Marks this type as used, so that the class is imported. + */ + public void useType() { + /* The topType will be printed */ + topType.useType(); + } + public String toString() { if (jode.Decompiler.isTypeDebugging)