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