Package org.jakstab.transformation

Source Code of org.jakstab.transformation.ExpressionSubstitution

/*
* ExpressionSubstitution.java - This file is part of the Jakstab project.
* Copyright 2007-2012 Johannes Kinder <jk@jakstab.org>
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, see <http://www.gnu.org/licenses/>.
*/
package org.jakstab.transformation;

import org.jakstab.Program;
import org.jakstab.analysis.*;
import org.jakstab.analysis.substitution.ExpressionSubstitutionAnalysis;
import org.jakstab.analysis.substitution.SubstitutionElement;
import org.jakstab.analysis.substitution.SubstitutionState;
import org.jakstab.cfa.CFAEdge;
import org.jakstab.rtl.Context;
import org.jakstab.rtl.expressions.RTLVariable;
import org.jakstab.rtl.statements.RTLSkip;
import org.jakstab.rtl.statements.RTLStatement;
import org.jakstab.util.Logger;

/**
* @author Johannes Kinder
*/
public class ExpressionSubstitution implements CFATransformation {

  @SuppressWarnings("unused")
  private static final Logger logger = Logger
      .getLogger(ExpressionSubstitution.class);
 
  private Program program;
  private CPAAlgorithm cpaAlgo;
 
  public ExpressionSubstitution(Program program) {
    this.program = program;
    cpaAlgo = CPAAlgorithm.createForwardAlgorithm(program, new ExpressionSubstitutionAnalysis());
  }
 
  public static void substituteCFAEdge(CFAEdge edge, SubstitutionState s) {
    RTLStatement stmt = (RTLStatement)edge.getTransformer();
    RTLStatement newStmt = substituteStatement(stmt, s);
    if (newStmt != stmt)
      edge.setTransformer(newStmt);
  }
 
  public static RTLStatement substituteStatement(RTLStatement stmt, SubstitutionState s) {
    Context substCtx = new Context();
    for (RTLVariable v : stmt.getUsedVariables()) {
      SubstitutionElement el = s.getValue(v);
      if (!el.isTop()) {
        substCtx.addAssignment(v, el.getExpression());
      }
    }
    if (!substCtx.getAssignments().isEmpty()) {
      //logger.info("Old stmt: " + stmt);
      RTLStatement newStmt = stmt.copy().evaluate(substCtx);
      //logger.info("New stmt: " + newStmt);
      if (newStmt != null) {
        return newStmt.evaluate(new Context());
      } else {
        RTLSkip skip = new RTLSkip();
        skip.setLabel(stmt.getLabel());
        skip.setNextLabel(stmt.getNextLabel());
        return skip;
      }
    }
    return stmt;
  }

  @Override
  public void run() {
   
    logger.info("Starting expression substitution.");
    long startTime = System.currentTimeMillis();
   
    cpaAlgo.run();
    ReachedSet exprSubstStates = cpaAlgo.getReachedStates().select(1);
   
    for (CFAEdge edge : program.getCFA()) {
      assert exprSubstStates.where(edge.getSource()).size() == 1;
      SubstitutionState s = (SubstitutionState)exprSubstStates.where(edge.getSource()).iterator().next();
      substituteCFAEdge(edge, s);
    }
   
    long endTime = System.currentTimeMillis();
    logger.verbose("Finished after " + (endTime - startTime) + "ms.");
  }
 
  public void stop() {
    cpaAlgo.stop();
  }
}
TOP

Related Classes of org.jakstab.transformation.ExpressionSubstitution

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.