1 /* 2 * Copyright (c) 2015, 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 package java.lang; 26 27 import java.lang.StackWalker.StackFrame; 28 import java.util.EnumSet; 29 import java.util.Set; 30 31 import static java.lang.StackWalker.ExtendedOption.LOCALS_AND_OPERANDS; 32 33 /** 34 * <em>UNSUPPORTED</em> This interface is intended to be package-private 35 * or move to an internal package.<p> 36 * 37 * {@code LiveStackFrame} represents a frame storing data and partial results. 38 * Each frame has its own array of local variables (JVMS section 2.6.1), 39 * its own operand stack (JVMS section 2.6.2) for a method invocation. 40 * 41 * @jvms 2.6 Frames 42 */ 43 /* package-private */ 44 interface LiveStackFrame extends StackFrame { 45 /** 46 * Return the monitors held by this stack frame. This method returns 47 * an empty array if no monitor is held by this stack frame. 48 * 49 * @return the monitors held by this stack frames 50 */ 51 public Object[] getMonitors(); 52 53 /** 54 * Gets the local variable array of this stack frame. 55 * 56 * <p>A single local variable can hold a value of type boolean, byte, char, 57 * short, int, float, reference or returnAddress. A pair of local variables 58 * can hold a value of type long or double. In other words, 59 * a value of type long or type double occupies two consecutive local 60 * variables. For a value of primitive type, the element in the 61 * local variable array is an {@link PrimitiveValue} object; 62 * otherwise, the element is an {@code Object}. 63 * 64 * <p>The returned array may contain null entries if a local variable is not 65 * live. 66 * 67 * @return the local variable array of this stack frame. 68 */ 69 public Object[] getLocals(); 70 71 /** 72 * Gets the operand stack of this stack frame. 73 * 74 * <p> 75 * The 0-th element of the returned array represents the top of the operand stack. 76 * This method returns an empty array if the operand stack is empty. 77 * 78 * <p>Each entry on the operand stack can hold a value of any Java Virtual 79 * Machine Type. 80 * For a value of primitive type, the element in the returned array is 81 * an {@link PrimitiveValue} object; otherwise, the element is the {@code Object} 82 * on the operand stack. 83 * 84 * @return the operand stack of this stack frame. 85 */ 86 public Object[] getStack(); 87 88 /** 89 * <em>UNSUPPORTED</em> This interface is intended to be package-private 90 * or move to an internal package.<p> 91 * 92 * Represents a local variable or an entry on the operand whose value is 93 * of primitive type. 94 */ 95 public abstract class PrimitiveValue { 96 /** 97 * Returns the base type of this primitive value, one of 98 * {@code B, D, C, F, I, J, S, Z}. 99 * 100 * @return Name of a base type 101 * @jvms table 4.3-A 102 */ 103 abstract char type(); 104 105 /** 106 * Returns the boolean value if this primitive value is of type boolean. 107 * @return the boolean value if this primitive value is of type boolean. 108 * 109 * @throws UnsupportedOperationException if this primitive value is not 110 * of type boolean. 111 */ 112 public boolean booleanValue() { 113 throw new UnsupportedOperationException("this primitive of type " + type()); 114 } 115 116 /** 117 * Returns the int value if this primitive value is of type int. 118 * @return the int value if this primitive value is of type int. 119 * 120 * @throws UnsupportedOperationException if this primitive value is not 121 * of type int. 122 */ 123 public int intValue() { 124 throw new UnsupportedOperationException("this primitive of type " + type()); 125 } 126 127 /** 128 * Returns the long value if this primitive value is of type long. 129 * @return the long value if this primitive value is of type long. 130 * 131 * @throws UnsupportedOperationException if this primitive value is not 132 * of type long. 133 */ 134 public long longValue() { 135 throw new UnsupportedOperationException("this primitive of type " + type()); 136 } 137 138 /** 139 * Returns the char value if this primitive value is of type char. 140 * @return the char value if this primitive value is of type char. 141 * 142 * @throws UnsupportedOperationException if this primitive value is not 143 * of type char. 144 */ 145 public char charValue() { 146 throw new UnsupportedOperationException("this primitive of type " + type()); 147 } 148 149 /** 150 * Returns the byte value if this primitive value is of type byte. 151 * @return the byte value if this primitive value is of type byte. 152 * 153 * @throws UnsupportedOperationException if this primitive value is not 154 * of type byte. 155 */ 156 public byte byteValue() { 157 throw new UnsupportedOperationException("this primitive of type " + type()); 158 } 159 160 /** 161 * Returns the short value if this primitive value is of type short. 162 * @return the short value if this primitive value is of type short. 163 * 164 * @throws UnsupportedOperationException if this primitive value is not 165 * of type short. 166 */ 167 public short shortValue() { 168 throw new UnsupportedOperationException("this primitive of type " + type()); 169 } 170 171 /** 172 * Returns the float value if this primitive value is of type float. 173 * @return the float value if this primitive value is of type float. 174 * 175 * @throws UnsupportedOperationException if this primitive value is not 176 * of type float. 177 */ 178 public float floatValue() { 179 throw new UnsupportedOperationException("this primitive of type " + type()); 180 } 181 182 /** 183 * Returns the double value if this primitive value is of type double. 184 * @return the double value if this primitive value is of type double. 185 * 186 * @throws UnsupportedOperationException if this primitive value is not 187 * of type double. 188 */ 189 public double doubleValue() { 190 throw new UnsupportedOperationException("this primitive of type " + type()); 191 } 192 } 193 194 195 /** 196 * Gets {@code StackWalker} that can get locals and operands. 197 * 198 * @throws SecurityException if the security manager is present and 199 * denies access to {@code RuntimePermission("liveStackFrames")} 200 */ 201 public static StackWalker getStackWalker() { 202 return getStackWalker(EnumSet.noneOf(StackWalker.Option.class)); 203 } 204 205 /** 206 * Gets a {@code StackWalker} instance with the given options specifying 207 * the stack frame information it can access, and which will traverse at most 208 * the given {@code maxDepth} number of stack frames. If no option is 209 * specified, this {@code StackWalker} obtains the method name and 210 * the class name with all 211 * {@linkplain StackWalker.Option#SHOW_HIDDEN_FRAMES hidden frames} skipped. 212 * The returned {@code StackWalker} can get locals and operands. 213 * 214 * @param options stack walk {@link StackWalker.Option options} 215 * 216 * @throws SecurityException if the security manager is present and 217 * it denies access to {@code RuntimePermission("liveStackFrames")}; or 218 * or if the given {@code options} contains 219 * {@link StackWalker.Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE} 220 * and it denies access to {@code StackFramePermission("retainClassReference")}. 221 */ 222 public static StackWalker getStackWalker(Set<StackWalker.Option> options) { 223 SecurityManager sm = System.getSecurityManager(); 224 if (sm != null) { 225 sm.checkPermission(new RuntimePermission("liveStackFrames")); 226 } 227 return StackWalker.newInstance(options, LOCALS_AND_OPERANDS); 228 } 229 }