[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;
    }
}