View Javadoc

    1   /*
    2    * Copyright  2000-2004 The Apache Software Foundation
    3    *
    4    *  Licensed under the Apache License, Version 2.0 (the "License");
    5    *  you may not use this file except in compliance with the License.
    6    *  You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   *  Unless required by applicable law or agreed to in writing, software
    11   *  distributed under the License is distributed on an "AS IS" BASIS,
    12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   *  See the License for the specific language governing permissions and
    14   *  limitations under the License.
    15   *
    16   */
    17  package org.apache.bcel.generic;
    18
    19  import java.io.DataOutputStream;
    20  import java.io.IOException;
    21  import org.apache.bcel.Constants;
    22  import org.apache.bcel.ExceptionConstants;
    23  import org.apache.bcel.classfile.ConstantPool;
    24  import org.apache.bcel.util.ByteSequence;
    25
    26  /***
    27   * INVOKEINTERFACE - Invoke interface method
    28   * <PRE>Stack: ..., objectref, [arg1, [arg2 ...]] -&gt; ...</PRE>
    29   *
    30   * @version $Id: INVOKEINTERFACE.java 386056 2006-03-15 11:31:56Z tcurdt $
    31   * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
    32   */
    33  public final class INVOKEINTERFACE extends InvokeInstruction {
    34
    35      private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2
    36
    37
    38      /***
    39       * Empty constructor needed for the Class.newInstance() statement in
    40       * Instruction.readInstruction(). Not to be used otherwise.
    41       */
    42      INVOKEINTERFACE() {
    43      }
    44
    45
    46      public INVOKEINTERFACE(int index, int nargs) {
    47          super(Constants.INVOKEINTERFACE, index);
    48          length = 5;
    49          if (nargs < 1) {
    50              throw new ClassGenException("Number of arguments must be > 0 " + nargs);
    51          }
    52          this.nargs = nargs;
    53      }
    54
    55
    56      /***
    57       * Dump instruction as byte code to stream out.
    58       * @param out Output stream
    59       */
    60      public void dump( DataOutputStream out ) throws IOException {
    61          out.writeByte(opcode);
    62          out.writeShort(index);
    63          out.writeByte(nargs);
    64          out.writeByte(0);
    65      }
    66
    67
    68      /***
    69       * The <B>count</B> argument according to the Java Language Specification,
    70       * Second Edition.
    71       */
    72      public int getCount() {
    73          return nargs;
    74      }
    75
    76
    77      /***
    78       * Read needed data (i.e., index) from file.
    79       */
    80      protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
    81          super.initFromFile(bytes, wide);
    82          length = 5;
    83          nargs = bytes.readUnsignedByte();
    84          bytes.readByte(); // Skip 0 byte
    85      }
    86
    87
    88      /***
    89       * @return mnemonic for instruction with symbolic references resolved
    90       */
    91      public String toString( ConstantPool cp ) {
    92          return super.toString(cp) + " " + nargs;
    93      }
    94
    95
    96      public int consumeStack( ConstantPoolGen cpg ) { // nargs is given in byte-code
    97          return nargs; // nargs includes this reference
    98      }
    99
    100
    101     public Class[] getExceptions() {
    102         Class[] cs = new Class[4 + ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length];
    103         System.arraycopy(ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION, 0, cs, 0,
    104                 ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length);
    105         cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 3] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR;
    106         cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 2] = ExceptionConstants.ILLEGAL_ACCESS_ERROR;
    107         cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 1] = ExceptionConstants.ABSTRACT_METHOD_ERROR;
    108         cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length] = ExceptionConstants.UNSATISFIED_LINK_ERROR;
    109         return cs;
    110     }
    111
    112
    113     /***
    114      * Call corresponding visitor method(s). The order is:
    115      * Call visitor methods of implemented interfaces first, then
    116      * call methods according to the class hierarchy in descending order,
    117      * i.e., the most specific visitXXX() call comes last.
    118      *
    119      * @param v Visitor object
    120      */
    121     public void accept( Visitor v ) {
    122         v.visitExceptionThrower(this);
    123         v.visitTypedInstruction(this);
    124         v.visitStackConsumer(this);
    125         v.visitStackProducer(this);
    126         v.visitLoadClass(this);
    127         v.visitCPInstruction(this);
    128         v.visitFieldOrMethod(this);
    129         v.visitInvokeInstruction(this);
    130         v.visitINVOKEINTERFACE(this);
    131     }
    132 }