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.util.*; 00038 import ca.mcgill.sable.soot.*; 00039 import ca.mcgill.sable.soot.jimple.*; 00040 import java.util.Hashtable; 00041 00042 /* 00043 * FGActionArrayRef.java 00044 * $Id: FGActionArrayRef.java,v 1.1.1.1 2002/01/24 03:42:07 pserver Exp $ 00045 */ 00046 00047 /** 00048 * This class describes the action to taken when new values arrive at the base 00049 * position of an array reference that appears on the RHS of an assignment 00050 * statement. 00051 * 00052 * For every value variant that flows into the AST Node annotated by this 00053 * action, we want to find the corresponding array variant node, and hook it 00054 * into the flowgraph so that all values flowing out of the memory cells 00055 * abstracted by the array variant flow into the AST Node annotated by this 00056 * action. 00057 * 00058 * @author <A HREF="http://www.cis.ksu.edu/~hatcliff">John Hatcliff</A> 00059 * @author 00060 * <a href="http://www.cis.ksu.edu/~rvprasad">Venkatesh Prasad Ranganath</a> 00061 * @version $Name: $($Revision: 1.1.1.1 $) 00062 */ 00063 public class FGActionArrayRef implements FGAction 00064 { 00065 /** 00066 * Array reference AST node. 00067 */ 00068 private FGNode arrayRefNode; 00069 00070 /** 00071 * Set of array variants that have been connected into the flow graph for 00072 * this node. 00073 */ 00074 private Set installedArrayVariants; 00075 00076 /** 00077 * Class token corresponding to the array type of the array in context. 00078 */ 00079 private ClassTokenArray refClassTokenArray; 00080 00081 /** 00082 * MethodVariant in which the array reference occurs. 00083 */ 00084 private MethodVariant methodVariant; 00085 00086 /* Eventually, we will have the method name here as well, and parameter 00087 passing will be more complicated */ 00088 00089 /** 00090 * Constructor for the class. 00091 * 00092 * @param refClassTokenArray the class token generated by the type in 00093 * the array ref AST node 00094 * 00095 * @param arrayRefNode the array reference AST node 00096 * @param methodVariant the method variant enclosing the reference node. 00097 */ 00098 public FGActionArrayRef(ClassTokenArray refClassTokenArray, 00099 FGNode arrayRefNode, MethodVariant methodVariant) 00100 { 00101 this.refClassTokenArray = refClassTokenArray; 00102 this.arrayRefNode = arrayRefNode; 00103 this.installedArrayVariants = new HashSet(); 00104 this.methodVariant = methodVariant; 00105 } 00106 /** 00107 * Hooks in the flow graph node associated with the array variant into the 00108 * graph as a producer node. The array variant is the values in the 00109 * incoming set. 00110 * 00111 * @param values triggered the action. 00112 * @see FGActionArrayStore#doAction FGActionArrayStore.doAction 00113 */ 00114 public void doAction(FASet values) 00115 { 00116 ClassToken classToken; 00117 ClassTokenArray classTokenArray; 00118 ArrayVariant arrayVariant; 00119 00120 /* Iterate through the given set of value variants */ 00121 for(Iterator i = values.iterator(); i.hasNext();) { 00122 ValueVariant valueVariant = (ValueVariant) i.next(); 00123 00124 /* First, extract the class token from the value variant. 00125 If the class token is not an array then we have a 00126 type-checking error. Such errors may actually be due 00127 to imprecision in the analysis. I have not observed this, 00128 but the possibility exists and is mentioned in Grove's thesis. 00129 For now, we will raise an exception if such a thing happens. 00130 00131 If the class token is an array class we could also type check 00132 with the array class given by refClassTokenArray. Ignore 00133 this for now. 00134 00135 If the class token is an array class, then call the 00136 array variant manager to select the appropriate array 00137 variant. For now, let's lookup the array variant using the 00138 ClassToken in the value variant. 00139 00140 If the array variant is not already installed here, 00141 - hook the node abstracting the contents of the array 00142 into the flowgraph. 00143 - generate work to move ALL values 00144 at the array variant node along to array ref AST node. 00145 */ 00146 00147 classToken = valueVariant.getClassToken(); 00148 00149 if (classToken instanceof ClassTokenArray) { 00150 classTokenArray = ((ClassTokenArray) classToken); 00151 } else { 00152 throw new RuntimeException 00153 ("BOFA: non-array object flowing into array ref site"); 00154 } 00155 00156 /* Select the appropriate array variant */ 00157 arrayVariant = 00158 ArrayVariantManager.select(classToken, valueVariant); 00159 00160 if (!installedArrayVariants.contains(arrayVariant)) { 00161 // hook array variant into the flowgraph 00162 FGNode arrayNode = arrayVariant.getNode(); 00163 00164 /* make value flow arc from the array cell summary to the 00165 * array reference AST node */ 00166 FGNode.makeArc(arrayNode, arrayRefNode); 00167 FA.workList.insert(new FGWorkSendVals(arrayNode.getValues(), 00168 arrayRefNode)); 00169 00170 /* Add the method variant to the list of variants installed 00171 * at this node. */ 00172 installedArrayVariants.add(arrayVariant); 00173 } /* end: if */ 00174 00175 } /* end: for each valueVariant */ 00176 } 00177 }