001 /***
002 * ASM: a very small and fast Java bytecode manipulation framework
003 * Copyright (c) 2000-2005 INRIA, France Telecom
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions
008 * are met:
009 * 1. Redistributions of source code must retain the above copyright
010 * notice, this list of conditions and the following disclaimer.
011 * 2. Redistributions in binary form must reproduce the above copyright
012 * notice, this list of conditions and the following disclaimer in the
013 * documentation and/or other materials provided with the distribution.
014 * 3. Neither the name of the copyright holders nor the names of its
015 * contributors may be used to endorse or promote products derived from
016 * this software without specific prior written permission.
017 *
018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
028 * THE POSSIBILITY OF SUCH DAMAGE.
029 */
030 package net.sourceforge.retroweaver.optimizer;
031
032 import java.util.HashMap;
033
034 import org.objectweb.asm.Type;
035
036 /**
037 * A constant pool.
038 *
039 * @author Eric Bruneton
040 */
041 public class ConstantPool extends HashMap<Constant, Constant> {
042
043 private Constant key1 = new Constant();
044
045 private Constant key2 = new Constant();
046
047 private Constant key3 = new Constant();
048
049 public Constant newInteger(final int value) {
050 key1.set(value);
051 Constant result = get(key1);
052 if (result == null) {
053 result = new Constant(key1);
054 put(result);
055 }
056 return result;
057 }
058
059 public Constant newFloat(final float value) {
060 key1.set(value);
061 Constant result = get(key1);
062 if (result == null) {
063 result = new Constant(key1);
064 put(result);
065 }
066 return result;
067 }
068
069 public Constant newLong(final long value) {
070 key1.set(value);
071 Constant result = get(key1);
072 if (result == null) {
073 result = new Constant(key1);
074 put(result);
075 }
076 return result;
077 }
078
079 public Constant newDouble(final double value) {
080 key1.set(value);
081 Constant result = get(key1);
082 if (result == null) {
083 result = new Constant(key1);
084 put(result);
085 }
086 return result;
087 }
088
089 public Constant newUTF8(final String value) {
090 key1.set('s', value, null, null);
091 Constant result = get(key1);
092 if (result == null) {
093 result = new Constant(key1);
094 put(result);
095 }
096 return result;
097 }
098
099 private Constant newString(final String value) {
100 key2.set('S', value, null, null);
101 Constant result = get(key2);
102 if (result == null) {
103 newUTF8(value);
104 result = new Constant(key2);
105 put(result);
106 }
107 return result;
108 }
109
110 public Constant newClass(final String value) {
111 key2.set('C', value, null, null);
112 Constant result = get(key2);
113 if (result == null) {
114 newUTF8(value);
115 result = new Constant(key2);
116 put(result);
117 }
118 return result;
119 }
120
121 public Constant newConst(final Object cst) {
122 if (cst instanceof Integer) {
123 int val = ((Integer) cst).intValue();
124 return newInteger(val);
125 } else if (cst instanceof Float) {
126 float val = ((Float) cst).floatValue();
127 return newFloat(val);
128 } else if (cst instanceof Long) {
129 long val = ((Long) cst).longValue();
130 return newLong(val);
131 } else if (cst instanceof Double) {
132 double val = ((Double) cst).doubleValue();
133 return newDouble(val);
134 } else if (cst instanceof String) {
135 return newString((String) cst);
136 } else if (cst instanceof Type) {
137 Type t = (Type) cst;
138 return newClass(t.getSort() == Type.OBJECT
139 ? t.getInternalName()
140 : t.getDescriptor());
141 } else {
142 throw new IllegalArgumentException("value " + cst);
143 }
144 }
145
146 public Constant newField(
147 final String owner,
148 final String name,
149 final String desc)
150 {
151 key3.set('G', owner, name, desc);
152 Constant result = get(key3);
153 if (result == null) {
154 newClass(owner);
155 newNameType(name, desc);
156 result = new Constant(key3);
157 put(result);
158 }
159 return result;
160 }
161
162 public Constant newMethod(
163 final String owner,
164 final String name,
165 final String desc,
166 final boolean itf)
167 {
168 key3.set(itf ? 'N' : 'M', owner, name, desc);
169 Constant result = get(key3);
170 if (result == null) {
171 newClass(owner);
172 newNameType(name, desc);
173 result = new Constant(key3);
174 put(result);
175 }
176 return result;
177 }
178
179 public Constant newNameType(final String name, final String desc) {
180 key2.set('T', name, desc, null);
181 Constant result = get(key2);
182 if (result == null) {
183 newUTF8(name);
184 newUTF8(desc);
185 result = new Constant(key2);
186 put(result);
187 }
188 return result;
189 }
190
191 private void put(final Constant cst) {
192 put(cst, cst);
193 }
194 }