Initial revision

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@39 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent d2f597be45
commit 5544356bf9
  1. 108
      jode/jode/flow/CaseBlock.java
  2. 134
      jode/jode/flow/CreateConstantArray.java
  3. 75
      jode/jode/flow/JsrBlock.java
  4. 53
      jode/jode/flow/RetBlock.java

@ -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…
Cancel
Save