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 }