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 public String toString() {
077 return (startPC + " " +
078 length + " " +
079 name.toString() + " " +
080 descriptor.toString() + " " +
081 frameIndex + "\n");
082 }
083 }
084
085 /**
086 * Construct the local variable table
087 *
088 * @param locals
089 */
090 LocalVariableTable(LocalVariable[] locals) {
091 this.locals = locals;
092 }
093
094 /**
095 * Read the local variable table
096 *
097 * @return a local variable table or null if none were present
098 */
099 static LocalVariableTable readLocalVariableTable(DataInputStream input, int[] constantPool) throws IOException {
100 int numVars = input.readUnsignedShort();
101 if (numVars > 0) {
102 LocalVariable[] lvs = new LocalVariable[numVars];
103 for (int i = 0; i < numVars; ++i) {
104 LocalVariable lv = new LocalVariable(
105 input.readUnsignedShort(),
106 input.readUnsignedShort(),
107 ClassFileReader.getUtf(constantPool, input.readUnsignedShort()),
108 ClassFileReader.getUtf(constantPool, input.readUnsignedShort()),
109 input.readUnsignedShort());
110 lvs[i] = lv;
111 }
112 return new LocalVariableTable(lvs);
113 } else {
114 return null;
115 }
116 }
117
118 /**
119 * String representation of the local variable table.
120 */
121 public String toString() {
122 StringBuilder sb = new StringBuilder();
123 sb.append("Local Variable Table: \n");
124 for (LocalVariable lv : locals) {
125 sb.append(lv.toString());
126 }
127 return sb.toString();
128 }
129 }