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