1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.bcel.internal.generic;
  23 
  24 import java.io.DataOutputStream;
  25 import java.io.IOException;
  26 
  27 import com.sun.org.apache.bcel.internal.Const;
  28 import com.sun.org.apache.bcel.internal.ExceptionConst;
  29 import com.sun.org.apache.bcel.internal.classfile.ConstantInvokeDynamic;
  30 import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType;
  31 import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
  32 import com.sun.org.apache.bcel.internal.util.ByteSequence;
  33 
  34 /**
  35  * Class for INVOKEDYNAMIC. Not an instance of InvokeInstruction, since that class
  36  * expects to be able to get the class of the method. Ignores the bootstrap
  37  * mechanism entirely.
  38  *
  39  * @version $Id: InvokeInstruction.java 1152072 2011-07-29 01:54:05Z dbrosius $
  40  * @see
  41  * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic">
  42  * The invokedynamic instruction in The Java Virtual Machine Specification</a>
  43  * @since 6.0
  44  */
  45 public class INVOKEDYNAMIC extends InvokeInstruction {
  46 
  47     /**
  48      * Empty constructor needed for the Class.newInstance() statement in
  49      * Instruction.readInstruction(). Not to be used otherwise.
  50      */
  51     INVOKEDYNAMIC() {
  52     }
  53 
  54 
  55     public INVOKEDYNAMIC(final int index) {
  56         super(Const.INVOKEDYNAMIC, index);
  57     }
  58 
  59 
  60     /**
  61      * Dump instruction as byte code to stream out.
  62      * @param out Output stream
  63      */
  64     @Override
  65     public void dump( final DataOutputStream out ) throws IOException {
  66         out.writeByte(super.getOpcode());
  67         out.writeShort(super.getIndex());
  68         out.writeByte(0);
  69         out.writeByte(0);
  70        }
  71 
  72 
  73     /**
  74      * Read needed data (i.e., index) from file.
  75      */
  76     @Override
  77     protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException {
  78         super.initFromFile(bytes, wide);
  79         super.setLength(5);
  80         bytes.readByte(); // Skip 0 byte
  81         bytes.readByte(); // Skip 0 byte
  82     }
  83 
  84 
  85     /**
  86      * @return mnemonic for instruction with symbolic references resolved
  87      */
  88     @Override
  89     public String toString( final ConstantPool cp ) {
  90         return super.toString(cp);
  91     }
  92 
  93 
  94     @Override
  95     public Class<?>[] getExceptions() {
  96         return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_INTERFACE_METHOD_RESOLUTION,
  97             ExceptionConst.UNSATISFIED_LINK_ERROR,
  98             ExceptionConst.ABSTRACT_METHOD_ERROR,
  99             ExceptionConst.ILLEGAL_ACCESS_ERROR,
 100             ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR);
 101     }
 102 
 103 
 104     /**
 105      * Call corresponding visitor method(s). The order is:
 106      * Call visitor methods of implemented interfaces first, then
 107      * call methods according to the class hierarchy in descending order,
 108      * i.e., the most specific visitXXX() call comes last.
 109      *
 110      * @param v Visitor object
 111      */
 112     @Override
 113     public void accept( final Visitor v ) {
 114         v.visitExceptionThrower(this);
 115         v.visitTypedInstruction(this);
 116         v.visitStackConsumer(this);
 117         v.visitStackProducer(this);
 118         v.visitLoadClass(this);
 119         v.visitCPInstruction(this);
 120         v.visitFieldOrMethod(this);
 121         v.visitInvokeInstruction(this);
 122         v.visitINVOKEDYNAMIC(this);
 123     }
 124 
 125     /**
 126      * Override the parent method because our classname is held elsewhere.
 127      */
 128     @Override
 129     public String getClassName( final ConstantPoolGen cpg ) {
 130         final ConstantPool cp = cpg.getConstantPool();
 131         final ConstantInvokeDynamic cid = (ConstantInvokeDynamic) cp.getConstant(super.getIndex(), Const.CONSTANT_InvokeDynamic);
 132         return ((ConstantNameAndType) cp.getConstant(cid.getNameAndTypeIndex())).getName(cp);
 133     }
 134 }