1 cananian 1.1.2.1 // PCALL.java, created Wed Jan 20 21:47:52 1999 by cananian 2 cananian 1.1.2.1 // Copyright (C) 1999 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.LowQuad; 5 cananian 1.1.2.1 6 cananian 1.1.2.1 import harpoon.ClassFile.HCodeElement; 7 cananian 1.1.2.1 import harpoon.Temp.Temp; 8 cananian 1.1.2.1 import harpoon.Temp.TempMap; 9 cananian 1.1.2.1 import harpoon.Util.Util; 10 cananian 1.1.2.1 11 cananian 1.1.2.1 /** 12 cananian 1.1.2.1 * <code>PCALL</code> objects represent a method pointer dereference and 13 cananian 1.1.2.7 * invocation. Interpretation is similar to that of 14 cananian 1.1.2.9 * <code>harpoon.IR.Quads.CALL</code>.<p> 15 cananian 1.1.2.7 * If an exception is thrown by the called method, the <code>Temp</code> 16 cananian 1.1.2.7 * specified by <code>retex</code> will be assigned the non-null 17 cananian 1.1.2.11 * reference to the thrown exception, and the <code>Temp</code> 18 cananian 1.1.2.11 * specified by the <code>retval</code> field will be undefined 19 cananian 1.1.2.11 * (that is, it may have any value at all). 20 cananian 1.1.2.7 * Execution will proceed along the second outgoing edge, 21 cananian 1.1.2.7 * <code>nextEdge(1)</code>. If no exception is thrown, the 22 cananian 1.1.2.7 * return value will be assigned to the <code>Temp</code> specified 23 cananian 1.1.2.7 * by <code>retval</code> (if any), and <code>retex</code> will 24 cananian 1.1.2.11 * be undefined. Execution will proceed along the first outgoing 25 cananian 1.1.2.7 * edge, <code>nextEdge(0)</code>. 26 cananian 1.1.2.7 * <p> 27 cananian 1.1.2.7 * See also <code>IR.Quads.CALL</code> and <code>IR.Tree.CALL</code>. 28 cananian 1.1.2.1 * 29 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 30 cananian 1.4 * @version $Id: PCALL.java,v 1.4 2002/04/10 03:04:57 cananian Exp $ 31 cananian 1.1.2.1 */ 32 cananian 1.1.2.3 public class PCALL extends harpoon.IR.Quads.SIGMA { 33 cananian 1.1.2.1 /** The method pointer to dereference. */ 34 cananian 1.1.2.1 protected final Temp ptr; 35 cananian 1.1.2.1 /** Parameters to pass to the method. */ 36 cananian 1.1.2.1 protected Temp[] params; 37 cananian 1.1.2.1 /** Destination for the method's return value; 38 cananian 1.1.2.1 * <code>null</code> for <code>void</code> methods. */ 39 cananian 1.1.2.1 protected Temp retval; 40 cananian 1.1.2.1 /** Destination for any exception thrown by the method. 41 cananian 1.1.2.1 * May not be <code>null</code>. */ 42 cananian 1.1.2.1 protected Temp retex; 43 cananian 1.1.2.4 /** Whether this is a virtual or non-virtual method invocation. */ 44 cananian 1.1.2.4 protected boolean isVirtual; 45 cananian 1.1.2.4 /** Whether this should be treated as a tail call. */ 46 cananian 1.1.2.4 protected boolean isTailCall; 47 cananian 1.1.2.1 48 cananian 1.1.2.1 /** Creates a <code>PCALL</code> representing a method pointer dereference 49 cananian 1.1.2.1 * and method invocation. Interpretation is similar to that of 50 cananian 1.1.2.11 * <code>harpoon.IR.Quads.CALL</code>.<p> 51 cananian 1.1.2.1 * If an exception is thrown by the called method, the <code>Temp</code> 52 cananian 1.1.2.1 * specified by <code>retex</code> will be assigned the non-null 53 cananian 1.1.2.11 * reference to the thrown exception, and the <code>Temp</code> 54 cananian 1.1.2.11 * specified by the <code>retval</code> field will be undefined 55 cananian 1.1.2.11 * (that is, it may have any value at all). 56 cananian 1.1.2.3 * Execution will proceed along the second outgoing edge, 57 cananian 1.1.2.3 * <code>nextEdge(1)</code>. If no exception is thrown, the 58 cananian 1.1.2.3 * return value will be assigned to the <code>Temp</code> specified 59 cananian 1.1.2.3 * by <code>retval</code> (if any), and <code>retex</code> will 60 cananian 1.1.2.11 * be undefined. Execution will proceed along the first outgoing 61 cananian 1.1.2.3 * edge, <code>nextEdge(0)</code>. 62 cananian 1.1.2.1 * @param ptr 63 cananian 1.1.2.1 * the method pointer to dereference and invoke. 64 cananian 1.1.2.1 * @param params 65 cananian 1.1.2.1 * an array of <code>Temp</code>s containing the parameters 66 cananian 1.1.2.1 * to pass to the method. The object on which to invoke the 67 cananian 1.1.2.1 * method is the first element in the parameter list of a 68 cananian 1.1.2.1 * virtual method; non-virtual methods do not need to specify a 69 cananian 1.1.2.1 * receiver. For non-virtual methods, <code>params</code> 70 cananian 1.1.2.1 * should match exactly the number and types of parameters in 71 cananian 1.1.2.1 * the method descriptor. For virtual methods, the receiver 72 cananian 1.1.2.1 * object (which is not included in the descriptor) is element 73 cananian 1.1.2.1 * zero of the <code>params</code> array. 74 cananian 1.1.2.1 * @param retval 75 cananian 1.1.2.1 * the destination <code>Temp</code> for the method's return 76 cananian 1.1.2.1 * value, or <code>null</code> if the method returns no 77 cananian 1.1.2.1 * value (return type is <code>void</code>. 78 cananian 1.1.2.1 * @param retex 79 cananian 1.1.2.1 * the destination <code>Temp</code> for any exception thrown 80 cananian 1.1.2.1 * by the called method. May not be <code>null</code>. 81 cananian 1.1.2.3 * @param dst 82 cananian 1.1.2.3 * the elements of the pairs on the left-hand side of 83 cananian 1.1.2.3 * the sigma function assignment block associated with 84 cananian 1.1.2.3 * this <code>PCALL</code>. 85 cananian 1.1.2.3 * @param src 86 cananian 1.1.2.3 * the arguments to the sigma functions associated with 87 cananian 1.1.2.3 * this <code>PCALL</code>. 88 cananian 1.1.2.4 * @param isVirtual 89 cananian 1.1.2.4 * <code>true</code> if this is a virtual method invocation, 90 cananian 1.1.2.4 * in which case <code>ptr</code> <i>points to</i> the address of 91 cananian 1.1.2.4 * the method to invoke, or <code>false</code> if this is a 92 cananian 1.1.2.4 * non-virtual invocation, in which case <code>ptr</code> is 93 cananian 1.1.2.4 * the <i>actual address</i> of the method to invoke. 94 cananian 1.1.2.4 * @param isTailCall 95 cananian 1.1.2.4 * <code>true</code> if this method should return the same 96 cananian 1.1.2.4 * value the callee returns or throw whatever exception the 97 cananian 1.1.2.4 * callee throws (in which case we can get rid of our 98 cananian 1.1.2.4 * stack and let the callee return directly to our caller). 99 cananian 1.1.2.4 * Usually <code>false</code>. 100 cananian 1.1.2.1 */ 101 cananian 1.1.2.1 public PCALL(LowQuadFactory qf, HCodeElement source, 102 cananian 1.1.2.3 Temp ptr, Temp[] params, Temp retval, Temp retex, 103 cananian 1.1.2.6 Temp[][] dst, Temp[] src, 104 cananian 1.1.2.4 boolean isVirtual, boolean isTailCall) { 105 cananian 1.1.2.3 super(qf, source, dst, src, 2/* always arity two */); 106 cananian 1.1.2.1 this.ptr = ptr; 107 cananian 1.1.2.1 this.params = params; 108 cananian 1.1.2.1 this.retval = retval; 109 cananian 1.1.2.1 this.retex = retex; 110 cananian 1.1.2.4 this.isVirtual = isVirtual; 111 cananian 1.1.2.4 this.isTailCall = isTailCall; 112 cananian 1.3.2.1 assert ptr!=null && params!=null && retex !=null; 113 cananian 1.1.2.1 // hm. can't check much else without knowing the method identity. 114 cananian 1.1.2.1 } 115 cananian 1.1.2.3 // convenience constructor. 116 cananian 1.1.2.3 /** Creates a <code>PCALL</code> with an empty <code>dst</code> array 117 cananian 1.1.2.3 * of the proper size and arity. Other arguments as above. */ 118 cananian 1.1.2.3 public PCALL(LowQuadFactory qf, HCodeElement source, 119 cananian 1.1.2.4 Temp ptr, Temp[] params, Temp retval, Temp retex, 120 cananian 1.1.2.6 Temp[] src, boolean isVirtual, boolean isTailCall){ 121 cananian 1.1.2.3 this(qf, source, ptr, params, retval, retex, 122 cananian 1.1.2.6 new Temp[src.length][2], src, isVirtual, isTailCall); 123 cananian 1.1.2.3 } 124 cananian 1.1.2.3 125 cananian 1.1.2.1 // ACCESSOR METHODS: 126 cananian 1.1.2.1 /** Returns the <code>POINTER</code> which is to be dereferenced by this 127 cananian 1.1.2.1 * <code>PCALL</code>. */ 128 cananian 1.1.2.1 public Temp ptr() { return ptr; } 129 cananian 1.1.2.1 /** Returns the parameters of this method invocation. */ 130 cananian 1.1.2.1 public Temp[] params() 131 cananian 1.1.2.1 { return (Temp[]) Util.safeCopy(Temp.arrayFactory, params); } 132 cananian 1.1.2.1 /** Returns a specified parameter in the <code>params</code> array. */ 133 cananian 1.1.2.1 public Temp params(int i) { return params[i]; } 134 cananian 1.1.2.1 /** Returns the number of parameters in the <code>params</code> array. */ 135 cananian 1.1.2.1 public int paramsLength() { return params.length; } 136 cananian 1.1.2.1 /** Returns the <code>Temp</code> which will hold the return value of 137 cananian 1.1.2.1 * the method, or the value <code>null</code> if the method returns 138 cananian 1.1.2.1 * no value. */ 139 cananian 1.1.2.1 public Temp retval() { return retval; } 140 cananian 1.1.2.1 /** Returns the <code>Temp</code> which will get any exception thrown 141 cananian 1.1.2.1 * by the called method, or <code>null</code> if exceptions are 142 cananian 1.1.2.1 * not caught. */ 143 cananian 1.1.2.1 public Temp retex() { return retex; } 144 cananian 1.1.2.4 /** Returns <code>true</code> if <code>ptr</code> <i>points to</i> 145 cananian 1.1.2.4 * the address of the method to invoke; or <code>false</code> if 146 cananian 1.1.2.4 * <code>ptr</code> contains the direct address of the method to 147 cananian 1.1.2.4 * invoke. */ 148 cananian 1.1.2.4 public boolean isVirtual() { return isVirtual; } 149 cananian 1.1.2.4 /** Return <code>true</code> if this method should return the same 150 cananian 1.1.2.4 * value the callee returns or throw whatever exception the 151 cananian 1.1.2.4 * callee throws (in which case we can get rid of our 152 cananian 1.1.2.4 * stack and let the callee return directly to our caller). 153 cananian 1.1.2.4 * Usually <code>false</code>. */ 154 cananian 1.1.2.4 public boolean isTailCall() { return isTailCall; } 155 cananian 1.1.2.1 156 cananian 1.1.2.1 public int kind() { return LowQuadKind.PCALL; } 157 cananian 1.1.2.1 158 cananian 1.1.2.1 public Temp[] use() { 159 cananian 1.1.2.3 Temp[] u = super.use(); 160 cananian 1.1.2.3 Temp[] r = new Temp[u.length+params.length+1]; 161 cananian 1.1.2.3 System.arraycopy(u, 0, r, 0, u.length); 162 cananian 1.1.2.3 System.arraycopy(params, 0, r, u.length, params.length); 163 cananian 1.1.2.3 r[u.length+params.length] = ptr; 164 cananian 1.1.2.3 return r; 165 cananian 1.1.2.1 } 166 cananian 1.1.2.1 public Temp[] def() { 167 cananian 1.1.2.3 Temp[] d = super.def(); 168 cananian 1.1.2.3 Temp[] r = new Temp[d.length+(retval==null?1:2)]; 169 cananian 1.1.2.3 System.arraycopy(d, 0, r, 0, d.length); 170 cananian 1.1.2.3 if (retval!=null) r[r.length-2] = retval; 171 cananian 1.1.2.3 r[r.length-1] = retex; 172 cananian 1.1.2.3 return r; 173 cananian 1.1.2.1 } 174 cananian 1.1.2.1 175 cananian 1.1.2.1 public harpoon.IR.Quads.Quad rename(harpoon.IR.Quads.QuadFactory qf, 176 cananian 1.1.2.1 TempMap defMap, TempMap useMap) { 177 cananian 1.1.2.1 return new PCALL((LowQuadFactory)qf, this, 178 cananian 1.1.2.1 map(useMap, ptr), map(useMap, params), 179 cananian 1.1.2.3 map(defMap, retval), map(defMap, retex), 180 cananian 1.1.2.4 map(defMap, dst), map(useMap, src), 181 cananian 1.1.2.6 isVirtual, isTailCall); 182 cananian 1.1.2.1 } 183 cananian 1.1.2.1 184 cananian 1.1.2.3 public void accept(harpoon.IR.Quads.QuadVisitor v) { 185 cananian 1.1.2.3 ((LowQuadVisitor)v).visit(this); 186 cananian 1.1.2.3 } 187 cananian 1.1.2.1 188 cananian 1.1.2.1 public String toString() { 189 cananian 1.1.2.1 StringBuffer sb = new StringBuffer(); 190 cananian 1.1.2.1 if (retval != null) 191 cananian 1.1.2.1 sb.append(retval.toString() + " = "); 192 cananian 1.1.2.4 sb.append("PCALL "); 193 cananian 1.1.2.4 if (isVirtual) sb.append("*"); 194 cananian 1.1.2.4 sb.append(ptr.toString()); 195 cananian 1.1.2.1 196 cananian 1.1.2.1 sb.append('('); 197 cananian 1.1.2.1 for (int i=0; i<params.length; i++) { 198 cananian 1.1.2.1 sb.append(params[i].toString()); 199 cananian 1.1.2.1 if (i<params.length-1) 200 cananian 1.1.2.1 sb.append(", "); 201 cananian 1.1.2.1 } 202 cananian 1.1.2.1 sb.append(')'); 203 cananian 1.1.2.1 204 cananian 1.1.2.4 if (isTailCall) sb.append(" [tail call]"); 205 cananian 1.1.2.1 sb.append(" exceptions in "+retex.toString()); 206 cananian 1.1.2.3 sb.append(" / "); sb.append(super.toString()); 207 cananian 1.1.2.1 return sb.toString(); 208 cananian 1.1.2.1 } 209 cananian 1.2 }