LocalVariableInfo.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  *  Unless required by applicable law or agreed to in writing, software
  12.  *  distributed under the License is distributed on an "AS IS" BASIS,
  13.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  *  See the License for the specific language governing permissions and
  15.  *  limitations under the License.
  16.  */
  17. package org.apache.bcel.verifier.statics;

  18. import java.util.Hashtable;

  19. import org.apache.bcel.generic.Type;
  20. import org.apache.bcel.verifier.exc.LocalVariableInfoInconsistentException;

  21. /**
  22.  * A utility class holding the information about the name and the type of a local variable in a given slot (== index).
  23.  * This information often changes in course of byte code offsets.
  24.  */
  25. public class LocalVariableInfo {

  26.     /** The types database. KEY: String representing the offset integer. */
  27.     private final Hashtable<String, Type> types = new Hashtable<>();

  28.     /** The names database. KEY: String representing the offset integer. */
  29.     private final Hashtable<String, String> names = new Hashtable<>();

  30.     /**
  31.      * Adds information about name and type for a given offset.
  32.      *
  33.      * @throws LocalVariableInfoInconsistentException if the new information conflicts with already gathered information.
  34.      */
  35.     private void add(final int offset, final String name, final Type t) throws LocalVariableInfoInconsistentException {
  36.         if (getName(offset) != null && !getName(offset).equals(name)) {
  37.             throw new LocalVariableInfoInconsistentException(
  38.                 "At bytecode offset '" + offset + "' a local variable has two different names: '" + getName(offset) + "' and '" + name + "'.");
  39.         }
  40.         if (getType(offset) != null && !getType(offset).equals(t)) {
  41.             throw new LocalVariableInfoInconsistentException(
  42.                 "At bytecode offset '" + offset + "' a local variable has two different types: '" + getType(offset) + "' and '" + t + "'.");
  43.         }
  44.         setName(offset, name);
  45.         setType(offset, t);
  46.     }

  47.     /**
  48.      * Adds some information about this local variable (slot).
  49.      *
  50.      * @param name variable name
  51.      * @param startPc Range in which the variable is valid.
  52.      * @param length length of ...
  53.      * @param type variable type
  54.      *
  55.      * @throws LocalVariableInfoInconsistentException if the new information conflicts with already gathered information.
  56.      */
  57.     public void add(final String name, final int startPc, final int length, final Type type) throws LocalVariableInfoInconsistentException {
  58.         for (int i = startPc; i <= startPc + length; i++) { // incl/incl-notation!
  59.             add(i, name, type);
  60.         }
  61.     }

  62.     /**
  63.      * Returns the name of the local variable that uses this local variable slot at the given bytecode offset. Care for
  64.      * legal bytecode offsets yourself, otherwise the return value might be wrong. May return 'null' if nothing is known
  65.      * about the type of this local variable slot at the given bytecode offset.
  66.      *
  67.      * @param offset bytecode offset.
  68.      * @return the name of the local variable that uses this local variable slot at the given bytecode offset.
  69.      */
  70.     public String getName(final int offset) {
  71.         return names.get(Integer.toString(offset));
  72.     }

  73.     /**
  74.      * Returns the type of the local variable that uses this local variable slot at the given bytecode offset. Care for
  75.      * legal bytecode offsets yourself, otherwise the return value might be wrong. May return 'null' if nothing is known
  76.      * about the type of this local variable slot at the given bytecode offset.
  77.      *
  78.      * @param offset bytecode offset.
  79.      * @return the type of the local variable that uses this local variable slot at the given bytecode offset.
  80.      */
  81.     public Type getType(final int offset) {
  82.         return types.get(Integer.toString(offset));
  83.     }

  84.     /**
  85.      * Adds a name of a local variable and a certain slot to our 'names' (Hashtable) database.
  86.      */
  87.     private void setName(final int offset, final String name) {
  88.         names.put(Integer.toString(offset), name);
  89.     }

  90.     /**
  91.      * Adds a type of a local variable and a certain slot to our 'types' (Hashtable) database.
  92.      */
  93.     private void setType(final int offset, final Type t) {
  94.         types.put(Integer.toString(offset), t);
  95.     }
  96. }