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    }