[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: JLookupSwitchStmt bug?
The list contains IntConstants. The setLookupValue method has a bug.
A fixed version of JLookupSwitchStmt.java is attached, and will appear
in the next version of Soot.
Ondrej
On Thu, Jan 02, 2003 at 04:36:48PM -0800, Archie Cobbs wrote:
> Hi,
>
> soot.jimple.internal.JLookupSwitchStmt contains these methods:
>
> public int getLookupValue(int index)
> {
> return ((IntConstant)lookupValues.get(index)).value;
> }
>
> public void setLookupValue(int index, int value)
> {
> this.lookupValues.set(index, new Integer(value));
> }
>
> It appears that there is confusion about whether the field
> 'lookupValues' is a List of Integers or a List of IntConstants.
>
> It may not matter if you're just calling 'toString()' but in
> general it would be nice for other code to know what to expect
> so that it can confidently cast these objects.
>
> Could one or the other be chosen (and that choice documented in Javadoc)?
>
> Thanks,
> -Archie
>
> __________________________________________________________________________
> Archie Cobbs * Packet Design * http://www.packetdesign.com
/* Soot - a J*va Optimization Framework
* Copyright (C) 1999 Patrick Lam
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the Sable Research Group and others 1997-1999.
* See the 'credits' file distributed with Soot for the complete list of
* contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
*/
/* Reference Version: $SootVersion: 1.2.3.dev.12 $ */
package soot.jimple.internal;
import soot.tagkit.*;
import soot.*;
import soot.jimple.*;
import soot.baf.*;
import soot.jimple.*;
import soot.util.*;
import java.util.*;
public class JLookupSwitchStmt extends AbstractStmt
implements LookupSwitchStmt, ConvertToBaf
{
UnitBox defaultTargetBox;
ValueBox keyBox;
/** List of lookup values from the corresponding bytecode instruction,
* represented as IntConstants. */
List lookupValues;
protected UnitBox[] targetBoxes;
List stmtBoxes;
// This method is necessary to deal with constructor-must-be-first-ism.
private static UnitBox[] getTargetBoxesArray(List targets)
{
UnitBox[] targetBoxes = new UnitBox[targets.size()];
for(int i = 0; i < targetBoxes.length; i++)
targetBoxes[i] = Jimple.v().newStmtBox((Stmt) targets.get(i));
return targetBoxes;
}
private static UnitBox[] unitBoxListToArray(List targets) {
UnitBox[] targetBoxes = new UnitBox[targets.size()];
for(int i = 0; i < targetBoxes.length; i++)
targetBoxes[i] = (UnitBox) targets.get(i);
return targetBoxes;
}
/** Constructs a new JLookupSwitchStmt. lookupValues should be a list of IntConst s. */
public JLookupSwitchStmt(Value key, List lookupValues, List targets, Unit defaultTarget)
{
this(Jimple.v().newImmediateBox(key),
lookupValues, getTargetBoxesArray(targets),
Jimple.v().newStmtBox(defaultTarget));
}
/** Constructs a new JLookupSwitchStmt. lookupValues should be a list of IntConst s. */
public JLookupSwitchStmt(Value key, List lookupValues, List targets, UnitBox defaultTarget)
{
this(Jimple.v().newImmediateBox(key),
lookupValues, unitBoxListToArray(targets),
defaultTarget);
}
public Object clone()
{
int lookupValueCount = lookupValues.size();
List clonedLookupValues = new ArrayList(lookupValueCount);
for( int i = 0; i < lookupValueCount ;i++) {
clonedLookupValues.add(i, IntConstant.v(getLookupValue(i)));
}
return new JLookupSwitchStmt(getKey(), clonedLookupValues, getTargets(), getDefaultTarget());
}
protected JLookupSwitchStmt(ValueBox keyBox, List lookupValues,
UnitBox[] targetBoxes,
UnitBox defaultTargetBox)
{
this.keyBox = keyBox;
this.defaultTargetBox = defaultTargetBox;
this.targetBoxes = targetBoxes;
this.lookupValues = new ArrayList();
this.lookupValues.addAll(lookupValues);
// Build up stmtBoxes
{
stmtBoxes = new ArrayList();
for(int i = 0; i < targetBoxes.length; i++)
stmtBoxes.add(targetBoxes[i]);
stmtBoxes.add(defaultTargetBox);
stmtBoxes = Collections.unmodifiableList(stmtBoxes);
}
}
protected String toString(boolean isBrief, Map stmtToName, String indentation)
{
StringBuffer buffer = new StringBuffer();
String endOfLine = (indentation.equals("")) ? " " : StringTools.lineSeparator;
buffer.append(indentation + Jimple.v().LOOKUPSWITCH + "(" + ((isBrief) ? ((ToBriefString) keyBox.getValue()).toBriefString() :
keyBox.getValue().toString()) + ")" + endOfLine);
buffer.append(indentation + "{" + endOfLine);
for(int i = 0; i < lookupValues.size(); i++)
{
buffer.append(indentation + " " + Jimple.v().CASE + " " + lookupValues.get(i) + ": " + Jimple.v().GOTO + " " +
(String) stmtToName.get(getTarget(i)) + ";" + endOfLine);
}
buffer.append(indentation + " " + Jimple.v().DEFAULT + ": " + Jimple.v().GOTO +
" " + (String) stmtToName.get(getDefaultTarget()) + ";" + endOfLine);
buffer.append(indentation + "}");
return buffer.toString();
}
public Unit getDefaultTarget()
{
return defaultTargetBox.getUnit();
}
public void setDefaultTarget(Unit defaultTarget)
{
defaultTargetBox.setUnit(defaultTarget);
}
public UnitBox getDefaultTargetBox()
{
return defaultTargetBox;
}
public Value getKey()
{
return keyBox.getValue();
}
public void setKey(Value key)
{
keyBox.setValue(key);
}
public ValueBox getKeyBox()
{
return keyBox;
}
public void setLookupValues(List lookupValues)
{
this.lookupValues = new ArrayList();
this.lookupValues.addAll(lookupValues);
}
public void setLookupValue(int index, int value)
{
this.lookupValues.set(index, IntConstant.v(value));
}
public int getLookupValue(int index)
{
return ((IntConstant)lookupValues.get(index)).value;
}
public List getLookupValues()
{
return Collections.unmodifiableList(lookupValues);
}
public int getTargetCount()
{
return targetBoxes.length;
}
public Unit getTarget(int index)
{
return targetBoxes[index].getUnit();
}
public UnitBox getTargetBox(int index)
{
return targetBoxes[index];
}
public void setTarget(int index, Unit target)
{
targetBoxes[index].setUnit(target);
}
public List getTargets()
{
List targets = new ArrayList();
for(int i = 0; i < targetBoxes.length; i++)
targets.add(targetBoxes[i].getUnit());
return targets;
}
public void setTargets(Unit[] targets)
{
for(int i = 0; i < targets.length; i++)
targetBoxes[i].setUnit(targets[i]);
}
public List getUseBoxes()
{
List list = new ArrayList();
list.addAll(keyBox.getValue().getUseBoxes());
list.add(keyBox);
return list;
}
public List getUnitBoxes()
{
return stmtBoxes;
}
public void apply(Switch sw)
{
((StmtSwitch) sw).caseLookupSwitchStmt(this);
}
public void convertToBaf(JimpleToBafContext context, List out)
{
ArrayList targetPlaceholders = new ArrayList();
((ConvertToBaf)(getKey())).convertToBaf(context, out);
for (int i = 0; i < targetBoxes.length; i++)
{
targetPlaceholders.add(Baf.v().newPlaceholderInst
(getTarget(i)));
}
Unit u;
out.add(u = Baf.v().newLookupSwitchInst
(Baf.v().newPlaceholderInst(getDefaultTarget()),
getLookupValues(), targetPlaceholders));
Unit currentUnit = this;
Iterator it = currentUnit.getTags().iterator();
while(it.hasNext()) {
u.addTag((Tag) it.next());
}
}
public boolean fallsThrough(){return false;}
public boolean branches(){return true;}
}