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