View Javadoc
1 package org.apache.bcel.generic; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache BCEL" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache BCEL", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>;. 55 */ 56 import org.apache.bcel.Constants; 57 58 /*** 59 * Instances of this class may be used, e.g., to generate typed 60 * versions of instructions. Its main purpose is to be used as the 61 * byte code generating backend of a compiler. You can subclass it to 62 * add your own create methods. 63 * 64 * @version $Id: InstructionFactory.java,v 1.6 2002/07/11 19:39:04 mdahm Exp $ 65 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> 66 * @see Constants 67 */ 68 public class InstructionFactory 69 implements InstructionConstants, java.io.Serializable 70 { 71 protected ClassGen cg; 72 protected ConstantPoolGen cp; 73 74 public InstructionFactory(ClassGen cg, ConstantPoolGen cp) { 75 this.cg = cg; 76 this.cp = cp; 77 } 78 79 /*** Initialize with ClassGen object 80 */ 81 public InstructionFactory(ClassGen cg) { 82 this(cg, cg.getConstantPool()); 83 } 84 85 /*** Initialize just with ConstantPoolGen object 86 */ 87 public InstructionFactory(ConstantPoolGen cp) { 88 this(null, cp); 89 } 90 91 /*** Create an invoke instruction. 92 * 93 * @param class_name name of the called class 94 * @param name name of the called method 95 * @param ret_type return type of method 96 * @param arg_types argument types of method 97 * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, 98 * or INVOKESPECIAL 99 * @see Constants 100 */ 101 public InvokeInstruction createInvoke(String class_name, String name, Type ret_type, 102 Type[] arg_types, short kind) { 103 int index; 104 int nargs = 0; 105 String signature = Type.getMethodSignature(ret_type, arg_types); 106 107 for(int i=0; i < arg_types.length; i++) // Count size of arguments 108 nargs += arg_types[i].getSize(); 109 110 if(kind == Constants.INVOKEINTERFACE) 111 index = cp.addInterfaceMethodref(class_name, name, signature); 112 else 113 index = cp.addMethodref(class_name, name, signature); 114 115 switch(kind) { 116 case Constants.INVOKESPECIAL: return new INVOKESPECIAL(index); 117 case Constants.INVOKEVIRTUAL: return new INVOKEVIRTUAL(index); 118 case Constants.INVOKESTATIC: return new INVOKESTATIC(index); 119 case Constants.INVOKEINTERFACE: return new INVOKEINTERFACE(index, nargs + 1); 120 default: 121 throw new RuntimeException("Oops: Unknown invoke kind:" + kind); 122 } 123 } 124 125 /*** Create a call to the most popular System.out.println() method. 126 * 127 * @param s the string to print 128 */ 129 public InstructionList createPrintln(String s) { 130 InstructionList il = new InstructionList(); 131 int out = cp.addFieldref("java.lang.System", "out", 132 "Ljava/io/PrintStream;"); 133 int println = cp.addMethodref("java.io.PrintStream", "println", 134 "(Ljava/lang/String;)V"); 135 136 il.append(new GETSTATIC(out)); 137 il.append(new PUSH(cp, s)); 138 il.append(new INVOKEVIRTUAL(println)); 139 140 return il; 141 } 142 143 /*** Uses PUSH to push a constant value onto the stack. 144 * @param value must be of type Number, Boolean, Character or String 145 */ 146 public Instruction createConstant(Object value) { 147 PUSH push; 148 149 if(value instanceof Number) 150 push = new PUSH(cp, (Number)value); 151 else if(value instanceof String) 152 push = new PUSH(cp, (String)value); 153 else if(value instanceof Boolean) 154 push = new PUSH(cp, (Boolean)value); 155 else if(value instanceof Character) 156 push = new PUSH(cp, (Character)value); 157 else 158 throw new ClassGenException("Illegal type: " + value.getClass()); 159 160 return push.getInstruction(); 161 } 162 163 private static class MethodObject { 164 Type[] arg_types; 165 Type result_type; 166 String[] arg_names; 167 String class_name; 168 String name; 169 int access; 170 171 MethodObject(String c, String n, Type r, Type[] a, int acc) { 172 class_name = c; 173 name = n; 174 result_type = r; 175 arg_types = a; 176 access = acc; 177 } 178 } 179 180 private InvokeInstruction createInvoke(MethodObject m, short kind) { 181 return createInvoke(m.class_name, m.name, m.result_type, m.arg_types, kind); 182 } 183 184 private static MethodObject[] append_mos = { 185 new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, 186 new Type[] { Type.STRING }, Constants.ACC_PUBLIC), 187 new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, 188 new Type[] { Type.OBJECT }, Constants.ACC_PUBLIC), 189 null, null, // indices 2, 3 190 new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, 191 new Type[] { Type.BOOLEAN }, Constants.ACC_PUBLIC), 192 new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, 193 new Type[] { Type.CHAR }, Constants.ACC_PUBLIC), 194 new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, 195 new Type[] { Type.FLOAT }, Constants.ACC_PUBLIC), 196 new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, 197 new Type[] { Type.DOUBLE }, Constants.ACC_PUBLIC), 198 new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, 199 new Type[] { Type.INT }, Constants.ACC_PUBLIC), 200 new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(byte) 201 new Type[] { Type.INT }, Constants.ACC_PUBLIC), 202 new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(short) 203 new Type[] { Type.INT }, Constants.ACC_PUBLIC), 204 new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, 205 new Type[] { Type.LONG }, Constants.ACC_PUBLIC) 206 }; 207 208 private static final boolean isString(Type type) { 209 return ((type instanceof ObjectType) && 210 ((ObjectType)type).getClassName().equals("java.lang.String")); 211 } 212 213 public Instruction createAppend(Type type) { 214 byte t = type.getType(); 215 216 if(isString(type)) 217 return createInvoke(append_mos[0], Constants.INVOKEVIRTUAL); 218 219 switch(t) { 220 case Constants.T_BOOLEAN: 221 case Constants.T_CHAR: 222 case Constants.T_FLOAT: 223 case Constants.T_DOUBLE: 224 case Constants.T_BYTE: 225 case Constants.T_SHORT: 226 case Constants.T_INT: 227 case Constants.T_LONG 228 : return createInvoke(append_mos[t], Constants.INVOKEVIRTUAL); 229 case Constants.T_ARRAY: 230 case Constants.T_OBJECT: 231 return createInvoke(append_mos[1], Constants.INVOKEVIRTUAL); 232 default: 233 throw new RuntimeException("Oops: No append for this type? " + type); 234 } 235 } 236 237 /*** Create a field instruction. 238 * 239 * @param class_name name of the accessed class 240 * @param name name of the referenced field 241 * @param type type of field 242 * @param kind how to access, i.e., GETFIELD, PUTFIELD, GETSTATIC, PUTSTATIC 243 * @see Constants 244 */ 245 public FieldInstruction createFieldAccess(String class_name, String name, Type type, short kind) { 246 int index; 247 String signature = type.getSignature(); 248 249 index = cp.addFieldref(class_name, name, signature); 250 251 switch(kind) { 252 case Constants.GETFIELD: return new GETFIELD(index); 253 case Constants.PUTFIELD: return new PUTFIELD(index); 254 case Constants.GETSTATIC: return new GETSTATIC(index); 255 case Constants.PUTSTATIC: return new PUTSTATIC(index); 256 257 default: 258 throw new RuntimeException("Oops: Unknown getfield kind:" + kind); 259 } 260 } 261 262 /*** Create reference to `this' 263 */ 264 public static Instruction createThis() { 265 return new ALOAD(0); 266 } 267 268 /*** Create typed return 269 */ 270 public static ReturnInstruction createReturn(Type type) { 271 switch(type.getType()) { 272 case Constants.T_ARRAY: 273 case Constants.T_OBJECT: return ARETURN; 274 case Constants.T_INT: 275 case Constants.T_SHORT: 276 case Constants.T_BOOLEAN: 277 case Constants.T_CHAR: 278 case Constants.T_BYTE: return IRETURN; 279 case Constants.T_FLOAT: return FRETURN; 280 case Constants.T_DOUBLE: return DRETURN; 281 case Constants.T_LONG: return LRETURN; 282 case Constants.T_VOID: return RETURN; 283 284 default: 285 throw new RuntimeException("Invalid type: " + type); 286 } 287 } 288 289 private static final ArithmeticInstruction createBinaryIntOp(char first, String op) { 290 switch(first) { 291 case '-' : return ISUB; 292 case '+' : return IADD; 293 case '%' : return IREM; 294 case '*' : return IMUL; 295 case '/' : return IDIV; 296 case '&' : return IAND; 297 case '|' : return IOR; 298 case '^' : return IXOR; 299 case '<' : return ISHL; 300 case '>' : return op.equals(">>>")? (ArithmeticInstruction)IUSHR : 301 (ArithmeticInstruction)ISHR; 302 default: throw new RuntimeException("Invalid operand " + op); 303 } 304 } 305 306 private static final ArithmeticInstruction createBinaryLongOp(char first, String op) { 307 switch(first) { 308 case '-' : return LSUB; 309 case '+' : return LADD; 310 case '%' : return LREM; 311 case '*' : return LMUL; 312 case '/' : return LDIV; 313 case '&' : return LAND; 314 case '|' : return LOR; 315 case '^' : return LXOR; 316 case '<' : return LSHL; 317 case '>' : return op.equals(">>>")? (ArithmeticInstruction)LUSHR : 318 (ArithmeticInstruction)LSHR; 319 default: throw new RuntimeException("Invalid operand " + op); 320 } 321 } 322 323 private static final ArithmeticInstruction createBinaryFloatOp(char op) { 324 switch(op) { 325 case '-' : return FSUB; 326 case '+' : return FADD; 327 case '*' : return FMUL; 328 case '/' : return FDIV; 329 default: throw new RuntimeException("Invalid operand " + op); 330 } 331 } 332 333 private static final ArithmeticInstruction createBinaryDoubleOp(char op) { 334 switch(op) { 335 case '-' : return DSUB; 336 case '+' : return DADD; 337 case '*' : return DMUL; 338 case '/' : return DDIV; 339 default: throw new RuntimeException("Invalid operand " + op); 340 } 341 } 342 343 /*** 344 * Create binary operation for simple basic types, such as int and float. 345 * 346 * @param op operation, such as "+", "*", "<<", etc. 347 */ 348 public static ArithmeticInstruction createBinaryOperation(String op, Type type) { 349 char first = op.toCharArray()[0]; 350 351 switch(type.getType()) { 352 case Constants.T_BYTE: 353 case Constants.T_SHORT: 354 case Constants.T_INT: 355 case Constants.T_CHAR: return createBinaryIntOp(first, op); 356 case Constants.T_LONG: return createBinaryLongOp(first, op); 357 case Constants.T_FLOAT: return createBinaryFloatOp(first); 358 case Constants.T_DOUBLE: return createBinaryDoubleOp(first); 359 default: throw new RuntimeException("Invalid type " + type); 360 } 361 } 362 363 /*** 364 * @param size size of operand, either 1 (int, e.g.) or 2 (double) 365 */ 366 public static StackInstruction createPop(int size) { 367 return (size == 2)? (StackInstruction)POP2 : 368 (StackInstruction)POP; 369 } 370 371 /*** 372 * @param size size of operand, either 1 (int, e.g.) or 2 (double) 373 */ 374 public static StackInstruction createDup(int size) { 375 return (size == 2)? (StackInstruction)DUP2 : 376 (StackInstruction)DUP; 377 } 378 379 /*** 380 * @param size size of operand, either 1 (int, e.g.) or 2 (double) 381 */ 382 public static StackInstruction createDup_2(int size) { 383 return (size == 2)? (StackInstruction)DUP2_X2 : 384 (StackInstruction)DUP_X2; 385 } 386 387 /*** 388 * @param size size of operand, either 1 (int, e.g.) or 2 (double) 389 */ 390 public static StackInstruction createDup_1(int size) { 391 return (size == 2)? (StackInstruction)DUP2_X1 : 392 (StackInstruction)DUP_X1; 393 } 394 395 /*** 396 * @param index index of local variable 397 */ 398 public static LocalVariableInstruction createStore(Type type, int index) { 399 switch(type.getType()) { 400 case Constants.T_BOOLEAN: 401 case Constants.T_CHAR: 402 case Constants.T_BYTE: 403 case Constants.T_SHORT: 404 case Constants.T_INT: return new ISTORE(index); 405 case Constants.T_FLOAT: return new FSTORE(index); 406 case Constants.T_DOUBLE: return new DSTORE(index); 407 case Constants.T_LONG: return new LSTORE(index); 408 case Constants.T_ARRAY: 409 case Constants.T_OBJECT: return new ASTORE(index); 410 default: throw new RuntimeException("Invalid type " + type); 411 } 412 } 413 414 /*** 415 * @param index index of local variable 416 */ 417 public static LocalVariableInstruction createLoad(Type type, int index) { 418 switch(type.getType()) { 419 case Constants.T_BOOLEAN: 420 case Constants.T_CHAR: 421 case Constants.T_BYTE: 422 case Constants.T_SHORT: 423 case Constants.T_INT: return new ILOAD(index); 424 case Constants.T_FLOAT: return new FLOAD(index); 425 case Constants.T_DOUBLE: return new DLOAD(index); 426 case Constants.T_LONG: return new LLOAD(index); 427 case Constants.T_ARRAY: 428 case Constants.T_OBJECT: return new ALOAD(index); 429 default: throw new RuntimeException("Invalid type " + type); 430 } 431 } 432 433 /*** 434 * @param type type of elements of array, i.e., array.getElementType() 435 */ 436 public static ArrayInstruction createArrayLoad(Type type) { 437 switch(type.getType()) { 438 case Constants.T_BOOLEAN: 439 case Constants.T_BYTE: return BALOAD; 440 case Constants.T_CHAR: return CALOAD; 441 case Constants.T_SHORT: return SALOAD; 442 case Constants.T_INT: return IALOAD; 443 case Constants.T_FLOAT: return FALOAD; 444 case Constants.T_DOUBLE: return DALOAD; 445 case Constants.T_LONG: return LALOAD; 446 case Constants.T_ARRAY: 447 case Constants.T_OBJECT: return AALOAD; 448 default: throw new RuntimeException("Invalid type " + type); 449 } 450 } 451 452 /*** 453 * @param type type of elements of array, i.e., array.getElementType() 454 */ 455 public static ArrayInstruction createArrayStore(Type type) { 456 switch(type.getType()) { 457 case Constants.T_BOOLEAN: 458 case Constants.T_BYTE: return BASTORE; 459 case Constants.T_CHAR: return CASTORE; 460 case Constants.T_SHORT: return SASTORE; 461 case Constants.T_INT: return IASTORE; 462 case Constants.T_FLOAT: return FASTORE; 463 case Constants.T_DOUBLE: return DASTORE; 464 case Constants.T_LONG: return LASTORE; 465 case Constants.T_ARRAY: 466 case Constants.T_OBJECT: return AASTORE; 467 default: throw new RuntimeException("Invalid type " + type); 468 } 469 } 470 471 472 /*** Create conversion operation for two stack operands, this may be an I2C, instruction, e.g., 473 * if the operands are basic types and CHECKCAST if they are reference types. 474 */ 475 public Instruction createCast(Type src_type, Type dest_type) { 476 if((src_type instanceof BasicType) && (dest_type instanceof BasicType)) { 477 byte dest = dest_type.getType(); 478 byte src = src_type.getType(); 479 480 if(dest == Constants.T_LONG && (src == Constants.T_CHAR || src == Constants.T_BYTE || 481 src == Constants.T_SHORT)) 482 src = Constants.T_INT; 483 484 String[] short_names = { "C", "F", "D", "B", "S", "I", "L" }; 485 486 String name = "org.apache.bcel.generic." + short_names[src - Constants.T_CHAR] + 487 "2" + short_names[dest - Constants.T_CHAR]; 488 489 Instruction i = null; 490 try { 491 i = (Instruction)java.lang.Class.forName(name).newInstance(); 492 } catch(Exception e) { 493 throw new RuntimeException("Could not find instruction: " + name); 494 } 495 496 return i; 497 } else if((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) { 498 if(dest_type instanceof ArrayType) 499 return new CHECKCAST(cp.addArrayClass((ArrayType)dest_type)); 500 else 501 return new CHECKCAST(cp.addClass(((ObjectType)dest_type).getClassName())); 502 } 503 else 504 throw new RuntimeException("Can not cast " + src_type + " to " + dest_type); 505 } 506 507 public GETFIELD createGetField(String class_name, String name, Type t) { 508 return new GETFIELD(cp.addFieldref(class_name, name, t.getSignature())); 509 } 510 511 public GETSTATIC createGetStatic(String class_name, String name, Type t) { 512 return new GETSTATIC(cp.addFieldref(class_name, name, t.getSignature())); 513 } 514 515 public PUTFIELD createPutField(String class_name, String name, Type t) { 516 return new PUTFIELD(cp.addFieldref(class_name, name, t.getSignature())); 517 } 518 519 public PUTSTATIC createPutStatic(String class_name, String name, Type t) { 520 return new PUTSTATIC(cp.addFieldref(class_name, name, t.getSignature())); 521 } 522 523 public CHECKCAST createCheckCast(ReferenceType t) { 524 if(t instanceof ArrayType) 525 return new CHECKCAST(cp.addArrayClass((ArrayType)t)); 526 else 527 return new CHECKCAST(cp.addClass((ObjectType)t)); 528 } 529 530 public INSTANCEOF createInstanceOf(ReferenceType t) { 531 if(t instanceof ArrayType) 532 return new INSTANCEOF(cp.addArrayClass((ArrayType)t)); 533 else 534 return new INSTANCEOF(cp.addClass((ObjectType)t)); 535 } 536 537 public NEW createNew(ObjectType t) { 538 return new NEW(cp.addClass(t)); 539 } 540 541 public NEW createNew(String s) { 542 return createNew(new ObjectType(s)); 543 } 544 545 /*** Create new array of given size and type. 546 * @return an instruction that creates the corresponding array at runtime, i.e. is an AllocationInstruction 547 */ 548 public Instruction createNewArray(Type t, short dim) { 549 if(dim == 1) { 550 if(t instanceof ObjectType) 551 return new ANEWARRAY(cp.addClass((ObjectType)t)); 552 else if(t instanceof ArrayType) 553 return new ANEWARRAY(cp.addArrayClass((ArrayType)t)); 554 else 555 return new NEWARRAY(((BasicType)t).getType()); 556 } else { 557 ArrayType at; 558 559 if(t instanceof ArrayType) 560 at = (ArrayType)t; 561 else 562 at = new ArrayType(t, dim); 563 564 return new MULTIANEWARRAY(cp.addArrayClass(at), dim); 565 } 566 } 567 568 /*** Create "null" value for reference types, 0 for basic types like int 569 */ 570 public static Instruction createNull(Type type) { 571 switch(type.getType()) { 572 case Constants.T_ARRAY: 573 case Constants.T_OBJECT: return ACONST_NULL; 574 case Constants.T_INT: 575 case Constants.T_SHORT: 576 case Constants.T_BOOLEAN: 577 case Constants.T_CHAR: 578 case Constants.T_BYTE: return ICONST_0; 579 case Constants.T_FLOAT: return FCONST_0; 580 case Constants.T_DOUBLE: return DCONST_0; 581 case Constants.T_LONG: return LCONST_0; 582 case Constants.T_VOID: return NOP; 583 584 default: 585 throw new RuntimeException("Invalid type: " + type); 586 } 587 } 588 589 /*** Create branch instruction by given opcode, except LOOKUPSWITCH and TABLESWITCH. 590 * For those you should use the SWITCH compound instruction. 591 */ 592 public static BranchInstruction createBranchInstruction(short opcode, InstructionHandle target) { 593 switch(opcode) { 594 case Constants.IFEQ: return new IFEQ(target); 595 case Constants.IFNE: return new IFNE(target); 596 case Constants.IFLT: return new IFLT(target); 597 case Constants.IFGE: return new IFGE(target); 598 case Constants.IFGT: return new IFGT(target); 599 case Constants.IFLE: return new IFLE(target); 600 case Constants.IF_ICMPEQ: return new IF_ICMPEQ(target); 601 case Constants.IF_ICMPNE: return new IF_ICMPNE(target); 602 case Constants.IF_ICMPLT: return new IF_ICMPLT(target); 603 case Constants.IF_ICMPGE: return new IF_ICMPGE(target); 604 case Constants.IF_ICMPGT: return new IF_ICMPGT(target); 605 case Constants.IF_ICMPLE: return new IF_ICMPLE(target); 606 case Constants.IF_ACMPEQ: return new IF_ACMPEQ(target); 607 case Constants.IF_ACMPNE: return new IF_ACMPNE(target); 608 case Constants.GOTO: return new GOTO(target); 609 case Constants.JSR: return new JSR(target); 610 case Constants.IFNULL: return new IFNULL(target); 611 case Constants.IFNONNULL: return new IFNONNULL(target); 612 case Constants.GOTO_W: return new GOTO_W(target); 613 case Constants.JSR_W: return new JSR_W(target); 614 default: 615 throw new RuntimeException("Invalid opcode: " + opcode); 616 } 617 } 618 619 public void setClassGen(ClassGen c) { cg = c; } 620 public ClassGen getClassGen() { return cg; } 621 public void setConstantPool(ConstantPoolGen c) { cp = c; } 622 public ConstantPoolGen getConstantPool() { return cp; } 623 }

This page was automatically generated by Maven