001 /* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013 package org.jikesrvm.classloader; 014 015 import java.io.DataInputStream; 016 import java.io.IOException; 017 018 /** 019 * A java method's local variable information 020 */ 021 public final class LocalVariableTable { 022 /** 023 * Local variables in this table 024 */ 025 private final LocalVariable[] locals; 026 027 /** 028 * Information needed to describe a local variable 029 */ 030 static class LocalVariable { 031 /** 032 * The start PC location where the variable is active 033 */ 034 private final int startPC; 035 036 /** 037 * The variable is active in PC values [startPC, startPC+length]. 038 */ 039 private final int length; 040 041 /** 042 * The variable's name. 043 */ 044 private final Atom name; 045 046 /** 047 * The variable's type descriptor. 048 */ 049 private final Atom descriptor; 050 051 /** 052 * The slot on the local variable stack where the variable is stored. 053 */ 054 private final int frameIndex; 055 056 /** 057 * Construct a local variable. 058 * 059 * @param startPC 060 * @param length 061 * @param name 062 * @param descriptor 063 * @param frameIndex 064 */ 065 LocalVariable(int startPC, int length, Atom name, Atom descriptor, int frameIndex) { 066 this.startPC = startPC; 067 this.length = length; 068 this.name = name; 069 this.descriptor = descriptor; 070 this.frameIndex = frameIndex; 071 } 072 073 /** 074 * String represenation of this local variable. 075 */ 076 @Override 077 public String toString() { 078 return (startPC + " " + 079 length + " " + 080 name.toString() + " " + 081 descriptor.toString() + " " + 082 frameIndex + "\n"); 083 } 084 } 085 086 /** 087 * Construct the local variable table 088 * 089 * @param locals 090 */ 091 LocalVariableTable(LocalVariable[] locals) { 092 this.locals = locals; 093 } 094 095 /** 096 * Read the local variable table 097 * 098 * @return a local variable table or null if none were present 099 */ 100 static LocalVariableTable readLocalVariableTable(DataInputStream input, int[] constantPool) throws IOException { 101 int numVars = input.readUnsignedShort(); 102 if (numVars > 0) { 103 LocalVariable[] lvs = new LocalVariable[numVars]; 104 for (int i = 0; i < numVars; ++i) { 105 LocalVariable lv = new LocalVariable( 106 input.readUnsignedShort(), 107 input.readUnsignedShort(), 108 ClassFileReader.getUtf(constantPool, input.readUnsignedShort()), 109 ClassFileReader.getUtf(constantPool, input.readUnsignedShort()), 110 input.readUnsignedShort()); 111 lvs[i] = lv; 112 } 113 return new LocalVariableTable(lvs); 114 } else { 115 return null; 116 } 117 } 118 119 /** 120 * String representation of the local variable table. 121 */ 122 @Override 123 public String toString() { 124 StringBuilder sb = new StringBuilder(); 125 sb.append("Local Variable Table: \n"); 126 for (LocalVariable lv : locals) { 127 sb.append(lv.toString()); 128 } 129 return sb.toString(); 130 } 131 }