001: /*
002: * Copyright 2000-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: *
016: */
017: package org.apache.bcel.generic;
018:
019: import java.io.DataOutputStream;
020: import java.io.IOException;
021: import org.apache.bcel.Constants;
022: import org.apache.bcel.ExceptionConstants;
023: import org.apache.bcel.classfile.ConstantPool;
024: import org.apache.bcel.util.ByteSequence;
025:
026: /**
027: * INVOKEINTERFACE - Invoke interface method
028: * <PRE>Stack: ..., objectref, [arg1, [arg2 ...]] -> ...</PRE>
029: *
030: * @version $Id: INVOKEINTERFACE.java 386056 2006-03-15 11:31:56Z tcurdt $
031: * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
032: */
033: public final class INVOKEINTERFACE extends InvokeInstruction {
034:
035: private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2
036:
037: /**
038: * Empty constructor needed for the Class.newInstance() statement in
039: * Instruction.readInstruction(). Not to be used otherwise.
040: */
041: INVOKEINTERFACE() {
042: }
043:
044: public INVOKEINTERFACE(int index, int nargs) {
045: super (Constants.INVOKEINTERFACE, index);
046: length = 5;
047: if (nargs < 1) {
048: throw new ClassGenException(
049: "Number of arguments must be > 0 " + nargs);
050: }
051: this .nargs = nargs;
052: }
053:
054: /**
055: * Dump instruction as byte code to stream out.
056: * @param out Output stream
057: */
058: public void dump(DataOutputStream out) throws IOException {
059: out.writeByte(opcode);
060: out.writeShort(index);
061: out.writeByte(nargs);
062: out.writeByte(0);
063: }
064:
065: /**
066: * The <B>count</B> argument according to the Java Language Specification,
067: * Second Edition.
068: */
069: public int getCount() {
070: return nargs;
071: }
072:
073: /**
074: * Read needed data (i.e., index) from file.
075: */
076: protected void initFromFile(ByteSequence bytes, boolean wide)
077: throws IOException {
078: super .initFromFile(bytes, wide);
079: length = 5;
080: nargs = bytes.readUnsignedByte();
081: bytes.readByte(); // Skip 0 byte
082: }
083:
084: /**
085: * @return mnemonic for instruction with symbolic references resolved
086: */
087: public String toString(ConstantPool cp) {
088: return super .toString(cp) + " " + nargs;
089: }
090:
091: public int consumeStack(ConstantPoolGen cpg) { // nargs is given in byte-code
092: return nargs; // nargs includes this reference
093: }
094:
095: public Class[] getExceptions() {
096: Class[] cs = new Class[4 + ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length];
097: System
098: .arraycopy(
099: ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION,
100: 0,
101: cs,
102: 0,
103: ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length);
104: cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 3] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR;
105: cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 2] = ExceptionConstants.ILLEGAL_ACCESS_ERROR;
106: cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 1] = ExceptionConstants.ABSTRACT_METHOD_ERROR;
107: cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length] = ExceptionConstants.UNSATISFIED_LINK_ERROR;
108: return cs;
109: }
110:
111: /**
112: * Call corresponding visitor method(s). The order is:
113: * Call visitor methods of implemented interfaces first, then
114: * call methods according to the class hierarchy in descending order,
115: * i.e., the most specific visitXXX() call comes last.
116: *
117: * @param v Visitor object
118: */
119: public void accept(Visitor v) {
120: v.visitExceptionThrower(this);
121: v.visitTypedInstruction(this);
122: v.visitStackConsumer(this);
123: v.visitStackProducer(this);
124: v.visitLoadClass(this);
125: v.visitCPInstruction(this);
126: v.visitFieldOrMethod(this);
127: v.visitInvokeInstruction(this);
128: v.visitINVOKEINTERFACE(this);
129: }
130: }
|