    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