1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 
  21 package com.sun.org.apache.bcel.internal.generic;
  22 
  23 import java.io.DataOutputStream;
  24 import java.io.IOException;
  25 
  26 import com.sun.org.apache.bcel.internal.Const;
  27 import com.sun.org.apache.bcel.internal.ExceptionConst;
  28 import com.sun.org.apache.bcel.internal.classfile.ConstantInvokeDynamic;
  29 import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType;
  30 import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
  31 import com.sun.org.apache.bcel.internal.util.ByteSequence;
  32 
  33 /**
  34  * Class for INVOKEDYNAMIC. Not an instance of InvokeInstruction, since that class
  35  * expects to be able to get the class of the method. Ignores the bootstrap
  36  * mechanism entirely.
  37  *
  38  * @version $Id: InvokeInstruction.java 1152072 2011-07-29 01:54:05Z dbrosius $
  39  * @see
  40  * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic">
  41  * The invokedynamic instruction in The Java Virtual Machine Specification</a>
  42  * @since 6.0
  43  * @LastModified: Nov 2017
  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      * @param cpg the ConstantPool generator
 129      * @deprecated in FieldOrMethod
 130      *
 131      * @return name of the referenced class/interface
 132      */
 133     @Override
 134     @Deprecated
 135     public String getClassName( final ConstantPoolGen cpg ) {
 136         final ConstantPool cp = cpg.getConstantPool();
 137         final ConstantInvokeDynamic cid = (ConstantInvokeDynamic) cp.getConstant(super.getIndex(), Const.CONSTANT_InvokeDynamic);
 138         return ((ConstantNameAndType) cp.getConstant(cid.getNameAndTypeIndex())).getName(cp);
 139     }
 140 }