jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java
author dbuck
Thu, 06 Nov 2014 23:14:02 -0800
changeset 27535 872cc59854b0
parent 25868 686eef1e7a79
child 27537 77d9ab3c1028
permissions -rw-r--r--
8062608: BCEL corrupts debug data of methods that use generics Summary: Fixed MethodGen constructor to not overwrite LocalVariableTable. Reviewed-by: 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
7f561c08de6b Initial load
duke
parents:
diff changeset
    61
import com.sun.org.apache.bcel.internal.Constants;
7f561c08de6b Initial load
duke
parents:
diff changeset
    62
import com.sun.org.apache.bcel.internal.classfile.*;
7f561c08de6b Initial load
duke
parents:
diff changeset
    63
import java.util.*;
7f561c08de6b Initial load
duke
parents:
diff changeset
    64
7f561c08de6b Initial load
duke
parents:
diff changeset
    65
/**
7f561c08de6b Initial load
duke
parents:
diff changeset
    66
 * Template class for building up a method. This is done by defining exception
7f561c08de6b Initial load
duke
parents:
diff changeset
    67
 * handlers, adding thrown exceptions, local variables and attributes, whereas
7f561c08de6b Initial load
duke
parents:
diff changeset
    68
 * the `LocalVariableTable' and `LineNumberTable' attributes will be set
7f561c08de6b Initial load
duke
parents:
diff changeset
    69
 * automatically for the code. Use stripAttributes() if you don't like this.
7f561c08de6b Initial load
duke
parents:
diff changeset
    70
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    71
 * While generating code it may be necessary to insert NOP operations. You can
7f561c08de6b Initial load
duke
parents:
diff changeset
    72
 * use the `removeNOPs' method to get rid off them.
7f561c08de6b Initial load
duke
parents:
diff changeset
    73
 * The resulting method object can be obtained via the `getMethod()' method.
7f561c08de6b Initial load
duke
parents:
diff changeset
    74
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    75
 * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
7f561c08de6b Initial load
duke
parents:
diff changeset
    76
 * @author  <A HREF="http://www.vmeng.com/beard">Patrick C. Beard</A> [setMaxStack()]
7f561c08de6b Initial load
duke
parents:
diff changeset
    77
 * @see     InstructionList
7f561c08de6b Initial load
duke
parents:
diff changeset
    78
 * @see     Method
7f561c08de6b Initial load
duke
parents:
diff changeset
    79
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    80
public class MethodGen extends FieldGenOrMethodGen {
7f561c08de6b Initial load
duke
parents:
diff changeset
    81
  private String          class_name;
7f561c08de6b Initial load
duke
parents:
diff changeset
    82
  private Type[]          arg_types;
7f561c08de6b Initial load
duke
parents:
diff changeset
    83
  private String[]        arg_names;
7f561c08de6b Initial load
duke
parents:
diff changeset
    84
  private int             max_locals;
7f561c08de6b Initial load
duke
parents:
diff changeset
    85
  private int             max_stack;
7f561c08de6b Initial load
duke
parents:
diff changeset
    86
  private InstructionList il;
7f561c08de6b Initial load
duke
parents:
diff changeset
    87
  private boolean         strip_attributes;
7f561c08de6b Initial load
duke
parents:
diff changeset
    88
7f561c08de6b Initial load
duke
parents:
diff changeset
    89
  private ArrayList       variable_vec    = new ArrayList();
7f561c08de6b Initial load
duke
parents:
diff changeset
    90
  private ArrayList       line_number_vec = new ArrayList();
7f561c08de6b Initial load
duke
parents:
diff changeset
    91
  private ArrayList       exception_vec   = new ArrayList();
7f561c08de6b Initial load
duke
parents:
diff changeset
    92
  private ArrayList       throws_vec      = new ArrayList();
7f561c08de6b Initial load
duke
parents:
diff changeset
    93
  private ArrayList       code_attrs_vec  = new ArrayList();
7f561c08de6b Initial load
duke
parents:
diff changeset
    94
7f561c08de6b Initial load
duke
parents:
diff changeset
    95
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    96
   * Declare method. If the method is non-static the constructor
7f561c08de6b Initial load
duke
parents:
diff changeset
    97
   * automatically declares a local variable `$this' in slot 0. The
7f561c08de6b Initial load
duke
parents:
diff changeset
    98
   * actual code is contained in the `il' parameter, which may further
7f561c08de6b Initial load
duke
parents:
diff changeset
    99
   * manipulated by the user. But he must take care not to remove any
7f561c08de6b Initial load
duke
parents:
diff changeset
   100
   * instruction (handles) that are still referenced from this object.
7f561c08de6b Initial load
duke
parents:
diff changeset
   101
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   102
   * For example one may not add a local variable and later remove the
7f561c08de6b Initial load
duke
parents:
diff changeset
   103
   * instructions it refers to without causing havoc. It is safe
7f561c08de6b Initial load
duke
parents:
diff changeset
   104
   * however if you remove that local variable, too.
7f561c08de6b Initial load
duke
parents:
diff changeset
   105
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   106
   * @param access_flags access qualifiers
7f561c08de6b Initial load
duke
parents:
diff changeset
   107
   * @param return_type  method type
7f561c08de6b Initial load
duke
parents:
diff changeset
   108
   * @param arg_types argument types
7f561c08de6b Initial load
duke
parents:
diff changeset
   109
   * @param arg_names argument names (if this is null, default names will be provided
7f561c08de6b Initial load
duke
parents:
diff changeset
   110
   * for them)
7f561c08de6b Initial load
duke
parents:
diff changeset
   111
   * @param method_name name of method
7f561c08de6b Initial load
duke
parents:
diff changeset
   112
   * @param class_name class name containing this method (may be null, if you don't care)
7f561c08de6b Initial load
duke
parents:
diff changeset
   113
   * @param il instruction list associated with this method, may be null only for
7f561c08de6b Initial load
duke
parents:
diff changeset
   114
   * abstract or native methods
7f561c08de6b Initial load
duke
parents:
diff changeset
   115
   * @param cp constant pool
7f561c08de6b Initial load
duke
parents:
diff changeset
   116
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   117
  public MethodGen(int access_flags, Type return_type, Type[] arg_types,
7f561c08de6b Initial load
duke
parents:
diff changeset
   118
                   String[] arg_names, String method_name, String class_name,
7f561c08de6b Initial load
duke
parents:
diff changeset
   119
                   InstructionList il, ConstantPoolGen cp) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   120
    setAccessFlags(access_flags);
7f561c08de6b Initial load
duke
parents:
diff changeset
   121
    setType(return_type);
7f561c08de6b Initial load
duke
parents:
diff changeset
   122
    setArgumentTypes(arg_types);
7f561c08de6b Initial load
duke
parents:
diff changeset
   123
    setArgumentNames(arg_names);
7f561c08de6b Initial load
duke
parents:
diff changeset
   124
    setName(method_name);
7f561c08de6b Initial load
duke
parents:
diff changeset
   125
    setClassName(class_name);
7f561c08de6b Initial load
duke
parents:
diff changeset
   126
    setInstructionList(il);
7f561c08de6b Initial load
duke
parents:
diff changeset
   127
    setConstantPool(cp);
7f561c08de6b Initial load
duke
parents:
diff changeset
   128
7f561c08de6b Initial load
duke
parents:
diff changeset
   129
    boolean abstract_ = isAbstract() || isNative();
7f561c08de6b Initial load
duke
parents:
diff changeset
   130
    InstructionHandle start = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   131
    InstructionHandle end   = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   132
7f561c08de6b Initial load
duke
parents:
diff changeset
   133
    if(!abstract_) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   134
      start = il.getStart();
7f561c08de6b Initial load
duke
parents:
diff changeset
   135
      end   = il.getEnd();
7f561c08de6b Initial load
duke
parents:
diff changeset
   136
7f561c08de6b Initial load
duke
parents:
diff changeset
   137
      /* Add local variables, namely the implicit `this' and the arguments
7f561c08de6b Initial load
duke
parents:
diff changeset
   138
       */
7f561c08de6b Initial load
duke
parents:
diff changeset
   139
      if(!isStatic() && (class_name != null)) { // Instance method -> `this' is local var 0
7f561c08de6b Initial load
duke
parents:
diff changeset
   140
        addLocalVariable("this", new ObjectType(class_name), start, end);
7f561c08de6b Initial load
duke
parents:
diff changeset
   141
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   142
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   143
7f561c08de6b Initial load
duke
parents:
diff changeset
   144
    if(arg_types != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   145
      int size = arg_types.length;
7f561c08de6b Initial load
duke
parents:
diff changeset
   146
7f561c08de6b Initial load
duke
parents:
diff changeset
   147
      for(int i=0; i < size; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   148
        if(Type.VOID == arg_types[i]) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   149
          throw new ClassGenException("'void' is an illegal argument type for a method");
7f561c08de6b Initial load
duke
parents:
diff changeset
   150
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   151
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   152
7f561c08de6b Initial load
duke
parents:
diff changeset
   153
      if(arg_names != null) { // Names for variables provided?
7f561c08de6b Initial load
duke
parents:
diff changeset
   154
        if(size != arg_names.length)
7f561c08de6b Initial load
duke
parents:
diff changeset
   155
          throw new ClassGenException("Mismatch in argument array lengths: " +
7f561c08de6b Initial load
duke
parents:
diff changeset
   156
                                      size + " vs. " + arg_names.length);
7f561c08de6b Initial load
duke
parents:
diff changeset
   157
      } else { // Give them dummy names
7f561c08de6b Initial load
duke
parents:
diff changeset
   158
        arg_names = new String[size];
7f561c08de6b Initial load
duke
parents:
diff changeset
   159
7f561c08de6b Initial load
duke
parents:
diff changeset
   160
        for(int i=0; i < size; i++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   161
          arg_names[i] = "arg" + i;
7f561c08de6b Initial load
duke
parents:
diff changeset
   162
7f561c08de6b Initial load
duke
parents:
diff changeset
   163
        setArgumentNames(arg_names);
7f561c08de6b Initial load
duke
parents:
diff changeset
   164
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   165
7f561c08de6b Initial load
duke
parents:
diff changeset
   166
      if(!abstract_) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   167
        for(int i=0; i < size; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   168
          addLocalVariable(arg_names[i], arg_types[i], start, end);
7f561c08de6b Initial load
duke
parents:
diff changeset
   169
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   170
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   171
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   172
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   173
7f561c08de6b Initial load
duke
parents:
diff changeset
   174
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   175
   * Instantiate from existing method.
7f561c08de6b Initial load
duke
parents:
diff changeset
   176
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   177
   * @param m method
7f561c08de6b Initial load
duke
parents:
diff changeset
   178
   * @param class_name class name containing this method
7f561c08de6b Initial load
duke
parents:
diff changeset
   179
   * @param cp constant pool
7f561c08de6b Initial load
duke
parents:
diff changeset
   180
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   181
  public MethodGen(Method m, String class_name, ConstantPoolGen cp) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   182
    this(m.getAccessFlags(), Type.getReturnType(m.getSignature()),
7f561c08de6b Initial load
duke
parents:
diff changeset
   183
         Type.getArgumentTypes(m.getSignature()), null /* may be overridden anyway */,
7f561c08de6b Initial load
duke
parents:
diff changeset
   184
         m.getName(), class_name,
7f561c08de6b Initial load
duke
parents:
diff changeset
   185
         ((m.getAccessFlags() & (Constants.ACC_ABSTRACT | Constants.ACC_NATIVE)) == 0)?
7f561c08de6b Initial load
duke
parents:
diff changeset
   186
         new InstructionList(m.getCode().getCode()) : null,
7f561c08de6b Initial load
duke
parents:
diff changeset
   187
         cp);
7f561c08de6b Initial load
duke
parents:
diff changeset
   188
7f561c08de6b Initial load
duke
parents:
diff changeset
   189
    Attribute[] attributes = m.getAttributes();
7f561c08de6b Initial load
duke
parents:
diff changeset
   190
    for(int i=0; i < attributes.length; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   191
      Attribute a = attributes[i];
7f561c08de6b Initial load
duke
parents:
diff changeset
   192
7f561c08de6b Initial load
duke
parents:
diff changeset
   193
      if(a instanceof Code) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   194
        Code c = (Code)a;
7f561c08de6b Initial load
duke
parents:
diff changeset
   195
        setMaxStack(c.getMaxStack());
7f561c08de6b Initial load
duke
parents:
diff changeset
   196
        setMaxLocals(c.getMaxLocals());
7f561c08de6b Initial load
duke
parents:
diff changeset
   197
7f561c08de6b Initial load
duke
parents:
diff changeset
   198
        CodeException[] ces = c.getExceptionTable();
7f561c08de6b Initial load
duke
parents:
diff changeset
   199
7f561c08de6b Initial load
duke
parents:
diff changeset
   200
        if(ces != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   201
          for(int j=0; j < ces.length; j++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   202
            CodeException ce     = ces[j];
7f561c08de6b Initial load
duke
parents:
diff changeset
   203
            int           type   = ce.getCatchType();
7f561c08de6b Initial load
duke
parents:
diff changeset
   204
            ObjectType    c_type = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   205
7f561c08de6b Initial load
duke
parents:
diff changeset
   206
            if(type > 0) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   207
              String cen = m.getConstantPool().getConstantString(type, Constants.CONSTANT_Class);
7f561c08de6b Initial load
duke
parents:
diff changeset
   208
              c_type = new ObjectType(cen);
7f561c08de6b Initial load
duke
parents:
diff changeset
   209
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   210
7f561c08de6b Initial load
duke
parents:
diff changeset
   211
            int end_pc = ce.getEndPC();
7f561c08de6b Initial load
duke
parents:
diff changeset
   212
            int length = m.getCode().getCode().length;
7f561c08de6b Initial load
duke
parents:
diff changeset
   213
7f561c08de6b Initial load
duke
parents:
diff changeset
   214
            InstructionHandle end;
7f561c08de6b Initial load
duke
parents:
diff changeset
   215
7f561c08de6b Initial load
duke
parents:
diff changeset
   216
            if(length == end_pc) { // May happen, because end_pc is exclusive
7f561c08de6b Initial load
duke
parents:
diff changeset
   217
              end = il.getEnd();
7f561c08de6b Initial load
duke
parents:
diff changeset
   218
            } else {
7f561c08de6b Initial load
duke
parents:
diff changeset
   219
              end = il.findHandle(end_pc);
7f561c08de6b Initial load
duke
parents:
diff changeset
   220
              end = end.getPrev(); // Make it inclusive
7f561c08de6b Initial load
duke
parents:
diff changeset
   221
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   222
7f561c08de6b Initial load
duke
parents:
diff changeset
   223
            addExceptionHandler(il.findHandle(ce.getStartPC()), end,
7f561c08de6b Initial load
duke
parents:
diff changeset
   224
                                il.findHandle(ce.getHandlerPC()), c_type);
7f561c08de6b Initial load
duke
parents:
diff changeset
   225
          }
7f561c08de6b Initial load
duke
parents:
diff changeset
   226
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   227
7f561c08de6b Initial load
duke
parents:
diff changeset
   228
        Attribute[] c_attributes = c.getAttributes();
7f561c08de6b Initial load
duke
parents:
diff changeset
   229
        for(int j=0; j < c_attributes.length; j++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   230
          a = c_attributes[j];
7f561c08de6b Initial load
duke
parents:
diff changeset
   231
7f561c08de6b Initial load
duke
parents:
diff changeset
   232
          if(a instanceof LineNumberTable) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   233
            LineNumber[] ln = ((LineNumberTable)a).getLineNumberTable();
7f561c08de6b Initial load
duke
parents:
diff changeset
   234
7f561c08de6b Initial load
duke
parents:
diff changeset
   235
            for(int k=0; k < ln.length; k++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   236
              LineNumber l = ln[k];
7f561c08de6b Initial load
duke
parents:
diff changeset
   237
              addLineNumber(il.findHandle(l.getStartPC()), l.getLineNumber());
7f561c08de6b Initial load
duke
parents:
diff changeset
   238
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   239
          } else if(a instanceof LocalVariableTable) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   240
            LocalVariable[] lv = ((LocalVariableTable)a).getLocalVariableTable();
7f561c08de6b Initial load
duke
parents:
diff changeset
   241
7f561c08de6b Initial load
duke
parents:
diff changeset
   242
            removeLocalVariables();
7f561c08de6b Initial load
duke
parents:
diff changeset
   243
7f561c08de6b Initial load
duke
parents:
diff changeset
   244
            for(int k=0; k < lv.length; k++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   245
              LocalVariable     l     = lv[k];
7f561c08de6b Initial load
duke
parents:
diff changeset
   246
              InstructionHandle start = il.findHandle(l.getStartPC());
7f561c08de6b Initial load
duke
parents:
diff changeset
   247
              InstructionHandle end   = il.findHandle(l.getStartPC() + l.getLength());
7f561c08de6b Initial load
duke
parents:
diff changeset
   248
7f561c08de6b Initial load
duke
parents:
diff changeset
   249
              // Repair malformed handles
7f561c08de6b Initial load
duke
parents:
diff changeset
   250
              if(null == start) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   251
                start = il.getStart();
7f561c08de6b Initial load
duke
parents:
diff changeset
   252
              }
7f561c08de6b Initial load
duke
parents:
diff changeset
   253
7f561c08de6b Initial load
duke
parents:
diff changeset
   254
              if(null == end) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   255
                end = il.getEnd();
7f561c08de6b Initial load
duke
parents:
diff changeset
   256
              }
7f561c08de6b Initial load
duke
parents:
diff changeset
   257
7f561c08de6b Initial load
duke
parents:
diff changeset
   258
              addLocalVariable(l.getName(), Type.getType(l.getSignature()),
7f561c08de6b Initial load
duke
parents:
diff changeset
   259
                               l.getIndex(), start, end);
7f561c08de6b Initial load
duke
parents:
diff changeset
   260
            }
15346
3f6fd93fec9a 8003147: port fix for BCEL bug 39695
dbuck
parents: 12457
diff changeset
   261
          } else if (a instanceof LocalVariableTypeTable) {
27535
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   262
             LocalVariable[] oldLV = ((LocalVariableTypeTable) a).getLocalVariableTypeTable();
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   263
             int lvLength = oldLV.length;
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   264
             LocalVariable[] newLV = new LocalVariable[lvLength];
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   265
             for (int k = 0; k < lvLength; k++) {
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   266
                 LocalVariable l = oldLV[k];
15346
3f6fd93fec9a 8003147: port fix for BCEL bug 39695
dbuck
parents: 12457
diff changeset
   267
                 InstructionHandle start = il.findHandle(l.getStartPC());
3f6fd93fec9a 8003147: port fix for BCEL bug 39695
dbuck
parents: 12457
diff changeset
   268
                 InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength());
3f6fd93fec9a 8003147: port fix for BCEL bug 39695
dbuck
parents: 12457
diff changeset
   269
                 // Repair malformed handles
3f6fd93fec9a 8003147: port fix for BCEL bug 39695
dbuck
parents: 12457
diff changeset
   270
                 if (null == start) {
3f6fd93fec9a 8003147: port fix for BCEL bug 39695
dbuck
parents: 12457
diff changeset
   271
                     start = il.getStart();
3f6fd93fec9a 8003147: port fix for BCEL bug 39695
dbuck
parents: 12457
diff changeset
   272
                 }
3f6fd93fec9a 8003147: port fix for BCEL bug 39695
dbuck
parents: 12457
diff changeset
   273
                 if (null == end) {
3f6fd93fec9a 8003147: port fix for BCEL bug 39695
dbuck
parents: 12457
diff changeset
   274
                     end = il.getEnd();
3f6fd93fec9a 8003147: port fix for BCEL bug 39695
dbuck
parents: 12457
diff changeset
   275
                 }
27535
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   276
                 LocalVariable newVar = new LocalVariable(l);
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   277
                 int startPosition = start.getPosition();
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   278
                 newVar.setStartPC(startPosition);
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   279
                 newVar.setLength(end.getPosition() - startPosition);
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   280
                 newLV[k] = newVar;
15346
3f6fd93fec9a 8003147: port fix for BCEL bug 39695
dbuck
parents: 12457
diff changeset
   281
              }
27535
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   282
              LocalVariableTypeTable newLVTT = new LocalVariableTypeTable(
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   283
                      (LocalVariableTypeTable)a);
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   284
              newLVTT.setLocalVariableTable(newLV);
872cc59854b0 8062608: BCEL corrupts debug data of methods that use generics
dbuck
parents: 25868
diff changeset
   285
              addCodeAttribute(newLVTT);
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   286
          } else
7f561c08de6b Initial load
duke
parents:
diff changeset
   287
            addCodeAttribute(a);
7f561c08de6b Initial load
duke
parents:
diff changeset
   288
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   289
      } else if(a instanceof ExceptionTable) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   290
        String[] names = ((ExceptionTable)a).getExceptionNames();
7f561c08de6b Initial load
duke
parents:
diff changeset
   291
        for(int j=0; j < names.length; j++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   292
          addException(names[j]);
7f561c08de6b Initial load
duke
parents:
diff changeset
   293
      } else
7f561c08de6b Initial load
duke
parents:
diff changeset
   294
        addAttribute(a);
7f561c08de6b Initial load
duke
parents:
diff changeset
   295
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   296
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   297
7f561c08de6b Initial load
duke
parents:
diff changeset
   298
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   299
   * Adds a local variable to this method.
7f561c08de6b Initial load
duke
parents:
diff changeset
   300
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   301
   * @param name variable name
7f561c08de6b Initial load
duke
parents:
diff changeset
   302
   * @param type variable type
7f561c08de6b Initial load
duke
parents:
diff changeset
   303
   * @param slot the index of the local variable, if type is long or double, the next available
7f561c08de6b Initial load
duke
parents:
diff changeset
   304
   * index is slot+2
7f561c08de6b Initial load
duke
parents:
diff changeset
   305
   * @param start from where the variable is valid
7f561c08de6b Initial load
duke
parents:
diff changeset
   306
   * @param end until where the variable is valid
7f561c08de6b Initial load
duke
parents:
diff changeset
   307
   * @return new local variable object
7f561c08de6b Initial load
duke
parents:
diff changeset
   308
   * @see LocalVariable
7f561c08de6b Initial load
duke
parents:
diff changeset
   309
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   310
  public LocalVariableGen addLocalVariable(String name, Type type, int slot,
7f561c08de6b Initial load
duke
parents:
diff changeset
   311
                                           InstructionHandle start,
7f561c08de6b Initial load
duke
parents:
diff changeset
   312
                                           InstructionHandle end) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   313
    byte t = type.getType();
7f561c08de6b Initial load
duke
parents:
diff changeset
   314
7f561c08de6b Initial load
duke
parents:
diff changeset
   315
    if(t != Constants.T_ADDRESS) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   316
      int  add = type.getSize();
7f561c08de6b Initial load
duke
parents:
diff changeset
   317
7f561c08de6b Initial load
duke
parents:
diff changeset
   318
      if(slot + add > max_locals)
7f561c08de6b Initial load
duke
parents:
diff changeset
   319
        max_locals = slot + add;
7f561c08de6b Initial load
duke
parents:
diff changeset
   320
7f561c08de6b Initial load
duke
parents:
diff changeset
   321
      LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end);
7f561c08de6b Initial load
duke
parents:
diff changeset
   322
      int i;
7f561c08de6b Initial load
duke
parents:
diff changeset
   323
7f561c08de6b Initial load
duke
parents:
diff changeset
   324
      if((i = variable_vec.indexOf(l)) >= 0) // Overwrite if necessary
7f561c08de6b Initial load
duke
parents:
diff changeset
   325
        variable_vec.set(i, l);
7f561c08de6b Initial load
duke
parents:
diff changeset
   326
      else
7f561c08de6b Initial load
duke
parents:
diff changeset
   327
        variable_vec.add(l);
7f561c08de6b Initial load
duke
parents:
diff changeset
   328
7f561c08de6b Initial load
duke
parents:
diff changeset
   329
      return l;
7f561c08de6b Initial load
duke
parents:
diff changeset
   330
    } else {
7f561c08de6b Initial load
duke
parents:
diff changeset
   331
      throw new IllegalArgumentException("Can not use " + type +
7f561c08de6b Initial load
duke
parents:
diff changeset
   332
                                         " as type for local variable");
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
7f561c08de6b Initial load
duke
parents:
diff changeset
   337
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   338
   * Adds a local variable to this method and assigns an index automatically.
7f561c08de6b Initial load
duke
parents:
diff changeset
   339
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   340
   * @param name variable name
7f561c08de6b Initial load
duke
parents:
diff changeset
   341
   * @param type variable type
7f561c08de6b Initial load
duke
parents:
diff changeset
   342
   * @param start from where the variable is valid, if this is null,
7f561c08de6b Initial load
duke
parents:
diff changeset
   343
   * it is valid from the start
7f561c08de6b Initial load
duke
parents:
diff changeset
   344
   * @param end until where the variable is valid, if this is null,
7f561c08de6b Initial load
duke
parents:
diff changeset
   345
   * it is valid to the end
7f561c08de6b Initial load
duke
parents:
diff changeset
   346
   * @return new local variable object
7f561c08de6b Initial load
duke
parents:
diff changeset
   347
   * @see LocalVariable
7f561c08de6b Initial load
duke
parents:
diff changeset
   348
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   349
  public LocalVariableGen addLocalVariable(String name, Type type,
7f561c08de6b Initial load
duke
parents:
diff changeset
   350
                                           InstructionHandle start,
7f561c08de6b Initial load
duke
parents:
diff changeset
   351
                                           InstructionHandle end) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   352
    return addLocalVariable(name, type, max_locals, start, end);
7f561c08de6b Initial load
duke
parents:
diff changeset
   353
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   354
7f561c08de6b Initial load
duke
parents:
diff changeset
   355
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   356
   * Remove a local variable, its slot will not be reused, if you do not use addLocalVariable
7f561c08de6b Initial load
duke
parents:
diff changeset
   357
   * with an explicit index argument.
7f561c08de6b Initial load
duke
parents:
diff changeset
   358
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   359
  public void removeLocalVariable(LocalVariableGen l) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   360
    variable_vec.remove(l);
7f561c08de6b Initial load
duke
parents:
diff changeset
   361
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   362
7f561c08de6b Initial load
duke
parents:
diff changeset
   363
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   364
   * Remove all local variables.
7f561c08de6b Initial load
duke
parents:
diff changeset
   365
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   366
  public void removeLocalVariables() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   367
    variable_vec.clear();
7f561c08de6b Initial load
duke
parents:
diff changeset
   368
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   369
7f561c08de6b Initial load
duke
parents:
diff changeset
   370
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   371
   * Sort local variables by index
7f561c08de6b Initial load
duke
parents:
diff changeset
   372
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   373
  private static final void sort(LocalVariableGen[] vars, int l, int r) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   374
    int i = l, j = r;
7f561c08de6b Initial load
duke
parents:
diff changeset
   375
    int m = vars[(l + r) / 2].getIndex();
7f561c08de6b Initial load
duke
parents:
diff changeset
   376
    LocalVariableGen h;
7f561c08de6b Initial load
duke
parents:
diff changeset
   377
7f561c08de6b Initial load
duke
parents:
diff changeset
   378
    do {
7f561c08de6b Initial load
duke
parents:
diff changeset
   379
      while(vars[i].getIndex() < m) i++;
7f561c08de6b Initial load
duke
parents:
diff changeset
   380
      while(m < vars[j].getIndex()) j--;
7f561c08de6b Initial load
duke
parents:
diff changeset
   381
7f561c08de6b Initial load
duke
parents:
diff changeset
   382
      if(i <= j) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   383
        h=vars[i]; vars[i]=vars[j]; vars[j]=h; // Swap elements
7f561c08de6b Initial load
duke
parents:
diff changeset
   384
        i++; j--;
7f561c08de6b Initial load
duke
parents:
diff changeset
   385
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   386
    } while(i <= j);
7f561c08de6b Initial load
duke
parents:
diff changeset
   387
7f561c08de6b Initial load
duke
parents:
diff changeset
   388
    if(l < j) sort(vars, l, j);
7f561c08de6b Initial load
duke
parents:
diff changeset
   389
    if(i < r) sort(vars, i, r);
7f561c08de6b Initial load
duke
parents:
diff changeset
   390
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   391
7f561c08de6b Initial load
duke
parents:
diff changeset
   392
  /*
7f561c08de6b Initial load
duke
parents:
diff changeset
   393
   * If the range of the variable has not been set yet, it will be set to be valid from
7f561c08de6b Initial load
duke
parents:
diff changeset
   394
   * the start to the end of the instruction list.
7f561c08de6b Initial load
duke
parents:
diff changeset
   395
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   396
   * @return array of declared local variables sorted by index
7f561c08de6b Initial load
duke
parents:
diff changeset
   397
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   398
  public LocalVariableGen[] getLocalVariables() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   399
    int                size = variable_vec.size();
7f561c08de6b Initial load
duke
parents:
diff changeset
   400
    LocalVariableGen[] lg   = new LocalVariableGen[size];
7f561c08de6b Initial load
duke
parents:
diff changeset
   401
    variable_vec.toArray(lg);
7f561c08de6b Initial load
duke
parents:
diff changeset
   402
7f561c08de6b Initial load
duke
parents:
diff changeset
   403
    for(int i=0; i < size; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   404
      if(lg[i].getStart() == null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   405
        lg[i].setStart(il.getStart());
7f561c08de6b Initial load
duke
parents:
diff changeset
   406
7f561c08de6b Initial load
duke
parents:
diff changeset
   407
      if(lg[i].getEnd() == null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   408
        lg[i].setEnd(il.getEnd());
7f561c08de6b Initial load
duke
parents:
diff changeset
   409
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   410
7f561c08de6b Initial load
duke
parents:
diff changeset
   411
    if(size > 1)
7f561c08de6b Initial load
duke
parents:
diff changeset
   412
      sort(lg, 0, size - 1);
7f561c08de6b Initial load
duke
parents:
diff changeset
   413
7f561c08de6b Initial load
duke
parents:
diff changeset
   414
    return lg;
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
   * @return `LocalVariableTable' attribute of all the local variables of this method.
7f561c08de6b Initial load
duke
parents:
diff changeset
   419
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   420
  public LocalVariableTable getLocalVariableTable(ConstantPoolGen cp) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   421
    LocalVariableGen[] lg   = getLocalVariables();
7f561c08de6b Initial load
duke
parents:
diff changeset
   422
    int                size = lg.length;
7f561c08de6b Initial load
duke
parents:
diff changeset
   423
    LocalVariable[]    lv   = new LocalVariable[size];
7f561c08de6b Initial load
duke
parents:
diff changeset
   424
7f561c08de6b Initial load
duke
parents:
diff changeset
   425
    for(int i=0; i < size; i++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   426
      lv[i] = lg[i].getLocalVariable(cp);
7f561c08de6b Initial load
duke
parents:
diff changeset
   427
7f561c08de6b Initial load
duke
parents:
diff changeset
   428
    return new LocalVariableTable(cp.addUtf8("LocalVariableTable"),
7f561c08de6b Initial load
duke
parents:
diff changeset
   429
                                  2 + lv.length * 10, lv, cp.getConstantPool());
7f561c08de6b Initial load
duke
parents:
diff changeset
   430
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   431
7f561c08de6b Initial load
duke
parents:
diff changeset
   432
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   433
   * Give an instruction a line number corresponding to the source code line.
7f561c08de6b Initial load
duke
parents:
diff changeset
   434
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   435
   * @param ih instruction to tag
7f561c08de6b Initial load
duke
parents:
diff changeset
   436
   * @return new line number object
7f561c08de6b Initial load
duke
parents:
diff changeset
   437
   * @see LineNumber
7f561c08de6b Initial load
duke
parents:
diff changeset
   438
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   439
  public LineNumberGen addLineNumber(InstructionHandle ih, int src_line) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   440
    LineNumberGen l = new LineNumberGen(ih, src_line);
7f561c08de6b Initial load
duke
parents:
diff changeset
   441
    line_number_vec.add(l);
7f561c08de6b Initial load
duke
parents:
diff changeset
   442
    return l;
7f561c08de6b Initial load
duke
parents:
diff changeset
   443
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   444
7f561c08de6b Initial load
duke
parents:
diff changeset
   445
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   446
   * Remove a line number.
7f561c08de6b Initial load
duke
parents:
diff changeset
   447
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   448
  public void removeLineNumber(LineNumberGen l) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   449
    line_number_vec.remove(l);
7f561c08de6b Initial load
duke
parents:
diff changeset
   450
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   451
7f561c08de6b Initial load
duke
parents:
diff changeset
   452
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   453
   * Remove all line numbers.
7f561c08de6b Initial load
duke
parents:
diff changeset
   454
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   455
  public void removeLineNumbers() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   456
    line_number_vec.clear();
7f561c08de6b Initial load
duke
parents:
diff changeset
   457
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   458
7f561c08de6b Initial load
duke
parents:
diff changeset
   459
  /*
7f561c08de6b Initial load
duke
parents:
diff changeset
   460
   * @return array of line numbers
7f561c08de6b Initial load
duke
parents:
diff changeset
   461
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   462
  public LineNumberGen[] getLineNumbers() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   463
    LineNumberGen[] lg = new LineNumberGen[line_number_vec.size()];
7f561c08de6b Initial load
duke
parents:
diff changeset
   464
    line_number_vec.toArray(lg);
7f561c08de6b Initial load
duke
parents:
diff changeset
   465
    return lg;
7f561c08de6b Initial load
duke
parents:
diff changeset
   466
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   467
7f561c08de6b Initial load
duke
parents:
diff changeset
   468
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   469
   * @return `LineNumberTable' attribute of all the local variables of this method.
7f561c08de6b Initial load
duke
parents:
diff changeset
   470
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   471
  public LineNumberTable getLineNumberTable(ConstantPoolGen cp) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   472
    int          size = line_number_vec.size();
7f561c08de6b Initial load
duke
parents:
diff changeset
   473
    LineNumber[] ln   = new LineNumber[size];
7f561c08de6b Initial load
duke
parents:
diff changeset
   474
7f561c08de6b Initial load
duke
parents:
diff changeset
   475
    try {
7f561c08de6b Initial load
duke
parents:
diff changeset
   476
      for(int i=0; i < size; i++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   477
        ln[i] = ((LineNumberGen)line_number_vec.get(i)).getLineNumber();
7f561c08de6b Initial load
duke
parents:
diff changeset
   478
    } catch(ArrayIndexOutOfBoundsException e) {} // Never occurs
7f561c08de6b Initial load
duke
parents:
diff changeset
   479
7f561c08de6b Initial load
duke
parents:
diff changeset
   480
    return new LineNumberTable(cp.addUtf8("LineNumberTable"),
7f561c08de6b Initial load
duke
parents:
diff changeset
   481
                               2 + ln.length * 4, ln, cp.getConstantPool());
7f561c08de6b Initial load
duke
parents:
diff changeset
   482
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   483
7f561c08de6b Initial load
duke
parents:
diff changeset
   484
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   485
   * Add an exception handler, i.e., specify region where a handler is active and an
7f561c08de6b Initial load
duke
parents:
diff changeset
   486
   * instruction where the actual handling is done.
7f561c08de6b Initial load
duke
parents:
diff changeset
   487
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   488
   * @param start_pc Start of region (inclusive)
7f561c08de6b Initial load
duke
parents:
diff changeset
   489
   * @param end_pc End of region (inclusive)
7f561c08de6b Initial load
duke
parents:
diff changeset
   490
   * @param handler_pc Where handling is done
7f561c08de6b Initial load
duke
parents:
diff changeset
   491
   * @param catch_type class type of handled exception or null if any
7f561c08de6b Initial load
duke
parents:
diff changeset
   492
   * exception is handled
7f561c08de6b Initial load
duke
parents:
diff changeset
   493
   * @return new exception handler object
7f561c08de6b Initial load
duke
parents:
diff changeset
   494
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   495
  public CodeExceptionGen addExceptionHandler(InstructionHandle start_pc,
7f561c08de6b Initial load
duke
parents:
diff changeset
   496
                                              InstructionHandle end_pc,
7f561c08de6b Initial load
duke
parents:
diff changeset
   497
                                              InstructionHandle handler_pc,
7f561c08de6b Initial load
duke
parents:
diff changeset
   498
                                              ObjectType catch_type) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   499
    if((start_pc == null) || (end_pc == null) || (handler_pc == null))
7f561c08de6b Initial load
duke
parents:
diff changeset
   500
      throw new ClassGenException("Exception handler target is null instruction");
7f561c08de6b Initial load
duke
parents:
diff changeset
   501
7f561c08de6b Initial load
duke
parents:
diff changeset
   502
    CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc,
7f561c08de6b Initial load
duke
parents:
diff changeset
   503
                                              handler_pc, catch_type);
7f561c08de6b Initial load
duke
parents:
diff changeset
   504
    exception_vec.add(c);
7f561c08de6b Initial load
duke
parents:
diff changeset
   505
    return c;
7f561c08de6b Initial load
duke
parents:
diff changeset
   506
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   507
7f561c08de6b Initial load
duke
parents:
diff changeset
   508
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   509
   * Remove an exception handler.
7f561c08de6b Initial load
duke
parents:
diff changeset
   510
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   511
  public void removeExceptionHandler(CodeExceptionGen c) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   512
    exception_vec.remove(c);
7f561c08de6b Initial load
duke
parents:
diff changeset
   513
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   514
7f561c08de6b Initial load
duke
parents:
diff changeset
   515
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   516
   * Remove all line numbers.
7f561c08de6b Initial load
duke
parents:
diff changeset
   517
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   518
  public void removeExceptionHandlers() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   519
    exception_vec.clear();
7f561c08de6b Initial load
duke
parents:
diff changeset
   520
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   521
7f561c08de6b Initial load
duke
parents:
diff changeset
   522
  /*
7f561c08de6b Initial load
duke
parents:
diff changeset
   523
   * @return array of declared exception handlers
7f561c08de6b Initial load
duke
parents:
diff changeset
   524
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   525
  public CodeExceptionGen[] getExceptionHandlers() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   526
    CodeExceptionGen[] cg   = new CodeExceptionGen[exception_vec.size()];
7f561c08de6b Initial load
duke
parents:
diff changeset
   527
    exception_vec.toArray(cg);
7f561c08de6b Initial load
duke
parents:
diff changeset
   528
    return cg;
7f561c08de6b Initial load
duke
parents:
diff changeset
   529
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   530
7f561c08de6b Initial load
duke
parents:
diff changeset
   531
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   532
   * @return code exceptions for `Code' attribute
7f561c08de6b Initial load
duke
parents:
diff changeset
   533
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   534
  private CodeException[] getCodeExceptions() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   535
    int             size  = exception_vec.size();
7f561c08de6b Initial load
duke
parents:
diff changeset
   536
    CodeException[] c_exc = new CodeException[size];
7f561c08de6b Initial load
duke
parents:
diff changeset
   537
7f561c08de6b Initial load
duke
parents:
diff changeset
   538
    try {
7f561c08de6b Initial load
duke
parents:
diff changeset
   539
      for(int i=0; i < size; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   540
        CodeExceptionGen c = (CodeExceptionGen)exception_vec.get(i);
7f561c08de6b Initial load
duke
parents:
diff changeset
   541
        c_exc[i] = c.getCodeException(cp);
7f561c08de6b Initial load
duke
parents:
diff changeset
   542
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   543
    } catch(ArrayIndexOutOfBoundsException e) {}
7f561c08de6b Initial load
duke
parents:
diff changeset
   544
7f561c08de6b Initial load
duke
parents:
diff changeset
   545
    return c_exc;
7f561c08de6b Initial load
duke
parents:
diff changeset
   546
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   547
7f561c08de6b Initial load
duke
parents:
diff changeset
   548
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   549
   * Add an exception possibly thrown by this method.
7f561c08de6b Initial load
duke
parents:
diff changeset
   550
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   551
   * @param class_name (fully qualified) name of exception
7f561c08de6b Initial load
duke
parents:
diff changeset
   552
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   553
  public void addException(String class_name) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   554
    throws_vec.add(class_name);
7f561c08de6b Initial load
duke
parents:
diff changeset
   555
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   556
7f561c08de6b Initial load
duke
parents:
diff changeset
   557
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   558
   * Remove an exception.
7f561c08de6b Initial load
duke
parents:
diff changeset
   559
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   560
  public void removeException(String c) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   561
    throws_vec.remove(c);
7f561c08de6b Initial load
duke
parents:
diff changeset
   562
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   563
7f561c08de6b Initial load
duke
parents:
diff changeset
   564
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   565
   * Remove all exceptions.
7f561c08de6b Initial load
duke
parents:
diff changeset
   566
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   567
  public void removeExceptions() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   568
    throws_vec.clear();
7f561c08de6b Initial load
duke
parents:
diff changeset
   569
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   570
7f561c08de6b Initial load
duke
parents:
diff changeset
   571
  /*
7f561c08de6b Initial load
duke
parents:
diff changeset
   572
   * @return array of thrown exceptions
7f561c08de6b Initial load
duke
parents:
diff changeset
   573
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   574
  public String[] getExceptions() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   575
    String[] e = new String[throws_vec.size()];
7f561c08de6b Initial load
duke
parents:
diff changeset
   576
    throws_vec.toArray(e);
7f561c08de6b Initial load
duke
parents:
diff changeset
   577
    return e;
7f561c08de6b Initial load
duke
parents:
diff changeset
   578
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   579
7f561c08de6b Initial load
duke
parents:
diff changeset
   580
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   581
   * @return `Exceptions' attribute of all the exceptions thrown by this method.
7f561c08de6b Initial load
duke
parents:
diff changeset
   582
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   583
  private ExceptionTable getExceptionTable(ConstantPoolGen cp) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   584
    int   size = throws_vec.size();
7f561c08de6b Initial load
duke
parents:
diff changeset
   585
    int[] ex   = new int[size];
7f561c08de6b Initial load
duke
parents:
diff changeset
   586
7f561c08de6b Initial load
duke
parents:
diff changeset
   587
    try {
7f561c08de6b Initial load
duke
parents:
diff changeset
   588
      for(int i=0; i < size; i++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   589
        ex[i] = cp.addClass((String)throws_vec.get(i));
7f561c08de6b Initial load
duke
parents:
diff changeset
   590
    } catch(ArrayIndexOutOfBoundsException e) {}
7f561c08de6b Initial load
duke
parents:
diff changeset
   591
7f561c08de6b Initial load
duke
parents:
diff changeset
   592
    return new ExceptionTable(cp.addUtf8("Exceptions"),
7f561c08de6b Initial load
duke
parents:
diff changeset
   593
                              2 + 2 * size, ex, cp.getConstantPool());
7f561c08de6b Initial load
duke
parents:
diff changeset
   594
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   595
7f561c08de6b Initial load
duke
parents:
diff changeset
   596
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   597
   * Add an attribute to the code. Currently, the JVM knows about the
7f561c08de6b Initial load
duke
parents:
diff changeset
   598
   * LineNumberTable, LocalVariableTable and StackMap attributes,
7f561c08de6b Initial load
duke
parents:
diff changeset
   599
   * where the former two will be generated automatically and the
7f561c08de6b Initial load
duke
parents:
diff changeset
   600
   * latter is used for the MIDP only. Other attributes will be
7f561c08de6b Initial load
duke
parents:
diff changeset
   601
   * ignored by the JVM but do no harm.
7f561c08de6b Initial load
duke
parents:
diff changeset
   602
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   603
   * @param a attribute to be added
7f561c08de6b Initial load
duke
parents:
diff changeset
   604
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   605
  public void addCodeAttribute(Attribute a) { code_attrs_vec.add(a); }
7f561c08de6b Initial load
duke
parents:
diff changeset
   606
7f561c08de6b Initial load
duke
parents:
diff changeset
   607
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   608
   * Remove a code attribute.
7f561c08de6b Initial load
duke
parents:
diff changeset
   609
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   610
  public void removeCodeAttribute(Attribute a) { code_attrs_vec.remove(a); }
7f561c08de6b Initial load
duke
parents:
diff changeset
   611
7f561c08de6b Initial load
duke
parents:
diff changeset
   612
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   613
   * Remove all code attributes.
7f561c08de6b Initial load
duke
parents:
diff changeset
   614
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   615
  public void removeCodeAttributes() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   616
    code_attrs_vec.clear();
7f561c08de6b Initial load
duke
parents:
diff changeset
   617
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   618
7f561c08de6b Initial load
duke
parents:
diff changeset
   619
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   620
   * @return all attributes of this method.
7f561c08de6b Initial load
duke
parents:
diff changeset
   621
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   622
  public Attribute[] getCodeAttributes() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   623
    Attribute[] attributes = new Attribute[code_attrs_vec.size()];
7f561c08de6b Initial load
duke
parents:
diff changeset
   624
    code_attrs_vec.toArray(attributes);
7f561c08de6b Initial load
duke
parents:
diff changeset
   625
    return attributes;
7f561c08de6b Initial load
duke
parents:
diff changeset
   626
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   627
7f561c08de6b Initial load
duke
parents:
diff changeset
   628
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   629
   * Get method object. Never forget to call setMaxStack() or setMaxStack(max), respectively,
7f561c08de6b Initial load
duke
parents:
diff changeset
   630
   * before calling this method (the same applies for max locals).
7f561c08de6b Initial load
duke
parents:
diff changeset
   631
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   632
   * @return method object
7f561c08de6b Initial load
duke
parents:
diff changeset
   633
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   634
  public Method getMethod() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   635
    String signature       = getSignature();
7f561c08de6b Initial load
duke
parents:
diff changeset
   636
    int    name_index      = cp.addUtf8(name);
7f561c08de6b Initial load
duke
parents:
diff changeset
   637
    int    signature_index = cp.addUtf8(signature);
7f561c08de6b Initial load
duke
parents:
diff changeset
   638
7f561c08de6b Initial load
duke
parents:
diff changeset
   639
    /* Also updates positions of instructions, i.e., their indices
7f561c08de6b Initial load
duke
parents:
diff changeset
   640
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   641
    byte[] byte_code = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   642
7f561c08de6b Initial load
duke
parents:
diff changeset
   643
    if(il != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   644
      byte_code = il.getByteCode();
7f561c08de6b Initial load
duke
parents:
diff changeset
   645
7f561c08de6b Initial load
duke
parents:
diff changeset
   646
    LineNumberTable    lnt = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   647
    LocalVariableTable lvt = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   648
7f561c08de6b Initial load
duke
parents:
diff changeset
   649
    /* Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.)
7f561c08de6b Initial load
duke
parents:
diff changeset
   650
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   651
    if((variable_vec.size() > 0) && !strip_attributes)
7f561c08de6b Initial load
duke
parents:
diff changeset
   652
      addCodeAttribute(lvt = getLocalVariableTable(cp));
7f561c08de6b Initial load
duke
parents:
diff changeset
   653
7f561c08de6b Initial load
duke
parents:
diff changeset
   654
    if((line_number_vec.size() > 0) && !strip_attributes)
7f561c08de6b Initial load
duke
parents:
diff changeset
   655
      addCodeAttribute(lnt = getLineNumberTable(cp));
7f561c08de6b Initial load
duke
parents:
diff changeset
   656
7f561c08de6b Initial load
duke
parents:
diff changeset
   657
    Attribute[] code_attrs = getCodeAttributes();
7f561c08de6b Initial load
duke
parents:
diff changeset
   658
7f561c08de6b Initial load
duke
parents:
diff changeset
   659
    /* Each attribute causes 6 additional header bytes
7f561c08de6b Initial load
duke
parents:
diff changeset
   660
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   661
    int                attrs_len  = 0;
7f561c08de6b Initial load
duke
parents:
diff changeset
   662
    for(int i=0; i < code_attrs.length; i++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   663
      attrs_len += (code_attrs[i].getLength() + 6);
7f561c08de6b Initial load
duke
parents:
diff changeset
   664
7f561c08de6b Initial load
duke
parents:
diff changeset
   665
    CodeException[] c_exc   = getCodeExceptions();
7f561c08de6b Initial load
duke
parents:
diff changeset
   666
    int             exc_len = c_exc.length * 8; // Every entry takes 8 bytes
7f561c08de6b Initial load
duke
parents:
diff changeset
   667
7f561c08de6b Initial load
duke
parents:
diff changeset
   668
    Code code = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   669
7f561c08de6b Initial load
duke
parents:
diff changeset
   670
    if((il != null) && !isAbstract()) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   671
      // Remove any stale code attribute
7f561c08de6b Initial load
duke
parents:
diff changeset
   672
      Attribute[] attributes = getAttributes();
7f561c08de6b Initial load
duke
parents:
diff changeset
   673
      for(int i=0; i < attributes.length; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   674
        Attribute a = attributes[i];
7f561c08de6b Initial load
duke
parents:
diff changeset
   675
7f561c08de6b Initial load
duke
parents:
diff changeset
   676
        if(a instanceof Code)
7f561c08de6b Initial load
duke
parents:
diff changeset
   677
          removeAttribute(a);
7f561c08de6b Initial load
duke
parents:
diff changeset
   678
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   679
7f561c08de6b Initial load
duke
parents:
diff changeset
   680
      code = new Code(cp.addUtf8("Code"),
7f561c08de6b Initial load
duke
parents:
diff changeset
   681
                      8 + byte_code.length + // prologue byte code
7f561c08de6b Initial load
duke
parents:
diff changeset
   682
                      2 + exc_len +          // exceptions
7f561c08de6b Initial load
duke
parents:
diff changeset
   683
                      2 + attrs_len,         // attributes
7f561c08de6b Initial load
duke
parents:
diff changeset
   684
                      max_stack, max_locals,
7f561c08de6b Initial load
duke
parents:
diff changeset
   685
                      byte_code, c_exc,
7f561c08de6b Initial load
duke
parents:
diff changeset
   686
                      code_attrs,
7f561c08de6b Initial load
duke
parents:
diff changeset
   687
                      cp.getConstantPool());
7f561c08de6b Initial load
duke
parents:
diff changeset
   688
7f561c08de6b Initial load
duke
parents:
diff changeset
   689
      addAttribute(code);
7f561c08de6b Initial load
duke
parents:
diff changeset
   690
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   691
7f561c08de6b Initial load
duke
parents:
diff changeset
   692
    ExceptionTable et = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   693
7f561c08de6b Initial load
duke
parents:
diff changeset
   694
    if(throws_vec.size() > 0)
7f561c08de6b Initial load
duke
parents:
diff changeset
   695
      addAttribute(et = getExceptionTable(cp)); // Add `Exceptions' if there are "throws" clauses
7f561c08de6b Initial load
duke
parents:
diff changeset
   696
7f561c08de6b Initial load
duke
parents:
diff changeset
   697
    Method m = new Method(access_flags, name_index, signature_index,
7f561c08de6b Initial load
duke
parents:
diff changeset
   698
                          getAttributes(), cp.getConstantPool());
7f561c08de6b Initial load
duke
parents:
diff changeset
   699
7f561c08de6b Initial load
duke
parents:
diff changeset
   700
    // Undo effects of adding attributes
7f561c08de6b Initial load
duke
parents:
diff changeset
   701
    if(lvt != null)  removeCodeAttribute(lvt);
7f561c08de6b Initial load
duke
parents:
diff changeset
   702
    if(lnt != null)  removeCodeAttribute(lnt);
7f561c08de6b Initial load
duke
parents:
diff changeset
   703
    if(code != null) removeAttribute(code);
7f561c08de6b Initial load
duke
parents:
diff changeset
   704
    if(et != null)   removeAttribute(et);
7f561c08de6b Initial load
duke
parents:
diff changeset
   705
7f561c08de6b Initial load
duke
parents:
diff changeset
   706
    return m;
7f561c08de6b Initial load
duke
parents:
diff changeset
   707
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   708
7f561c08de6b Initial load
duke
parents:
diff changeset
   709
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   710
   * Remove all NOPs from the instruction list (if possible) and update every
7f561c08de6b Initial load
duke
parents:
diff changeset
   711
   * object refering to them, i.e., branch instructions, local variables and
7f561c08de6b Initial load
duke
parents:
diff changeset
   712
   * exception handlers.
7f561c08de6b Initial load
duke
parents:
diff changeset
   713
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   714
  public void removeNOPs() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   715
    if(il != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   716
      InstructionHandle next;
7f561c08de6b Initial load
duke
parents:
diff changeset
   717
      /* Check branch instructions.
7f561c08de6b Initial load
duke
parents:
diff changeset
   718
       */
7f561c08de6b Initial load
duke
parents:
diff changeset
   719
      for(InstructionHandle ih = il.getStart(); ih != null; ih = next) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   720
        next = ih.next;
7f561c08de6b Initial load
duke
parents:
diff changeset
   721
7f561c08de6b Initial load
duke
parents:
diff changeset
   722
        if((next != null) && (ih.getInstruction() instanceof NOP)) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   723
          try {
7f561c08de6b Initial load
duke
parents:
diff changeset
   724
            il.delete(ih);
7f561c08de6b Initial load
duke
parents:
diff changeset
   725
          } catch(TargetLostException e) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   726
            InstructionHandle[] targets = e.getTargets();
7f561c08de6b Initial load
duke
parents:
diff changeset
   727
7f561c08de6b Initial load
duke
parents:
diff changeset
   728
            for(int i=0; i < targets.length; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   729
              InstructionTargeter[] targeters = targets[i].getTargeters();
7f561c08de6b Initial load
duke
parents:
diff changeset
   730
7f561c08de6b Initial load
duke
parents:
diff changeset
   731
              for(int j=0; j < targeters.length; j++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   732
                targeters[j].updateTarget(targets[i], next);
7f561c08de6b Initial load
duke
parents:
diff changeset
   733
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   734
          }
7f561c08de6b Initial load
duke
parents:
diff changeset
   735
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   736
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   737
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   738
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   739
7f561c08de6b Initial load
duke
parents:
diff changeset
   740
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   741
   * Set maximum number of local variables.
7f561c08de6b Initial load
duke
parents:
diff changeset
   742
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   743
  public void   setMaxLocals(int m)  { max_locals = m; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   744
  public int    getMaxLocals()       { return max_locals; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   745
7f561c08de6b Initial load
duke
parents:
diff changeset
   746
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   747
   * Set maximum stack size for this method.
7f561c08de6b Initial load
duke
parents:
diff changeset
   748
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   749
  public void   setMaxStack(int m)  { max_stack = m; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   750
  public int    getMaxStack()       { return max_stack; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   751
7f561c08de6b Initial load
duke
parents:
diff changeset
   752
  /** @return class that contains this method
7f561c08de6b Initial load
duke
parents:
diff changeset
   753
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   754
  public String getClassName()                     { return class_name; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   755
  public void   setClassName(String class_name)    { this.class_name = class_name; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   756
7f561c08de6b Initial load
duke
parents:
diff changeset
   757
  public void   setReturnType(Type return_type)    { setType(return_type); }
7f561c08de6b Initial load
duke
parents:
diff changeset
   758
  public Type   getReturnType()                    { return getType(); }
7f561c08de6b Initial load
duke
parents:
diff changeset
   759
7f561c08de6b Initial load
duke
parents:
diff changeset
   760
  public void   setArgumentTypes(Type[] arg_types)  { this.arg_types = arg_types; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   761
  public Type[] getArgumentTypes()                  { return (Type[])arg_types.clone(); }
7f561c08de6b Initial load
duke
parents:
diff changeset
   762
  public void   setArgumentType(int i, Type type)       { arg_types[i] = type; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   763
  public Type   getArgumentType(int i)                  { return arg_types[i]; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   764
7f561c08de6b Initial load
duke
parents:
diff changeset
   765
  public void     setArgumentNames(String[] arg_names) { this.arg_names = arg_names; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   766
  public String[] getArgumentNames()                   { return (String[])arg_names.clone(); }
7f561c08de6b Initial load
duke
parents:
diff changeset
   767
  public void     setArgumentName(int i, String name)     { arg_names[i] = name; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   768
  public String   getArgumentName(int i)                  { return arg_names[i]; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   769
7f561c08de6b Initial load
duke
parents:
diff changeset
   770
  public InstructionList getInstructionList()                    { return il; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   771
  public void            setInstructionList(InstructionList il)  { this.il = il; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   772
7f561c08de6b Initial load
duke
parents:
diff changeset
   773
  public String getSignature() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   774
    return Type.getMethodSignature(type, arg_types);
7f561c08de6b Initial load
duke
parents:
diff changeset
   775
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   776
7f561c08de6b Initial load
duke
parents:
diff changeset
   777
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   778
   * Computes max. stack size by performing control flow analysis.
7f561c08de6b Initial load
duke
parents:
diff changeset
   779
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   780
  public void setMaxStack() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   781
    if(il != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   782
      max_stack = getMaxStack(cp, il, getExceptionHandlers());
7f561c08de6b Initial load
duke
parents:
diff changeset
   783
    else
7f561c08de6b Initial load
duke
parents:
diff changeset
   784
      max_stack = 0;
7f561c08de6b Initial load
duke
parents:
diff changeset
   785
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   786
7f561c08de6b Initial load
duke
parents:
diff changeset
   787
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   788
   * Compute maximum number of local variables.
7f561c08de6b Initial load
duke
parents:
diff changeset
   789
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   790
  public void setMaxLocals() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   791
    if(il != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   792
      int max = isStatic()? 0 : 1;
7f561c08de6b Initial load
duke
parents:
diff changeset
   793
7f561c08de6b Initial load
duke
parents:
diff changeset
   794
      if(arg_types != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   795
        for(int i=0; i < arg_types.length; i++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   796
          max += arg_types[i].getSize();
7f561c08de6b Initial load
duke
parents:
diff changeset
   797
7f561c08de6b Initial load
duke
parents:
diff changeset
   798
      for(InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   799
        Instruction ins = ih.getInstruction();
7f561c08de6b Initial load
duke
parents:
diff changeset
   800
7f561c08de6b Initial load
duke
parents:
diff changeset
   801
        if((ins instanceof LocalVariableInstruction) ||
7f561c08de6b Initial load
duke
parents:
diff changeset
   802
           (ins instanceof RET) || (ins instanceof IINC))
7f561c08de6b Initial load
duke
parents:
diff changeset
   803
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   804
          int index = ((IndexedInstruction)ins).getIndex() +
7f561c08de6b Initial load
duke
parents:
diff changeset
   805
            ((TypedInstruction)ins).getType(cp).getSize();
7f561c08de6b Initial load
duke
parents:
diff changeset
   806
7f561c08de6b Initial load
duke
parents:
diff changeset
   807
          if(index > max)
7f561c08de6b Initial load
duke
parents:
diff changeset
   808
            max = index;
7f561c08de6b Initial load
duke
parents:
diff changeset
   809
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   810
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   811
7f561c08de6b Initial load
duke
parents:
diff changeset
   812
      max_locals = max;
7f561c08de6b Initial load
duke
parents:
diff changeset
   813
    } else
7f561c08de6b Initial load
duke
parents:
diff changeset
   814
      max_locals = 0;
7f561c08de6b Initial load
duke
parents:
diff changeset
   815
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   816
7f561c08de6b Initial load
duke
parents:
diff changeset
   817
  /** Do not/Do produce attributes code attributesLineNumberTable and
7f561c08de6b Initial load
duke
parents:
diff changeset
   818
   * LocalVariableTable, like javac -O
7f561c08de6b Initial load
duke
parents:
diff changeset
   819
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   820
  public void stripAttributes(boolean flag) { strip_attributes = flag; }
7f561c08de6b Initial load
duke
parents:
diff changeset
   821
7f561c08de6b Initial load
duke
parents:
diff changeset
   822
  static final class BranchTarget {
7f561c08de6b Initial load
duke
parents:
diff changeset
   823
    InstructionHandle target;
7f561c08de6b Initial load
duke
parents:
diff changeset
   824
    int               stackDepth;
7f561c08de6b Initial load
duke
parents:
diff changeset
   825
7f561c08de6b Initial load
duke
parents:
diff changeset
   826
    BranchTarget(InstructionHandle target, int stackDepth) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   827
      this.target = target;
7f561c08de6b Initial load
duke
parents:
diff changeset
   828
      this.stackDepth = stackDepth;
7f561c08de6b Initial load
duke
parents:
diff changeset
   829
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   830
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   831
7f561c08de6b Initial load
duke
parents:
diff changeset
   832
  static final class BranchStack {
7f561c08de6b Initial load
duke
parents:
diff changeset
   833
    Stack     branchTargets  = new Stack();
7f561c08de6b Initial load
duke
parents:
diff changeset
   834
    Hashtable visitedTargets = new Hashtable();
7f561c08de6b Initial load
duke
parents:
diff changeset
   835
7f561c08de6b Initial load
duke
parents:
diff changeset
   836
    public void push(InstructionHandle target, int stackDepth) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   837
      if(visited(target))
7f561c08de6b Initial load
duke
parents:
diff changeset
   838
        return;
7f561c08de6b Initial load
duke
parents:
diff changeset
   839
7f561c08de6b Initial load
duke
parents:
diff changeset
   840
      branchTargets.push(visit(target, stackDepth));
7f561c08de6b Initial load
duke
parents:
diff changeset
   841
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   842
7f561c08de6b Initial load
duke
parents:
diff changeset
   843
    public BranchTarget pop() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   844
      if(!branchTargets.empty()) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   845
        BranchTarget bt = (BranchTarget) branchTargets.pop();
7f561c08de6b Initial load
duke
parents:
diff changeset
   846
        return bt;
7f561c08de6b Initial load
duke
parents:
diff changeset
   847
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   848
7f561c08de6b Initial load
duke
parents:
diff changeset
   849
      return null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   850
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   851
7f561c08de6b Initial load
duke
parents:
diff changeset
   852
    private final BranchTarget visit(InstructionHandle target, int stackDepth) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   853
      BranchTarget bt = new BranchTarget(target, stackDepth);
7f561c08de6b Initial load
duke
parents:
diff changeset
   854
      visitedTargets.put(target, bt);
7f561c08de6b Initial load
duke
parents:
diff changeset
   855
7f561c08de6b Initial load
duke
parents:
diff changeset
   856
      return bt;
7f561c08de6b Initial load
duke
parents:
diff changeset
   857
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   858
7f561c08de6b Initial load
duke
parents:
diff changeset
   859
    private final boolean visited(InstructionHandle target) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   860
      return (visitedTargets.get(target) != null);
7f561c08de6b Initial load
duke
parents:
diff changeset
   861
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   862
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   863
7f561c08de6b Initial load
duke
parents:
diff changeset
   864
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   865
   * Computes stack usage of an instruction list by performing control flow analysis.
7f561c08de6b Initial load
duke
parents:
diff changeset
   866
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   867
   * @return maximum stack depth used by method
7f561c08de6b Initial load
duke
parents:
diff changeset
   868
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   869
  public static int getMaxStack(ConstantPoolGen cp, InstructionList il, CodeExceptionGen[] et) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   870
    BranchStack branchTargets = new BranchStack();
7f561c08de6b Initial load
duke
parents:
diff changeset
   871
7f561c08de6b Initial load
duke
parents:
diff changeset
   872
    /* Initially, populate the branch stack with the exception
7f561c08de6b Initial load
duke
parents:
diff changeset
   873
     * handlers, because these aren't (necessarily) branched to
7f561c08de6b Initial load
duke
parents:
diff changeset
   874
     * explicitly. in each case, the stack will have depth 1,
7f561c08de6b Initial load
duke
parents:
diff changeset
   875
     * containing the exception object.
7f561c08de6b Initial load
duke
parents:
diff changeset
   876
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   877
    for (int i = 0; i < et.length; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   878
      InstructionHandle handler_pc = et[i].getHandlerPC();
7f561c08de6b Initial load
duke
parents:
diff changeset
   879
      if (handler_pc != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   880
        branchTargets.push(handler_pc, 1);
7f561c08de6b Initial load
duke
parents:
diff changeset
   881
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   882
7f561c08de6b Initial load
duke
parents:
diff changeset
   883
    int               stackDepth = 0, maxStackDepth = 0;
7f561c08de6b Initial load
duke
parents:
diff changeset
   884
    InstructionHandle ih         = il.getStart();
7f561c08de6b Initial load
duke
parents:
diff changeset
   885
7f561c08de6b Initial load
duke
parents:
diff changeset
   886
    while(ih != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   887
      Instruction instruction = ih.getInstruction();
7f561c08de6b Initial load
duke
parents:
diff changeset
   888
      short opcode = instruction.getOpcode();
7f561c08de6b Initial load
duke
parents:
diff changeset
   889
      int delta = instruction.produceStack(cp) - instruction.consumeStack(cp);
7f561c08de6b Initial load
duke
parents:
diff changeset
   890
7f561c08de6b Initial load
duke
parents:
diff changeset
   891
      stackDepth += delta;
7f561c08de6b Initial load
duke
parents:
diff changeset
   892
      if(stackDepth > maxStackDepth)
7f561c08de6b Initial load
duke
parents:
diff changeset
   893
        maxStackDepth = stackDepth;
7f561c08de6b Initial load
duke
parents:
diff changeset
   894
7f561c08de6b Initial load
duke
parents:
diff changeset
   895
      // choose the next instruction based on whether current is a branch.
7f561c08de6b Initial load
duke
parents:
diff changeset
   896
      if(instruction instanceof BranchInstruction) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   897
        BranchInstruction branch = (BranchInstruction) instruction;
7f561c08de6b Initial load
duke
parents:
diff changeset
   898
        if(instruction instanceof Select) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   899
          // explore all of the select's targets. the default target is handled below.
7f561c08de6b Initial load
duke
parents:
diff changeset
   900
          Select select = (Select) branch;
7f561c08de6b Initial load
duke
parents:
diff changeset
   901
          InstructionHandle[] targets = select.getTargets();
7f561c08de6b Initial load
duke
parents:
diff changeset
   902
          for (int i = 0; i < targets.length; i++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   903
            branchTargets.push(targets[i], stackDepth);
7f561c08de6b Initial load
duke
parents:
diff changeset
   904
          // nothing to fall through to.
7f561c08de6b Initial load
duke
parents:
diff changeset
   905
          ih = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   906
        } else if(!(branch instanceof IfInstruction)) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   907
          // if an instruction that comes back to following PC,
7f561c08de6b Initial load
duke
parents:
diff changeset
   908
          // push next instruction, with stack depth reduced by 1.
7f561c08de6b Initial load
duke
parents:
diff changeset
   909
          if(opcode == Constants.JSR || opcode == Constants.JSR_W)
7f561c08de6b Initial load
duke
parents:
diff changeset
   910
            branchTargets.push(ih.getNext(), stackDepth - 1);
7f561c08de6b Initial load
duke
parents:
diff changeset
   911
          ih = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   912
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   913
        // for all branches, the target of the branch is pushed on the branch stack.
7f561c08de6b Initial load
duke
parents:
diff changeset
   914
        // conditional branches have a fall through case, selects don't, and
7f561c08de6b Initial load
duke
parents:
diff changeset
   915
        // jsr/jsr_w return to the next instruction.
7f561c08de6b Initial load
duke
parents:
diff changeset
   916
        branchTargets.push(branch.getTarget(), stackDepth);
7f561c08de6b Initial load
duke
parents:
diff changeset
   917
      } else {
7f561c08de6b Initial load
duke
parents:
diff changeset
   918
        // check for instructions that terminate the method.
7f561c08de6b Initial load
duke
parents:
diff changeset
   919
        if(opcode == Constants.ATHROW || opcode == Constants.RET ||
7f561c08de6b Initial load
duke
parents:
diff changeset
   920
           (opcode >= Constants.IRETURN && opcode <= Constants.RETURN))
7f561c08de6b Initial load
duke
parents:
diff changeset
   921
          ih = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   922
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   923
      // normal case, go to the next instruction.
7f561c08de6b Initial load
duke
parents:
diff changeset
   924
      if(ih != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   925
        ih = ih.getNext();
7f561c08de6b Initial load
duke
parents:
diff changeset
   926
      // if we have no more instructions, see if there are any deferred branches to explore.
7f561c08de6b Initial load
duke
parents:
diff changeset
   927
      if(ih == null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   928
        BranchTarget bt = branchTargets.pop();
7f561c08de6b Initial load
duke
parents:
diff changeset
   929
        if (bt != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   930
          ih = bt.target;
7f561c08de6b Initial load
duke
parents:
diff changeset
   931
          stackDepth = bt.stackDepth;
7f561c08de6b Initial load
duke
parents:
diff changeset
   932
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   933
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   934
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   935
7f561c08de6b Initial load
duke
parents:
diff changeset
   936
    return maxStackDepth;
7f561c08de6b Initial load
duke
parents:
diff changeset
   937
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   938
7f561c08de6b Initial load
duke
parents:
diff changeset
   939
  private ArrayList observers;
7f561c08de6b Initial load
duke
parents:
diff changeset
   940
7f561c08de6b Initial load
duke
parents:
diff changeset
   941
  /** Add observer for this object.
7f561c08de6b Initial load
duke
parents:
diff changeset
   942
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   943
  public void addObserver(MethodObserver o) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   944
    if(observers == null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   945
      observers = new ArrayList();
7f561c08de6b Initial load
duke
parents:
diff changeset
   946
7f561c08de6b Initial load
duke
parents:
diff changeset
   947
    observers.add(o);
7f561c08de6b Initial load
duke
parents:
diff changeset
   948
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   949
7f561c08de6b Initial load
duke
parents:
diff changeset
   950
  /** Remove observer for this object.
7f561c08de6b Initial load
duke
parents:
diff changeset
   951
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   952
  public void removeObserver(MethodObserver o) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   953
    if(observers != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   954
      observers.remove(o);
7f561c08de6b Initial load
duke
parents:
diff changeset
   955
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   956
7f561c08de6b Initial load
duke
parents:
diff changeset
   957
  /** Call notify() method on all observers. This method is not called
7f561c08de6b Initial load
duke
parents:
diff changeset
   958
   * automatically whenever the state has changed, but has to be
7f561c08de6b Initial load
duke
parents:
diff changeset
   959
   * called by the user after he has finished editing the object.
7f561c08de6b Initial load
duke
parents:
diff changeset
   960
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   961
  public void update() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   962
    if(observers != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   963
      for(Iterator e = observers.iterator(); e.hasNext(); )
7f561c08de6b Initial load
duke
parents:
diff changeset
   964
        ((MethodObserver)e.next()).notify(this);
7f561c08de6b Initial load
duke
parents:
diff changeset
   965
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   966
7f561c08de6b Initial load
duke
parents:
diff changeset
   967
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   968
   * Return string representation close to declaration format,
7f561c08de6b Initial load
duke
parents:
diff changeset
   969
   * `public static void _main(String[]) throws IOException', e.g.
7f561c08de6b Initial load
duke
parents:
diff changeset
   970
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   971
   * @return String representation of the method.
7f561c08de6b Initial load
duke
parents:
diff changeset
   972
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   973
  public final String toString() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   974
    String access    = Utility.accessToString(access_flags);
7f561c08de6b Initial load
duke
parents:
diff changeset
   975
    String signature = Type.getMethodSignature(type, arg_types);
7f561c08de6b Initial load
duke
parents:
diff changeset
   976
7f561c08de6b Initial load
duke
parents:
diff changeset
   977
    signature = Utility.methodSignatureToString(signature, name, access,
7f561c08de6b Initial load
duke
parents:
diff changeset
   978
                                                true, getLocalVariableTable(cp));
7f561c08de6b Initial load
duke
parents:
diff changeset
   979
7f561c08de6b Initial load
duke
parents:
diff changeset
   980
    StringBuffer buf = new StringBuffer(signature);
7f561c08de6b Initial load
duke
parents:
diff changeset
   981
7f561c08de6b Initial load
duke
parents:
diff changeset
   982
    if(throws_vec.size() > 0) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   983
      for(Iterator e = throws_vec.iterator(); e.hasNext(); )
7f561c08de6b Initial load
duke
parents:
diff changeset
   984
        buf.append("\n\t\tthrows " + e.next());
7f561c08de6b Initial load
duke
parents:
diff changeset
   985
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   986
7f561c08de6b Initial load
duke
parents:
diff changeset
   987
    return buf.toString();
7f561c08de6b Initial load
duke
parents:
diff changeset
   988
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   989
7f561c08de6b Initial load
duke
parents:
diff changeset
   990
  /** @return deep copy of this method
7f561c08de6b Initial load
duke
parents:
diff changeset
   991
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   992
  public MethodGen copy(String class_name, ConstantPoolGen cp) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   993
    Method    m  = ((MethodGen)clone()).getMethod();
7f561c08de6b Initial load
duke
parents:
diff changeset
   994
    MethodGen mg = new MethodGen(m, class_name, this.cp);
7f561c08de6b Initial load
duke
parents:
diff changeset
   995
7f561c08de6b Initial load
duke
parents:
diff changeset
   996
    if(this.cp != cp) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   997
      mg.setConstantPool(cp);
7f561c08de6b Initial load
duke
parents:
diff changeset
   998
      mg.getInstructionList().replaceConstantPool(this.cp, cp);
7f561c08de6b Initial load
duke
parents:
diff changeset
   999
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
  1000
7f561c08de6b Initial load
duke
parents:
diff changeset
  1001
    return mg;
7f561c08de6b Initial load
duke
parents:
diff changeset
  1002
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
  1003
}