[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bug report




Hi,

I have not managed to send a bug report from the Web.
Maybe it is a local problem, I do not know.

In any case I report this bug here.

I am writing a metaobject protocol for java by the help of soot.
If you have already met this problem and you know how to avoid it please
let me know.

The problem is that locals get confused when adding new code into the body
of a method.
As I saw it occures when in the added code I refer to one of the formal
parameters (if there exists one).

I show an example.

The method to be transformed:

  void m(String s){
    System.out.println(s);
  }

The important part of the transforming code:

    SootMethod sm = sc.getMethodByName("m");
    Body b = sm.retrieveActiveBody();
    soot.util.Chain units = b.getUnits();
    Stmt firstStmt = (Stmt) units.getFirst();

    Local tmpRef = Jimple.v().newLocal("tmpRef",
           RefType.v("java.io.PrintStream"));
    b.getLocals().add(tmpRef);

    units.insertBefore(
      Jimple.v().newAssignStmt(
        tmpRef,
        Jimple.v().newStaticFieldRef(
       Scene.v().getField("<java.lang.System: java.io.PrintStream out>")
      )),
      firstStmt
    );

    Local par0 = Jimple.v().newLocal("par0",
          RefType.v("java.lang.String"));
    b.getLocals().add(par0);
    units.insertBefore(Jimple.v().newIdentityStmt(par0,
           Jimple.v().newParameterRef(RefType.v(), 0)), firstStmt);

    SootMethod toCall =
    Scene.v().getMethod("<java.io.PrintStream: void println(java.lang.String)>");


units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newVirtualInvokeExpr(tmpRef,
  toCall, par0)), firstStmt);

    SootMethod toCall =
      Scene.v().getMethod("<java.io.PrintStream: void println(java.lang.String)>");

 units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newVirtualInvokeExpr(tmpRef,
  toCall, par0)), firstStmt);

The jimple code produced by printTo seems to be all right, but the
method write makes an incorrect class file. It does not pass the java
verifier at all.
The jimple code regenerated from this class file shows the problem:

    void m(java.lang.String)
    {
        C r0;
        java.lang.String r1, r4, r5;
        java.io.PrintStream r2, r3;

        r0 := @this: C;
        r1 := @parameter0: java.lang.String;
        r2 = <java.lang.System: java.io.PrintStream out>;
        r4 = (java.lang.String) r2;
        virtualinvoke r2.<java.io.PrintStream: void
println(java.lang.String)>(r4);
        r3 = <java.lang.System: java.io.PrintStream out>;
        r5 = (java.lang.String) r2;
        virtualinvoke r3.<java.io.PrintStream: void
println(java.lang.String)>(r5);
        return;
    }



Please reply if you know how to by-pass this bug.

Thanks,

Miklos Espak