1 cananian 1.1.2.1 // MethodMutator.java, created Fri Oct 6 20:57:16 2000 by cananian 2 cananian 1.1.2.1 // Copyright (C) 2000 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1.2.1 package harpoon.Analysis.Transformation; 5 cananian 1.1.2.1 6 cananian 1.1.2.2 import harpoon.ClassFile.HCode; 7 cananian 1.1.2.2 import harpoon.ClassFile.HCodeAndMaps; 8 cananian 1.5 import harpoon.ClassFile.HCodeElement; 9 cananian 1.1.2.2 import harpoon.ClassFile.HCodeFactory; 10 cananian 1.1.2.2 import harpoon.ClassFile.HMethod; 11 cananian 1.1.2.2 import harpoon.ClassFile.SerializableCodeFactory; 12 cananian 1.1.2.2 import harpoon.Util.Util; 13 cananian 1.1.2.1 14 cananian 1.1.2.2 import java.util.HashMap; 15 cananian 1.1.2.2 import java.util.Map; 16 cananian 1.1.2.1 /** 17 cananian 1.1.2.1 * <code>MethodMutator</code> makes it easier to implement simple 18 cananian 1.1.2.1 * method code mutations. It is meant to be subclassed. In your 19 cananian 1.1.2.1 * subclass, you will likely want to override <code>mutateHCode()</code> 20 cananian 1.1.2.1 * to effect the change. 21 cananian 1.1.2.1 * 22 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 23 cananian 1.5 * @version $Id: MethodMutator.java,v 1.5 2002/09/01 07:46:31 cananian Exp $ 24 cananian 1.1.2.1 */ 25 cananian 1.5 public abstract class MethodMutator<HCE extends HCodeElement> 26 cananian 1.5 implements java.io.Serializable { 27 cananian 1.1.2.1 /** This is the code factory which contains the representations of the 28 cananian 1.1.2.1 * original (unsplit) methods. */ 29 cananian 1.1.2.1 private final HCodeFactory parent; 30 cananian 1.1.2.1 31 cananian 1.1.2.1 /** Creates a <code>MethodMutator</code>. */ 32 cananian 1.1.2.1 public MethodMutator(HCodeFactory parent) { 33 cananian 1.1.2.1 this.parent = parent; 34 cananian 1.1.2.1 } 35 cananian 1.1.2.1 /** Override this method to effect transformations on split 36 cananian 1.1.2.1 * methods. */ 37 cananian 1.5 protected HCode<HCE> mutateHCode(HCodeAndMaps<HCE> input) { 38 cananian 1.1.2.1 return input.hcode(); 39 cananian 1.1.2.1 } 40 cananian 1.1.2.4 /** Override this method to change the codename which this 41 cananian 1.1.2.4 * <code>MethodMutator</code>'s codefactory reports. */ 42 cananian 1.1.2.4 protected String mutateCodeName(String codeName) { 43 cananian 1.1.2.4 return codeName; 44 cananian 1.1.2.4 } 45 cananian 1.1.2.5 /** Override this method if you do not want the mutatable HCode to be 46 cananian 1.1.2.5 * a straight clone of the original HCode: for example, if the 47 cananian 1.1.2.5 * input HCodes were <code>QuadSSI</code> and you wanted to 48 cananian 1.1.2.5 * clone them into <code>QuadRSSI</code>s before mutating. 49 cananian 1.1.2.5 * By default, this method returns <code>hc.clone(newmethod)</code>. */ 50 cananian 1.5 protected HCodeAndMaps<HCE> cloneHCode(HCode<HCE> hc, HMethod newmethod) 51 cananian 1.1.2.5 throws CloneNotSupportedException { 52 cananian 1.1.2.5 return hc.clone(newmethod); 53 cananian 1.1.2.5 } 54 cananian 1.1.2.1 /** Returns a <code>HCodeFactory</code> containing representations for 55 cananian 1.1.2.6 * the methods altered by the <code>MethodMutator</code>. */ 56 cananian 1.1.2.6 public HCodeFactory codeFactory() { return hcf; } 57 cananian 1.1.2.1 /** This is the code factory which contains the representations of the 58 cananian 1.1.2.1 * new split methods. */ 59 cananian 1.1.2.1 private final HCodeFactory hcf = new SerializableCodeFactory() { 60 cananian 1.5 private final Map<HMethod,HCode<HCE>> cache = 61 cananian 1.5 new HashMap<HMethod,HCode<HCE>>(); 62 cananian 1.1.2.4 public String getCodeName() { 63 cananian 1.1.2.4 return mutateCodeName(parent.getCodeName()); 64 cananian 1.1.2.4 } 65 cananian 1.1.2.1 public HCode convert(HMethod m) { 66 cananian 1.5 if (cache.containsKey(m)) return cache.get(m); 67 cananian 1.5 HCode<HCE> hc = parent.convert(m); 68 cananian 1.1.2.1 if (hc!=null) 69 cananian 1.1.2.1 try { 70 cananian 1.1.2.5 hc = mutateHCode(cloneHCode(hc, m)); 71 cananian 1.1.2.1 } catch (CloneNotSupportedException ex) { 72 cananian 1.3.2.1 assert false : ("cloning HCode failed: "+ex); 73 cananian 1.1.2.1 } 74 cananian 1.1.2.1 cache.put(m, hc); 75 cananian 1.1.2.1 return hc; 76 cananian 1.1.2.1 } 77 cananian 1.1.2.1 public void clear(HMethod m) { 78 cananian 1.1.2.1 cache.remove(m); parent.clear(m); 79 cananian 1.1.2.1 } 80 cananian 1.1.2.1 }; 81 cananian 1.2 }