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     }