Package dk.brics.xact.analysis.soot

Examples of dk.brics.xact.analysis.soot.ControlFlowBuilder


  /**
   * Transforms the given flow graph.
   */
  public void run(final FlowGraph graph) {
    final ControlFlowBuilder cfg = new ControlFlowBuilder(graph, null);
    final UnionFindForest<Variable,Component> var_alias = new UnionFindForest<Variable, Component>() {
      @Override
      protected Component mergeNodeData(Component a, Component b) {
        a.array |= b.array;
        a.escaped |= b.escaped;
        a.stringsrc = a.stringsrc.union(b.stringsrc);
        return a;
      }
      @Override
      protected Component defaultNodeData() {
        return new Component();
      }
    };
    for (Statement s : graph.getNodes()) {
      s.visitBy(new BasicStatementVisitor() {
        @Override
        public void visitEmptyStm(EmptyStm s) {
          if (s.isArray()) {
            var_alias.getData(s.getDest()).array = true;
          }
        }
        @Override
        public void visitEscapeStm(EscapeStm s) {
          var_alias.getData(s.getVar()).escaped = true;
        }
        @Override
        public void visitUnknownStm(UnknownStm s) {
          var_alias.getData(s.getDest()).escaped = true;
        }
        @Override
        public void visitArrayWriteStringStm(ArrayWriteStringStm s) {
          Component c = var_alias.getData(s.getDest());
          c.stringsrc = c.stringsrc.union(s.getStringsrc());
        }
        @Override
        public void visitArrayReadStm(ArrayReadStm s) {
          var_alias.getData(s.getSource()).array = true;
        }
        @Override
        public void visitArrayWriteStm(ArrayWriteStm s) {
          var_alias.getData(s.getDest()).array = true;
        }
        @Override
        public void visitConcatStm(ConcatStm s) {
          var_alias.getData(s.getXMLSource()).array = true;
        }
        @Override
        public void visitPlugStm(PlugStm s) {
          if (s.getKind() == PlugStm.Kind.PLUGMULTI || s.getKind() == PlugStm.Kind.PLUGWRAP)
            var_alias.getData(s.getXMLSource()).array = true;
        }
        @Override
        public void visitVarStm(VarStm s) {
          var_alias.merge(s.getSource(), s.getDest());
        }
      });
    }
    for (Statement s : new LinkedHashSet<Statement>(graph.getNodes())) {
      if (s instanceof Assignment) {
        if (var_alias.getData(((Assignment) s).getDest()).array) {
          NopStm nop = new NopStm(s.getOrigin());
          graph.addNode(nop);
          for (Edge<Statement,VariableFilter> e : graph.getInEdges(s)) {
            graph.addEdge(e.getFrom(), nop, e.getData());
          }
          for (Edge<Statement,VariableFilter> e : graph.getOutEdges(s)) {
            graph.addEdge(nop, e.getTo(), e.getData());
          }
        }
      }
      s.visitBy(new BasicStatementVisitor() {
        private void replace(Statement old, StatementPair st) {
          replaceNode(graph, old, st);
        }

        @Override
        public void visitArrayWriteStringStm(ArrayWriteStringStm s) {
          replace(s, cfg.finish()); // replace the statement with a nop
        }
        @Override
        public void visitArrayReadStm(ArrayReadStm s) {
          // merge arrays if one array is stored in the other
          if (var_alias.getData(s.getDest()).array) {
            var_alias.merge(s.getSource(), s.getDest());
          }
          cfg.addStatement(new VarStm(s.getDest(), s.getSource(), s.getOrigin()));
          replace(s, cfg.finish());
        }
        @Override
        public void visitArrayWriteStm(ArrayWriteStm s) {
          // merge arrays if one array is stored in the other
          if (var_alias.getData(s.getSource()).array) {
            var_alias.merge(s.getSource(), s.getDest());
          }
          cfg.addStatement(new VarStm(s.getDest(), s.getSource(), s.getOrigin()));
          replace(s, cfg.finish());
        }
        @Override
        public void visitCallStm(CallStm s) {
          for (int i=0; i<s.getArguments().length; i++) {
            // merge argument and parameter if either one is used as an array
            Variable arg = s.getArgument(i);
            Variable param = s.getMethod().getParameter(i);
            if (var_alias.getData(arg).array || var_alias.getData(param).array) {
              var_alias.merge(arg, param);
              s.setArgumentMutable(i, true);
            }
          }
          // merge return var and result if ether one is used as an array
          if (var_alias.getData(s.getResult()).array || var_alias.getData(s.getMethod().getReturnVar()).array) {
            var_alias.merge(s.getResult(), s.getMethod().getReturnVar());
          }
        }
        @Override
        public void visitEscapeStm(EscapeStm s) {
          Component c = var_alias.getData(s.getVar());
          if (c.array) {
            cfg.addStatement(new UnknownStm(s.getVar(), s.getOrigin()));
            replace(s, cfg.finish());
          } else {
            cfg.setOrigin(s.getOrigin());
            replace(s, cfg.finish());
          }
        }
      });
    }
    // replace each variable by its component representative IF the representative is an array
View Full Code Here


    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());
View Full Code Here

TOP

Related Classes of dk.brics.xact.analysis.soot.ControlFlowBuilder

Copyright © 2018 www.massapicom. 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.