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 */
013package org.jikesrvm.classloader;
014
015import java.io.DataInputStream;
016import java.io.IOException;
017
018/**
019 * A java method's local variable information
020 */
021public 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    LocalVariable(int startPC, int length, Atom name, Atom descriptor, int frameIndex) {
057      this.startPC = startPC;
058      this.length = length;
059      this.name = name;
060      this.descriptor = descriptor;
061      this.frameIndex = frameIndex;
062    }
063
064    @Override
065    public String toString() {
066      return (startPC + " " +
067             length + " " +
068             name.toString() + " " +
069             descriptor.toString() + " " +
070             frameIndex + "\n");
071    }
072  }
073
074  LocalVariableTable(LocalVariable[] locals) {
075    this.locals = locals;
076  }
077
078  static LocalVariableTable readLocalVariableTable(DataInputStream input, int[] constantPool) throws IOException {
079    int numVars = input.readUnsignedShort();
080    if (numVars > 0) {
081      LocalVariable[] lvs = new LocalVariable[numVars];
082      for (int i = 0; i < numVars; ++i) {
083        LocalVariable lv = new LocalVariable(
084            input.readUnsignedShort(),
085            input.readUnsignedShort(),
086            ClassFileReader.getUtf(constantPool, input.readUnsignedShort()),
087            ClassFileReader.getUtf(constantPool, input.readUnsignedShort()),
088            input.readUnsignedShort());
089        lvs[i] = lv;
090      }
091      return new LocalVariableTable(lvs);
092    } else {
093      return null;
094    }
095  }
096
097  /**
098   * String representation of the local variable table.
099   */
100  @Override
101  public String toString() {
102    StringBuilder sb = new StringBuilder();
103    sb.append("Local Variable Table: \n");
104    for (LocalVariable lv : locals) {
105      sb.append(lv.toString());
106    }
107    return sb.toString();
108  }
109}