1 /* 2 * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.bcel.internal.classfile; 22 23 import java.io.DataInput; 24 import java.io.DataOutputStream; 25 import java.io.IOException; 26 27 import com.sun.org.apache.bcel.internal.Const; 28 29 /** 30 * This class represents a local variable within a method. It contains its 31 * scope, name, signature and index on the method's frame. 32 * 33 * @version $Id$ 34 * @see LocalVariableTable 35 * @LastModified: Jun 2019 36 */ 37 public final class LocalVariable implements Cloneable, Node { 38 39 private int start_pc; // Range in which the variable is valid 40 private int length; 41 private int name_index; // Index in constant pool of variable name 42 private int signature_index; // Index of variable signature 43 private int index; /* Variable is `index'th local variable on 44 * this method's frame. 45 */ 46 private ConstantPool constant_pool; 47 private int orig_index; // never changes; used to match up with LocalVariableTypeTable entries 48 49 50 /** 51 * Initialize from another object. Note that both objects use the same 52 * references (shallow copy). Use copy() for a physical copy. 53 */ 54 public LocalVariable(final LocalVariable c) { 55 this(c.getStartPC(), c.getLength(), c.getNameIndex(), c.getSignatureIndex(), c.getIndex(), 56 c.getConstantPool()); 57 this.orig_index = c.getOrigIndex(); 58 } 59 60 61 /** 62 * Construct object from file stream. 63 * @param file Input stream 64 * @throws IOException 65 */ 66 LocalVariable(final DataInput file, final ConstantPool constant_pool) throws IOException { 67 this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file 68 .readUnsignedShort(), file.readUnsignedShort(), constant_pool); 69 } 70 71 72 /** 73 * @param start_pc Range in which the variable 74 * @param length ... is valid 75 * @param name_index Index in constant pool of variable name 76 * @param signature_index Index of variable's signature 77 * @param index Variable is `index'th local variable on the method's frame 78 * @param constant_pool Array of constants 79 */ 80 public LocalVariable(final int start_pc, final int length, final int name_index, final int signature_index, final int index, 81 final ConstantPool constant_pool) { 82 this.start_pc = start_pc; 83 this.length = length; 84 this.name_index = name_index; 85 this.signature_index = signature_index; 86 this.index = index; 87 this.constant_pool = constant_pool; 88 this.orig_index = index; 89 } 90 91 92 /** 93 * @param start_pc Range in which the variable 94 * @param length ... is valid 95 * @param name_index Index in constant pool of variable name 96 * @param signature_index Index of variable's signature 97 * @param index Variable is `index'th local variable on the method's frame 98 * @param constant_pool Array of constants 99 * @param orig_index Variable is `index'th local variable on the method's frame prior to any changes 100 */ 101 public LocalVariable(final int start_pc, final int length, final int name_index, final int signature_index, final int index, 102 final ConstantPool constant_pool, final int orig_index) { 103 this.start_pc = start_pc; 104 this.length = length; 105 this.name_index = name_index; 106 this.signature_index = signature_index; 107 this.index = index; 108 this.constant_pool = constant_pool; 109 this.orig_index = orig_index; 110 } 111 112 113 /** 114 * Called by objects that are traversing the nodes of the tree implicitely 115 * defined by the contents of a Java class. I.e., the hierarchy of methods, 116 * fields, attributes, etc. spawns a tree of objects. 117 * 118 * @param v Visitor object 119 */ 120 @Override 121 public void accept( final Visitor v ) { 122 v.visitLocalVariable(this); 123 } 124 125 126 /** 127 * Dump local variable to file stream in binary format. 128 * 129 * @param file Output file stream 130 * @throws IOException 131 */ 132 public final void dump( final DataOutputStream file ) throws IOException { 133 file.writeShort(start_pc); 134 file.writeShort(length); 135 file.writeShort(name_index); 136 file.writeShort(signature_index); 137 file.writeShort(index); 138 } 139 140 141 /** 142 * @return Constant pool used by this object. 143 */ 144 public final ConstantPool getConstantPool() { 145 return constant_pool; 146 } 147 148 149 /** 150 * @return Variable is valid within getStartPC() .. getStartPC()+getLength() 151 */ 152 public final int getLength() { 153 return length; 154 } 155 156 157 /** 158 * @return Variable name. 159 */ 160 public final String getName() { 161 ConstantUtf8 c; 162 c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); 163 return c.getBytes(); 164 } 165 166 167 /** 168 * @return Index in constant pool of variable name. 169 */ 170 public final int getNameIndex() { 171 return name_index; 172 } 173 174 175 /** 176 * @return Signature. 177 */ 178 public final String getSignature() { 179 ConstantUtf8 c; 180 c = (ConstantUtf8) constant_pool.getConstant(signature_index, Const.CONSTANT_Utf8); 181 return c.getBytes(); 182 } 183 184 185 /** 186 * @return Index in constant pool of variable signature. 187 */ 188 public final int getSignatureIndex() { 189 return signature_index; 190 } 191 192 193 /** 194 * @return index of register where variable is stored 195 */ 196 public final int getIndex() { 197 return index; 198 } 199 200 201 /** 202 * @return index of register where variable was originally stored 203 */ 204 public final int getOrigIndex() { 205 return orig_index; 206 } 207 208 209 /** 210 * @return Start of range where he variable is valid 211 */ 212 public final int getStartPC() { 213 return start_pc; 214 } 215 216 217 /* 218 * Helper method shared with LocalVariableTypeTable 219 */ 220 final String toStringShared( final boolean typeTable ) { 221 final String name = getName(); 222 final String signature = Utility.signatureToString(getSignature(), false); 223 final String label = "LocalVariable" + (typeTable ? "Types" : "" ); 224 return label + "(start_pc = " + start_pc + ", length = " + length + ", index = " 225 + index + ":" + signature + " " + name + ")"; 226 } 227 228 229 /** 230 * @param constant_pool Constant pool to be used for this object. 231 */ 232 public final void setConstantPool( final ConstantPool constant_pool ) { 233 this.constant_pool = constant_pool; 234 } 235 236 237 /** 238 * @param length the length of this local variable 239 */ 240 public final void setLength( final int length ) { 241 this.length = length; 242 } 243 244 245 /** 246 * @param name_index the index into the constant pool for the name of this variable 247 */ 248 public final void setNameIndex( final int name_index ) { // TODO unused 249 this.name_index = name_index; 250 } 251 252 253 /** 254 * @param signature_index the index into the constant pool for the signature of this variable 255 */ 256 public final void setSignatureIndex( final int signature_index ) { // TODO unused 257 this.signature_index = signature_index; 258 } 259 260 261 /** 262 * @param index the index in the local variable table of this variable 263 */ 264 public final void setIndex( final int index ) { // TODO unused 265 this.index = index; 266 } 267 268 269 /** 270 * @param start_pc Specify range where the local variable is valid. 271 */ 272 public final void setStartPC( final int start_pc ) { // TODO unused 273 this.start_pc = start_pc; 274 } 275 276 277 /** 278 * @return string representation. 279 */ 280 @Override 281 public final String toString() { 282 return toStringShared(false); 283 } 284 285 286 /** 287 * @return deep copy of this object 288 */ 289 public LocalVariable copy() { 290 try { 291 return (LocalVariable) clone(); 292 } catch (final CloneNotSupportedException e) { 293 // TODO should this throw? 294 } 295 return null; 296 } 297 }