git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@39 379699f6-c40d-0410-875b-85095c16579estable
parent
d2f597be45
commit
5544356bf9
@ -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(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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<arraylength; i++) |
||||||
|
newConsts[i] = new Expression |
||||||
|
(new ConstOperator(MyType.tUnknown, "0"), |
||||||
|
new Expression[0]); |
||||||
|
consts = newConsts; |
||||||
|
} |
||||||
|
} catch (NullPointerException ex) { |
||||||
|
return false; |
||||||
|
} catch (ClassCastException ex) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (jode.Decompiler.isVerbose) |
||||||
|
System.err.print("a"); |
||||||
|
|
||||||
|
lastBlock.setInstruction |
||||||
|
(new Expression(new ConstantArrayOperator(type, consts.length), |
||||||
|
consts)); |
||||||
|
lastBlock.replace(sequBlock.subBlocks[0], lastBlock); |
||||||
|
flow.lastModified.replace(sequBlock.subBlocks[1], flow.lastModified); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,75 @@ |
|||||||
|
/* JsrBlock 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 jsr instruction. A jsr instruction is |
||||||
|
* used to call the finally block, or to call the monitorexit block in |
||||||
|
* a synchronized block. |
||||||
|
* |
||||||
|
* @author Jochen Hoenicke |
||||||
|
*/ |
||||||
|
public class JsrBlock extends StructuredBlock { |
||||||
|
/** |
||||||
|
* The inner block that jumps to the subroutine. |
||||||
|
*/ |
||||||
|
StructuredBlock innerBlock; |
||||||
|
|
||||||
|
public JsrBlock(Jump next, Jump subroutine) { |
||||||
|
innerBlock = new EmptyBlock(subroutine); |
||||||
|
innerBlock.outer = this; |
||||||
|
setJump(next); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* The implementation of getNext[Flow]Block is the standard |
||||||
|
* implementation */ |
||||||
|
|
||||||
|
/** |
||||||
|
* 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 (innerBlock == oldBlock) |
||||||
|
innerBlock = newBlock; |
||||||
|
else |
||||||
|
return false; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns all sub block of this structured block. |
||||||
|
*/ |
||||||
|
public StructuredBlock[] getSubBlocks() { |
||||||
|
StructuredBlock[] result = { innerBlock }; |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
public void dumpInstruction(jode.TabbedPrintWriter writer) |
||||||
|
throws java.io.IOException |
||||||
|
{ |
||||||
|
writer.println("JSR"); |
||||||
|
writer.tab(); |
||||||
|
innerBlock.dumpSource(writer); |
||||||
|
writer.untab(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* RetBlock 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.LocalInfo; |
||||||
|
|
||||||
|
/** |
||||||
|
* This block represents a ret instruction. A ret instruction is |
||||||
|
* used to call the finally block, or to call the monitorexit block in |
||||||
|
* a synchronized block. |
||||||
|
* |
||||||
|
* @author Jochen Hoenicke |
||||||
|
*/ |
||||||
|
public class RetBlock extends StructuredBlock { |
||||||
|
/** |
||||||
|
* The local containing the return address |
||||||
|
*/ |
||||||
|
LocalInfo local; |
||||||
|
|
||||||
|
public RetBlock(LocalInfo local) { |
||||||
|
this.local = local; |
||||||
|
used.addElement(local); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Fill all in variables into the given VariableSet. |
||||||
|
* @param in The VariableSet, the in variables should be stored to. |
||||||
|
*/ |
||||||
|
public void fillInSet(VariableSet in) { |
||||||
|
in.addElement(local); |
||||||
|
} |
||||||
|
|
||||||
|
public void dumpInstruction(jode.TabbedPrintWriter writer) |
||||||
|
throws java.io.IOException |
||||||
|
{ |
||||||
|
writer.println("RET "+local); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue