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