Mirror of the JODE repository
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
jode/jode/jode/flow/CreateConstantArray.java

129 lines
5.0 KiB

/* 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.ComplexExpression;
import jode.ArrayStoreOperator;
import jode.NewArrayOperator;
import jode.ConstantArrayOperator;
import jode.ConstOperator;
import jode.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;
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 = ib.getInstruction();
sequBlock = (SequentialBlock) sequBlock.outer;
ib = (InstructionBlock) sequBlock.subBlocks[0];
Expression indexexpr = ib.getInstruction();
ConstOperator indexop =
(ConstOperator) indexexpr.getOperator();
if (!indexop.getType().isOfType(Type.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 ConstOperator(Type.tUnknown, "0");
}
}
consts[lastindex--] = lastconst;
sequBlock = (SequentialBlock) sequBlock.outer;
SpecialBlock dup = (SpecialBlock) sequBlock.subBlocks[0];
if (dup.type != SpecialBlock.DUP
|| dup.depth != 0
|| dup.count != 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 ConstOperator(Type.tUnknown, "0");
ComplexExpression newArrayExpr =
(ComplexExpression) ib.getInstruction();
NewArrayOperator newArrayOp =
(NewArrayOperator) newArrayExpr.getOperator();
type = newArrayOp.getType();
if (newArrayOp.getOperandCount() != 1)
return false;
Expression countexpr = newArrayExpr.getSubExpressions()[0];
ConstOperator countop =
(ConstOperator) countexpr.getOperator();
if (!countop.getType().isOfType(Type.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 ConstOperator(Type.tUnknown, "0");
consts = newConsts;
}
} catch (NullPointerException ex) {
return false;
} catch (ClassCastException ex) {
return false;
}
if (jode.Decompiler.isVerbose)
System.err.print("a");
lastBlock.setInstruction
(new ComplexExpression
(new ConstantArrayOperator(type, consts.length),
consts));
lastBlock.moveDefinitions(sequBlock.subBlocks[0], lastBlock);
lastBlock.replace(sequBlock.subBlocks[0]);
flow.lastModified.moveDefinitions(sequBlock.subBlocks[1],
flow.lastModified);
flow.lastModified.replace(sequBlock.subBlocks[1]);
return true;
}
}