1 cananian 1.12.2.5 // HCode.java, created Sun Aug 2 20:11:26 1998 by cananian 2 cananian 1.10 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.10 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1 package harpoon.ClassFile; 5 cananian 1.1 6 cananian 1.12.2.1 import harpoon.Util.ArrayFactory; 7 cananian 1.18 import net.cscott.jutil.Indexer; 8 cananian 1.12.2.1 9 cananian 1.9 import java.util.Enumeration; 10 cananian 1.12.2.3 import java.util.Iterator; 11 cananian 1.1 /** 12 cananian 1.2 * <code>HCode</code> is an abstract class that all views of a particular 13 cananian 1.2 * method's executable code should extend. 14 cananian 1.1 * <p> 15 cananian 1.1 * An <code>HCode</code> corresponds roughly to a "list of instructions". 16 cananian 1.1 * 17 cananian 1.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 18 cananian 1.18 * @version $Id: HCode.java,v 1.18 2004/02/08 01:58:03 cananian Exp $ 19 cananian 1.1 * @see HMethod 20 cananian 1.1 * @see HCodeElement 21 cananian 1.6 * @see harpoon.IR.Bytecode.Code 22 cananian 1.6 * @see harpoon.IR.Bytecode.Instr 23 cananian 1.1 */ 24 cananian 1.13.2.1 public abstract class HCode<HCE extends HCodeElement> { 25 cananian 1.1 /** 26 cananian 1.3 * Return the <code>HMethod</code> to which this <code>HCode</code> 27 cananian 1.1 * belongs. 28 cananian 1.1 */ 29 cananian 1.1 public abstract HMethod getMethod(); 30 cananian 1.1 31 cananian 1.1 /** 32 cananian 1.1 * Return the name of this code view. 33 cananian 1.1 * The default bytecode view is named <code>"bytecode"</code>. 34 cananian 1.1 * It is suggested that additional views be named in a similarly 35 cananian 1.1 * human-friendly fashion. 36 cananian 1.1 */ 37 cananian 1.1 public abstract String getName(); 38 cananian 1.1 39 cananian 1.1 /** 40 cananian 1.1 * Return an ordered list of the component objects making up this 41 cananian 1.1 * code view. If there is a 'root' to the code view, it should 42 cananian 1.12.2.3 * occupy index 0 of the <code>HCodeElement</code> array.<p> 43 cananian 1.12.2.3 * @deprecated use getElementsL() instead. 44 cananian 1.6 * @see harpoon.IR.Bytecode.Instr 45 cananian 1.1 */ 46 cananian 1.13.2.1 public HCE[] getElements() { 47 cananian 1.13.2.1 java.util.List<HCE> l = getElementsL(); 48 cananian 1.13.2.1 HCE[] r = elementArrayFactory().newArray(l.size()); 49 cananian 1.13.2.1 return l.toArray(r); 50 cananian 1.12.2.3 } 51 cananian 1.12.2.3 /** 52 cananian 1.12.2.3 * Return an ordered <code>Collection</code> (a <code>List</code>) of 53 cananian 1.12.2.3 * the component objects making up this code view. If there is a 54 cananian 1.12.2.3 * 'root' to the code view, it should be the first element in the 55 cananian 1.15 * List. Note that the object returned need not be static; i.e. 56 cananian 1.15 * the contents of the <code>List</code> may (or may not) change as 57 cananian 1.15 * the underlying representation is modified. If you need a 58 cananian 1.15 * static view, see <code>SnapshotIterator</code>; if you need 59 cananian 1.15 * a dynamic view, don't cache the returned <code>List</code>. 60 cananian 1.15 * <p> 61 cananian 1.17 * The <code>getElementsI()</code> method 62 cananian 1.12.2.3 * must have been implemented for the default implementation to work 63 cananian 1.12.2.3 * properly. 64 cananian 1.12.2.3 */ 65 cananian 1.15 // the default implementation gives a snapshot view, for what it's worth. 66 cananian 1.13.2.1 public java.util.List<HCE> getElementsL() { 67 cananian 1.13.2.1 java.util.List<HCE> l = new java.util.ArrayList<HCE>(); 68 cananian 1.13.2.1 for (Iterator<HCE> i = getElementsI(); i.hasNext(); ) 69 cananian 1.12.2.3 l.add(i.next()); 70 cananian 1.12.2.3 return java.util.Collections.unmodifiableList(l); 71 cananian 1.12.2.3 } 72 cananian 1.17 73 cananian 1.12.2.3 /** 74 cananian 1.12.2.3 * Return an Iterator over the component objects making up this 75 cananian 1.12.2.3 * code view. If there is a 'root' to the code view, it should 76 cananian 1.12.2.3 * be the first element enumerated.<p> 77 cananian 1.17 * Subclasses must override the default implementation of 78 cananian 1.17 * at least one of 79 cananian 1.17 * <code>getElementsL()</code> or <code>getElementsI()</code> 80 cananian 1.17 * in order to work properly. 81 cananian 1.12.2.3 */ 82 cananian 1.13.2.1 public Iterator<HCE> getElementsI() { 83 cananian 1.17 return getElementsL().iterator(); 84 cananian 1.12.2.3 } 85 cananian 1.1 86 cananian 1.1 /** 87 cananian 1.5 * Return the 'root' element of this code view. 88 cananian 1.5 * @return root of the code view, or <code>null</code> if this notion 89 cananian 1.5 * is not applicable. 90 cananian 1.1 */ 91 cananian 1.13.2.1 public HCE getRootElement() { 92 cananian 1.13.2.1 return getElementsI().next(); 93 cananian 1.12.2.3 } 94 cananian 1.7 /** 95 cananian 1.7 * Return the 'leaves' of this code view; that is, 96 cananian 1.7 * the elements with no successors. 97 cananian 1.7 * @return leaves of the code view, or <code>null</code> if this notion 98 cananian 1.7 * is not applicable. 99 cananian 1.7 */ 100 cananian 1.13.2.1 public HCE[] getLeafElements() { return null; } 101 cananian 1.4 102 cananian 1.4 /** 103 cananian 1.12.2.1 * Return an <code>ArrayFactory</code> for the <code>HCodeElement</code>s 104 cananian 1.12.2.1 * composing this <code>HCode</code>. 105 cananian 1.12.2.1 */ 106 cananian 1.13.2.1 public abstract ArrayFactory<HCE> elementArrayFactory(); 107 cananian 1.12.2.6 108 cananian 1.12.2.6 /** 109 cananian 1.12.2.6 * Return an <code>Indexer</code> for the <code>HCodeElement</code>s 110 cananian 1.12.2.6 * composing this <code>HCode</code>. The default <code>Indexer</code> 111 cananian 1.12.2.6 * returned does not implement <code>Indexer.getByID()</code>. 112 cananian 1.12.2.6 */ 113 cananian 1.12.2.6 public Indexer elementIndexer() { return _indexer; } 114 cananian 1.12.2.6 private static final Indexer _indexer = new Indexer() { 115 cananian 1.12.2.6 public int getID(Object o) { return ((HCodeElement)o).getID(); } 116 cananian 1.12.2.6 }; 117 cananian 1.4 118 cananian 1.4 /** 119 cananian 1.12.2.2 * Clone this <code>HCode</code>, possibly moving it to a different method. 120 cananian 1.12.2.2 * Throws <code>CloneNotSupportedException</code> if not overridden. 121 cananian 1.12 * @exception CloneNotSupportedException if it is not possible to clone 122 cananian 1.12 * this <code>HCode</code>. 123 cananian 1.11 */ 124 cananian 1.16 public HCodeAndMaps<HCE> clone(HMethod newMethod) 125 cananian 1.12.2.8 throws CloneNotSupportedException { 126 cananian 1.11 throw new CloneNotSupportedException(this.toString()); 127 cananian 1.11 } 128 cananian 1.12.2.7 /** 129 cananian 1.12.2.7 * Clone this <code>HCode</code> and all associated 130 cananian 1.12.2.7 * <code>HCodeElement</code>s. 131 cananian 1.12.2.7 * Calls <code>clone(getMethod())</code>. 132 cananian 1.12.2.7 */ 133 cananian 1.18 public HCode<HCE> clone() throws CloneNotSupportedException { 134 cananian 1.12.2.8 return clone(getMethod()).hcode(); 135 cananian 1.11 } 136 cananian 1.11 137 cananian 1.11 /** 138 cananian 1.12.2.9 * Pretty-print this code view using an empty callback. 139 cananian 1.4 */ 140 cananian 1.12.2.9 public final void print(java.io.PrintWriter pw) { 141 cananian 1.13.2.1 print(pw, new PrintCallback<HCE>()); 142 cananian 1.12.2.9 } 143 cananian 1.12.2.9 /** 144 cananian 1.12.2.9 * Pretty-print this code view using the specified callback. 145 cananian 1.4 */ 146 cananian 1.13.2.1 public void print(java.io.PrintWriter pw, PrintCallback<HCE> callback) { 147 cananian 1.13.2.2 if (callback==null) callback = new PrintCallback<HCE>(); // nop callback 148 cananian 1.4 pw.println("Codeview \""+getName()+"\" for "+getMethod()+":"); 149 cananian 1.13.2.1 for (Iterator<HCE> it = getElementsI(); it.hasNext(); ) { 150 cananian 1.13.2.1 HCE hce = it.next(); 151 cananian 1.12.2.9 callback.printBefore(pw, hce); 152 cananian 1.12.2.9 pw.println(" #"+hce.getID()+"/"+ 153 cananian 1.12.2.9 hce.getSourceFile()+":"+hce.getLineNumber()+" - " + 154 cananian 1.12.2.9 hce.toString()); 155 cananian 1.12.2.9 callback.printAfter(pw, hce); 156 cananian 1.12.2.9 } 157 cananian 1.12.2.10 pw.println(); 158 cananian 1.12.2.10 pw.flush(); 159 cananian 1.12 } 160 cananian 1.12 161 cananian 1.12 /** Returns a human-readable representation of this <code>HCode</code>. */ 162 cananian 1.12 public String toString() { 163 cananian 1.12 return "codeview " + getName() + " for " + getMethod(); 164 cananian 1.12.2.9 } 165 cananian 1.12.2.9 166 cananian 1.12.2.9 /** Callback interface for annotating pretty-prints of <code>HCode</code>s.*/ 167 cananian 1.13.2.1 public static class PrintCallback<HCE extends HCodeElement> { 168 cananian 1.12.2.9 /** This method is called right *before* each <code>HCodeElement</code> 169 cananian 1.12.2.9 * is output. */ 170 cananian 1.13.2.1 public void printBefore(java.io.PrintWriter pw, HCE hce) { } 171 cananian 1.12.2.9 /** This method is called right *after* each <code>HCodeElement</code> 172 cananian 1.12.2.9 * is output. */ 173 cananian 1.13.2.1 public void printAfter(java.io.PrintWriter pw, HCE hce) { } 174 cananian 1.4 } 175 cananian 1.1 } 176 cananian 1.11 177 cananian 1.11 // set emacs indentation style. 178 cananian 1.11 // Local Variables: 179 cananian 1.11 // c-basic-offset:2 180 cananian 1.11 // End: