• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
18 package org.apache.bcel.verifier.statics;
19 
20 
21 import java.util.Hashtable;
22 
23 import org.apache.bcel.generic.Type;
24 import org.apache.bcel.verifier.exc.LocalVariableInfoInconsistentException;
25 
26 /**
27  * A utility class holding the information about
28  * the name and the type of a local variable in
29  * a given slot (== index). This information
30  * often changes in course of byte code offsets.
31  *
32  * @version $Id$
33  */
34 public class LocalVariableInfo{
35 
36     /** The types database. KEY: String representing the offset integer. */
37     private final Hashtable<String, Type> types = new Hashtable<>();
38     /** The names database. KEY: String representing the offset integer. */
39     private final Hashtable<String, String> names = new Hashtable<>();
40 
41     /**
42      * Adds a name of a local variable and a certain slot to our 'names'
43      * (Hashtable) database.
44      */
setName(final int offset, final String name)45     private void setName(final int offset, final String name) {
46         names.put(Integer.toString(offset), name);
47     }
48     /**
49      * Adds a type of a local variable and a certain slot to our 'types'
50      * (Hashtable) database.
51      */
setType(final int offset, final Type t)52     private void setType(final int offset, final Type t) {
53         types.put(Integer.toString(offset), t);
54     }
55 
56     /**
57      * Returns the type of the local variable that uses this local
58      * variable slot at the given bytecode offset.
59      * Care for legal bytecode offsets yourself, otherwise the return value
60      * might be wrong.
61      * May return 'null' if nothing is known about the type of this local
62      * variable slot at the given bytecode offset.
63      */
getType(final int offset)64     public Type getType(final int offset) {
65         return types.get(Integer.toString(offset));
66     }
67     /**
68      * Returns the name of the local variable that uses this local
69      * variable slot at the given bytecode offset.
70      * Care for legal bytecode offsets yourself, otherwise the return value
71      * might be wrong.
72      * May return 'null' if nothing is known about the type of this local
73      * variable slot at the given bytecode offset.
74      */
getName(final int offset)75     public String getName(final int offset) {
76         return names.get(Integer.toString(offset));
77     }
78     /**
79      * Adds some information about this local variable (slot).
80      * @throws LocalVariableInfoInconsistentException if the new information conflicts
81      *         with already gathered information.
82      */
add(final String name, final int startpc, final int length, final Type t)83     public void add(final String name, final int startpc, final int length, final Type t) throws LocalVariableInfoInconsistentException{
84         for (int i=startpc; i<=startpc+length; i++) { // incl/incl-notation!
85             add(i,name,t);
86         }
87     }
88 
89     /**
90      * Adds information about name and type for a given offset.
91      * @throws LocalVariableInfoInconsistentException if the new information conflicts
92      *         with already gathered information.
93      */
add(final int offset, final String name, final Type t)94     private void add(final int offset, final String name, final Type t) throws LocalVariableInfoInconsistentException{
95         if (getName(offset) != null) {
96             if (! getName(offset).equals(name)) {
97                 throw new LocalVariableInfoInconsistentException("At bytecode offset '"+offset+
98                     "' a local variable has two different names: '"+getName(offset)+"' and '"+name+"'.");
99             }
100         }
101         if (getType(offset) != null) {
102             if (! getType(offset).equals(t)) {
103                 throw new LocalVariableInfoInconsistentException("At bytecode offset '"+offset+
104                     "' a local variable has two different types: '"+getType(offset)+"' and '"+t+"'.");
105             }
106         }
107         setName(offset, name);
108         setType(offset, t);
109     }
110 }
111