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

JimpleStoreBuilder.java

00001 package edu.ksu.cis.bandera.birc;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1998, 1999   James Corbett (corbett@hawaii.edu)     *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project in the SAnToS Laboratory,         *
00009  * Department of Computing and Information Sciences, Kansas State    *
00010  * University, USA (http://www.cis.ksu.edu/santos).                  *
00011  * It is understood that any modification not identified as such is  *
00012  * not covered by the preceding statement.                           *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this toolkit; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * Java is a trademark of Sun Microsystems, Inc.                     *
00030  *                                                                   *
00031  * To submit a bug report, send a comment, or get the latest news on *
00032  * this project and other SAnToS projects, please visit the web-site *
00033  *                http://www.cis.ksu.edu/santos                      *
00034  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00035 import ca.mcgill.sable.soot.SootClass;
00036 import ca.mcgill.sable.soot.SootField;
00037 
00038 import edu.ksu.cis.bandera.bir.*;
00039 import edu.ksu.cis.bandera.jext.*;
00040 
00041 import java.util.*;
00042 
00043 /**
00044  * Jimple type switch that constructs a JimpleStore from a BirState
00045  * by translating BIR literal values into JimpleLiterals (by type).
00046  * <p>
00047  * Most cases are straightforward (we just map the BIR Literal to
00048  * the equivalent Jimple Literal).  For objects (records an arrays),
00049  * however, we must collect all their components from the BIR state
00050  * vector into a ClassLiteral or ArrayLiteral.
00051  */
00052 
00053 public class JimpleStoreBuilder extends AbstractTypeSwitch 
00054     implements BirConstants {
00055 
00056     BirState state;               // BIR state we're working from
00057     Literal [] birStore;          // Local copy of state vector from BirState
00058     TransSystem system;
00059 
00060     /**
00061      * The object table holds the set of ObjectLiterals that we have
00062      * already constructed.   We want to translate a given object 
00063      * only once per state, but we may encounter many references 
00064      * to the same object, so we check this table before constructing
00065      * an array or record object literal.
00066      */
00067 
00068     Hashtable objectTable = new Hashtable(); 
00069 
00070     public JimpleStoreBuilder(BirState state) {
00071     this.state = state;
00072     this.birStore = state.getStore();
00073     this.system = state.getSystem();
00074     }
00075     public void caseArray(Array type, Object o)
00076     {
00077     // See if we've already translated this array 
00078     // (o = Integer holding the address of the array)
00079     Object alreadyComputed = objectTable.get(o);
00080     if (alreadyComputed != null) {
00081         // If so, return the result of the previous translation
00082         setResult((ArrayLiteral)alreadyComputed);
00083         return;
00084     }
00085     // Otherwise, collect all the array elements into an ArrayLiteral
00086     int arrayAddr = getVarOffset(o);
00087     int length = ((IntLit)getVarValue(o)).getValue();
00088     ArrayLiteral array = new ArrayLiteral(length,arrayAddr);
00089     // Store this literal so we won't translate this array again
00090     objectTable.put(o,array);
00091     for (int i = 0; i < length; i++) {
00092         int address = arrayAddr + 1 + i;
00093         // Translate the ith array element
00094         type.getBaseType().apply(this, new Integer(address));
00095         array.contents[i] = (JimpleLiteral) getResult();
00096     }
00097     setResult(array);
00098     }
00099     public void caseBool(Bool type, Object o)
00100     {
00101         // robbyjo's patch begin
00102         Literal ll = getVarValue(o);
00103         boolean value = false;
00104         if (ll instanceof BoolLit)
00105             value = ((BoolLit) ll).getValue();
00106         else if (ll instanceof IntLit)
00107             value = ((IntLit) ll).getValue() == 0;
00108 
00109         // robbyjo's patch end
00110         setResult(new BooleanLiteral(value));
00111     }
00112     public void caseLock(Lock type, Object o)
00113     {
00114     LockLit lock = (LockLit) getVarValue(o);
00115     setResult(new LockLiteral(lock));
00116     }
00117     public void caseRange(Range type, Object o) 
00118     {
00119     int value = ((IntLit)getVarValue(o)).getValue();
00120     setResult(new IntegerLiteral(value));
00121     }
00122     public void caseRecord(Record type, Object o)
00123     {
00124     // See if we've already translated this record 
00125     // (o = Integer holding the address of the record)
00126     Object alreadyComputed = objectTable.get(o);
00127     if (alreadyComputed != null) {
00128         // If so, return result of previous translation
00129         setResult((ClassLiteral)alreadyComputed);
00130         return;
00131     }
00132     // Otherwise, collect all the fields into a ClassLiteral
00133     int recAddr = getVarOffset(o);
00134     ClassLiteral classLit = 
00135         new ClassLiteral((SootClass)system.getSource(type),recAddr);
00136     // Store this literal so we won't translate this record again
00137     objectTable.put(o, classLit);
00138     Vector fields = type.getFields();
00139     for (int i = 0; i < fields.size(); i++) {
00140         Field field = (Field) fields.elementAt(i);
00141         SootField sField = (SootField) system.getSource(field);
00142         int address = recAddr + field.getOffset();
00143         // Translate field value
00144         field.getType().apply(this, new Integer(address));
00145         JimpleLiteral value = (JimpleLiteral)getResult();
00146         // The BIRLock field is special---it has no source
00147         if (sField != null)
00148         classLit.setFieldValue(sField,value);
00149         else
00150         classLit.setLockValue(value);
00151     }
00152     setResult(classLit);
00153     }
00154     public void caseRef(Ref type, Object o)
00155     {
00156     Literal value = getVarValue(o);
00157     if (value instanceof RefLit) {
00158         // Translate the target pointed to and then return
00159         // a ReferenceLiteral pointing to this value
00160         RefLit ref = (RefLit) getVarValue(o);
00161         int address = ref.getCollection().getOffset();
00162         if (ref.getCollection().getType().isKind(COLLECTION)) 
00163         address += ref.getIndex() * type.getTargetType().getExtent();
00164         Type targetType = ref.getTargetType();
00165         targetType.apply(this, new Integer(address));
00166         setResult(new ReferenceLiteral((JimpleLiteral)getResult()));
00167     } else  // NullExpr
00168         setResult(new ReferenceLiteral(null));
00169     }
00170     public void defaultCase(Object obj) 
00171     {
00172     throw new RuntimeException("Case not handled: " + obj);
00173     }
00174     /**
00175      * Get offset of context in state vector.
00176      * <p>
00177      * The context is either an Integer (address) or StateVar.
00178      */
00179 
00180     int getVarOffset(Object context) {
00181     if (context instanceof Integer)
00182         return ((Integer)context).intValue();
00183     else
00184         return ((StateVar)context).getOffset();
00185     }
00186     /**
00187      * Get the value of a context in the state vector.
00188      */
00189 
00190     Literal getVarValue(Object context) {
00191     return birStore[getVarOffset(context)];
00192     }
00193 }

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