1 2 package org.quilt.cl; 3 4 import java.util.Hashtable ; 5 import java.util.List ; 6 7 import org.apache.bcel.classfile.*; 8 import org.apache.bcel.Constants; 9 import org.apache.bcel.generic.*; 10 import org.quilt.graph.*; 11 12 21 public class MethodTransformer { 22 23 25 private Hashtable methodHash = new Hashtable (); 26 27 28 private List mxf; 29 30 31 private List gxf; 32 33 34 private GraphTransformer xformer; 35 36 40 public MethodTransformer( List mxf, List gxf) { 41 this.mxf = mxf; 42 this.gxf = gxf; 43 xformer = new GraphTransformer (gxf); 44 } 45 46 50 public Hashtable getMethodHash() { 51 return methodHash; 52 } 53 58 private void zapMethodXformer ( MethodXformer mxf, Exception e) { 59 System.err.println("WARNING: exception in " 60 + mxf.getName() + ": transformation will not be applied" ); 61 e.printStackTrace(); 62 mxf = null; 63 } 64 71 public MethodGen xform ( ClassGen clazz, Method orig ) { 72 if (orig == null) { 73 throw new IllegalArgumentException ("null method"); 74 } 75 MethodGen method = new MethodGen (orig, clazz.getClassName(), 76 clazz.getConstantPool()); 77 MethodXformer [] xf = new MethodXformer[ mxf.size() ]; 79 80 for (int i = 0; i < xf.length; i++) { 82 try { 83 xf[i] = (MethodXformer) ( 84 (mxf.get(i)).getClass().newInstance() ); 85 } catch (IllegalAccessException e) { 86 zapMethodXformer (xf[i], e); 87 } catch (InstantiationException e) { 88 zapMethodXformer (xf[i], e); 89 } 90 if (xf[i] != null && method != null) { 91 xf[i].preGraph (clazz, method); 92 } 93 } 94 if (gxf.size() > 0 && method != null) { 96 InstructionList ilist = xformer.xform (clazz, method); 97 if (ilist == null) { 98 System.out.println("MethodTransformer.xformer: WARNING: " 99 + "xformer returned null instruction list"); 100 return null; 101 } 102 109 method.removeExceptionHandlers(); 111 ilist.setPositions(true); 113 method.setInstructionList (ilist); 114 115 CodeExceptionGen [] cgs = xformer.getExceptionHandlers(); 116 for (int i = 0; i < cgs.length; i++) { 117 System.out.println("adding exception " + i 119 + " to method " + method.getName() 120 + ": [" + cgs[i].getStartPC().getPosition() 121 + ".." + cgs[i].getEndPC().getPosition() 122 + "] --> " + cgs[i].getHandlerPC().getPosition() 123 ); 124 126 method.addExceptionHandler ( 127 cgs[i].getStartPC(), cgs[i].getEndPC(), 128 cgs[i].getHandlerPC(), cgs[i].getCatchType() ); 129 } 130 method.removeNOPs(); 131 method.update(); try { 134 method.setMaxStack(); 135 method.setMaxLocals(); 136 } catch (RuntimeException e) { 138 e.printStackTrace(); 139 System.out.println("GraphTransformer.xformer:\n" 140 + " EXCEPTION finishing method " + e); 141 throw e; 142 } 143 } 149 150 for (int i = xf.length-1; i >= 0; i--) { 152 if (xf[i] != null && method != null) { 153 xf[i].postGraph (clazz, method); 154 } 155 } 156 return method; 158 } 159 void dumpExceptionHandlers (MethodGen method, String where, int len) { 161 CodeExceptionGen handlers[] = method.getExceptionHandlers(); 162 if (handlers.length != len) { 163 System.out.println("EXPECTED " + len 164 + " exception handlers, found " + handlers.length); 165 } 166 if (handlers.length > 0) { 167 System.out.println("Exception handlers for method " 168 + method.getName() + " " + where + ":"); 169 170 for (int j = 0; j < handlers.length; j++) { 171 System.out.println(" " + j 172 + ": [" + handlers[j].getStartPC().getPosition() 173 + ".." + handlers[j].getEndPC().getPosition() 174 + "] --> " + handlers[j].getHandlerPC().getPosition() 175 ); 176 } 177 } 178 } 179 void dumpIList(MethodGen method, String where) { 180 InstructionList myList = method.getInstructionList(); 181 System.out.println( 182 "MethodTransformer: instruction list " + where + ":"); 183 int i = 0; 184 for (InstructionHandle ih = myList.getStart(); ih != null; 185 ih = ih.getNext() ) { 186 System.out.println( " " + (i++) + " " + ih); 187 } 188 } 189 } 190 | Popular Tags |