[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Duplicate Locals - bug or feature?
Hi,
I don't know if this is a bug or if I am doing something wring here. I
use the latest release of Soot: 2.1 that is.
I used the attached SimplePrinter program to look what is going on
inside the classes that I process.
As an example I have something as simple as:
public class MyClass {
public static double compute (double x){
double z;
x = Math.sin(x);
z = x;
return z;
}
}
and the output that I get with the following command-line:
java SimplePrinter -f dava -w -p cg off -p jb use-original-names:true
-soot-classpath
.:/usr/java/jre/lib/rt.jar:gnu-crypto-2.0.1-bin/lib/javax-crypto.jar
MyClass
is located in the file simple_printer.txt. The generated MyClass.java
(implied by the -f dava switch) is also attached.
Now, the problem that I have here are located at lines 15 and 17 in the
file simple_printer.txt (variable x is defined two times) which leads to
the instantiation of "x" on line 13 in the MyClass.java file which is
obviously wrong since "x" it is already declared in the parameter list.
In short, there is a duplicate local here -> "x".
The questions that I have are:
1. Where does the second instance of x come from?
2. Am I doing something wrong (soot calling sequence, flags etc)?
3. If there is a problem in Soot, where should I look? If nobody has a
quick fix to this, I would do it myself, but I would like to have an
idea about where should I start.
I think that a possible problem is the fact that x is a LHS as well as a
RHS, although I can't see exactly how this is relevant... However, just
try and replace:
x = Math.sin(x);
z = x;
with:
z = Math.sin(x);
and you'll notice that this problem does not appear anymore.
Cheers,
Emil
import soot.*;
import soot.jimple.*;
import soot.util.*;
import java.io.*;
import java.util.*;
/**
Example of iterating all the classes.
*/
public class SimplePrinter
{
public static void main(String[] args)
{
if(args.length == 0)
{
System.out.println("Syntax: java SimplePrinter [soot options]");
System.exit(0);
}
// Register class GPrt as a transformer,
// So that the "internalTransform" will be called after all classes
// loaded
PackManager.v().getPack("wjtp").add(new Transform("wjtp.gprinter", GPrt.v()));
// Execute soot
soot.Main.main(args);
}
}
class GPrt extends SceneTransformer
{
// Hooks needed by Framwork:
private static GPrt instance = new GPrt();
private GPrt() {}
public static GPrt v() { return instance; }
// This is the key method:
protected void internalTransform(String phaseName, Map options)
{
System.out.println("Start Printer");
System.out.println("=======================================");
// Scene is the root of AST
Chain classList = Scene.v().getApplicationClasses();
Iterator classIt = classList.iterator();
while (classIt.hasNext()){
// Iterate over all classes
SootClass sc = (SootClass) classIt.next();
System.out.println(sc.getName());
Iterator fIt = sc.getFields().iterator();
while (fIt.hasNext()){
// Iterate over all fields of the current class
SootField sf = (SootField) fIt.next();
System.out.println(" "+sf.getName()+" "+sf.getType().getClass());
if(sf.getType() instanceof ArrayType){
ArrayType aType = (ArrayType)sf.getType();
System.out.println("\t ArrayType BT & Dim: "+aType.baseType+
"; "+aType.numDimensions);
}
}
Iterator mIt = sc.getMethods().iterator();
while (mIt.hasNext()){
// Iterate over all methods of the current class
SootMethod sm = (SootMethod) mIt.next();
System.out.println(" "+sm.getSignature());
if (sc.isPhantomClass()){
continue;
}
Body mthdBody = sm.retrieveActiveBody();
Iterator varIt = mthdBody.getLocals().iterator();
while (varIt.hasNext()){
// Iterate over all variables of the current method
Local l = (Local) varIt.next();
System.out.print(" "+l.getType().toString());
System.out.println(" "+l.getName());
}
System.out.println("");
Iterator stmtIt = mthdBody.getUnits().iterator();
while (stmtIt.hasNext()){
// Iterate over all statements of the current method
Stmt s = (Stmt) stmtIt.next();
System.out.println(" StmtClass:"+s.getClass());
System.out.println(" "+s.toString());
if (s instanceof AssignStmt){
AssignStmt jassgnm = (AssignStmt)s;
System.out.println(" AssignStmt LHS:"+jassgnm.getLeftOp().getClass());
System.out.println(" AssignStmt RHS:"+jassgnm.getRightOp().getClass());
}
}
}
}
System.out.println("====================================");
System.out.println("Finished!");
}
}
Soot started on Wed Sep 01 18:50:09 CEST 2004
Start Printer
=======================================
AppSource
<AppSource: void <init>()>
AppSource l0
StmtClass:class soot.jimple.internal.JIdentityStmt
l0 := @this: AppSource
StmtClass:class soot.jimple.internal.JInvokeStmt
specialinvoke l0.<java.lang.Object: void <init>()>()
StmtClass:class soot.jimple.internal.JReturnVoidStmt
return
<AppSource: double compute(double)>
double x
double z
double x
StmtClass:class soot.jimple.internal.JIdentityStmt
x := @parameter0: double
StmtClass:class soot.jimple.internal.JAssignStmt
x = staticinvoke <java.lang.Math: double sin(double)>(x)
AssignStmt LHS:class soot.jimple.internal.JimpleLocal
AssignStmt RHS:class soot.jimple.internal.JStaticInvokeExpr
StmtClass:class soot.jimple.internal.JAssignStmt
z = x
AssignStmt LHS:class soot.jimple.internal.JimpleLocal
AssignStmt RHS:class soot.jimple.internal.JimpleLocal
StmtClass:class soot.jimple.internal.JReturnStmt
return z
====================================
Finished!
Verifying exception handling.. Warning: using incomplete callgraph containing only application classes.
[Call Graph] For information on where the call graph may be incomplete, use the verbose option to the cg phase.
.
Decompiling AppSource...
Generating sootOutput/dava/src/AppSource.java...
Soot finished on Wed Sep 01 18:50:16 CEST 2004
Soot has run for 0 min. 7 sec.
public class MyClass
{
public MyClass()
{
super();
return;
}
public static double compute(double x)
{
double z, x;
x = Math.sin(x);
z = x;
return z;
}
}