1 /* 2 * Copyright (c) 2011, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package jdk.vm.ci.meta; 24 25 import java.util.ArrayList; 26 import java.util.List; 27 28 /** 29 * Describes the {@link Local}s for a Java method. 30 * 31 * @see "https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.13" 32 */ 33 public class LocalVariableTable { 34 35 private final Local[] locals; 36 37 /** 38 * Creates an object describing the {@link Local}s for a Java method. 39 * 40 * @param locals array of objects describing local variables. This array is now owned by this 41 * object and must not be mutated by the caller. 42 */ 43 @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `locals`") 44 public LocalVariableTable(Local[] locals) { 45 this.locals = locals; 46 } 47 48 /** 49 * Gets a description of a local variable that occupies the bytecode frame slot indexed by 50 * {@code slot} and is live at the bytecode index {@code bci} 51 * 52 * @return a description of the requested local variable or null if no such variable matches 53 * {@code slot} and {@code bci} 54 */ 55 public Local getLocal(int slot, int bci) { 56 Local result = null; 57 for (Local local : locals) { 58 if (local.getSlot() == slot && local.getStartBCI() <= bci && local.getEndBCI() >= bci) { 59 if (result == null) { 60 result = local; 61 } else { 62 throw new IllegalStateException("Locals overlap!"); 63 } 64 } 65 } 66 return result; 67 } 68 69 /** 70 * Gets a copy of the array of {@link Local}s that was passed to this object's constructor. 71 */ 72 public Local[] getLocals() { 73 return locals.clone(); 74 } 75 76 /** 77 * Gets a description of all the local variables live at the bytecode index {@code bci} 78 */ 79 public Local[] getLocalsAt(int bci) { 80 List<Local> result = new ArrayList<>(); 81 for (Local l : locals) { 82 if (l.getStartBCI() <= bci && bci <= l.getEndBCI()) { 83 result.add(l); 84 } 85 } 86 return result.toArray(new Local[result.size()]); 87 } 88 }