1 /* 2 * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.lang.classfile.attribute; 27 28 import java.lang.classfile.ClassFile; 29 import java.lang.classfile.Label; 30 import java.lang.classfile.Opcode; 31 import java.lang.classfile.constantpool.ClassEntry; 32 import java.lang.classfile.instruction.BranchInstruction; 33 import java.lang.constant.ClassDesc; 34 import java.util.List; 35 36 import jdk.internal.classfile.impl.StackMapDecoder; 37 import jdk.internal.classfile.impl.TemporaryConstantPool; 38 39 /** 40 * Models a stack map frame in a {@link StackMapTableAttribute StackMapTable} 41 * attribute (JVMS {@jvms 4.7.4}). A stack map frame must appear at the 42 * beginning of each basic block in a method (JVMS {@jvms 4.10.1}). 43 * 44 * @apiNote 45 * In general, a stack map frame should be defined for each target of a 46 * {@link BranchInstruction}, or unreachable code right after an unconditional 47 * branch instruction like {@link Opcode#GOTO goto}. The automatic stack map 48 * generation cannot handle unreachable code right after an unconditional jump; 49 * The {@link ClassFile.DeadCodeOption} allows substituting such code, or 50 * advanced users can provide their own stack maps for dead code. 51 * 52 * @see StackMapTableAttribute#entries() 53 * @jvms 4.7.4 The {@code StackMapTable} Attribute 54 * @jvms 4.10.1 Verification by Type Checking 55 * @since 24 56 */ 57 public sealed interface StackMapFrameInfo 58 permits StackMapDecoder.StackMapFrameImpl { 59 60 /** 61 * {@return the raw {@code u1 frame_type}} 62 */ 63 int frameType(); 64 65 /** 66 * {@return the frame target label} 67 */ 68 Label target(); 69 70 /** 71 * {@return the expanded local variable types} 72 */ 73 List<VerificationTypeInfo> locals(); 74 75 /** 76 * {@return the expanded operand stack types} 77 */ 78 List<VerificationTypeInfo> stack(); 79 80 /** 81 * {@return a new stack map frame} 82 * 83 * @param target the location of the frame 84 * @param locals the complete list of frame locals 85 * @param stack the complete frame stack 86 */ 87 public static StackMapFrameInfo of(Label target, 88 List<VerificationTypeInfo> locals, 89 List<VerificationTypeInfo> stack) { 90 return new StackMapDecoder.StackMapFrameImpl(255, target, locals, stack); 91 } 92 93 /** 94 * The type of a stack or local variable value. 95 * 96 * @see #locals() 97 * @see #stack() 98 * @jvms 4.7.4 The {@code StackMapTable} Attribute 99 * @since 24 100 */ 101 sealed interface VerificationTypeInfo { 102 103 /** The {@link #tag() tag} for verification type info {@link SimpleVerificationTypeInfo#TOP TOP}. */ 104 int ITEM_TOP = 0; 105 106 /** The {@link #tag() tag} for verification type info {@link SimpleVerificationTypeInfo#INTEGER INTEGER}. */ 107 int ITEM_INTEGER = 1; 108 109 /** The {@link #tag() tag} for verification type info {@link SimpleVerificationTypeInfo#FLOAT FLOAT}. */ 110 int ITEM_FLOAT = 2; 111 112 /** The {@link #tag() tag} for verification type info {@link SimpleVerificationTypeInfo#DOUBLE DOUBLE}. */ 113 int ITEM_DOUBLE = 3; 114 115 /** The {@link #tag() tag} for verification type info {@link SimpleVerificationTypeInfo#LONG LONG}. */ 116 int ITEM_LONG = 4; 117 118 /** The {@link #tag() tag} for verification type info {@link SimpleVerificationTypeInfo#NULL NULL}. */ 119 int ITEM_NULL = 5; 120 121 /** The {@link #tag() tag} for verification type info {@link SimpleVerificationTypeInfo#UNINITIALIZED_THIS UNINITIALIZED_THIS}. */ 122 int ITEM_UNINITIALIZED_THIS = 6; 123 124 /** The {@link #tag() tag} for verification type info {@link ObjectVerificationTypeInfo OBJECT}. */ 125 int ITEM_OBJECT = 7; 126 127 /** The {@link #tag() tag} for verification type info {@link UninitializedVerificationTypeInfo UNINITIALIZED}. */ 128 int ITEM_UNINITIALIZED = 8; 129 130 /** 131 * {@return the tag of the type info} 132 * 133 * @apiNote 134 * {@code ITEM_}-prefixed constants in this class, such as {@link #ITEM_TOP}, describe the 135 * possible return values of this method. 136 */ 137 int tag(); 138 } 139 140 /** 141 * A simple stack value. 142 * 143 * @since 24 144 */ 145 public enum SimpleVerificationTypeInfo implements VerificationTypeInfo { 146 147 /** Verification type top. */ 148 TOP(ITEM_TOP), 149 150 /** Verification type int. */ 151 INTEGER(ITEM_INTEGER), 152 153 /** Verification type float. */ 154 FLOAT(ITEM_FLOAT), 155 156 /** Verification type double. */ 157 DOUBLE(ITEM_DOUBLE), 158 159 /** Verification type long. */ 160 LONG(ITEM_LONG), 161 162 /** Verification type null. */ 163 NULL(ITEM_NULL), 164 165 /** Verification type uninitializedThis. */ 166 UNINITIALIZED_THIS(ITEM_UNINITIALIZED_THIS); 167 168 169 private final int tag; 170 171 SimpleVerificationTypeInfo(int tag) { 172 this.tag = tag; 173 } 174 175 @Override 176 public int tag() { 177 return tag; 178 } 179 } 180 181 /** 182 * A stack value for an object type. Its {@link #tag() tag} is {@value #ITEM_OBJECT}. 183 * 184 * @jvms 4.7.4 The {@code StackMapTable} Attribute 185 * @since 24 186 */ 187 sealed interface ObjectVerificationTypeInfo extends VerificationTypeInfo 188 permits StackMapDecoder.ObjectVerificationTypeInfoImpl { 189 190 /** 191 * {@return a new object verification type info} 192 * @param className the class of the object 193 */ 194 public static ObjectVerificationTypeInfo of(ClassEntry className) { 195 return new StackMapDecoder.ObjectVerificationTypeInfoImpl(className); 196 } 197 198 /** 199 * {@return a new object verification type info} 200 * @param classDesc the class of the object 201 * @throws IllegalArgumentException if {@code classDesc} represents a primitive type 202 */ 203 public static ObjectVerificationTypeInfo of(ClassDesc classDesc) { 204 return of(TemporaryConstantPool.INSTANCE.classEntry(classDesc)); 205 } 206 207 /** 208 * {@return the class of the object} 209 */ 210 ClassEntry className(); 211 212 /** 213 * {@return the class of the object, as a symbolic descriptor} 214 */ 215 default ClassDesc classSymbol() { 216 return className().asSymbol(); 217 } 218 } 219 220 /** 221 * An uninitialized stack value. Its {@link #tag() tag} is {@value #ITEM_UNINITIALIZED}. 222 * 223 * @jvms 4.7.4 The {@code StackMapTable} Attribute 224 * @since 24 225 */ 226 sealed interface UninitializedVerificationTypeInfo extends VerificationTypeInfo 227 permits StackMapDecoder.UninitializedVerificationTypeInfoImpl { 228 229 /** 230 * {@return the label immediately before the {@link Opcode#NEW new} 231 * instruction that creates this uninitialized object} 232 */ 233 Label newTarget(); 234 235 /** 236 * {@return an uninitialized verification type info} 237 * @param newTarget the label immediately before the {@link Opcode#NEW new} 238 * instruction that creates this uninitialized object 239 */ 240 public static UninitializedVerificationTypeInfo of(Label newTarget) { 241 return new StackMapDecoder.UninitializedVerificationTypeInfoImpl(newTarget); 242 } 243 } 244 }