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