1 /*
   2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /*
  26  * This file is available under and governed by the GNU General Public
  27  * License version 2 only, as published by the Free Software Foundation.
  28  * However, the following notice accompanied the original version of this
  29  * file:
  30  *
  31  * ASM: a very small and fast Java bytecode manipulation framework
  32  * Copyright (c) 2000-2011 INRIA, France Telecom
  33  * All rights reserved.
  34  *
  35  * Redistribution and use in source and binary forms, with or without
  36  * modification, are permitted provided that the following conditions
  37  * are met:
  38  * 1. Redistributions of source code must retain the above copyright
  39  *    notice, this list of conditions and the following disclaimer.
  40  * 2. Redistributions in binary form must reproduce the above copyright
  41  *    notice, this list of conditions and the following disclaimer in the
  42  *    documentation and/or other materials provided with the distribution.
  43  * 3. Neither the name of the copyright holders nor the names of its
  44  *    contributors may be used to endorse or promote products derived from
  45  *    this software without specific prior written permission.
  46  *
  47  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  48  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  49  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  50  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  51  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  52  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  53  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  54  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  55  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  56  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  57  * THE POSSIBILITY OF SUCH DAMAGE.
  58  */
  59 package jdk.internal.org.objectweb.asm.tree;
  60 
  61 import java.util.ArrayList;
  62 import java.util.List;
  63 import java.util.Map;
  64 
  65 import jdk.internal.org.objectweb.asm.MethodVisitor;
  66 
  67 /**
  68  * A node that represents a bytecode instruction. <i>An instruction can appear
  69  * at most once in at most one {@link InsnList} at a time</i>.
  70  *
  71  * @author Eric Bruneton
  72  */
  73 public abstract class AbstractInsnNode {
  74 
  75     /**
  76      * The type of {@link InsnNode} instructions.
  77      */
  78     public static final int INSN = 0;
  79 
  80     /**
  81      * The type of {@link IntInsnNode} instructions.
  82      */
  83     public static final int INT_INSN = 1;
  84 
  85     /**
  86      * The type of {@link VarInsnNode} instructions.
  87      */
  88     public static final int VAR_INSN = 2;
  89 
  90     /**
  91      * The type of {@link TypeInsnNode} instructions.
  92      */
  93     public static final int TYPE_INSN = 3;
  94 
  95     /**
  96      * The type of {@link FieldInsnNode} instructions.
  97      */
  98     public static final int FIELD_INSN = 4;
  99 
 100     /**
 101      * The type of {@link MethodInsnNode} instructions.
 102      */
 103     public static final int METHOD_INSN = 5;
 104 
 105     /**
 106      * The type of {@link InvokeDynamicInsnNode} instructions.
 107      */
 108     public static final int INVOKE_DYNAMIC_INSN = 6;
 109 
 110     /**
 111      * The type of {@link JumpInsnNode} instructions.
 112      */
 113     public static final int JUMP_INSN = 7;
 114 
 115     /**
 116      * The type of {@link LabelNode} "instructions".
 117      */
 118     public static final int LABEL = 8;
 119 
 120     /**
 121      * The type of {@link LdcInsnNode} instructions.
 122      */
 123     public static final int LDC_INSN = 9;
 124 
 125     /**
 126      * The type of {@link IincInsnNode} instructions.
 127      */
 128     public static final int IINC_INSN = 10;
 129 
 130     /**
 131      * The type of {@link TableSwitchInsnNode} instructions.
 132      */
 133     public static final int TABLESWITCH_INSN = 11;
 134 
 135     /**
 136      * The type of {@link LookupSwitchInsnNode} instructions.
 137      */
 138     public static final int LOOKUPSWITCH_INSN = 12;
 139 
 140     /**
 141      * The type of {@link MultiANewArrayInsnNode} instructions.
 142      */
 143     public static final int MULTIANEWARRAY_INSN = 13;
 144 
 145     /**
 146      * The type of {@link FrameNode} "instructions".
 147      */
 148     public static final int FRAME = 14;
 149 
 150     /**
 151      * The type of {@link LineNumberNode} "instructions".
 152      */
 153     public static final int LINE = 15;
 154 
 155     /**
 156      * The opcode of this instruction.
 157      */
 158     protected int opcode;
 159 
 160     /**
 161      * The runtime visible type annotations of this instruction. This field is
 162      * only used for real instructions (i.e. not for labels, frames, or line
 163      * number nodes). This list is a list of {@link TypeAnnotationNode} objects.
 164      * May be <tt>null</tt>.
 165      *
 166      * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
 167      * @label visible
 168      */
 169     public List<TypeAnnotationNode> visibleTypeAnnotations;
 170 
 171     /**
 172      * The runtime invisible type annotations of this instruction. This field is
 173      * only used for real instructions (i.e. not for labels, frames, or line
 174      * number nodes). This list is a list of {@link TypeAnnotationNode} objects.
 175      * May be <tt>null</tt>.
 176      *
 177      * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
 178      * @label invisible
 179      */
 180     public List<TypeAnnotationNode> invisibleTypeAnnotations;
 181 
 182     /**
 183      * Previous instruction in the list to which this instruction belongs.
 184      */
 185     AbstractInsnNode prev;
 186 
 187     /**
 188      * Next instruction in the list to which this instruction belongs.
 189      */
 190     AbstractInsnNode next;
 191 
 192     /**
 193      * Index of this instruction in the list to which it belongs. The value of
 194      * this field is correct only when {@link InsnList#cache} is not null. A
 195      * value of -1 indicates that this instruction does not belong to any
 196      * {@link InsnList}.
 197      */
 198     int index;
 199 
 200     /**
 201      * Constructs a new {@link AbstractInsnNode}.
 202      *
 203      * @param opcode
 204      *            the opcode of the instruction to be constructed.
 205      */
 206     protected AbstractInsnNode(final int opcode) {
 207         this.opcode = opcode;
 208         this.index = -1;
 209     }
 210 
 211     /**
 212      * Returns the opcode of this instruction.
 213      *
 214      * @return the opcode of this instruction.
 215      */
 216     public int getOpcode() {
 217         return opcode;
 218     }
 219 
 220     /**
 221      * Returns the type of this instruction.
 222      *
 223      * @return the type of this instruction, i.e. one the constants defined in
 224      *         this class.
 225      */
 226     public abstract int getType();
 227 
 228     /**
 229      * Returns the previous instruction in the list to which this instruction
 230      * belongs, if any.
 231      *
 232      * @return the previous instruction in the list to which this instruction
 233      *         belongs, if any. May be <tt>null</tt>.
 234      */
 235     public AbstractInsnNode getPrevious() {
 236         return prev;
 237     }
 238 
 239     /**
 240      * Returns the next instruction in the list to which this instruction
 241      * belongs, if any.
 242      *
 243      * @return the next instruction in the list to which this instruction
 244      *         belongs, if any. May be <tt>null</tt>.
 245      */
 246     public AbstractInsnNode getNext() {
 247         return next;
 248     }
 249 
 250     /**
 251      * Makes the given code visitor visit this instruction.
 252      *
 253      * @param cv
 254      *            a code visitor.
 255      */
 256     public abstract void accept(final MethodVisitor cv);
 257 
 258     /**
 259      * Makes the given visitor visit the annotations of this instruction.
 260      *
 261      * @param mv
 262      *            a method visitor.
 263      */
 264     protected final void acceptAnnotations(final MethodVisitor mv) {
 265         int n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations
 266                 .size();
 267         for (int i = 0; i < n; ++i) {
 268             TypeAnnotationNode an = visibleTypeAnnotations.get(i);
 269             an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc,
 270                     true));
 271         }
 272         n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
 273                 .size();
 274         for (int i = 0; i < n; ++i) {
 275             TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
 276             an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc,
 277                     false));
 278         }
 279     }
 280 
 281     /**
 282      * Returns a copy of this instruction.
 283      *
 284      * @param labels
 285      *            a map from LabelNodes to cloned LabelNodes.
 286      * @return a copy of this instruction. The returned instruction does not
 287      *         belong to any {@link InsnList}.
 288      */
 289     public abstract AbstractInsnNode clone(
 290             final Map<LabelNode, LabelNode> labels);
 291 
 292     /**
 293      * Returns the clone of the given label.
 294      *
 295      * @param label
 296      *            a label.
 297      * @param map
 298      *            a map from LabelNodes to cloned LabelNodes.
 299      * @return the clone of the given label.
 300      */
 301     static LabelNode clone(final LabelNode label,
 302             final Map<LabelNode, LabelNode> map) {
 303         return map.get(label);
 304     }
 305 
 306     /**
 307      * Returns the clones of the given labels.
 308      *
 309      * @param labels
 310      *            a list of labels.
 311      * @param map
 312      *            a map from LabelNodes to cloned LabelNodes.
 313      * @return the clones of the given labels.
 314      */
 315     static LabelNode[] clone(final List<LabelNode> labels,
 316             final Map<LabelNode, LabelNode> map) {
 317         LabelNode[] clones = new LabelNode[labels.size()];
 318         for (int i = 0; i < clones.length; ++i) {
 319             clones[i] = map.get(labels.get(i));
 320         }
 321         return clones;
 322     }
 323 
 324     /**
 325      * Clones the annotations of the given instruction into this instruction.
 326      *
 327      * @param insn
 328      *            the source instruction.
 329      * @return this instruction.
 330      */
 331     protected final AbstractInsnNode cloneAnnotations(
 332             final AbstractInsnNode insn) {
 333         if (insn.visibleTypeAnnotations != null) {
 334             this.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>();
 335             for (int i = 0; i < insn.visibleTypeAnnotations.size(); ++i) {
 336                 TypeAnnotationNode src = insn.visibleTypeAnnotations.get(i);
 337                 TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef,
 338                         src.typePath, src.desc);
 339                 src.accept(ann);
 340                 this.visibleTypeAnnotations.add(ann);
 341             }
 342         }
 343         if (insn.invisibleTypeAnnotations != null) {
 344             this.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>();
 345             for (int i = 0; i < insn.invisibleTypeAnnotations.size(); ++i) {
 346                 TypeAnnotationNode src = insn.invisibleTypeAnnotations.get(i);
 347                 TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef,
 348                         src.typePath, src.desc);
 349                 src.accept(ann);
 350                 this.invisibleTypeAnnotations.add(ann);
 351             }
 352         }
 353         return this;
 354     }
 355 }