1 17 package org.apache.bcel.util; 18 19 import java.io.PrintWriter ; 20 import java.util.ArrayList ; 21 import java.util.HashMap ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import java.util.Locale ; 25 import java.util.Map ; 26 import org.apache.bcel.Constants; 27 import org.apache.bcel.classfile.Utility; 28 import org.apache.bcel.generic.AllocationInstruction; 29 import org.apache.bcel.generic.ArrayInstruction; 30 import org.apache.bcel.generic.ArrayType; 31 import org.apache.bcel.generic.BranchHandle; 32 import org.apache.bcel.generic.BranchInstruction; 33 import org.apache.bcel.generic.CHECKCAST; 34 import org.apache.bcel.generic.CPInstruction; 35 import org.apache.bcel.generic.CodeExceptionGen; 36 import org.apache.bcel.generic.ConstantPoolGen; 37 import org.apache.bcel.generic.ConstantPushInstruction; 38 import org.apache.bcel.generic.EmptyVisitor; 39 import org.apache.bcel.generic.FieldInstruction; 40 import org.apache.bcel.generic.IINC; 41 import org.apache.bcel.generic.INSTANCEOF; 42 import org.apache.bcel.generic.Instruction; 43 import org.apache.bcel.generic.InstructionConstants; 44 import org.apache.bcel.generic.InstructionHandle; 45 import org.apache.bcel.generic.InvokeInstruction; 46 import org.apache.bcel.generic.LDC; 47 import org.apache.bcel.generic.LDC2_W; 48 import org.apache.bcel.generic.LocalVariableInstruction; 49 import org.apache.bcel.generic.MULTIANEWARRAY; 50 import org.apache.bcel.generic.MethodGen; 51 import org.apache.bcel.generic.NEWARRAY; 52 import org.apache.bcel.generic.ObjectType; 53 import org.apache.bcel.generic.RET; 54 import org.apache.bcel.generic.ReturnInstruction; 55 import org.apache.bcel.generic.Select; 56 import org.apache.bcel.generic.Type; 57 58 66 class BCELFactory extends EmptyVisitor { 67 68 private MethodGen _mg; 69 private PrintWriter _out; 70 private ConstantPoolGen _cp; 71 72 73 BCELFactory(MethodGen mg, PrintWriter out) { 74 _mg = mg; 75 _cp = mg.getConstantPool(); 76 _out = out; 77 } 78 79 private Map branch_map = new HashMap (); 81 82 public void start() { 83 if (!_mg.isAbstract() && !_mg.isNative()) { 84 for (InstructionHandle ih = _mg.getInstructionList().getStart(); ih != null; ih = ih 85 .getNext()) { 86 Instruction i = ih.getInstruction(); 87 if (i instanceof BranchInstruction) { 88 branch_map.put(i, ih); } 90 if (ih.hasTargeters()) { 91 if (i instanceof BranchInstruction) { 92 _out.println(" InstructionHandle ih_" + ih.getPosition() + ";"); 93 } else { 94 _out.print(" InstructionHandle ih_" + ih.getPosition() + " = "); 95 } 96 } else { 97 _out.print(" "); 98 } 99 if (!visitInstruction(i)) { 100 i.accept(this); 101 } 102 } 103 updateBranchTargets(); 104 updateExceptionHandlers(); 105 } 106 } 107 108 109 private boolean visitInstruction( Instruction i ) { 110 short opcode = i.getOpcode(); 111 if ((InstructionConstants.INSTRUCTIONS[opcode] != null) 112 && !(i instanceof ConstantPushInstruction) && !(i instanceof ReturnInstruction)) { _out.println("il.append(InstructionConstants." 114 + i.getName().toUpperCase(Locale.ENGLISH) + ");"); 115 return true; 116 } 117 return false; 118 } 119 120 121 public void visitLocalVariableInstruction( LocalVariableInstruction i ) { 122 short opcode = i.getOpcode(); 123 Type type = i.getType(_cp); 124 if (opcode == Constants.IINC) { 125 _out.println("il.append(new IINC(" + i.getIndex() + ", " + ((IINC) i).getIncrement() 126 + "));"); 127 } else { 128 String kind = (opcode < Constants.ISTORE) ? "Load" : "Store"; 129 _out.println("il.append(_factory.create" + kind + "(" + BCELifier.printType(type) 130 + ", " + i.getIndex() + "));"); 131 } 132 } 133 134 135 public void visitArrayInstruction( ArrayInstruction i ) { 136 short opcode = i.getOpcode(); 137 Type type = i.getType(_cp); 138 String kind = (opcode < Constants.IASTORE) ? "Load" : "Store"; 139 _out.println("il.append(_factory.createArray" + kind + "(" + BCELifier.printType(type) 140 + "));"); 141 } 142 143 144 public void visitFieldInstruction( FieldInstruction i ) { 145 short opcode = i.getOpcode(); 146 String class_name = i.getClassName(_cp); 147 String field_name = i.getFieldName(_cp); 148 Type type = i.getFieldType(_cp); 149 _out.println("il.append(_factory.createFieldAccess(\"" + class_name + "\", \"" + field_name 150 + "\", " + BCELifier.printType(type) + ", " + "Constants." 151 + Constants.OPCODE_NAMES[opcode].toUpperCase(Locale.ENGLISH) + "));"); 152 } 153 154 155 public void visitInvokeInstruction( InvokeInstruction i ) { 156 short opcode = i.getOpcode(); 157 String class_name = i.getClassName(_cp); 158 String method_name = i.getMethodName(_cp); 159 Type type = i.getReturnType(_cp); 160 Type[] arg_types = i.getArgumentTypes(_cp); 161 _out.println("il.append(_factory.createInvoke(\"" + class_name + "\", \"" + method_name 162 + "\", " + BCELifier.printType(type) + ", " 163 + BCELifier.printArgumentTypes(arg_types) + ", " + "Constants." 164 + Constants.OPCODE_NAMES[opcode].toUpperCase(Locale.ENGLISH) + "));"); 165 } 166 167 168 public void visitAllocationInstruction( AllocationInstruction i ) { 169 Type type; 170 if (i instanceof CPInstruction) { 171 type = ((CPInstruction) i).getType(_cp); 172 } else { 173 type = ((NEWARRAY) i).getType(); 174 } 175 short opcode = ((Instruction) i).getOpcode(); 176 int dim = 1; 177 switch (opcode) { 178 case Constants.NEW: 179 _out.println("il.append(_factory.createNew(\"" + ((ObjectType) type).getClassName() 180 + "\"));"); 181 break; 182 case Constants.MULTIANEWARRAY: 183 dim = ((MULTIANEWARRAY) i).getDimensions(); 184 case Constants.ANEWARRAY: 185 case Constants.NEWARRAY: 186 if (type instanceof ArrayType) { 187 type = ((ArrayType) type).getBasicType(); 188 } 189 _out.println("il.append(_factory.createNewArray(" + BCELifier.printType(type) 190 + ", (short) " + dim + "));"); 191 break; 192 default: 193 throw new RuntimeException ("Oops: " + opcode); 194 } 195 } 196 197 198 private void createConstant( Object value ) { 199 String embed = value.toString(); 200 if (value instanceof String ) { 201 embed = '"' + Utility.convertString(value.toString()) + '"'; 202 } else if (value instanceof Character ) { 203 embed = "(char)0x" + Integer.toHexString(((Character ) value).charValue()); 204 } 205 _out.println("il.append(new PUSH(_cp, " + embed + "));"); 206 } 207 208 209 public void visitLDC( LDC i ) { 210 createConstant(i.getValue(_cp)); 211 } 212 213 214 public void visitLDC2_W( LDC2_W i ) { 215 createConstant(i.getValue(_cp)); 216 } 217 218 219 public void visitConstantPushInstruction( ConstantPushInstruction i ) { 220 createConstant(i.getValue()); 221 } 222 223 224 public void visitINSTANCEOF( INSTANCEOF i ) { 225 Type type = i.getType(_cp); 226 _out.println("il.append(new INSTANCEOF(_cp.addClass(" + BCELifier.printType(type) + ")));"); 227 } 228 229 230 public void visitCHECKCAST( CHECKCAST i ) { 231 Type type = i.getType(_cp); 232 _out.println("il.append(_factory.createCheckCast(" + BCELifier.printType(type) + "));"); 233 } 234 235 236 public void visitReturnInstruction( ReturnInstruction i ) { 237 Type type = i.getType(_cp); 238 _out.println("il.append(_factory.createReturn(" + BCELifier.printType(type) + "));"); 239 } 240 241 private List branches = new ArrayList (); 243 244 245 public void visitBranchInstruction( BranchInstruction bi ) { 246 BranchHandle bh = (BranchHandle) branch_map.get(bi); 247 int pos = bh.getPosition(); 248 String name = bi.getName() + "_" + pos; 249 if (bi instanceof Select) { 250 Select s = (Select) bi; 251 branches.add(bi); 252 StringBuffer args = new StringBuffer ("new int[] { "); 253 int[] matchs = s.getMatchs(); 254 for (int i = 0; i < matchs.length; i++) { 255 args.append(matchs[i]); 256 if (i < matchs.length - 1) { 257 args.append(", "); 258 } 259 } 260 args.append(" }"); 261 _out.print("Select " + name + " = new " + bi.getName().toUpperCase(Locale.ENGLISH) 262 + "(" + args + ", new InstructionHandle[] { "); 263 for (int i = 0; i < matchs.length; i++) { 264 _out.print("null"); 265 if (i < matchs.length - 1) { 266 _out.print(", "); 267 } 268 } 269 _out.println(" }, null);"); 270 } else { 271 int t_pos = bh.getTarget().getPosition(); 272 String target; 273 if (pos > t_pos) { 274 target = "ih_" + t_pos; 275 } else { 276 branches.add(bi); 277 target = "null"; 278 } 279 _out.println(" BranchInstruction " + name + " = _factory.createBranchInstruction(" 280 + "Constants." + bi.getName().toUpperCase(Locale.ENGLISH) + ", " + target 281 + ");"); 282 } 283 if (bh.hasTargeters()) { 284 _out.println(" ih_" + pos + " = il.append(" + name + ");"); 285 } else { 286 _out.println(" il.append(" + name + ");"); 287 } 288 } 289 290 291 public void visitRET( RET i ) { 292 _out.println("il.append(new RET(" + i.getIndex() + ")));"); 293 } 294 295 296 private void updateBranchTargets() { 297 for (Iterator i = branches.iterator(); i.hasNext();) { 298 BranchInstruction bi = (BranchInstruction) i.next(); 299 BranchHandle bh = (BranchHandle) branch_map.get(bi); 300 int pos = bh.getPosition(); 301 String name = bi.getName() + "_" + pos; 302 int t_pos = bh.getTarget().getPosition(); 303 _out.println(" " + name + ".setTarget(ih_" + t_pos + ");"); 304 if (bi instanceof Select) { 305 InstructionHandle[] ihs = ((Select) bi).getTargets(); 306 for (int j = 0; j < ihs.length; j++) { 307 t_pos = ihs[j].getPosition(); 308 _out.println(" " + name + ".setTarget(" + j + ", ih_" + t_pos + ");"); 309 } 310 } 311 } 312 } 313 314 315 private void updateExceptionHandlers() { 316 CodeExceptionGen[] handlers = _mg.getExceptionHandlers(); 317 for (int i = 0; i < handlers.length; i++) { 318 CodeExceptionGen h = handlers[i]; 319 String type = (h.getCatchType() == null) ? "null" : BCELifier.printType(h 320 .getCatchType()); 321 _out.println(" method.addExceptionHandler(" + "ih_" + h.getStartPC().getPosition() 322 + ", " + "ih_" + h.getEndPC().getPosition() + ", " + "ih_" 323 + h.getHandlerPC().getPosition() + ", " + type + ");"); 324 } 325 } 326 } 327 | Popular Tags |