001    /*
002     * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
003     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004     *
005     * This code is free software; you can redistribute it and/or modify it
006     * under the terms of the GNU General Public License version 2 only, as
007     * published by the Free Software Foundation.  Sun designates this
008     * particular file as subject to the "Classpath" exception as provided
009     * by Sun in the LICENSE file that accompanied this code.
010     *
011     * This code is distributed in the hope that it will be useful, but WITHOUT
012     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013     * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014     * version 2 for more details (a copy is included in the LICENSE file that
015     * accompanied this code).
016     *
017     * You should have received a copy of the GNU General Public License version
018     * 2 along with this work; if not, write to the Free Software Foundation,
019     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020     *
021     * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022     * CA 95054 USA or visit www.sun.com if you need additional information or
023     * have any questions.
024     */
025    
026    
027    package sun.tools.javap;
028    
029    import java.util.Hashtable;
030    import java.util.Vector;
031    
032    
033    public class Tables implements Constants {
034        /**
035         * Define mnemocodes table.
036         */
037      static  Hashtable<String,Integer> mnemocodes = new Hashtable<String,Integer>(301, 0.5f);
038      static  String opcExtNamesTab[]=new String[128];
039      static  String opcPrivExtNamesTab[]=new String[128];
040      static  void defineNonPriv(int opc, String mnem) {
041            mnemocodes.put(opcExtNamesTab[opc]=mnem, opc_nonpriv*256+opc);
042      }
043      static  void definePriv(int opc, String mnem) {
044            mnemocodes.put(opcPrivExtNamesTab[opc]="priv_"+mnem, opc_priv*256+opc);
045      }
046      static  void defineExt(int opc, String mnem) {
047            defineNonPriv(opc, mnem);
048            definePriv(opc, mnem);
049      }
050      static { int k;
051            for (k=0; k<opc_wide; k++) {
052                    mnemocodes.put(opcNamesTab[k], k);
053            }
054            for (k=opc_wide+1; k<opcNamesTab.length; k++) {
055                    mnemocodes.put(opcNamesTab[k], k);
056            }
057            mnemocodes.put("invokenonvirtual", opc_invokespecial);
058    
059            mnemocodes.put("iload_w", opc_iload_w);
060            mnemocodes.put("lload_w", opc_lload_w);
061            mnemocodes.put("fload_w", opc_fload_w);
062            mnemocodes.put("dload_w", opc_dload_w);
063            mnemocodes.put("aload_w", opc_aload_w);
064            mnemocodes.put("istore_w", opc_istore_w);
065            mnemocodes.put("lstore_w", opc_lstore_w);
066            mnemocodes.put("fstore_w", opc_fstore_w);
067            mnemocodes.put("dstore_w", opc_dstore_w);
068            mnemocodes.put("astore_w", opc_astore_w);
069            mnemocodes.put("ret_w", opc_ret_w);
070            mnemocodes.put("iinc_w", opc_iinc_w);
071    
072            mnemocodes.put("nonpriv", opc_nonpriv);
073            mnemocodes.put("priv", opc_priv);
074    
075            defineExt(0, "load_ubyte");
076            defineExt(1, "load_byte");
077            defineExt(2, "load_char");
078            defineExt(3, "load_short");
079            defineExt(4, "load_word");
080            defineExt(10, "load_char_oe");
081            defineExt(11, "load_short_oe");
082            defineExt(12, "load_word_oe");
083            defineExt(16, "ncload_ubyte");
084            defineExt(17, "ncload_byte");
085            defineExt(18, "ncload_char");
086            defineExt(19, "ncload_short");
087            defineExt(20, "ncload_word");
088            defineExt(26, "ncload_char_oe");
089            defineExt(27, "ncload_short_oe");
090            defineExt(28, "ncload_word_oe");
091            defineExt(30, "cache_flush");
092            defineExt(32, "store_byte");
093            defineExt(34, "store_short");
094            defineExt(36, "store_word");
095            defineExt(42, "store_short_oe");
096            defineExt(44, "store_word_oe");
097            defineExt(48, "ncstore_byte");
098            defineExt(50, "ncstore_short");
099            defineExt(52, "ncstore_word");
100            defineExt(58, "ncstore_short_oe");
101            defineExt(60, "ncstore_word_oe");
102            defineExt(62, "zero_line");
103            defineNonPriv(5, "ret_from_sub");
104            defineNonPriv(63, "enter_sync_method");
105            definePriv(5, "ret_from_trap");
106            definePriv(6, "read_dcache_tag");
107            definePriv(7, "read_dcache_data");
108            definePriv(14, "read_icache_tag");
109            definePriv(15, "read_icache_data");
110            definePriv(22, "powerdown");
111            definePriv(23, "read_scache_data");
112            definePriv(31, "cache_index_flush");
113            definePriv(38, "write_dcache_tag");
114            definePriv(39, "write_dcache_data");
115            definePriv(46, "write_icache_tag");
116            definePriv(47, "write_icache_data");
117            definePriv(54, "reset");
118            definePriv(55, "write_scache_data");
119            for (k=0; k<32; k++) {
120                    definePriv(k+64, "read_reg_"+k);
121            }
122            for (k=0; k<32; k++) {
123                    definePriv(k+96, "write_reg_"+k);
124            }
125     }
126    
127      public static int opcLength(int opc) throws ArrayIndexOutOfBoundsException {
128            switch (opc>>8) {
129              case 0:
130                    return opcLengthsTab[opc];
131              case opc_wide:
132                    switch (opc&0xFF) {
133                      case opc_aload: case opc_astore:
134                      case opc_fload: case opc_fstore:
135                      case opc_iload: case opc_istore:
136                      case opc_lload: case opc_lstore:
137                      case opc_dload: case opc_dstore:
138                      case opc_ret:
139                            return  4;
140                      case opc_iinc:
141                            return  6;
142                      default:
143                            throw new ArrayIndexOutOfBoundsException();
144                    }
145              case opc_nonpriv:
146              case opc_priv:
147                    return 2;
148              default:
149                    throw new ArrayIndexOutOfBoundsException();
150            }
151      }
152    
153      public static String opcName(int opc) {
154            try {
155                    switch (opc>>8) {
156                      case 0:
157                            return opcNamesTab[opc];
158                      case opc_wide: {
159                            String mnem=opcNamesTab[opc&0xFF]+"_w";
160                            if (mnemocodes.get(mnem) == null)
161                                    return null; // non-existent opcode
162                            return mnem;
163                      }
164                      case opc_nonpriv:
165                            return opcExtNamesTab[opc&0xFF];
166                      case opc_priv:
167                            return opcPrivExtNamesTab[opc&0xFF];
168                      default:
169                            return null;
170                    }
171            } catch (ArrayIndexOutOfBoundsException e) {
172                    switch (opc) {
173                      case opc_nonpriv:
174                            return "nonpriv";
175                      case opc_priv:
176                            return "priv";
177                      default:
178                            return null;
179                    }
180            }
181      }
182    
183      public static int opcode(String mnem) {
184            Integer Val=mnemocodes.get(mnem);
185            if (Val == null) return -1;
186            return Val.intValue();
187      }
188    
189        /**
190         * Initialized keyword and token Hashtables
191         */
192      static Vector<String> keywordNames = new Vector<String>(40);
193      private static void defineKeywordName(String id, int token) {
194    
195            if (token>=keywordNames.size()) {
196                    keywordNames.setSize(token+1);
197            }
198            keywordNames.setElementAt(id, token);
199      }
200      public static String keywordName(int token) {
201            if (token==-1) return "EOF";
202            if (token>=keywordNames.size()) return null;
203            return keywordNames.elementAt(token);
204      }
205      static {
206            defineKeywordName("ident", IDENT);
207            defineKeywordName("STRINGVAL", STRINGVAL);
208            defineKeywordName("intVal", INTVAL);
209            defineKeywordName("longVal", LONGVAL);
210            defineKeywordName("floatVal", FLOATVAL);
211            defineKeywordName("doubleVal", DOUBLEVAL);
212            defineKeywordName("SEMICOLON", SEMICOLON);
213            defineKeywordName("COLON", COLON);
214            defineKeywordName("LBRACE", LBRACE);
215            defineKeywordName("RBRACE", RBRACE);
216      }
217    
218      static Hashtable<String,Integer> keywords = new Hashtable<String,Integer>(40);
219      public static int keyword(String idValue) {
220            Integer val=keywords.get(idValue);
221            if (val == null) return IDENT;
222            return val.intValue();
223      }
224    
225      private static void defineKeyword(String id, int token) {
226            keywords.put(id, token);
227            defineKeywordName(id, token);
228      }
229      static {
230            // Modifier keywords
231            defineKeyword("private", PRIVATE);
232            defineKeyword("public", PUBLIC);
233            defineKeyword("protected",      PROTECTED);
234            defineKeyword("static", STATIC);
235            defineKeyword("transient",      TRANSIENT);
236            defineKeyword("synchronized",   SYNCHRONIZED);
237            defineKeyword("super",  SUPER);
238            defineKeyword("native", NATIVE);
239            defineKeyword("abstract",       ABSTRACT);
240            defineKeyword("volatile", VOLATILE);
241            defineKeyword("final",  FINAL);
242            defineKeyword("interface",INTERFACE);
243            defineKeyword("synthetic",SYNTHETIC);
244            defineKeyword("strict",STRICT);
245    
246            // Declaration keywords
247            defineKeyword("package",PACKAGE);
248            defineKeyword("class",CLASS);
249            defineKeyword("extends",EXTENDS);
250            defineKeyword("implements",IMPLEMENTS);
251            defineKeyword("const",  CONST);
252            defineKeyword("throws",THROWS);
253            defineKeyword("interface",INTERFACE);
254            defineKeyword("Method",METHODREF);
255            defineKeyword("Field",FIELDREF);
256            defineKeyword("stack",STACK);
257            defineKeyword("locals",LOCAL);
258    
259            // used in switchtables
260            defineKeyword("default",        DEFAULT);
261    
262            // used in inner class declarations
263            defineKeyword("InnerClass",     INNERCLASS);
264            defineKeyword("of",     OF);
265    
266            // misc
267            defineKeyword("bits",BITS);
268            defineKeyword("Infinity",INF);
269            defineKeyword("Inf",INF);
270            defineKeyword("NaN",NAN);
271      }
272    
273       /**
274         * Define tag table.
275         */
276      private static Vector<String> tagNames = new Vector<String>(10);
277      private static Hashtable<String,Integer> Tags = new Hashtable<String,Integer>(10);
278      static {
279            defineTag("Asciz",CONSTANT_UTF8);
280            defineTag("int",CONSTANT_INTEGER);
281            defineTag("float",CONSTANT_FLOAT);
282            defineTag("long",CONSTANT_LONG);
283            defineTag("double",CONSTANT_DOUBLE);
284            defineTag("class",CONSTANT_CLASS);
285            defineTag("String",CONSTANT_STRING);
286            defineTag("Field",CONSTANT_FIELD);
287            defineTag("Method",CONSTANT_METHOD);
288            defineTag("InterfaceMethod",CONSTANT_INTERFACEMETHOD);
289            defineTag("NameAndType",CONSTANT_NAMEANDTYPE);
290      }
291      private static void defineTag(String id, int val) {
292            Tags.put(id, val);
293            if (val>=tagNames.size()) {
294                    tagNames.setSize(val+1);
295            }
296            tagNames.setElementAt(id, val);
297      }
298      public static String tagName(int tag) {
299            if (tag>=tagNames.size()) return null;
300            return tagNames.elementAt(tag);
301      }
302      public static int tagValue(String idValue) {
303            Integer Val=Tags.get(idValue);
304            if (Val == null) return 0;
305            return Val.intValue();
306      }
307    
308       /**
309         * Define type table. These types used in "newarray" instruction only.
310         */
311      private static Vector<String> typeNames = new Vector<String>(10);
312      private static Hashtable<String,Integer> Types = new Hashtable<String,Integer>(10);
313      static {
314            defineType("int",T_INT);
315            defineType("long",T_LONG);
316            defineType("float",T_FLOAT);
317            defineType("double",T_DOUBLE);
318            defineType("class",T_CLASS);
319            defineType("boolean",T_BOOLEAN);
320            defineType("char",T_CHAR);
321            defineType("byte",T_BYTE);
322            defineType("short",T_SHORT);
323      }
324      private static void defineType(String id, int val) {
325            Types.put(id, val);
326            if (val>=typeNames.size()) {
327                    typeNames.setSize(val+1);
328            }
329            typeNames.setElementAt(id, val);
330      }
331      public static int typeValue(String idValue) {
332            Integer Val=Types.get(idValue);
333            if (Val == null) return -1;
334            return Val.intValue();
335      }
336      public static String typeName(int type) {
337            if (type>=typeNames.size()) return null;
338            return typeNames.elementAt(type);
339      }
340    
341       /**
342         * Define MapTypes table.
343         * These constants used in stackmap tables only.
344         */
345      private static Vector<String> mapTypeNames = new Vector<String>(10);
346      private static Hashtable<String,Integer> MapTypes = new Hashtable<String,Integer>(10);
347      static {
348            defineMapType("bogus",             ITEM_Bogus);
349            defineMapType("int",               ITEM_Integer);
350            defineMapType("float",             ITEM_Float);
351            defineMapType("double",            ITEM_Double);
352            defineMapType("long",              ITEM_Long);
353            defineMapType("null",              ITEM_Null);
354            defineMapType("this",              ITEM_InitObject);
355            defineMapType("CP",                ITEM_Object);
356            defineMapType("uninitialized",     ITEM_NewObject);
357      }
358      private static void defineMapType(String id, int val) {
359            MapTypes.put(id, val);
360            if (val>=mapTypeNames.size()) {
361                    mapTypeNames.setSize(val+1);
362            }
363            mapTypeNames.setElementAt(id, val);
364      }
365      public static int mapTypeValue(String idValue) {
366            Integer Val=MapTypes.get(idValue);
367            if (Val == null) return -1;
368            return Val.intValue();
369      }
370      public static String mapTypeName(int type) {
371            if (type>=mapTypeNames.size()) return null;
372            return mapTypeNames.elementAt(type);
373      }
374    
375    }