Package dk.brics.xact.analysis.transformations

Source Code of dk.brics.xact.analysis.transformations.CallTransformer

package dk.brics.xact.analysis.transformations;

import java.util.LinkedList;

import dk.brics.xact.analysis.flowgraph.Edge;
import dk.brics.xact.analysis.flowgraph.FlowGraph;
import dk.brics.xact.analysis.flowgraph.Method;
import dk.brics.xact.analysis.flowgraph.Statement;
import dk.brics.xact.analysis.flowgraph.Variable;
import dk.brics.xact.analysis.flowgraph.VariableFilter;
import dk.brics.xact.analysis.flowgraph.statements.CallStm;
import dk.brics.xact.analysis.flowgraph.statements.VarStm;
import dk.brics.xact.analysis.soot.ControlFlowBuilder;
import dk.brics.xact.analysis.soot.StatementPair;

/**
* Removes all call statements and inserts assignments and interprocedural edges instead.
*/
public class CallTransformer {
  public void run(FlowGraph graph) {
    // collect all call statements first so we don't modify the node set while iterating it
    LinkedList<CallStm> calls = new LinkedList<CallStm>();
    for (Statement stm : graph.getNodes()) {
      if (stm instanceof CallStm)
        calls.add((CallStm)stm);
    }
    ControlFlowBuilder cfg = new ControlFlowBuilder(graph, null);
    // transform!
    for (CallStm call : calls) {
      Method target = call.getMethod();
      cfg.setOrigin(call.getOrigin());
      Statement start = cfg.currentStatement();
      Variable[] params = target.getParameters();
      Variable[] args = call.getArguments();
      VariableFilter paramsOnly = new VariableFilter(false, VariableFilter.Kind.CALL);
      VariableFilter argsOnly = new VariableFilter(false);
      VariableFilter notArgs = new VariableFilter(true);
      VariableFilter resultFilter = new VariableFilter(call.getResult(), VariableFilter.Kind.RETURN);
      VariableFilter returnFilter = new VariableFilter(target.getReturnVar());
      for (int i=0; i<args.length; i++) {
        paramsOnly.addVariable(params[i]);
        argsOnly.addVariable(args[i]);
        notArgs.removeVariable(args[i]);
        if (call.isArgumentMutable(i)) {
          resultFilter.addVariable(call.getArgument(i));
          returnFilter.addVariable(target.getParameter(i));
        }
      }
      cfg.addFilter(argsOnly);
      for (int i=0; i<args.length; i++) {
        cfg.addStatement(new VarStm(params[i], args[i], call.getOrigin()));
      }
      graph.addEdge(cfg.currentStatement(), target.getEntry(), paramsOnly);
      cfg.moveToStatement(target.getExit());
      cfg.addStatement(new VarStm(call.getResult(), target.getReturnVar(), call.getOrigin()), returnFilter);
      /*for (int i=0; i<args.length; i++) {
        if (call.isArgumentMutable(i)) {
          cfg.addStatement(new VarStm(call.getArgument(i), target.getParameter(i), call.getOrigin()));
        }
      }*/
      cfg.addFilter(resultFilter);
      VariableFilter notResult = new VariableFilter(true);
      notResult.removeVariable(call.getResult());
      graph.addEdge(start, cfg.currentStatement(), notResult);
      StatementPair pair = cfg.finish();
      for (Edge<Statement,VariableFilter> edge : graph.getInEdges(call)) {
        graph.addEdge(edge.getFrom(), pair.first, edge.getData());
      }
      for (Edge<Statement,VariableFilter> edge : graph.getOutEdges(call)) {
        graph.addEdge(pair.last, edge.getTo(), edge.getData());
      }
      graph.removeNode(call);
    }
  }
}
TOP

Related Classes of dk.brics.xact.analysis.transformations.CallTransformer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.