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

Re: Performing a scene transformation _after_ body transforms...




>
>I hope these pointers help. I encourage other soot-list readers to
>comment on this approach (or point out errors), since it is based on
>code I wrote 2 years ago.

Well, it still seems pretty limiting...  What if I want to run a 
SceneTransformation,
a BodyTransformation and then another SceneTransformation?

What I've done is to implement an Adaptor that turns BodyTransformations 
into SceneTransformations:

public class TransformerAdapter extends SceneTransformer {
     /** Construct a new transformer
      */
     public TransformerAdapter(BodyTransformer transformer) {
         _transformer = transformer;
     }

     protected void internalTransform(String phaseName, Map options) {
         System.out.println("TransformerAdapter.internalTransform("
                 + phaseName + ", " + options + ")");

         Iterator classes = Scene.v().getApplicationClasses().iterator();
         while(classes.hasNext()) {
             SootClass theClass = (SootClass)classes.next();
             Iterator methods = theClass.getMethods().iterator();
             while(methods.hasNext()) {
                 SootMethod m = (SootMethod) methods.next();
                 if(!m.isConcrete())
                     continue;

                 JimpleBody body = (JimpleBody) m.retrieveActiveBody();

                 // FIXME: pass in the options.
                 // Currently this is not possible because the
                 // internalTransform method is protected.
                 _transformer.transform(body, phaseName, "");
             }
         }
     }

     private BodyTransformer _transformer;
}

This is much cleaner than the instanceof check that currently exists 
somewhere (Scene, I think?) to handle
the two types of classes separately...  it also fixes the annoyance with 
the required ordering between
the two types of transformers...

My current problem is that the whole idea of the way transforms are 
organized in soot:
1) means that I have to know what transformations I want to execute before 
looking at my program
2) The topology of the transformations is a list...

Consider the following....  I want to inline all static methods, 
unfortunately, static methods may all other static methods.
This means I have to iterate until there are no invocations that can be 
inlined...
There is no way to build this within Soot transformation mechanism, 
starting from a transformation that inlines all the method invocations that
are currently available...
while(sites can be inlined) {
         inlineAllAvailableSites();
}

Another...  I write a tranformation that is fast, but makes certain 
assumptions about the code.... I write another that is slow, but makes no 
assumptions...  I write an analysis that determines if the assumptions hold:

if(assumptions hold) {
         doFast();
} else {
         doSlow();
}
There is no way to build the comparison within the transformation mechanism...

Yes, I can do both of these by creating an action method, and then calling 
that action method from a transformation that implements the comparison, or 
the loop, but then I am not leveraging the Transformation mechanism, and 
the nice interface to the transformations is lost.
One way of thinking about this, is that an unconditional sequential list is 
not a terribly rich language for describing the ordering of transformations

My actual problem is this problem, scaled up...  Basically I am creating 
classes as copies of other classes and transforming them (approximately 25 
individual transformations), but I don't
know what classes I want to create beforehand (it depends on input to the 
'compiler')  Furthermore, Some of the generated classes themselves need to 
be copied and transformed themselves recursively.  This can happen an 
arbitrary number of times... There is (unfortunately) no way to describe 
this using the transformation mechanism....

BTW, any outlook on the new version of soot?

Steve