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 }