git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@57 379699f6-c40d-0410-875b-85095c16579estable
parent
7be8903482
commit
671bd91c6f
@ -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(); |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue