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 import org.apache.bcel.generic.Type;
23 import org.apache.bcel.verifier.exc.LocalVariableInfoInconsistentException;
24
25 /**
26 * A utility class holding the information about
27 * the name and the type of a local variable in
28 * a given slot (== index). This information
29 * often changes in course of byte code offsets.
30 *
31 * @version $Id: LocalVariableInfo.java 1149459 2011-07-22 04:34:27Z dbrosius $
32 * @author Enver Haase
33 */
34 public class LocalVariableInfo{
35
36 /** The types database. KEY: String representing the offset integer. */
37 private Hashtable<String, Type> types = new Hashtable<String, Type>();
38 /** The names database. KEY: String representing the offset integer. */
39 private Hashtable<String, String> names = new Hashtable<String, String>();
40
41 /**
42 * Adds a name of a local variable and a certain slot to our 'names'
43 * (Hashtable) database.
44 */
45 private void setName(int offset, 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 */
52 private void setType(int offset, 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 */
64 public Type getType(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 */
75 public String getName(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 */
83 public void add(String name, int startpc, int length, 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 */
94 private void add(int offset, String name, Type t) throws LocalVariableInfoInconsistentException{
95 if (getName(offset) != null){
96 if (! getName(offset).equals(name)){
97 throw new LocalVariableInfoInconsistentException("At bytecode offset '"+offset+"' a local variable has two different names: '"+getName(offset)+"' and '"+name+"'.");
98 }
99 }
100 if (getType(offset) != null){
101 if (! getType(offset).equals(t)){
102 throw new LocalVariableInfoInconsistentException("At bytecode offset '"+offset+"' a local variable has two different types: '"+getType(offset)+"' and '"+t+"'.");
103 }
104 }
105 setName(offset, name);
106 setType(offset, t);
107 }
108 }