use of soot.toolkits.scalar.LiveLocals in project soot by Sable.
the class XMLPrinter method printStatementsInBody.
/**
* Prints the given <code>JimpleBody</code> to the specified <code>PrintWriter</code>.
*/
private void printStatementsInBody(Body body, java.io.PrintWriter out) {
LabeledUnitPrinter up = new NormalUnitPrinter(body);
Map<Unit, String> stmtToName = up.labels();
Chain<Unit> units = body.getUnits();
// UnitGraph unitGraph = new soot.toolkits.graph.BriefUnitGraph( body );
ExceptionalUnitGraph exceptionalUnitGraph = new soot.toolkits.graph.ExceptionalUnitGraph(body);
// include any analysis which will be used in the xml output
LiveLocals sll = new SimpleLiveLocals(exceptionalUnitGraph);
// iterate through each statement
String cleanMethodName = cleanMethod(body.getMethod().getName());
Iterator<Unit> unitIt = units.iterator();
Unit currentStmt = null;
String currentLabel = "default";
long statementCount = 0;
long labelCount = 0;
long labelID = 0;
// lists
Vector<String> useList = new Vector<String>();
Vector<Vector<Long>> useDataList = new Vector<Vector<Long>>();
Vector<String> defList = new Vector<String>();
Vector<Vector<Long>> defDataList = new Vector<Vector<Long>>();
Vector<Vector<String>> paramData = new Vector<Vector<String>>();
Vector<XMLLabel> xmlLabelsList = new Vector<XMLLabel>();
long maxStmtCount = 0;
/*
// for invokes, add a list of potential targets
if (!Scene.v().hasActiveInvokeGraph()) {
InvokeGraphBuilder.v().transform("jil.igb");
}
// build an invoke graph based on class hiearchy analysis
InvokeGraph igCHA = Scene.v().getActiveInvokeGraph();
// build an invoke graph based on variable type analysis
InvokeGraph igVTA = Scene.v().getActiveInvokeGraph();
try {
VariableTypeAnalysis vta = null;
int VTApasses = 1;
//Options.getInt( PackManager.v().getPhaseOptions( "jil.igb" ), "VTA-passes" );
for (int i = 0; i < VTApasses; i++) {
vta = new VariableTypeAnalysis(igVTA);
vta.trimActiveInvokeGraph();
igVTA.refreshReachableMethods();
}
} catch (RuntimeException re) {
// this will fail if the --analyze-context flag is not specified
// logger.debug(""+ "JIL VTA FAILED: " + re );
igVTA = null;
}
*/
// add method node
XMLNode methodNode = xmlNode.addChild("method", new String[] { "name", "returntype", "class" }, new String[] { cleanMethodName, body.getMethod().getReturnType().toString(), body.getMethod().getDeclaringClass().getName().toString() });
String declarationStr = body.getMethod().getDeclaration().toString().trim();
methodNode.addChild("declaration", toCDATA(declarationStr), new String[] { "length" }, new String[] { declarationStr.length() + "" });
// create references to parameters, locals, labels, stmts nodes
XMLNode parametersNode = methodNode.addChild("parameters", new String[] { "method" }, new String[] { cleanMethodName });
XMLNode localsNode = methodNode.addChild("locals");
XMLNode labelsNode = methodNode.addChild("labels");
XMLNode stmtsNode = methodNode.addChild("statements");
// create default label
XMLLabel xmlLabel = new XMLLabel(labelCount, cleanMethodName, currentLabel);
labelsNode.addChild("label", new String[] { "id", "name", "method" }, new String[] { (labelCount++) + "", currentLabel, cleanMethodName });
// for each statement...
while (unitIt.hasNext()) {
currentStmt = (Unit) unitIt.next();
// new label
if (stmtToName.containsKey(currentStmt)) {
currentLabel = stmtToName.get(currentStmt).toString();
// fill in the stmt count for the previous label
// index = xmlLabels.indexOf( "%s" );
// if( index != -1 )
// xmlLabels = xmlLabels.substring( 0, index ) + ( labelID ) + xmlLabels.substring( index + 2 );
// index = xmlLabels.indexOf( "%d" );
// if( index != -1 )
// xmlLabels = xmlLabels.substring( 0, index ) + new Float( ( new Float( labelID ).floatValue() / new Float( units.size() ).intValue() ) * 100.0 ).intValue() + xmlLabels.substring( index + 2 );
xmlLabel.stmtCount = labelID;
xmlLabel.stmtPercentage = new Float((new Float(labelID).floatValue() / new Float(units.size()).intValue()) * 100.0).longValue();
if (xmlLabel.stmtPercentage > maxStmtCount)
maxStmtCount = xmlLabel.stmtPercentage;
xmlLabelsList.addElement(xmlLabel);
// xmlLabel.clear();
xmlLabel = new XMLLabel(labelCount, cleanMethodName, currentLabel);
labelsNode.addChild("label", new String[] { "id", "name", "method" }, new String[] { labelCount + "", currentLabel, cleanMethodName });
labelCount++;
labelID = 0;
}
// examine each statement
XMLNode stmtNode = stmtsNode.addChild("statement", new String[] { "id", "label", "method", "labelid" }, new String[] { statementCount + "", currentLabel, cleanMethodName, labelID + "" });
XMLNode sootstmtNode = stmtNode.addChild("soot_statement", new String[] { "branches", "fallsthrough" }, new String[] { boolToString(currentStmt.branches()), boolToString(currentStmt.fallsThrough()) });
// uses for each statement
int j = 0;
Iterator<ValueBox> boxIt = currentStmt.getUseBoxes().iterator();
while (boxIt.hasNext()) {
ValueBox box = (ValueBox) boxIt.next();
if (box.getValue() instanceof Local) {
String local = cleanLocal(((Local) box.getValue()).toString());
sootstmtNode.addChild("uses", new String[] { "id", "local", "method" }, new String[] { j + "", local, cleanMethodName });
j++;
Vector<Long> tempVector = null;
int useIndex = useList.indexOf(local);
if (useIndex == -1) {
useDataList.addElement(tempVector);
useList.addElement(local);
useIndex = useList.indexOf(local);
}
if (useDataList.size() > useIndex) {
tempVector = useDataList.elementAt(useIndex);
if (tempVector == null) {
tempVector = new Vector<Long>();
}
tempVector.addElement(new Long(statementCount));
useDataList.setElementAt(tempVector, useIndex);
}
}
}
// defines for each statement
j = 0;
boxIt = currentStmt.getDefBoxes().iterator();
while (boxIt.hasNext()) {
ValueBox box = (ValueBox) boxIt.next();
if (box.getValue() instanceof Local) {
String local = cleanLocal(((Local) box.getValue()).toString());
sootstmtNode.addChild("defines", new String[] { "id", "local", "method" }, new String[] { j + "", local, cleanMethodName });
j++;
Vector<Long> tempVector = null;
int defIndex = defList.indexOf(local);
if (defIndex == -1) {
defDataList.addElement(tempVector);
defList.addElement(local);
defIndex = defList.indexOf(local);
}
if (defDataList.size() > defIndex) {
tempVector = defDataList.elementAt(defIndex);
if (tempVector == null) {
tempVector = new Vector<Long>();
}
tempVector.addElement(new Long(statementCount));
defDataList.setElementAt(tempVector, defIndex);
}
}
}
/*
// for invokes, add a list of potential targets
if (stmtCurrentStmt.containsInvokeExpr()) {
// default analysis is CHA
if (igCHA != null) {
try {
List targets = igCHA.getTargetsOf(stmtCurrentStmt);
XMLNode CHAinvoketargetsNode =
sootstmtNode.addChild(
"invoketargets",
new String[] { "analysis", "count" },
new String[] { "CHA", targets.size() + "" });
for (int i = 0; i < targets.size(); i++) {
SootMethod meth = (SootMethod) targets.get(i);
CHAinvoketargetsNode.addChild(
"target",
new String[] { "id", "class", "method" },
new String[] {
i + "",
meth.getDeclaringClass().getFullName(),
cleanMethod(meth.getName())});
}
} catch (RuntimeException re) {
//logger.debug(""+ "XML: " + re + " (" + stmtCurrentStmt + ")" );
}
}
// now try VTA, which will only work if the -a or --analyze-context switch is specified
if (igVTA != null) {
InvokeExpr ie =
(InvokeExpr) stmtCurrentStmt.getInvokeExpr();
if (!(ie instanceof StaticInvokeExpr)
&& !(ie instanceof SpecialInvokeExpr)) {
try {
List targets = igVTA.getTargetsOf(stmtCurrentStmt);
XMLNode VTAinvoketargetsNode =
sootstmtNode.addChild(
"invoketargets",
new String[] { "analysis", "count" },
new String[] {
"VTA",
targets.size() + "" });
for (int i = 0; i < targets.size(); i++) {
SootMethod meth = (SootMethod) targets.get(i);
VTAinvoketargetsNode.addChild(
"target",
new String[] { "id", "class", "method" },
new String[] {
i + "",
meth.getDeclaringClass().getFullName(),
cleanMethod(meth.getName())});
}
} catch (RuntimeException re) {
//logger.debug(""+ "XML: " + re + " (" + stmtCurrentStmt + ")" );
}
}
}
}
*/
// simple live locals
List<Local> liveLocalsIn = sll.getLiveLocalsBefore(currentStmt);
List<Local> liveLocalsOut = sll.getLiveLocalsAfter(currentStmt);
XMLNode livevarsNode = sootstmtNode.addChild("livevariables", new String[] { "incount", "outcount" }, new String[] { liveLocalsIn.size() + "", liveLocalsOut.size() + "" });
for (int i = 0; i < liveLocalsIn.size(); i++) {
livevarsNode.addChild("in", new String[] { "id", "local", "method" }, new String[] { i + "", cleanLocal(liveLocalsIn.get(i).toString()), cleanMethodName });
}
for (int i = 0; i < liveLocalsOut.size(); i++) {
livevarsNode.addChild("out", new String[] { "id", "local", "method" }, new String[] { i + "", cleanLocal(liveLocalsOut.get(i).toString()), cleanMethodName });
}
// parameters
for (int i = 0; i < body.getMethod().getParameterTypes().size(); i++) {
Vector<String> tempVec = new Vector<String>();
paramData.addElement(tempVec);
}
// parse any info from the statement code
currentStmt.toString(up);
String jimpleStr = up.toString().trim();
if (currentStmt instanceof soot.jimple.IdentityStmt && jimpleStr.indexOf("@parameter") != -1) {
// this line is a use of a parameter
String tempStr = jimpleStr.substring(jimpleStr.indexOf("@parameter") + 10);
if (tempStr.indexOf(":") != -1)
tempStr = tempStr.substring(0, tempStr.indexOf(":")).trim();
if (tempStr.indexOf(" ") != -1)
tempStr = tempStr.substring(0, tempStr.indexOf(" ")).trim();
int paramIndex = new Integer(tempStr).intValue();
Vector<String> tempVec = paramData.elementAt(paramIndex);
if (tempVec != null)
tempVec.addElement(Long.toString(statementCount));
paramData.setElementAt(tempVec, paramIndex);
}
// add plain jimple representation of each statement
sootstmtNode.addChild("jimple", toCDATA(jimpleStr), new String[] { "length" }, new String[] { (jimpleStr.length() + 1) + "" });
// increment statement counters
labelID++;
statementCount++;
}
// add count to statments
stmtsNode.addAttribute("count", statementCount + "");
// method parameters
parametersNode.addAttribute("count", body.getMethod().getParameterCount() + "");
for (int i = 0; i < body.getMethod().getParameterTypes().size(); i++) {
XMLNode paramNode = parametersNode.addChild("parameter", new String[] { "id", "type", "method", "name" }, new String[] { i + "", body.getMethod().getParameterTypes().get(i).toString(), cleanMethodName, "_parameter" + i });
XMLNode sootparamNode = paramNode.addChild("soot_parameter");
Vector<String> tempVec = paramData.elementAt(i);
for (int k = 0; k < tempVec.size(); k++) {
sootparamNode.addChild("use", new String[] { "id", "line", "method" }, new String[] { k + "", String.valueOf(tempVec.elementAt(k)) + "", cleanMethodName });
}
sootparamNode.addAttribute("uses", tempVec.size() + "");
}
/*
index = xmlLabels.indexOf( "%s" );
if( index != -1 )
xmlLabels = xmlLabels.substring( 0, index ) + ( labelID ) + xmlLabels.substring( index + 2 );
index = xmlLabels.indexOf( "%d" );
if( index != -1 )
xmlLabels = xmlLabels.substring( 0, index ) + new Float( ( new Float( labelID ).floatValue() / new Float( units.size() ).floatValue() ) * 100.0 ).intValue() + xmlLabels.substring( index + 2 );
*/
xmlLabel.stmtCount = labelID;
xmlLabel.stmtPercentage = new Float((new Float(labelID).floatValue() / new Float(units.size()).floatValue()) * 100.0).longValue();
if (xmlLabel.stmtPercentage > maxStmtCount)
maxStmtCount = xmlLabel.stmtPercentage;
xmlLabelsList.addElement(xmlLabel);
// print out locals
Collection<Local> locals = body.getLocals();
Iterator<Local> localsIterator = locals.iterator();
Vector<String> localTypes = new Vector<String>();
Vector<Vector<XMLNode>> typedLocals = new Vector<Vector<XMLNode>>();
Vector<Integer> typeCounts = new Vector<Integer>();
int j = 0;
int currentType = 0;
while (localsIterator.hasNext()) {
int useCount = 0;
int defineCount = 0;
Local localData = (Local) localsIterator.next();
String local = cleanLocal((String) localData.toString());
String localType = localData.getType().toString();
// collect the local types
if (!localTypes.contains(localType)) {
localTypes.addElement(localType);
typedLocals.addElement(new Vector<XMLNode>());
typeCounts.addElement(new Integer(0));
}
// create a reference to the local node
XMLNode localNode = new XMLNode("local", "", new String[] { "id", "method", "name", "type" }, new String[] { j + "", cleanMethodName, local, localType });
XMLNode sootlocalNode = localNode.addChild("soot_local");
currentType = 0;
for (int k = 0; k < localTypes.size(); k++) {
if (localType.equalsIgnoreCase(localTypes.elementAt(k))) {
currentType = k;
Integer tempInt = new Integer(typeCounts.elementAt(k).intValue() + 1);
typeCounts.setElementAt(tempInt, k);
break;
}
}
// add all uses to this local
for (int k = 0; k < useList.size(); k++) {
String query = useList.elementAt(k);
if (query.equalsIgnoreCase(local)) {
Vector<Long> tempVector = useDataList.elementAt(useList.indexOf(local));
for (int i = 0; i < tempVector.size(); i++) {
sootlocalNode.addChild("use", new String[] { "id", "line", "method" }, new String[] { i + "", ((Long) tempVector.elementAt(i)).toString(), cleanMethodName });
}
useCount = tempVector.size();
break;
}
}
// add all definitions to this local
for (int k = 0; k < defList.size(); k++) {
String query = (defList.elementAt(k));
if (query.equalsIgnoreCase(local)) {
Vector<Long> tempVector = defDataList.elementAt(defList.indexOf(local));
for (int i = 0; i < tempVector.size(); i++) {
sootlocalNode.addChild("definition", new String[] { "id", "line", "method" }, new String[] { i + "", ((Long) tempVector.elementAt(i)).toString(), cleanMethodName });
}
defineCount = tempVector.size();
break;
}
}
// add number of uses and defines to this local
sootlocalNode.addAttribute("uses", useCount + "");
sootlocalNode.addAttribute("defines", defineCount + "");
// create a list of locals sorted by type
Vector<XMLNode> list = typedLocals.elementAt(currentType);
list.addElement(localNode);
typedLocals.setElementAt(list, currentType);
// add local to locals node
localsNode.addChild((XMLNode) localNode.clone());
j++;
}
// add count to the locals node
localsNode.addAttribute("count", locals.size() + "");
// add types node to locals node, and each type with each local per type
XMLNode typesNode = localsNode.addChild("types", new String[] { "count" }, new String[] { localTypes.size() + "" });
for (int i = 0; i < localTypes.size(); i++) {
String type = localTypes.elementAt(i);
XMLNode typeNode = typesNode.addChild("type", new String[] { "id", "type", "count" }, new String[] { i + "", type, typeCounts.elementAt(i) + "" });
Vector<XMLNode> list = typedLocals.elementAt(i);
for (j = 0; j < list.size(); j++) {
typeNode.addChild(list.elementAt(j));
}
}
// add count attribute to labels node, and stmtcount, and stmtpercentage attributes to each label node
labelsNode.addAttribute("count", labelCount + "");
XMLNode current = labelsNode.child;
for (int i = 0; i < xmlLabelsList.size(); i++) {
XMLLabel tempLabel = xmlLabelsList.elementAt(i);
tempLabel.stmtPercentage = new Float((new Float(tempLabel.stmtPercentage).floatValue() / new Float(maxStmtCount).floatValue()) * 100.0).longValue();
if (current != null) {
current.addAttribute("stmtcount", tempLabel.stmtCount + "");
current.addAttribute("stmtpercentage", tempLabel.stmtPercentage + "");
current = current.next;
}
}
// Print out exceptions
statementCount = 0;
XMLNode exceptionsNode = methodNode.addChild("exceptions");
Iterator<Trap> trapIt = body.getTraps().iterator();
if (trapIt.hasNext()) {
while (trapIt.hasNext()) {
Trap trap = trapIt.next();
// catch java.io.IOException from label0 to label1 with label2;
XMLNode catchNode = exceptionsNode.addChild("exception", new String[] { "id", "method", "type" }, new String[] { (statementCount++) + "", cleanMethodName, Scene.v().quotedNameOf(trap.getException().getName()) });
catchNode.addChild("begin", new String[] { "label" }, new String[] { stmtToName.get(trap.getBeginUnit()).toString() });
catchNode.addChild("end", new String[] { "label" }, new String[] { stmtToName.get(trap.getEndUnit()).toString() });
catchNode.addChild("handler", new String[] { "label" }, new String[] { stmtToName.get(trap.getHandlerUnit()).toString() });
}
}
exceptionsNode.addAttribute("count", exceptionsNode.getNumberOfChildren() + "");
return;
}
Aggregations