Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

MethodVariant.java

00001 package edu.ksu.cis.bandera.bofa;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1998, 1999                                          *
00006  * John Hatcliff (hatcliff@cis.ksu.edu)
00007  * All rights reserved.                                              *
00008  *                                                                   *
00009  * This work was done as a project in the SAnToS Laboratory,         *
00010  * Department of Computing and Information Sciences, Kansas State    *
00011  * University, USA (http://www.cis.ksu.edu/santos).                  *
00012  * It is understood that any modification not identified as such is  *
00013  * not covered by the preceding statement.                           *
00014  *                                                                   *
00015  * This work is free software; you can redistribute it and/or        *
00016  * modify it under the terms of the GNU Library General Public       *
00017  * License as published by the Free Software Foundation; either      *
00018  * version 2 of the License, or (at your option) any later version.  *
00019  *                                                                   *
00020  * This work is distributed in the hope that it will be useful,      *
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00023  * Library General Public License for more details.                  *
00024  *                                                                   *
00025  * You should have received a copy of the GNU Library General Public *
00026  * License along with this toolkit; if not, write to the             *
00027  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00028  * Boston, MA  02111-1307, USA.                                      *
00029  *                                                                   *
00030  * Java is a trademark of Sun Microsystems, Inc.                     *
00031  *                                                                   *
00032  * To submit a bug report, send a comment, or get the latest news on *
00033  * this project and other SAnToS projects, please visit the web-site *
00034  *                http://www.cis.ksu.edu/santos                      *
00035  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00036 
00037 import ca.mcgill.sable.soot.*;
00038 import ca.mcgill.sable.soot.jimple.*;
00039 import ca.mcgill.sable.util.*;
00040 import org.apache.log4j.Category;
00041 
00042 /* 
00043  * MethodVariant.java 
00044  * $Id: MethodVariant.java,v 1.1.1.1 2002/01/24 03:42:08 pserver Exp $
00045  */
00046 
00047 /**
00048  * This class represents a variant of a method.
00049  *
00050  * @author <A HREF="http://www.cis.ksu.edu/~hatcliff">John Hatcliff</A>
00051  * @author 
00052  * <a href="http://www.cis.ksu.edu/~rvprasad">Venkatesh Prasad Ranganath</a>
00053  * @version $Name:  $($Revision: 1.1.1.1 $)
00054  */
00055 public class MethodVariant
00056 {
00057     /** 
00058      * The method represented by this object.
00059      */
00060     private SootMethod  sootMethod;         
00061 
00062     /** 
00063      * The index associated with this object.
00064      */
00065     private Index methodIndex;              
00066 
00067     /** 
00068      *The flow graph nodes corresponding to the parameters of the method. 
00069      */
00070     private FGNodeParameter[] parameterNodes;
00071 
00072     /** 
00073      * The flow graph nodes correpsonding to the local variables in the
00074      * method. */ 
00075     private Map localNodes;                  
00076 
00077     /** 
00078      * The flow graph nodes corresponding to the AST nodes occuring in the
00079      * method. */ 
00080     private Map ASTNodes; 
00081 
00082     /** 
00083      * The flow graph node corresponding to the return point of the method. 
00084      */ 
00085     private FGNodeAST returnNode;
00086 
00087     /** 
00088      * The flow graph node corresponding to the "this" variable of the method. 
00089      */
00090     private FGNodeThis thisNode;             
00091 
00092     /** 
00093      * FGStmt object used to extend the flow graph for this variant. 
00094      */
00095     private FGStmt fgStmt;
00096 
00097     /**
00098      * Provides logging capability through log4j.
00099      *
00100      */
00101     private static Category cat = 
00102         Category.getInstance(MethodVariant.class.getName()); 
00103 
00104     /**
00105      * Constructor of the class.
00106      * 
00107      * @param sootMethod the method represented by this variant.
00108      * @param methodIndex the index associated with this variant. 
00109      */
00110     public MethodVariant(SootMethod sootMethod, Index methodIndex)
00111     {
00112         this.sootMethod  = sootMethod;
00113         this.methodIndex = methodIndex;
00114         this.returnNode  = new FGNodeAST((Object)null); 
00115         this.thisNode    = new FGNodeThis(this);
00116         this.ASTNodes    = new HashMap();
00117         Local local;
00118         JimpleBody body;
00119         StmtList   stmts;
00120 
00121         // Create set variables for each parameter. 
00122         // Hold in an array indexed by parameter number
00123         int num_parameters = sootMethod.getParameterCount();
00124         parameterNodes     = new FGNodeParameter[num_parameters];
00125 
00126         for (int j=0;j<num_parameters;j++) {
00127             parameterNodes[j] = new FGNodeParameter(j, this);
00128         }
00129 
00130         localNodes = new HashMap();
00131         /* generates graph for each statement */
00132         fgStmt = new FGStmt(this, ASTNodes);
00133         try {
00134             body  = (JimpleBody) sootMethod.getBody(Jimple.v());
00135             stmts = body.getStmtList();
00136         } catch (RuntimeException e) {
00137             cat.info("Exception occurred while processing " + sootMethod + ": "
00138                      + e.getMessage());
00139             /* 
00140              * External methods will not have body to be compiled and hence an
00141              * exception will be raised.  In such a situation we will insert an
00142              * emptyiness and it will act as a sink for all values flowing in.
00143              * Also, if the return type is not void a value of a particular type
00144              * but unknown expression and statement needs to be plugged in.
00145              */
00146             if (false) { // !sootMethod.getReturnType().equals(VoidType.v())) {
00147                 ValueVariant valueVariant = 
00148                     ValueVariantManager.select(ClassTokenSimple.unknownClassToken,
00149                                                this, null, null);
00150                 FGNode externalNode = new FGNode();  
00151                 FGNode.makeArc(externalNode, returnNode);
00152                 FGWork work = new FGWorkSendVals(new FASet(valueVariant), 
00153                                                  externalNode); 
00154                 FA.workList.insert(work);
00155             } // end of if (!sootMethod.getReturnType().equals(VoidType.v()))
00156             return;
00157         }
00158 
00159         // Create a set of variables for each local held in a hashMap.
00160         for(Iterator i = body.getLocals().iterator(); i.hasNext();) {
00161             local = (Local) i.next();
00162             // Assume that we only have non-static locals.  Can there be
00163             // static locals in Jimple?
00164             localNodes.put(local, new FGNodeLocal(local));
00165         }
00166 
00167         //Venkatesh's original code
00168         /*
00169         for (int i=0; i<stmts.size(); i++)
00170             fgStmt.build((Stmt) stmts.get(i));
00171             */
00172         // robbyjo's patch begin
00173             for (int i=0; i<stmts.size(); i++)
00174             {
00175                 // System.out.println("Stmt #"+i+": "+stmts.get(i));
00176 
00177                 // If one statement dies, don't let it affect others
00178                 // to create ripple effect.
00179 //              try {
00180                     fgStmt.build((Stmt) stmts.get(i));
00181 /*              } catch (Exception e)
00182                 {
00183                     System.out.println("WAUUUGGH! I'm dead!");
00184                     System.out.println("The statement #"+i+" was: "+stmts.get(i));
00185                     if (e != null)
00186                     {
00187                         System.out.println("The exception was: "+e.getMessage());
00188                         System.out.println("The stack trace was:");
00189                         e.printStackTrace();
00190                     }
00191                 }*/
00192             }
00193             // robbyjo's patch end
00194                 
00195     }
00196     /**
00197      * Provides the flow graph node associated with the AST node.
00198      *
00199      * @param obj the AST node corresponding to which the flow graph node is
00200      * required. 
00201      * @return the flow graph node associated with the AST node. 
00202      */
00203     FGNodeAST getASTNode(Object obj)
00204     {
00205         return (FGNodeAST) ASTNodes.get(obj);
00206     }
00207     /**
00208      * Provides a collection of flow graph nodes associated with all AST nodes
00209      * in the method.
00210      *
00211      * @return the collection of flow graph nodes associated with all AST nodes
00212      * in the method. 
00213      */ 
00214     Collection getASTNodes()
00215     {
00216         return ASTNodes.values();
00217     }
00218     /**
00219      * Assumptions: obj must be a valid reference to Jimple expression 
00220      * within the current method.
00221      */
00222 
00223     /**
00224      * Provide the set of FG nodes associated with the given AST node.
00225      * @param obj the AST node corresonding to which the FG nodes are required.
00226      * @return the set of FG nodes assocaited with the given AST node. 
00227      */
00228     public Set getASTValues(Object obj)
00229     {
00230         if (ASTNodes.containsKey(obj)) {
00231             return getASTNode(obj).getValues();
00232         } else {
00233             /* 
00234              * if Node is not found in the ASTNode table and we assume that obj
00235              * is a valid reference, this means that the expression referenced
00236              * by obj has not been included in the flow graph because it doesn't
00237              * give rise to any objects (e.g., it is an expression of base
00238              * type).  Thus, we return an empty set.
00239              */
00240             return new HashSet();
00241         }
00242     }
00243     /**
00244      * Provides the flow graph node associated with the local variable.
00245      *
00246      * @param local the local variable corresponding to which the flow graph
00247      * node is required.
00248      * @return the flow graph node associated with the local variable. 
00249      */
00250     FGNodeLocal getLocalNode(Local local)
00251     {
00252         return (FGNodeLocal) localNodes.get(local);
00253     }
00254     /**
00255      * Provide a collection of flow graph nodes associated with all local
00256      * variables.  
00257      * 
00258      * @return the collection of flow graph nodes associated with all local
00259      * variables. 
00260      */
00261     Map getLocalNodes()
00262     {
00263         return localNodes;
00264     }
00265     /**
00266      * Provides the set of values flowing into the provided local variable.
00267      * @param local a <code>Local</code> value
00268      * @return set of values flowing into the given local variable.
00269      */
00270     public Set getLocalValues(Local local)
00271     {
00272         return getLocalNode(local).getValues();
00273     }
00274     /* The following methods have public access.  They form the interface for
00275      *  clients outside of the FA package.  These clients should never need to
00276      *  know the structure of the flow graph nor the representation for
00277      *  flowgraph nodes.  Typically, the clients should only be looking up the
00278      *  results of the flow analysis, i.e., that should only be fetching the set
00279      *  of value variants for a particular construct.
00280      
00281      *   The methods for an interface for callers within the FA package follows
00282      *   the public interface.  */
00283 
00284     /**
00285      * Provides the method being represented.
00286      *
00287      * @return the represented method. 
00288      */  
00289     public SootMethod getMethod()
00290     {
00291         return sootMethod;
00292     }
00293     /**
00294      * Provides the associated index.
00295      *
00296      * @return the associated index. 
00297      */
00298     public Index getMethodIndex()
00299     {
00300         return methodIndex;
00301     }
00302     /**
00303      * Returns the FGNode for the n'th paramter (0-based indexing)
00304      *
00305      * @param n the parameter number.
00306      * @return the flow graph node describing the nth parameter.
00307      */
00308     FGNodeParameter getParameterNode(int n)
00309     {
00310         if (n < sootMethod.getParameterCount()) {
00311             return parameterNodes[n];
00312         } else {
00313             throw new RuntimeException("Parameter count exceeded:  " + 
00314                                        sootMethod.getName() + "  Param#: " + n);
00315         }
00316     }
00317     /**
00318      * Provide a collection of flow graph nodes associated with all the
00319      * parameters.  
00320      * 
00321      * @return the array of flow graph nodes associated with all the
00322      * parameters. 
00323      */ 
00324     FGNodeParameter[] getParameterNodes()
00325     {
00326         return parameterNodes;
00327     }
00328     /**
00329      * Provides the set of values flowing into the nth parameter of the method.
00330      * @param n an <code>int</code> value
00331      * @return set of values flowing into the given parameter.
00332      */
00333     public Set getParameterValues(int n)
00334     {
00335         return getParameterNode(n).getValues();
00336     }
00337     /**
00338      * Provides the flow graph node associated with the return value of the
00339      * method.
00340      *
00341      * @return the flow graph node associated with the return value of the
00342      * method. 
00343      */ 
00344     FGNode getReturnNode()
00345     {
00346         return returnNode;
00347     }
00348     /** 
00349      * Provides the set of values flowing returned by the method.
00350      * @return set of values flowing returned by the method. 
00351      */
00352     public Set getReturnValues()
00353     {
00354         return getReturnNode().getValues();
00355     }
00356     /**
00357      * Provides the flow graph node associated with "this" variable.
00358      *
00359      * @return the flow graph node associated with "this" variable. 
00360      */
00361     FGNodeThis getThisNode()
00362     {
00363         return thisNode;
00364     }
00365     /** 
00366      * Provides the set of values flowing into "this" variable.
00367      * @return set of values flowing into "this" variable. 
00368      */
00369     public Set getThisValues()
00370     {
00371         return getThisNode().getValues();
00372     }
00373 }

Generated at Thu Feb 7 06:50:29 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001