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 }