1 cananian 1.1.2.1 // CloneSynthesizer.java, created Fri Oct 20 18:46:05 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.IR.Quads;
 5 cananian 1.1.2.1 
 6 cananian 1.1.2.1 import harpoon.ClassFile.HClass;
 7 cananian 1.1.2.1 import harpoon.ClassFile.HCode;
 8 cananian 1.1.2.1 import harpoon.ClassFile.HCodeFactory;
 9 cananian 1.1.2.1 import harpoon.ClassFile.HMethod;
10 cananian 1.1.2.1 import harpoon.Temp.Temp;
11 cananian 1.1.2.1 import harpoon.Util.Util;
12 cananian 1.1.2.1 
13 cananian 1.1.2.1 import java.util.HashMap;
14 cananian 1.1.2.1 import java.util.Map;
15 cananian 1.1.2.1 /**
16 cananian 1.1.2.1  * <code>CloneSynthesizer</code> adds synthetic implementations for
17 cananian 1.1.2.1  * array clone methods.
18 cananian 1.1.2.1  * 
19 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
20 cananian 1.4      * @version $Id: CloneSynthesizer.java,v 1.4 2002/04/10 03:05:14 cananian Exp $
21 cananian 1.1.2.1  */
22 cananian 1.1.2.1 class CloneSynthesizer implements HCodeFactory, java.io.Serializable {
23 cananian 1.1.2.1     /** Parent code factory. */
24 cananian 1.1.2.1     final HCodeFactory parent;
25 cananian 1.1.2.1     /** Representation cache. */
26 cananian 1.1.2.1     final Map cache = new HashMap();
27 cananian 1.1.2.1 
28 cananian 1.1.2.1     /** Creates a <code>CloneSynthesizer</code>. */
29 cananian 1.1.2.1     public CloneSynthesizer(HCodeFactory parent) { 
30 cananian 1.3.2.1         assert parent.getCodeName().equals(QuadWithTry.codename);
31 cananian 1.1.2.1         this.parent = parent;
32 cananian 1.1.2.1     }
33 cananian 1.1.2.1     public String getCodeName() { return parent.getCodeName(); }
34 cananian 1.1.2.1     public void clear(HMethod m) { cache.remove(m); parent.clear(m); }
35 cananian 1.1.2.1     public HCode convert(HMethod m) {
36 cananian 1.1.2.1         // check cache first
37 cananian 1.1.2.1         if (cache.containsKey(m)) return (HCode) cache.get(m);
38 cananian 1.1.2.1         // now see if we need to synthesize a code for this method.
39 cananian 1.1.2.2         HClass hc = m.getDeclaringClass();
40 cananian 1.1.2.2         HClass oa = hc.getLinker().forDescriptor("[Ljava/lang/Object;");
41 cananian 1.1.2.2         if (hc.isArray() &&
42 cananian 1.1.2.2             !hc.getComponentType().isPrimitive() && // not primitive array
43 cananian 1.1.2.2             !hc.equals(oa) && // not java.lang.Object[].clone
44 cananian 1.1.2.1             m.getName().equals("clone") &&
45 cananian 1.1.2.1             m.getDescriptor().equals("()Ljava/lang/Object;")) {
46 cananian 1.1.2.2             // Create a Code which turns around and calls Object[].clone().
47 cananian 1.1.2.1             QuadWithTry qwt = new QuadWithTry(m, null) { };
48 cananian 1.1.2.2             HMethod hm = oa.getMethod("clone", new HClass[0]);
49 cananian 1.1.2.1             Temp thisT = new Temp(qwt.qf.tempFactory());
50 cananian 1.1.2.1             Quad q0 = new HEADER(qwt.qf, null);
51 cananian 1.1.2.1             Quad q1 = new METHOD(qwt.qf, null, new Temp[] { thisT }, 1);
52 cananian 1.1.2.1             Quad q2 = new CALL(qwt.qf, null, hm, new Temp[] { thisT },
53 cananian 1.1.2.1                                thisT, null, false, true, new Temp[0]);
54 cananian 1.1.2.1             Quad q3 = new RETURN(qwt.qf, null, thisT);
55 cananian 1.1.2.1             Quad q4 = new FOOTER(qwt.qf, null, 2);
56 cananian 1.1.2.1             Quad.addEdge(q0, 0, q4, 0);
57 cananian 1.1.2.1             Quad.addEdge(q0, 1, q1, 0);
58 cananian 1.1.2.1             Quad.addEdges(new Quad[] { q1, q2, q3 });
59 cananian 1.1.2.1             Quad.addEdge(q3, 0, q4, 1);
60 cananian 1.1.2.1             qwt.quads = q0;
61 cananian 1.1.2.1             cache.put(m, qwt);
62 cananian 1.1.2.1             return qwt;
63 cananian 1.1.2.1         } else return parent.convert(m); // not synthetic: use parent's code.
64 cananian 1.1.2.1     }
65 cananian 1.2     }