/*
* This is a prototype implementation of the concept of Feature-Sen
* sitive Dataflow Analysis. More details in the AOSD'12 paper:
* Dataflow Analysis for Software Product Lines
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package br;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import soot.ArrayType;
import soot.Local;
import soot.Modifier;
import soot.RefType;
import soot.Scene;
import soot.SootClass;
import soot.SootMethod;
import soot.SourceLocator;
import soot.Type;
import soot.Unit;
import soot.VoidType;
import soot.jimple.JasminClass;
import soot.jimple.Jimple;
import soot.jimple.JimpleBody;
import soot.jimple.StringConstant;
import soot.options.Options;
import soot.toolkits.graph.BriefUnitGraph;
import soot.toolkits.graph.UnitGraph;
import soot.toolkits.scalar.InitAnalysis;
import soot.toolkits.scalar.SimpleLiveLocals;
import soot.toolkits.scalar.SimpleLocalDefs;
import soot.toolkits.scalar.SimpleLocalUses;
import soot.util.Chain;
import soot.util.JasminOutputStream;
public class Main {
// #ifdef CACHEPURGE
//@ private static long[] wasteOfSpace = new long[131072]; // 131072*64 bits =
//@ // 8388608 bits =
//@ // 8MB
//@ private static Random rdm = new Random();
//@ private static long acc = 0;
//@
//@ static {
//@ for (int index = 0; index < wasteOfSpace.length; index++) {
//@ wasteOfSpace[index] = rdm.nextLong();
//@ }
//@ }
//@
//@ public static long randomLong() {
//@ return wasteOfSpace[rdm.nextInt(wasteOfSpace.length)];
//@ }
//@
// #endif
public static void main(String[] args) throws IOException {
Options.v().set_whole_program(true);
Options.v().set_verbose(false);
Scene scene = Scene.v();
SootClass sClass;
SootMethod method;
// Carregar depend�ncias e a raiz Object
SootClass objClass = scene.loadClassAndSupport("java.lang.Object");
scene.loadClassAndSupport("java.lang.System");
// Declarar a classe como public
sClass = new SootClass("HelloWorld", Modifier.PUBLIC);
/*
* � obrigat�rio definir a superclasse, pois quando ela n�o � definida,
* o compilador se encarrega de faz�-lo, mas nesse caso � obrigat�rio
* explicit�-la.
*/
sClass.setSuperclass(Scene.v().getSootClass("java.lang.Object"));
scene.addClass(sClass);
/*
* Criar a assinatura do m�todo(nome, par�metros e retorno):
*
* public static void main(String[])
*
* o corpo ser� definido mais abaixo
*/
method = new SootMethod("main", Arrays.asList(new Type[] { ArrayType.v(
RefType.v("java.lang.String"), 1) }), VoidType.v(),
Modifier.PUBLIC | Modifier.STATIC);
sClass.addMethod(method);
// Este bloco � utilizado para definir o corpo do m�todo
{
// Um Body s� deve ser instanciado relacionando-o diretamente a uma
// IR
JimpleBody body = Jimple.v().newBody(method);
method.setActiveBody(body);
Chain<Local> locals = body.getLocals();
Chain<Unit> units = body.getUnits();
Local arg, tmpRef;
// Add some locals, java.lang.String l0
arg = Jimple.v().newLocal("l0",
ArrayType.v(RefType.v("java.lang.String"), 1));
locals.add(arg);
// Add locals, java.io.printStream tmpRef
tmpRef = Jimple.v().newLocal("tmpRef",
RefType.v("java.io.PrintStream"));
locals.add(tmpRef);
// add "l0 = @parameter0"
units.add(Jimple.v().newIdentityStmt(
arg,
Jimple.v().newParameterRef(
ArrayType.v(RefType.v("java.lang.String"), 1), 0)));
// add "tmpRef = java.lang.System.out"
Unit tmpRefAssignUnit = Jimple
.v()
.newAssignStmt(
tmpRef,
Jimple
.v()
.newStaticFieldRef(
Scene
.v()
.getField(
"<java.lang.System: java.io.PrintStream out>")
.makeRef()));
units.add(tmpRefAssignUnit);
// insert "tmpRef.println("Hello world!")"
{
SootMethod toCall = Scene
.v()
.getMethod(
"<java.io.PrintStream: void println(java.lang.String)>");
units.add(Jimple.v().newInvokeStmt(
Jimple.v().newVirtualInvokeExpr(tmpRef,
toCall.makeRef(),
StringConstant.v("Hello world!"))));
}
// insert "return"
units.add(Jimple.v().newReturnVoidStmt());
{
UnitGraph unitGraph = new BriefUnitGraph(body);
SimpleLocalDefs localDefs = new SimpleLocalDefs(unitGraph);
SimpleLocalUses localUses = new SimpleLocalUses(unitGraph,
localDefs);
List localUsesOfTmpRefValueBoxPair = localUses
.getUsesOf(tmpRefAssignUnit);
SimpleLiveLocals liveLocals = new SimpleLiveLocals(unitGraph);
List liveLocalsBefore = liveLocals
.getLiveLocalsAfter(tmpRefAssignUnit);
scene.setMainClass(sClass);
scene.loadNecessaryClasses();
InitAnalysis init = new InitAnalysis(unitGraph);
for (Unit unit : units) {
System.out.println(init.getFlowAfter(unit));
}
// CHATransformer.v().transform();
// CallGraph cg = Scene.v().getCallGraph();
// ReachingDefs reachingDefs = new ReachingDefs(unitGraph);
// System.out.println(reachingDefs);
}
}
// String fileName = SourceLocator.v().getFileNameFor(sClass,
// Options.output_format_class);
String fileName = SourceLocator.v().getSourceForClass(sClass.getName());
System.out.println(fileName);
OutputStream streamOut = new JasminOutputStream(new FileOutputStream(
fileName));
PrintWriter writerOut = new PrintWriter(new OutputStreamWriter(
streamOut));
JasminClass jasminClass = new soot.jimple.JasminClass(sClass);
jasminClass.print(writerOut);
writerOut.flush();
streamOut.close();
}
// #ifdef CACHEPURGE
//@ public static void waste() {
//@ // reads cells from the useless array and do some useless calculations
//@ long acc = 0;
//@ boolean bool = rdm.nextBoolean();
//@ for (int i = 0; i < wasteOfSpace.length; i++) {
//@ if (bool) {
//@ bool = !bool;
//@ acc += wasteOfSpace[i];
//@ } else {
//@ bool = !bool;
//@ acc -= wasteOfSpace[i];
//@ }
//@ }
//@ Main.acc = acc;
//@ }
// #endif
}