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: