Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* Soot - a J*va Optimization Framework
   * Copyright (C) 1997-2000 Etienne Gagnon.  All rights reserved.
   *
   * This library 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 library 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 library; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 /*
  * Modified by the Sable Research Group and others 1997-1999.  
  * See the 'credits' file distributed with Soot for the complete list of
  * contributors.  (Soot is distributed at http://www.sable.mcgill.ca/soot)
  */
 
 
 package soot.jimple.toolkits.typing.integer;
 
 import soot.*;
 import soot.jimple.*;
 import java.util.*;
 import java.io.*;

This class resolves the type of local variables.
 
 public class TypeResolver
 {
  
All type variable instances
 
   private final List<TypeVariabletypeVariableList = new ArrayList<TypeVariable>();

  
Hashtable: [TypeNode or Local] -> TypeVariable
 
   private final Map<ObjectTypeVariabletypeVariableMap = new HashMap<ObjectTypeVariable>();
 
   private final JimpleBody stmtBody;
 
   final TypeVariable BOOLEAN = typeVariable(ClassHierarchy.v().);
   final TypeVariable BYTE = typeVariable(ClassHierarchy.v().);
   final TypeVariable SHORT = typeVariable(ClassHierarchy.v().);
   final TypeVariable CHAR = typeVariable(ClassHierarchy.v().);
   final TypeVariable INT = typeVariable(ClassHierarchy.v().);
   final TypeVariable TOP = typeVariable(ClassHierarchy.v().);
   final TypeVariable R0_1 = typeVariable(ClassHierarchy.v().);
   final TypeVariable R0_127 = typeVariable(ClassHierarchy.v().);
   final TypeVariable R0_32767 = typeVariable(ClassHierarchy.v().);
 
   private static final boolean DEBUG = false;
 
   // categories for type variables (solved = hard, unsolved = soft)
   private List<TypeVariableunsolved;
   private List<TypeVariablesolved;

  
Get type variable for the given local.
 
   {
     TypeVariable result = .get(local);
 
     if(result == null)
       {
 	int id = .size();
 
 	result = new TypeVariable(idthis);
 
 	.set(idresult);
 	.put(localresult);
 	
 	if()
 	  {
 	    G.v()..println("[LOCAL VARIABLE \"" + local + "\" -> " + id + "]");
 	  }
       }
     
     return result;
   }

  
Get type variable for the given type node.
 
   public TypeVariable typeVariable(TypeNode typeNode)
   {
     TypeVariable result = .get(typeNode);
 
     if(result == null)
       {
 	int id = .size();
 
 	result = new TypeVariable(idthistypeNode);
 
 	.set(idresult);
	.put(typeNoderesult);
      }
    return result;
  }

  
Get type variable for the given type.
  public TypeVariable typeVariable(Type type)
  {
    return typeVariable(ClassHierarchy.v().typeNode(type));
  }

  
Get new type variable
  {
    int id = .size();
    .add(null);
    
    TypeVariable result = new TypeVariable(idthis);
    
    .set(idresult);
    
    return result;
  }
  private TypeResolver(JimpleBody stmtBody)
  {
    this. = stmtBody;
  }
  public static void resolve(JimpleBody stmtBody)
  {
    if()
      {
	G.v()..println(stmtBody.getMethod());
      }
    try
      {
	TypeResolver resolver = new TypeResolver(stmtBody);
	resolver.resolve_step_1();
      }
    catch(TypeException e1)
      {
	  {
	    G.v()..println("[integer] Step 1 Exception-->" + e1.getMessage());
	  }
	try
	  {
	    TypeResolver resolver = new TypeResolver(stmtBody);
	    resolver.resolve_step_2();
	  }
	catch(TypeException e2)
	  {
              StringWriter st = new StringWriter();
	      PrintWriter pw = new PrintWriter(st);
	      e2.printStackTrace(pw);
	      pw.close();
              throw new RuntimeException(st.toString());
	  }
      }
  }
  
  private void debug_vars(String message)
  {
    if()
      {
	int count = 0;
	G.v()..println("**** START:" + message);
	for (TypeVariable var : ) {
	    G.v()..println(count++ + " " + var);
	  }
	G.v()..println("**** END:" + message);
      }
  }
  private void resolve_step_1() throws TypeException
  {
    debug_vars("constraints");
    debug_vars("components");
    debug_vars("single");
    debug_vars("assign");
    try
      {
      }
    catch(TypeException e)
      {
	  {
	    G.v()..println("[integer] Step 1(check) Exception [" + .getMethod() + "]-->" + e.getMessage());
	  }
      }
  }
  private void resolve_step_2() throws TypeException
  {
  }
  private void collect_constraints_1()
  {
    ConstraintCollector collector = new ConstraintCollector(thistrue);
    forIterator stmtIt = .getUnits().iterator(); stmtIt.hasNext(); ) {
        final Stmt stmt = (StmtstmtIt.next();
	  {
	    G.v()..print("stmt: ");
	  }
	collector.collect(stmt);
	  {
	    G.v()..println(stmt);
	  }
      }
  }
  private void collect_constraints_2()
  {
    ConstraintCollector collector = new ConstraintCollector(thisfalse);
    forIterator stmtIt = .getUnits().iterator(); stmtIt.hasNext(); ) {
        final Stmt stmt = (StmtstmtIt.next();
	  {
	    G.v()..print("stmt: ");
	  }
	collector.collect(stmt);
	  {
	    G.v()..println(stmt);
	  }
      }
  }
  private void merge_connected_components() throws TypeException
  {
    List<TypeVariablelist = new LinkedList<TypeVariable>();
    list.addAll();
    list.addAll();
    
    StronglyConnectedComponents.merge(list);
  }
  
  private void merge_single_constraints() throws TypeException
  {
    boolean modified = true;
    
    while(modified)
      {
	modified = false;
	for (TypeVariable var : ) {
	    List<TypeVariablechildren_to_remove = new LinkedList<TypeVariable>();
	    TypeNode lca = null;
	    
	    var.fixChildren();
	    
	    for (TypeVariable child : var.children()) {
	    
	        TypeNode type = child.type();
		if(type != null)
		  {
		    children_to_remove.add(child);
		    
		    if(lca == null)
		      {
			lca = type;
		      }
		    else
		      {
			lca = lca.lca_1(type);
		      }
		  }
	      }
	    
	    if(lca != null)
	      {
		  {
		    if(lca == ClassHierarchy.v().)
		      {
			G.v()..println("*** TOP *** " + var);
			for (TypeVariable typeVariable : children_to_remove) {
			    G.v()..println("-- " + typeVariable);
			  }
		      }
		  }
		for (TypeVariable child : children_to_remove) {
		    var.removeChild(child);
		  }
	      }
	    if(var.children().size() == 1)
	      {
		TypeVariable child = var.children().get(0);
		TypeNode type = child.type();
		if(type == null || type.type() != null)
		  {
		    var.union(child);
		    modified = true;
		  }
	      }
	  }
      
	if(!modified)
	  {
	    for (TypeVariable var : ) {
	        List<TypeVariableparents_to_remove = new LinkedList<TypeVariable>();
		TypeNode gcd = null;
		for (TypeVariable parent : var.parents()) {
		    TypeNode type = parent.type();
		    
		    if(type != null)
		      {
			parents_to_remove.add(parent);
			if(gcd == null)
			  {
			    gcd = type;
			  }
			else
			  {
			    gcd = gcd.gcd_1(type);
			  }
		      }
		  }
		if(gcd != null)
		  {
		    for (TypeVariable parent : parents_to_remove) {
		        var.removeParent(parent);
		      }
		    
		    var.addParent(typeVariable(gcd));
		  }
		if(var.parents().size() == 1)
		  {
		    TypeVariable parent = var.parents().get(0);
		    TypeNode type = parent.type();
		    
		    if(type == null || type.type() != null)
		      {
			var.union(parent);
			modified = true;
		      }
		  }
	      }
	  }
	if(!modified)
	  {
	    for (TypeVariable var : ) {
	        if(var.type() == null && var.inv_approx() != null && var.inv_approx().type() != null)
		  {
		    if()
		      {
			G.v()..println("*** I->" + var.inv_approx().type() + " *** " + var);
		      }
		    
		    var.union(typeVariable(var.inv_approx()));
		    modified = true;
		  }
	      }
	  }
	if(!modified)
	  {
	    for (TypeVariable var : ) {
	        if(var.type() == null && var.approx() != null && var.approx().type() != null)
		  {
		    if()
		      {
			G.v()..println("*** A->" + var.approx().type() + " *** " + var);
		      }
		    
		    var.union(typeVariable(var.approx()));
		    modified = true;
		  }
	      }
	  }
	if(!modified)
	  {
	    for (TypeVariable var : ) {
	        if(var.type() == null && var.approx() == ClassHierarchy.v().)
		  {
		    if()
		      {
			G.v()..println("*** R->SHORT *** " + var);
		      }
		    
		    var.union();
		    modified = true;
		  }
	      }
	  }
	if(!modified)
	  {
	    for (TypeVariable var : ) {
	        if(var.type() == null && var.approx() == ClassHierarchy.v().)
		  {
		    if()
		      {
			G.v()..println("*** R->BYTE *** " + var);
		      }
		    
		    var.union();
		    modified = true;
		  }
	      }
	  }
	if(!modified)
	  {
	    for (TypeVariable var : .parents()) {
	        if(var.type() == null && var.approx() == ClassHierarchy.v().)
		  {
		    if()
		      {
			G.v()..println("*** R->BOOLEAN *** " + var);
		      }
		    var.union();
		    modified = true;
		  }
	      }
	  }
      }
  }
  private void assign_types_1() throws TypeException
  {
    forIterator localIt = .getLocals().iterator(); localIt.hasNext(); ) {
        final Local local = (LocallocalIt.next();
	if(local.getType() instanceof IntegerType)
	  {
	    TypeVariable var = typeVariable(local);
	    
	    if(var.type() == null || var.type().type() == null)
	      {
		TypeVariable.error("Type Error(21):  Variable without type");
	      }
	    else
	      {
		local.setType(var.type().type());
	      }
	    
	    if()
	      {
		if((var != null) &&
		   (var.approx() != null) &&
		   (var.approx().type() != null) &&
		   (local != null) &&
		   (local.getType() != null) &&
		   !local.getType().equals(var.approx().type()))
		  {
		    G.v()..println("local: " + local + ", type: " + local.getType() + ", approx: " + var.approx().type());
		  }
	      }
	  }
      }
  }
  
  private void assign_types_2() throws TypeException
  {
    forIterator localIt = .getLocals().iterator(); localIt.hasNext(); ) {
        final Local local = (LocallocalIt.next();
	if(local.getType() instanceof IntegerType)
	  {
	    TypeVariable var = typeVariable(local);
	    
	    if(var.inv_approx() != null && var.inv_approx().type() != null)
	      {
		local.setType(var.inv_approx().type());
	      }
	    else if(var.approx().type() != null)
	      {
		local.setType(var.approx().type());
	      }
	    else if(var.approx() == ClassHierarchy.v().)
	      {
		local.setType(BooleanType.v());
	      }
	    else if(var.approx() == ClassHierarchy.v().)
	      {
		local.setType(ByteType.v());
	      }
	    else
	      {
		local.setType(ShortType.v());
	      }
	  }
      }
  }
  private void check_constraints() throws TypeException
  {
    ConstraintChecker checker = new ConstraintChecker(thisfalse);
    StringBuffer s = null;
    if()
      {
	s = new StringBuffer("Checking:\n");
      }
    forIterator stmtIt = .getUnits().iterator(); stmtIt.hasNext(); ) {
        final Stmt stmt = (StmtstmtIt.next();
	  {
	    s.append(" " + stmt + "\n");
	  }
	try
	  {
	    checker.check(stmt);
	  }
	catch(TypeException e)
	  {
	    if()
	      {
		G.v()..println(s);
	      }
	    throw e;
	  }
      }
  }
  private void check_and_fix_constraints() throws TypeException
  {
    ConstraintChecker checker = new ConstraintChecker(thistrue);
    StringBuffer s = null;
    PatchingChain units = .getUnits();
    Stmt[] stmts = new Stmt[units.size()];
    units.toArray(stmts);
    if()
      {
	s = new StringBuffer("Checking:\n");
      }
    for (Stmt stmt : stmts) {
	  {
	    s.append(" " + stmt + "\n");
	  }
	try
	  {
	    checker.check(stmt);
	  }
	catch(TypeException e)
	  {
	    if()
	      {
		G.v()..println(s);
	      }
	    throw e;
	  }
      }
  }
  private void compute_approximate_types() throws TypeException
  {
    TreeSet<TypeVariableworkList = new TreeSet<TypeVariable>();
    for (TypeVariable var : ) {
        if(var.type() != null)
	  {
	    workList.add(var);
	  }
      }
    TypeVariable.computeApprox(workList);
    workList = new TreeSet<TypeVariable>();
    for (TypeVariable var : ) {
        if(var.type() != null)
	  {
	    workList.add(var);
	  }
      }
    TypeVariable.computeInvApprox(workList);
    for (TypeVariable var : ) {
        if (var.approx() == null)
	  {
	    var.union();
	  }
      }
  }
  
  private void compute_solved()
  {
    Set<TypeVariableunsolved_set = new TreeSet<TypeVariable>();
    Set<TypeVariablesolved_set = new TreeSet<TypeVariable>();
    
    for (TypeVariable var : ) {
    
        if(var.type() == null)
	  {
	    unsolved_set.add(var);
	  }
	else
	  {
	    solved_set.add(var);
	  }
      }
    
     = new LinkedList<TypeVariable>(solved_set);
     = new LinkedList<TypeVariable>(unsolved_set);
  }
  private void refresh_solved() throws TypeException
  {
    Set<TypeVariableunsolved_set = new TreeSet<TypeVariable>();
    Set<TypeVariablesolved_set = new TreeSet<TypeVariable>();
    
    for (TypeVariable var : ) {
    
        if(var.type() == null)
	  {
	    unsolved_set.add(var);
	  }
	else
	  {
	    solved_set.add(var);
	  }
      }
    
     = new LinkedList<TypeVariable>(solved_set);
     = new LinkedList<TypeVariable>(unsolved_set);
  }
New to GrepCode? Check out our FAQ X