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

FGActionInvoke.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 
00041 import org.apache.log4j.Category;
00042 
00043 /*
00044  * FGActionInvoke.java
00045  *
00046  * $Id: FGActionInvoke.java,v 1.1.1.1 2002/01/24 03:42:07 pserver Exp $
00047  */
00048 
00049 /*
00050  * Open questions:
00051  * - what is the appropriate time place for the flowgraph to be
00052  * generated for the body of the method.  Currently in the 
00053  * driver and FA classes, it seems like the nodes for the body of a method
00054  * are already created before this action is invoked.
00055  * 
00056  * - what happens when we have multiple value variants that map to the
00057  * same method variants (e.g., two different value variants of the
00058  * same class but allocated at different positions)?
00059  *
00060  */
00061 
00062 /**
00063  * This class describes the action to be taken when new values arrive at the
00064  * method position of a method invocation AST node.
00065  *
00066  * @author <A HREF="http://www.cis.ksu.edu/~hatcliff">John Hatcliff</A>
00067  * @author 
00068  * <a href="http://www.ci.ksu.edu/~rvprasad">Venkatesh Prasad Ranganath</a>
00069  * @version $Revision: 1.1.1.1 $
00070  */
00071 public class FGActionInvoke implements FGAction
00072 {
00073     /** 
00074      * Number of arguments to the method 
00075      */
00076     private int      argCount; 
00077 
00078     /** 
00079      * Array of FGNodes corresponding to the argument ASTs 
00080      */
00081     private FGNode[] argNodes;
00082 
00083     /** 
00084      * FGNode for the invocation AST 
00085      */
00086     private FGNode   invokeNode;
00087 
00088     /** 
00089      * Name of the method 
00090      */
00091     private String   methodName;       
00092 
00093     /** 
00094      * Types of the parameters provided to the method 
00095      */
00096     private List     parameterTypes;       
00097 
00098     /** 
00099      * Return type of the method 
00100      */
00101     private Type     returnType; 
00102 
00103     /** 
00104      * Set of method variants that have been hooked into the flow graph for this
00105      * node.
00106      */
00107     private Set      installedMethodVariants;
00108 
00109     /** 
00110      * The class from which the method needs to be hooked into the flow graph.
00111      * This is required for constructor calls. 
00112      */
00113     private SootClass sc;
00114 
00115     /**
00116      * Provides logging capabilities through log4j.
00117      *
00118      */
00119     private static Category cat;
00120 
00121     static {
00122         cat = Category.getInstance(FGActionInvoke.class.getName());
00123     }
00124 
00125     /** 
00126      * Constructor of the class.
00127      * 
00128      * @param argCount number of arguments to the invoked method.
00129      * @param argNodes the nodes corresponding to the arguments.
00130      * @param invokeNode the node corresponding to the invocation AST.  This
00131      * will also be the node which provides the return value of the method
00132      * during flow analysis.
00133      * @param methodName the name of the invoked method.
00134      * @param parameterTypes the types of the parameter provided to the method.
00135      * @param returnType the type of the return value.
00136      */
00137     public FGActionInvoke(int      argCount,
00138                           FGNode[] argNodes, 
00139                           FGNode   invokeNode,
00140                           String   methodName,
00141                           List     parameterTypes,
00142                           Type     returnType)
00143     {
00144         this.argCount      = argCount;
00145         this.argNodes      = argNodes;
00146         this.invokeNode    = invokeNode;
00147         this.methodName    = methodName;
00148         this.parameterTypes = parameterTypes;
00149         this.returnType    = returnType;
00150         this.installedMethodVariants = new HashSet();
00151     }
00152     /** 
00153      * Constructor of the class to be used when SpecialInvokeExpr is being
00154      * handled. 
00155      * 
00156      * @param argCount number of arguments to the invoked method.
00157      * @param argNodes the nodes corresponding to the arguments.
00158      * @param invokeNode the node corresponding to the invocation AST.This
00159      * will also be the node which provides the return value of the method during
00160      * flow analysis. This will not have any use as constructors do not return
00161      * values. 
00162      * @param methodName the name of the invoked method.
00163      * @param parameterTypes the types of the parameter provided to the method.
00164      * @param returnType the type of the return value.
00165      * @param sootClass the class to which the method body belongs during
00166      * invocation. 
00167      */
00168     public FGActionInvoke(int      argCount,
00169                           FGNode[] argNodes, 
00170                           FGNode   invokeNode,
00171                           String   methodName,
00172                           List     parameterTypes,
00173                           Type     returnType,
00174                           SootClass sootClass)
00175     {
00176         this.sc = sootClass;
00177         this.argCount      = argCount;
00178         this.argNodes      = argNodes;
00179         this.invokeNode    = invokeNode;
00180         this.methodName    = methodName;
00181         this.parameterTypes = parameterTypes;
00182         this.returnType    = returnType;
00183         this.installedMethodVariants = new HashSet();
00184     }
00185     /**
00186      * 
00187      * 
00188      * @param values the set of new values that arrived at the node to
00189      *        to which this action is attached.
00190      */
00191     public void doAction(FASet values)
00192     {
00193         ClassToken classToken;
00194         SootClass  sootClass;   // class of a particular value variant
00195         
00196         /* the declaring method for a particular value variant */
00197         SootMethod sootMethod;  
00198 
00199         /* the selected method variant for the * given base class and method
00200            signature. */
00201         MethodVariant methodVariant; 
00202       
00203         /* Iterate through the given set of value variants */
00204         for(Iterator i = values.iterator(); i.hasNext();) {
00205             ValueVariant valueVariant = (ValueVariant) i.next();
00206 
00207             /* valueVariant is a new variant for this site, so...
00208                Scan class hierarchy (starting from class of value
00209                variant) to find the appropriate declaring class for this
00210                method, and call the Method Variant Manager to select
00211                the appropriate variant.
00212 
00213                If the method variant is not already installed here, 
00214                - hook the code for the method into the flow graph. This
00215                involves connecting the argument nodes to parameter nodes,
00216                connecting the method outflow node ('last' node) to
00217                the node for the AST of the invoke.
00218                - generate work to move ALL values
00219                at the argument Nodes along to parameter nodes
00220                - push current value variant to 'this' parameter.
00221                If the method is already installed (i.e., already hooked
00222                into the flowgraph), then argument nodes and return
00223                points are already connected.  We only ...
00224                - push current value variant to 'this' parameter.
00225             */
00226 
00227             /* Scan class hierarchy and find the soot method that 
00228                matches the method signature */
00229 
00230             classToken = valueVariant.getClassToken();
00231             /* In case there is a null in the values ignore it */ 
00232             if (classToken.equals(ClassTokenSimple.unknownClassToken)
00233                 || classToken.equals(ClassTokenSimple.nullClassToken)) { 
00234                 System.out
00235                     .println("BOFA: Null may flow into the invocation site.");
00236                 continue;
00237             } 
00238             
00239             if (classToken instanceof ClassTokenSimple) {
00240                 if (sc == null) {
00241                     sootClass = 
00242                         ((ClassTokenSimple) classToken).getSootClass();
00243                 } // end of if ()
00244                 else {
00245                     sootClass = sc;
00246                 } // end of else
00247                 sootMethod = MethodVariantManager.findDeclaringMethod
00248                     (sootClass, methodName, parameterTypes, returnType);
00249             } else {
00250                 throw new RuntimeException
00251                     ("BOFA: array object flowing into invoke site");
00252             }
00253       
00254             /* Select the appropriate method variant */
00255             methodVariant = MethodVariantManager.select(sootMethod);
00256       
00257             if (!installedMethodVariants.contains(methodVariant)) {
00258                 /* - hook method variant into the flowgraph 
00259                  * For each arg...
00260                  *   - make arcs from arg to corresponding parameter node
00261                  *   - add work: send values that are currently
00262                  *   at arg to corresponding method parameter
00263                  */
00264                 FGNode paramNode;
00265                 for (int j=0; j<argCount; j++) {
00266                     paramNode = methodVariant.getParameterNode(j);
00267                     FGNode.makeArc(argNodes[j], paramNode);
00268                     try {                           
00269                         FA.workList.insert(new FGWorkSendVals
00270                             (argNodes[j].getValues(), paramNode));
00271                     }
00272                     catch (NullPointerException e) {
00273                         cat.error(e.getMessage() + "\n Argument Node: " + 
00274                                   argNodes[j]);
00275                         System.out.println(argNodes[j] +
00276                                                "==============="); 
00277                     } 
00278                 }
00279 
00280                 /* make arc from last node of method to AST node. */
00281 
00282                 FGNode lastNode = methodVariant.getReturnNode();
00283                 FGNode.makeArc(lastNode, invokeNode);
00284                 /* This below should be optimized?  
00285                    If value set is currently empty,
00286                    no work should be created. 
00287                 */
00288                 FA.workList.insert(new FGWorkSendVals
00289                     (lastNode.getValues(), invokeNode));
00290 
00291                 /* The value set for 'this' parameter for the method
00292                    should include only the objects that are flowing into
00293                    this variant.  Therefore, we should not make an arc
00294                    from the base node to the 'this' parameter (in
00295                    analogy with the conventional parameters above).
00296                    Instead, we should send only the current value
00297                    variant.  In essence, we are picking up information
00298                    at a split point --- we know that this variant will
00299                    only be called on objects that are represented by the
00300                    current value variant.  TRY TO EXPLAIN THIS BETTER.  */
00301 
00302                 FA.workList.insert
00303                     (new FGWorkSendVals(new FASet(valueVariant), 
00304                                         methodVariant.getThisNode()));
00305 
00306                 /* Add the method variant to the list of variants
00307                  * installed at this node.  */
00308       
00309                 installedMethodVariants.add(methodVariant);
00310             } else {
00311                 /* Push current value variant to 'this' node */
00312 
00313                 FA.workList.insert
00314                     (new FGWorkSendVals(new FASet(valueVariant),
00315                                         methodVariant.getThisNode()));
00316             } /* end: if */
00317         } /* end: for each valueVariant */
00318     }
00319 }

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