2 * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
25 package org.apidesign.vm4brwsr;
27 import java.io.ByteArrayInputStream;
28 import java.io.DataInputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import org.apidesign.bck2brwsr.core.JavaScriptBody;
32 import org.apidesign.bck2brwsr.core.JavaScriptPrototype;
34 /** This is a byte code parser heavily based on original code of JavaP utility.
35 * As such I decided to keep the original Oracle's GPLv2 header.
37 * @author Jaroslav Tulach <jtulach@netbeans.org>
39 final class ByteCodeParser {
40 private ByteCodeParser() {
42 /* Signature Characters */
43 public static final char SIGC_VOID = 'V';
44 public static final String SIG_VOID = "V";
45 public static final char SIGC_BOOLEAN = 'Z';
46 public static final String SIG_BOOLEAN = "Z";
47 public static final char SIGC_BYTE = 'B';
48 public static final String SIG_BYTE = "B";
49 public static final char SIGC_CHAR = 'C';
50 public static final String SIG_CHAR = "C";
51 public static final char SIGC_SHORT = 'S';
52 public static final String SIG_SHORT = "S";
53 public static final char SIGC_INT = 'I';
54 public static final String SIG_INT = "I";
55 public static final char SIGC_LONG = 'J';
56 public static final String SIG_LONG = "J";
57 public static final char SIGC_FLOAT = 'F';
58 public static final String SIG_FLOAT = "F";
59 public static final char SIGC_DOUBLE = 'D';
60 public static final String SIG_DOUBLE = "D";
61 public static final char SIGC_ARRAY = '[';
62 public static final String SIG_ARRAY = "[";
63 public static final char SIGC_CLASS = 'L';
64 public static final String SIG_CLASS = "L";
65 public static final char SIGC_METHOD = '(';
66 public static final String SIG_METHOD = "(";
67 public static final char SIGC_ENDCLASS = ';';
68 public static final String SIG_ENDCLASS = ";";
69 public static final char SIGC_ENDMETHOD = ')';
70 public static final String SIG_ENDMETHOD = ")";
71 public static final char SIGC_PACKAGE = '/';
72 public static final String SIG_PACKAGE = "/";
74 /* Class File Constants */
75 public static final int JAVA_MAGIC = 0xcafebabe;
76 public static final int JAVA_VERSION = 45;
77 public static final int JAVA_MINOR_VERSION = 3;
80 public static final int CONSTANT_UTF8 = 1;
81 public static final int CONSTANT_UNICODE = 2;
82 public static final int CONSTANT_INTEGER = 3;
83 public static final int CONSTANT_FLOAT = 4;
84 public static final int CONSTANT_LONG = 5;
85 public static final int CONSTANT_DOUBLE = 6;
86 public static final int CONSTANT_CLASS = 7;
87 public static final int CONSTANT_STRING = 8;
88 public static final int CONSTANT_FIELD = 9;
89 public static final int CONSTANT_METHOD = 10;
90 public static final int CONSTANT_INTERFACEMETHOD = 11;
91 public static final int CONSTANT_NAMEANDTYPE = 12;
94 public static final int ACC_PUBLIC = 0x00000001;
95 public static final int ACC_PRIVATE = 0x00000002;
96 public static final int ACC_PROTECTED = 0x00000004;
97 public static final int ACC_STATIC = 0x00000008;
98 public static final int ACC_FINAL = 0x00000010;
99 public static final int ACC_SYNCHRONIZED = 0x00000020;
100 public static final int ACC_SUPER = 0x00000020;
101 public static final int ACC_VOLATILE = 0x00000040;
102 public static final int ACC_TRANSIENT = 0x00000080;
103 public static final int ACC_NATIVE = 0x00000100;
104 public static final int ACC_INTERFACE = 0x00000200;
105 public static final int ACC_ABSTRACT = 0x00000400;
106 public static final int ACC_STRICT = 0x00000800;
107 public static final int ACC_EXPLICIT = 0x00001000;
108 public static final int ACC_SYNTHETIC = 0x00010000; // actually, this is an attribute
111 public static final int T_CLASS = 0x00000002;
112 public static final int T_BOOLEAN = 0x00000004;
113 public static final int T_CHAR = 0x00000005;
114 public static final int T_FLOAT = 0x00000006;
115 public static final int T_DOUBLE = 0x00000007;
116 public static final int T_BYTE = 0x00000008;
117 public static final int T_SHORT = 0x00000009;
118 public static final int T_INT = 0x0000000a;
119 public static final int T_LONG = 0x0000000b;
121 /* Type codes for StackMap attribute */
122 public static final int ITEM_Bogus =0; // an unknown or uninitialized value
123 public static final int ITEM_Integer =1; // a 32-bit integer
124 public static final int ITEM_Float =2; // not used
125 public static final int ITEM_Double =3; // not used
126 public static final int ITEM_Long =4; // a 64-bit integer
127 public static final int ITEM_Null =5; // the type of null
128 public static final int ITEM_InitObject =6; // "this" in constructor
129 public static final int ITEM_Object =7; // followed by 2-byte index of class name
130 public static final int ITEM_NewObject =8; // followed by 2-byte ref to "new"
132 /* Constants used in StackMapTable attribute */
133 public static final int SAME_FRAME_BOUND = 64;
134 public static final int SAME_LOCALS_1_STACK_ITEM_BOUND = 128;
135 public static final int SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247;
136 public static final int SAME_FRAME_EXTENDED = 251;
137 public static final int FULL_FRAME = 255;
140 public static final int opc_dead = -2;
141 public static final int opc_label = -1;
142 public static final int opc_nop = 0;
143 public static final int opc_aconst_null = 1;
144 public static final int opc_iconst_m1 = 2;
145 public static final int opc_iconst_0 = 3;
146 public static final int opc_iconst_1 = 4;
147 public static final int opc_iconst_2 = 5;
148 public static final int opc_iconst_3 = 6;
149 public static final int opc_iconst_4 = 7;
150 public static final int opc_iconst_5 = 8;
151 public static final int opc_lconst_0 = 9;
152 public static final int opc_lconst_1 = 10;
153 public static final int opc_fconst_0 = 11;
154 public static final int opc_fconst_1 = 12;
155 public static final int opc_fconst_2 = 13;
156 public static final int opc_dconst_0 = 14;
157 public static final int opc_dconst_1 = 15;
158 public static final int opc_bipush = 16;
159 public static final int opc_sipush = 17;
160 public static final int opc_ldc = 18;
161 public static final int opc_ldc_w = 19;
162 public static final int opc_ldc2_w = 20;
163 public static final int opc_iload = 21;
164 public static final int opc_lload = 22;
165 public static final int opc_fload = 23;
166 public static final int opc_dload = 24;
167 public static final int opc_aload = 25;
168 public static final int opc_iload_0 = 26;
169 public static final int opc_iload_1 = 27;
170 public static final int opc_iload_2 = 28;
171 public static final int opc_iload_3 = 29;
172 public static final int opc_lload_0 = 30;
173 public static final int opc_lload_1 = 31;
174 public static final int opc_lload_2 = 32;
175 public static final int opc_lload_3 = 33;
176 public static final int opc_fload_0 = 34;
177 public static final int opc_fload_1 = 35;
178 public static final int opc_fload_2 = 36;
179 public static final int opc_fload_3 = 37;
180 public static final int opc_dload_0 = 38;
181 public static final int opc_dload_1 = 39;
182 public static final int opc_dload_2 = 40;
183 public static final int opc_dload_3 = 41;
184 public static final int opc_aload_0 = 42;
185 public static final int opc_aload_1 = 43;
186 public static final int opc_aload_2 = 44;
187 public static final int opc_aload_3 = 45;
188 public static final int opc_iaload = 46;
189 public static final int opc_laload = 47;
190 public static final int opc_faload = 48;
191 public static final int opc_daload = 49;
192 public static final int opc_aaload = 50;
193 public static final int opc_baload = 51;
194 public static final int opc_caload = 52;
195 public static final int opc_saload = 53;
196 public static final int opc_istore = 54;
197 public static final int opc_lstore = 55;
198 public static final int opc_fstore = 56;
199 public static final int opc_dstore = 57;
200 public static final int opc_astore = 58;
201 public static final int opc_istore_0 = 59;
202 public static final int opc_istore_1 = 60;
203 public static final int opc_istore_2 = 61;
204 public static final int opc_istore_3 = 62;
205 public static final int opc_lstore_0 = 63;
206 public static final int opc_lstore_1 = 64;
207 public static final int opc_lstore_2 = 65;
208 public static final int opc_lstore_3 = 66;
209 public static final int opc_fstore_0 = 67;
210 public static final int opc_fstore_1 = 68;
211 public static final int opc_fstore_2 = 69;
212 public static final int opc_fstore_3 = 70;
213 public static final int opc_dstore_0 = 71;
214 public static final int opc_dstore_1 = 72;
215 public static final int opc_dstore_2 = 73;
216 public static final int opc_dstore_3 = 74;
217 public static final int opc_astore_0 = 75;
218 public static final int opc_astore_1 = 76;
219 public static final int opc_astore_2 = 77;
220 public static final int opc_astore_3 = 78;
221 public static final int opc_iastore = 79;
222 public static final int opc_lastore = 80;
223 public static final int opc_fastore = 81;
224 public static final int opc_dastore = 82;
225 public static final int opc_aastore = 83;
226 public static final int opc_bastore = 84;
227 public static final int opc_castore = 85;
228 public static final int opc_sastore = 86;
229 public static final int opc_pop = 87;
230 public static final int opc_pop2 = 88;
231 public static final int opc_dup = 89;
232 public static final int opc_dup_x1 = 90;
233 public static final int opc_dup_x2 = 91;
234 public static final int opc_dup2 = 92;
235 public static final int opc_dup2_x1 = 93;
236 public static final int opc_dup2_x2 = 94;
237 public static final int opc_swap = 95;
238 public static final int opc_iadd = 96;
239 public static final int opc_ladd = 97;
240 public static final int opc_fadd = 98;
241 public static final int opc_dadd = 99;
242 public static final int opc_isub = 100;
243 public static final int opc_lsub = 101;
244 public static final int opc_fsub = 102;
245 public static final int opc_dsub = 103;
246 public static final int opc_imul = 104;
247 public static final int opc_lmul = 105;
248 public static final int opc_fmul = 106;
249 public static final int opc_dmul = 107;
250 public static final int opc_idiv = 108;
251 public static final int opc_ldiv = 109;
252 public static final int opc_fdiv = 110;
253 public static final int opc_ddiv = 111;
254 public static final int opc_irem = 112;
255 public static final int opc_lrem = 113;
256 public static final int opc_frem = 114;
257 public static final int opc_drem = 115;
258 public static final int opc_ineg = 116;
259 public static final int opc_lneg = 117;
260 public static final int opc_fneg = 118;
261 public static final int opc_dneg = 119;
262 public static final int opc_ishl = 120;
263 public static final int opc_lshl = 121;
264 public static final int opc_ishr = 122;
265 public static final int opc_lshr = 123;
266 public static final int opc_iushr = 124;
267 public static final int opc_lushr = 125;
268 public static final int opc_iand = 126;
269 public static final int opc_land = 127;
270 public static final int opc_ior = 128;
271 public static final int opc_lor = 129;
272 public static final int opc_ixor = 130;
273 public static final int opc_lxor = 131;
274 public static final int opc_iinc = 132;
275 public static final int opc_i2l = 133;
276 public static final int opc_i2f = 134;
277 public static final int opc_i2d = 135;
278 public static final int opc_l2i = 136;
279 public static final int opc_l2f = 137;
280 public static final int opc_l2d = 138;
281 public static final int opc_f2i = 139;
282 public static final int opc_f2l = 140;
283 public static final int opc_f2d = 141;
284 public static final int opc_d2i = 142;
285 public static final int opc_d2l = 143;
286 public static final int opc_d2f = 144;
287 public static final int opc_i2b = 145;
288 public static final int opc_int2byte = 145;
289 public static final int opc_i2c = 146;
290 public static final int opc_int2char = 146;
291 public static final int opc_i2s = 147;
292 public static final int opc_int2short = 147;
293 public static final int opc_lcmp = 148;
294 public static final int opc_fcmpl = 149;
295 public static final int opc_fcmpg = 150;
296 public static final int opc_dcmpl = 151;
297 public static final int opc_dcmpg = 152;
298 public static final int opc_ifeq = 153;
299 public static final int opc_ifne = 154;
300 public static final int opc_iflt = 155;
301 public static final int opc_ifge = 156;
302 public static final int opc_ifgt = 157;
303 public static final int opc_ifle = 158;
304 public static final int opc_if_icmpeq = 159;
305 public static final int opc_if_icmpne = 160;
306 public static final int opc_if_icmplt = 161;
307 public static final int opc_if_icmpge = 162;
308 public static final int opc_if_icmpgt = 163;
309 public static final int opc_if_icmple = 164;
310 public static final int opc_if_acmpeq = 165;
311 public static final int opc_if_acmpne = 166;
312 public static final int opc_goto = 167;
313 public static final int opc_jsr = 168;
314 public static final int opc_ret = 169;
315 public static final int opc_tableswitch = 170;
316 public static final int opc_lookupswitch = 171;
317 public static final int opc_ireturn = 172;
318 public static final int opc_lreturn = 173;
319 public static final int opc_freturn = 174;
320 public static final int opc_dreturn = 175;
321 public static final int opc_areturn = 176;
322 public static final int opc_return = 177;
323 public static final int opc_getstatic = 178;
324 public static final int opc_putstatic = 179;
325 public static final int opc_getfield = 180;
326 public static final int opc_putfield = 181;
327 public static final int opc_invokevirtual = 182;
328 public static final int opc_invokenonvirtual = 183;
329 public static final int opc_invokespecial = 183;
330 public static final int opc_invokestatic = 184;
331 public static final int opc_invokeinterface = 185;
332 // public static final int opc_xxxunusedxxx = 186;
333 public static final int opc_new = 187;
334 public static final int opc_newarray = 188;
335 public static final int opc_anewarray = 189;
336 public static final int opc_arraylength = 190;
337 public static final int opc_athrow = 191;
338 public static final int opc_checkcast = 192;
339 public static final int opc_instanceof = 193;
340 public static final int opc_monitorenter = 194;
341 public static final int opc_monitorexit = 195;
342 public static final int opc_wide = 196;
343 public static final int opc_multianewarray = 197;
344 public static final int opc_ifnull = 198;
345 public static final int opc_ifnonnull = 199;
346 public static final int opc_goto_w = 200;
347 public static final int opc_jsr_w = 201;
348 /* Pseudo-instructions */
349 public static final int opc_bytecode = 203;
350 public static final int opc_try = 204;
351 public static final int opc_endtry = 205;
352 public static final int opc_catch = 206;
353 public static final int opc_var = 207;
354 public static final int opc_endvar = 208;
355 public static final int opc_localsmap = 209;
356 public static final int opc_stackmap = 210;
357 /* PicoJava prefixes */
358 public static final int opc_nonpriv = 254;
359 public static final int opc_priv = 255;
361 /* Wide instructions */
362 public static final int opc_iload_w = (opc_wide<<8)|opc_iload;
363 public static final int opc_lload_w = (opc_wide<<8)|opc_lload;
364 public static final int opc_fload_w = (opc_wide<<8)|opc_fload;
365 public static final int opc_dload_w = (opc_wide<<8)|opc_dload;
366 public static final int opc_aload_w = (opc_wide<<8)|opc_aload;
367 public static final int opc_istore_w = (opc_wide<<8)|opc_istore;
368 public static final int opc_lstore_w = (opc_wide<<8)|opc_lstore;
369 public static final int opc_fstore_w = (opc_wide<<8)|opc_fstore;
370 public static final int opc_dstore_w = (opc_wide<<8)|opc_dstore;
371 public static final int opc_astore_w = (opc_wide<<8)|opc_astore;
372 public static final int opc_ret_w = (opc_wide<<8)|opc_ret;
373 public static final int opc_iinc_w = (opc_wide<<8)|opc_iinc;
376 public static final String opcNamesTab[] = {
560 "invokespecial", // was "invokenonvirtual",
563 "bytecode 186", //"xxxunusedxxx",
579 "bytecode 202", // "breakpoint",
591 public static final int opcLengthsTab[] = {
795 1, 0, 0, 0, 0, 0 // pseudo
801 public static final int EOF = -1;
806 public static final int F_VERBOSE = 1 << 0;
807 public static final int F_DUMP = 1 << 1;
808 public static final int F_WARNINGS = 1 << 2;
809 public static final int F_DEBUG = 1 << 3;
810 public static final int F_OPTIMIZE = 1 << 4;
811 public static final int F_DEPENDENCIES = 1 << 5;
816 public static final int TC_BOOLEAN = 0;
817 public static final int TC_BYTE = 1;
818 public static final int TC_CHAR = 2;
819 public static final int TC_SHORT = 3;
820 public static final int TC_INT = 4;
821 public static final int TC_LONG = 5;
822 public static final int TC_FLOAT = 6;
823 public static final int TC_DOUBLE = 7;
824 public static final int TC_NULL = 8;
825 public static final int TC_ARRAY = 9;
826 public static final int TC_CLASS = 10;
827 public static final int TC_VOID = 11;
828 public static final int TC_METHOD = 12;
829 public static final int TC_ERROR = 13;
834 public static final int TM_NULL = 1 << TC_NULL;
835 public static final int TM_VOID = 1 << TC_VOID;
836 public static final int TM_BOOLEAN = 1 << TC_BOOLEAN;
837 public static final int TM_BYTE = 1 << TC_BYTE;
838 public static final int TM_CHAR = 1 << TC_CHAR;
839 public static final int TM_SHORT = 1 << TC_SHORT;
840 public static final int TM_INT = 1 << TC_INT;
841 public static final int TM_LONG = 1 << TC_LONG;
842 public static final int TM_FLOAT = 1 << TC_FLOAT;
843 public static final int TM_DOUBLE = 1 << TC_DOUBLE;
844 public static final int TM_ARRAY = 1 << TC_ARRAY;
845 public static final int TM_CLASS = 1 << TC_CLASS;
846 public static final int TM_METHOD = 1 << TC_METHOD;
847 public static final int TM_ERROR = 1 << TC_ERROR;
849 public static final int TM_INT32 = TM_BYTE | TM_SHORT | TM_CHAR | TM_INT;
850 public static final int TM_NUM32 = TM_INT32 | TM_FLOAT;
851 public static final int TM_NUM64 = TM_LONG | TM_DOUBLE;
852 public static final int TM_INTEGER = TM_INT32 | TM_LONG;
853 public static final int TM_REAL = TM_FLOAT | TM_DOUBLE;
854 public static final int TM_NUMBER = TM_INTEGER | TM_REAL;
855 public static final int TM_REFERENCE = TM_ARRAY | TM_CLASS | TM_NULL;
860 public static final int CS_UNDEFINED = 0;
861 public static final int CS_UNDECIDED = 1;
862 public static final int CS_BINARY = 2;
863 public static final int CS_SOURCE = 3;
864 public static final int CS_PARSED = 4;
865 public static final int CS_COMPILED = 5;
866 public static final int CS_NOTFOUND = 6;
871 public static final int ATT_ALL = -1;
872 public static final int ATT_CODE = 1;
875 * Number of bits used in file offsets
877 public static final int OFFSETBITS = 19;
878 public static final int MAXFILESIZE = (1 << OFFSETBITS) - 1;
879 public static final int MAXLINENUMBER = (1 << (32 - OFFSETBITS)) - 1;
884 public final int COMMA = 0;
885 public final int ASSIGN = 1;
887 public final int ASGMUL = 2;
888 public final int ASGDIV = 3;
889 public final int ASGREM = 4;
890 public final int ASGADD = 5;
891 public final int ASGSUB = 6;
892 public final int ASGLSHIFT = 7;
893 public final int ASGRSHIFT = 8;
894 public final int ASGURSHIFT = 9;
895 public final int ASGBITAND = 10;
896 public final int ASGBITOR = 11;
897 public final int ASGBITXOR = 12;
899 public final int COND = 13;
900 public final int OR = 14;
901 public final int AND = 15;
902 public final int BITOR = 16;
903 public final int BITXOR = 17;
904 public final int BITAND = 18;
905 public final int NE = 19;
906 public final int EQ = 20;
907 public final int GE = 21;
908 public final int GT = 22;
909 public final int LE = 23;
910 public final int LT = 24;
911 public final int INSTANCEOF = 25;
912 public final int LSHIFT = 26;
913 public final int RSHIFT = 27;
914 public final int URSHIFT = 28;
915 public final int ADD = 29;
916 public final int SUB = 30;
917 public final int DIV = 31;
918 public final int REM = 32;
919 public final int MUL = 33;
920 public final int CAST = 34; // (x)y
921 public final int POS = 35; // +x
922 public final int NEG = 36; // -x
923 public final int NOT = 37;
924 public final int BITNOT = 38;
925 public final int PREINC = 39; // ++x
926 public final int PREDEC = 40; // --x
927 public final int NEWARRAY = 41;
928 public final int NEWINSTANCE = 42;
929 public final int NEWFROMNAME = 43;
930 public final int POSTINC = 44; // x++
931 public final int POSTDEC = 45; // x--
932 public final int FIELD = 46;
933 public final int METHOD = 47; // x(y)
934 public final int ARRAYACCESS = 48; // x[y]
935 public final int NEW = 49;
936 public final int INC = 50;
937 public final int DEC = 51;
939 public final int CONVERT = 55; // implicit conversion
940 public final int EXPR = 56; // (x)
941 public final int ARRAY = 57; // {x, y, ...}
942 public final int GOTO = 58;
947 public final int IDENT = 60;
948 public final int BOOLEANVAL = 61;
949 public final int BYTEVAL = 62;
950 public final int CHARVAL = 63;
951 public final int SHORTVAL = 64;
952 public final int INTVAL = 65;
953 public final int LONGVAL = 66;
954 public final int FLOATVAL = 67;
955 public final int DOUBLEVAL = 68;
956 public final int STRINGVAL = 69;
961 public final int BYTE = 70;
962 public final int CHAR = 71;
963 public final int SHORT = 72;
964 public final int INT = 73;
965 public final int LONG = 74;
966 public final int FLOAT = 75;
967 public final int DOUBLE = 76;
968 public final int VOID = 77;
969 public final int BOOLEAN = 78;
972 * Expression keywords
974 public final int TRUE = 80;
975 public final int FALSE = 81;
976 public final int THIS = 82;
977 public final int SUPER = 83;
978 public final int NULL = 84;
983 public final int IF = 90;
984 public final int ELSE = 91;
985 public final int FOR = 92;
986 public final int WHILE = 93;
987 public final int DO = 94;
988 public final int SWITCH = 95;
989 public final int CASE = 96;
990 public final int DEFAULT = 97;
991 public final int BREAK = 98;
992 public final int CONTINUE = 99;
993 public final int RETURN = 100;
994 public final int TRY = 101;
995 public final int CATCH = 102;
996 public final int FINALLY = 103;
997 public final int THROW = 104;
998 public final int STAT = 105;
999 public final int EXPRESSION = 106;
1000 public final int DECLARATION = 107;
1001 public final int VARDECLARATION = 108;
1004 * Declaration keywords
1006 public final int IMPORT = 110;
1007 public final int CLASS = 111;
1008 public final int EXTENDS = 112;
1009 public final int IMPLEMENTS = 113;
1010 public final int INTERFACE = 114;
1011 public final int PACKAGE = 115;
1016 public final int PRIVATE = 120;
1017 public final int PUBLIC = 121;
1018 public final int PROTECTED = 122;
1019 public final int CONST = 123;
1020 public final int STATIC = 124;
1021 public final int TRANSIENT = 125;
1022 public final int SYNCHRONIZED = 126;
1023 public final int NATIVE = 127;
1024 public final int FINAL = 128;
1025 public final int VOLATILE = 129;
1026 public final int ABSTRACT = 130;
1027 public final int STRICT = 165;
1032 public final int SEMICOLON = 135;
1033 public final int COLON = 136;
1034 public final int QUESTIONMARK = 137;
1035 public final int LBRACE = 138;
1036 public final int RBRACE = 139;
1037 public final int LPAREN = 140;
1038 public final int RPAREN = 141;
1039 public final int LSQBRACKET = 142;
1040 public final int RSQBRACKET = 143;
1041 public final int THROWS = 144;
1046 public final int ERROR = 145; // an error
1047 public final int COMMENT = 146; // not used anymore.
1048 public final int TYPE = 147;
1049 public final int LENGTH = 148;
1050 public final int INLINERETURN = 149;
1051 public final int INLINEMETHOD = 150;
1052 public final int INLINENEWINSTANCE = 151;
1057 public final int METHODREF = 152;
1058 public final int FIELDREF = 153;
1059 public final int STACK = 154;
1060 public final int LOCAL = 155;
1061 public final int CPINDEX = 156;
1062 public final int CPNAME = 157;
1063 public final int SIGN = 158;
1064 public final int BITS = 159;
1065 public final int INF = 160;
1066 public final int NAN = 161;
1067 public final int INNERCLASS = 162;
1068 public final int OF = 163;
1069 public final int SYNTHETIC = 164;
1073 * Operator precedence
1075 public static final int opPrecedence[] = {
1076 10, 11, 11, 11, 11, 11, 11, 11, 11, 11,
1077 11, 11, 11, 12, 13, 14, 15, 16, 17, 18,
1078 18, 19, 19, 19, 19, 19, 20, 20, 20, 21,
1079 21, 22, 22, 22, 23, 24, 24, 24, 24, 24,
1080 24, 25, 25, 26, 26, 26, 26, 26, 26
1086 public static final String opNames[] = {
1087 ",", "=", "*=", "/=", "%=",
1088 "+=", "-=", "<<=", ">>=", "<<<=",
1089 "&=", "|=", "^=", "?:", "||",
1090 "&&", "|", "^", "&", "!=",
1091 "==", ">=", ">", "<=", "<",
1092 "instanceof", "<<", ">>", "<<<", "+",
1093 "-", "/", "%", "*", "cast",
1094 "+", "-", "!", "~", "++",
1095 "--", "new", "new", "new", "++",
1096 "--", "field", "method", "[]", "new",
1097 "++", "--", null, null, null,
1099 "convert", "expr", "array", "goto", null,
1101 "Identifier", "Boolean", "Byte", "Char", "Short",
1102 "Integer", "Long", "Float", "Double", "String",
1104 "byte", "char", "short", "int", "long",
1105 "float", "double", "void", "boolean", null,
1107 "true", "false", "this", "super", "null",
1108 null, null, null, null, null,
1110 "if", "else", "for", "while", "do",
1111 "switch", "case", "default", "break", "continue",
1112 "return", "try", "catch", "finally", "throw",
1113 "stat", "expression", "declaration", "declaration", null,
1115 "import", "class", "extends", "implements", "interface",
1116 "package", null, null, null, null,
1118 "private", "public", "protected", "const", "static",
1119 "transient", "synchronized", "native", "final", "volatile",
1120 "abstract", null, null, null, null,
1122 ";", ":", "?", "{", "}",
1123 "(", ")", "[", "]", "throws",
1124 "error", "comment", "type", "length", "inline-return",
1125 "inline-method", "inline-new",
1126 "method", "field", "stack", "locals", "CPINDEX", "CPName", "SIGN",
1127 "bits", "INF", "NaN", "InnerClass", "of", "synthetic"
1130 static class AnnotationParser {
1132 private final boolean textual;
1133 private final boolean iterateArray;
1135 protected AnnotationParser(boolean textual, boolean iterateArray) {
1136 this.textual = textual;
1137 this.iterateArray = iterateArray;
1140 protected void visitAnnotationStart(String type, boolean top) throws IOException {
1143 protected void visitAnnotationEnd(String type, boolean top) throws IOException {
1146 protected void visitValueStart(String attrName, char type) throws IOException {
1149 protected void visitValueEnd(String attrName, char type) throws IOException {
1152 protected void visitAttr(
1153 String annoType, String attr, String attrType, String value) throws IOException {
1156 protected void visitEnumAttr(
1157 String annoType, String attr, String attrType, String value) throws IOException {
1158 visitAttr(annoType, attr, attrType, value);
1162 * Initialize the parsing with constant pool from
1165 * @param attr the attribute defining annotations
1166 * @param cd constant pool
1167 * @throws IOException in case I/O fails
1169 public final void parse(byte[] attr, ClassData cd) throws IOException {
1170 ByteArrayInputStream is = new ByteArrayInputStream(attr);
1171 DataInputStream dis = new DataInputStream(is);
1179 private void read(DataInputStream dis, ClassData cd) throws IOException {
1180 int cnt = dis.readUnsignedShort();
1181 for (int i = 0; i < cnt; i++) {
1182 readAnno(dis, cd, true);
1186 private void readAnno(DataInputStream dis, ClassData cd, boolean top) throws IOException {
1187 int type = dis.readUnsignedShort();
1188 String typeName = cd.StringValue(type);
1189 visitAnnotationStart(typeName, top);
1190 int cnt = dis.readUnsignedShort();
1191 for (int i = 0; i < cnt; i++) {
1192 String attrName = cd.StringValue(dis.readUnsignedShort());
1193 readValue(dis, cd, typeName, attrName);
1195 visitAnnotationEnd(typeName, top);
1197 visitAttr(typeName, null, null, null);
1201 private void readValue(
1202 DataInputStream dis, ClassData cd, String typeName, String attrName) throws IOException {
1203 char type = (char) dis.readByte();
1204 visitValueStart(attrName, type);
1206 readAnno(dis, cd, false);
1207 } else if ("CFJZsSIDB".indexOf(type) >= 0) { // NOI18N
1208 int primitive = dis.readUnsignedShort();
1209 String val = cd.stringValue(primitive, textual);
1212 attrType = "Ljava_lang_String_2";
1214 val = '"' + val + '"';
1217 attrType = "" + type;
1219 visitAttr(typeName, attrName, attrType, val);
1220 } else if (type == 'c') {
1221 int cls = dis.readUnsignedShort();
1222 } else if (type == '[') {
1223 int cnt = dis.readUnsignedShort();
1224 for (int i = 0; i < cnt; i++) {
1225 readValue(dis, cd, typeName, iterateArray ? attrName : null);
1227 } else if (type == 'e') {
1228 int enumT = dis.readUnsignedShort();
1229 String attrType = cd.stringValue(enumT, textual);
1230 int enumN = dis.readUnsignedShort();
1231 String val = cd.stringValue(enumN, textual);
1232 visitEnumAttr(typeName, attrName, attrType, val);
1234 throw new IOException("Unknown type " + type);
1236 visitValueEnd(attrName, type);
1241 * Reads and stores attribute information.
1243 * @author Sucheta Dambalkar (Adopted code from jdis)
1245 private static class AttrData {
1252 public AttrData(ClassData cls) {
1257 * Reads unknown attribute.
1259 public void read(int name_cpx, DataInputStream in) throws IOException {
1260 this.name_cpx = name_cpx;
1261 datalen = in.readInt();
1262 data = new byte[datalen];
1267 * Reads just the name of known attribute.
1269 public void read(int name_cpx) {
1270 this.name_cpx = name_cpx;
1274 * Returns attribute name.
1276 public String getAttrName() {
1277 return cls.getString(name_cpx);
1281 * Returns attribute data.
1283 public byte[] getData() {
1289 * Stores constant pool entry information with one field.
1291 * @author Sucheta Dambalkar (Adopted code from jdis)
1293 private static class CPX {
1303 * Stores constant pool entry information with two fields.
1305 * @author Sucheta Dambalkar (Adopted code from jdis)
1307 private static class CPX2 {
1311 CPX2(int cpx1, int cpx2) {
1318 * Central data repository of the Java Disassembler. Stores all the
1319 * information in java class file.
1321 * @author Sucheta Dambalkar (Adopted code from jdis)
1323 static final class ClassData {
1326 private int minor_version;
1327 private int major_version;
1328 private int cpool_count;
1329 private Object cpool[];
1331 private int this_class = 0;
1332 private int super_class;
1333 private int interfaces_count;
1334 private int[] interfaces = new int[0];
1335 private int fields_count;
1336 private FieldData[] fields;
1337 private int methods_count;
1338 private MethodData[] methods;
1339 private InnerClassData[] innerClasses;
1340 private int attributes_count;
1341 private AttrData[] attrs;
1342 private String classname;
1343 private String superclassname;
1344 private int source_cpx = 0;
1345 private byte tags[];
1346 private Hashtable indexHashAscii = new Hashtable();
1347 private String pkgPrefix = "";
1348 private int pkgPrefixLen = 0;
1351 * Read classfile to disassemble.
1353 public ClassData(InputStream infile) throws IOException {
1354 this.read(new DataInputStream(infile));
1358 * Reads and stores class file information.
1360 public void read(DataInputStream in) throws IOException {
1362 magic = in.readInt();
1363 if (magic != JAVA_MAGIC) {
1364 throw new ClassFormatError("wrong magic: "
1365 + toHex(magic) + ", expected "
1366 + toHex(JAVA_MAGIC));
1368 minor_version = in.readShort();
1369 major_version = in.readShort();
1370 if (major_version != JAVA_VERSION) {
1373 // Read the constant pool
1375 access = in.readUnsignedShort();
1376 this_class = in.readUnsignedShort();
1377 super_class = in.readUnsignedShort();
1380 interfaces_count = in.readUnsignedShort();
1381 if (interfaces_count > 0) {
1382 interfaces = new int[interfaces_count];
1384 for (int i = 0; i < interfaces_count; i++) {
1385 interfaces[i] = in.readShort();
1394 // Read the attributes
1395 attributes_count = in.readUnsignedShort();
1396 attrs = new AttrData[attributes_count];
1397 for (int k = 0; k < attributes_count; k++) {
1398 int name_cpx = in.readUnsignedShort();
1399 if (getTag(name_cpx) == CONSTANT_UTF8
1400 && getString(name_cpx).equals("SourceFile")) {
1401 if (in.readInt() != 2) {
1402 throw new ClassFormatError("invalid attr length");
1404 source_cpx = in.readUnsignedShort();
1405 AttrData attr = new AttrData(this);
1406 attr.read(name_cpx);
1409 } else if (getTag(name_cpx) == CONSTANT_UTF8
1410 && getString(name_cpx).equals("InnerClasses")) {
1411 int length = in.readInt();
1412 int num = in.readUnsignedShort();
1413 if (2 + num * 8 != length) {
1414 throw new ClassFormatError("invalid attr length");
1416 innerClasses = new InnerClassData[num];
1417 for (int j = 0; j < num; j++) {
1418 InnerClassData innerClass = new InnerClassData(this);
1419 innerClass.read(in);
1420 innerClasses[j] = innerClass;
1422 AttrData attr = new AttrData(this);
1423 attr.read(name_cpx);
1426 AttrData attr = new AttrData(this);
1427 attr.read(name_cpx, in);
1432 } // end ClassData.read()
1435 * Reads and stores constant pool info.
1437 void readCP(DataInputStream in) throws IOException {
1438 cpool_count = in.readUnsignedShort();
1439 tags = new byte[cpool_count];
1440 cpool = new Object[cpool_count];
1441 for (int i = 1; i < cpool_count; i++) {
1442 byte tag = in.readByte();
1444 switch (tags[i] = tag) {
1446 String str = in.readUTF();
1447 indexHashAscii.put(cpool[i] = str, new Integer(i));
1449 case CONSTANT_INTEGER:
1450 cpool[i] = new Integer(in.readInt());
1452 case CONSTANT_FLOAT:
1453 cpool[i] = new Float(in.readFloat());
1456 cpool[i++] = new Long(in.readLong());
1458 case CONSTANT_DOUBLE:
1459 cpool[i++] = new Double(in.readDouble());
1461 case CONSTANT_CLASS:
1462 case CONSTANT_STRING:
1463 cpool[i] = new CPX(in.readUnsignedShort());
1466 case CONSTANT_FIELD:
1467 case CONSTANT_METHOD:
1468 case CONSTANT_INTERFACEMETHOD:
1469 case CONSTANT_NAMEANDTYPE:
1470 cpool[i] = new CPX2(in.readUnsignedShort(), in.readUnsignedShort());
1475 throw new ClassFormatError("invalid constant type: " + (int) tags[i]);
1481 * Reads and strores field info.
1483 protected void readFields(DataInputStream in) throws IOException {
1484 int fields_count = in.readUnsignedShort();
1485 fields = new FieldData[fields_count];
1486 for (int k = 0; k < fields_count; k++) {
1487 FieldData field = new FieldData(this);
1494 * Reads and strores Method info.
1496 protected void readMethods(DataInputStream in) throws IOException {
1497 int methods_count = in.readUnsignedShort();
1498 methods = new MethodData[methods_count];
1499 for (int k = 0; k < methods_count; k++) {
1500 MethodData method = new MethodData(this);
1502 methods[k] = method;
1509 public String getString(int n) {
1513 return (String) cpool[n];
1518 * get the type of constant given an index
1520 public byte getTag(int n) {
1523 } catch (ArrayIndexOutOfBoundsException e) {
1527 static final String hexString = "0123456789ABCDEF";
1528 public static char hexTable[] = hexString.toCharArray();
1530 static String toHex(long val, int width) {
1531 StringBuffer s = new StringBuffer();
1532 for (int i = width - 1; i >= 0; i--) {
1533 s.append(hexTable[((int) (val >> (4 * i))) & 0xF]);
1535 return "0x" + s.toString();
1538 static String toHex(long val) {
1540 for (width = 16; width > 0; width--) {
1541 if ((val >> (width - 1) * 4) != 0) {
1545 return toHex(val, width);
1548 static String toHex(int val) {
1550 for (width = 8; width > 0; width--) {
1551 if ((val >> (width - 1) * 4) != 0) {
1555 return toHex(val, width);
1559 * Returns the name of this class.
1561 public String getClassName() {
1563 if (this_class == 0) {
1568 if (tags[this_class] != CONSTANT_CLASS) {
1569 return res; //"<CP["+cpx+"] is not a Class> ";
1571 tcpx = ((CPX) cpool[this_class]).cpx;
1572 } catch (ArrayIndexOutOfBoundsException e) {
1573 return res; // "#"+cpx+"// invalid constant pool index";
1574 } catch (Throwable e) {
1575 return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
1579 return (String) (cpool[tcpx]);
1580 } catch (ArrayIndexOutOfBoundsException e) {
1581 return res; // "class #"+scpx+"// invalid constant pool index";
1582 } catch (ClassCastException e) {
1583 return res; // "class #"+scpx+"// invalid constant pool reference";
1584 } catch (Throwable e) {
1585 return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
1591 * Returns the name of class at perticular index.
1593 public String getClassName(int cpx) {
1594 String res = "#" + cpx;
1600 if (tags[cpx] != CONSTANT_CLASS) {
1601 return res; //"<CP["+cpx+"] is not a Class> ";
1603 scpx = ((CPX) cpool[cpx]).cpx;
1604 } catch (ArrayIndexOutOfBoundsException e) {
1605 return res; // "#"+cpx+"// invalid constant pool index";
1606 } catch (Throwable e) {
1607 return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
1611 return (String) (cpool[scpx]);
1612 } catch (ArrayIndexOutOfBoundsException e) {
1613 return res; // "class #"+scpx+"// invalid constant pool index";
1614 } catch (ClassCastException e) {
1615 return res; // "class #"+scpx+"// invalid constant pool reference";
1616 } catch (Throwable e) {
1617 return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
1621 public int getAccessFlags() {
1626 * Returns true if it is a class
1628 public boolean isClass() {
1629 if ((access & ACC_INTERFACE) == 0) {
1636 * Returns true if it is a interface.
1638 public boolean isInterface() {
1639 if ((access & ACC_INTERFACE) != 0) {
1646 * Returns true if this member is public, false otherwise.
1648 public boolean isPublic() {
1649 return (access & ACC_PUBLIC) != 0;
1653 * Returns the access of this class or interface.
1655 public String[] getAccess() {
1656 Vector v = new Vector();
1657 if ((access & ACC_PUBLIC) != 0) {
1658 v.addElement("public");
1660 if ((access & ACC_FINAL) != 0) {
1661 v.addElement("final");
1663 if ((access & ACC_ABSTRACT) != 0) {
1664 v.addElement("abstract");
1666 String[] accflags = new String[v.size()];
1667 v.copyInto(accflags);
1672 * Returns list of innerclasses.
1674 public InnerClassData[] getInnerClasses() {
1675 return innerClasses;
1679 * Returns list of attributes.
1681 final AttrData[] getAttributes() {
1685 public byte[] findAnnotationData(boolean classRetention) {
1686 String n = classRetention
1687 ? "RuntimeInvisibleAnnotations" : // NOI18N
1688 "RuntimeVisibleAnnotations"; // NOI18N
1689 return findAttr(n, attrs);
1693 * Returns true if superbit is set.
1695 public boolean isSuperSet() {
1696 if ((access & ACC_SUPER) != 0) {
1703 * Returns super class name.
1705 public String getSuperClassName() {
1707 if (super_class == 0) {
1712 if (tags[super_class] != CONSTANT_CLASS) {
1713 return res; //"<CP["+cpx+"] is not a Class> ";
1715 scpx = ((CPX) cpool[super_class]).cpx;
1716 } catch (ArrayIndexOutOfBoundsException e) {
1717 return res; // "#"+cpx+"// invalid constant pool index";
1718 } catch (Throwable e) {
1719 return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
1723 return (String) (cpool[scpx]);
1724 } catch (ArrayIndexOutOfBoundsException e) {
1725 return res; // "class #"+scpx+"// invalid constant pool index";
1726 } catch (ClassCastException e) {
1727 return res; // "class #"+scpx+"// invalid constant pool reference";
1728 } catch (Throwable e) {
1729 return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
1734 * Returns list of super interfaces.
1736 public String[] getSuperInterfaces() {
1737 String interfacenames[] = new String[interfaces.length];
1738 int interfacecpx = -1;
1739 for (int i = 0; i < interfaces.length; i++) {
1740 interfacecpx = ((CPX) cpool[interfaces[i]]).cpx;
1741 interfacenames[i] = (String) (cpool[interfacecpx]);
1743 return interfacenames;
1747 * Returns string at prticular constant pool index.
1749 public String getStringValue(int cpoolx) {
1751 return ((String) cpool[cpoolx]);
1752 } catch (ArrayIndexOutOfBoundsException e) {
1753 return "//invalid constant pool index:" + cpoolx;
1754 } catch (ClassCastException e) {
1755 return "//invalid constant pool ref:" + cpoolx;
1760 * Returns list of field info.
1762 public FieldData[] getFields() {
1767 * Returns list of method info.
1769 public MethodData[] getMethods() {
1774 * Returns constant pool entry at that index.
1776 public CPX2 getCpoolEntry(int cpx) {
1777 return ((CPX2) (cpool[cpx]));
1780 public Object getCpoolEntryobj(int cpx) {
1781 return (cpool[cpx]);
1785 * Returns index of this class.
1787 public int getthis_cpx() {
1792 * Returns string at that index.
1794 public String StringValue(int cpx) {
1795 return stringValue(cpx, false);
1798 public String stringValue(int cpx, boolean textual) {
1799 return stringValue(cpx, textual, null);
1802 public String stringValue(int cpx, String[] classRefs) {
1803 return stringValue(cpx, true, classRefs);
1806 private String stringValue(int cpx, boolean textual, String[] refs) {
1816 } catch (IndexOutOfBoundsException e) {
1817 return "<Incorrect CP index:" + cpx + ">";
1824 case CONSTANT_UTF8: {
1828 StringBuilder sb = new StringBuilder();
1829 String s = (String) x;
1830 for (int k = 0; k < s.length(); k++) {
1831 char c = s.charAt(k);
1834 sb.append('\\').append('\\');
1837 sb.append('\\').append('t');
1840 sb.append('\\').append('n');
1843 sb.append('\\').append('r');
1846 sb.append('\\').append('\"');
1852 return sb.toString();
1854 case CONSTANT_DOUBLE: {
1855 Double d = (Double) x;
1856 String sd = d.toString();
1862 case CONSTANT_FLOAT: {
1863 Float f = (Float) x;
1864 String sf = (f).toString();
1870 case CONSTANT_LONG: {
1873 return ln.toString();
1875 return ln.toString() + 'l';
1877 case CONSTANT_INTEGER: {
1878 Integer in = (Integer) x;
1879 return in.toString();
1881 case CONSTANT_CLASS:
1882 String jn = getClassName(cpx);
1889 return javaName(jn);
1890 case CONSTANT_STRING:
1891 String sv = stringValue(((CPX) x).cpx, textual);
1893 return '"' + sv + '"';
1897 case CONSTANT_FIELD:
1898 case CONSTANT_METHOD:
1899 case CONSTANT_INTERFACEMETHOD:
1900 //return getShortClassName(((CPX2)x).cpx1)+"."+StringValue(((CPX2)x).cpx2);
1901 return javaName(getClassName(((CPX2) x).cpx1)) + "." + StringValue(((CPX2) x).cpx2);
1903 case CONSTANT_NAMEANDTYPE:
1904 return getName(((CPX2) x).cpx1) + ":" + StringValue(((CPX2) x).cpx2);
1906 return "UnknownTag"; //TBD
1911 * Returns resolved java type name.
1913 public String javaName(String name) {
1917 int len = name.length();
1925 for (int k = 0; k < len; k += Character.charCount(cp)) {
1926 cp = name.codePointAt(k);
1928 if (!isJavaIdentifierStart(cp)) {
1931 } else if (cp != '/') {
1932 if (!isJavaIdentifierPart(cp)) {
1940 return "\"" + name + "\"";
1943 public String getName(int cpx) {
1946 return javaName((String) cpool[cpx]); //.replace('/','.');
1947 } catch (ArrayIndexOutOfBoundsException e) {
1948 return "<invalid constant pool index:" + cpx + ">";
1949 } catch (ClassCastException e) {
1950 return "<invalid constant pool ref:" + cpx + ">";
1955 * Returns unqualified class name.
1957 public String getShortClassName(int cpx) {
1958 String classname = javaName(getClassName(cpx));
1959 pkgPrefixLen = classname.lastIndexOf("/") + 1;
1960 if (pkgPrefixLen != 0) {
1961 pkgPrefix = classname.substring(0, pkgPrefixLen);
1962 if (classname.startsWith(pkgPrefix)) {
1963 return classname.substring(pkgPrefixLen);
1970 * Returns source file name.
1972 public String getSourceName() {
1973 return getName(source_cpx);
1977 * Returns package name.
1979 public String getPkgName() {
1980 String classname = getClassName(this_class);
1981 pkgPrefixLen = classname.lastIndexOf("/") + 1;
1982 if (pkgPrefixLen != 0) {
1983 pkgPrefix = classname.substring(0, pkgPrefixLen);
1984 return /* ("package " + */ pkgPrefix.substring(0, pkgPrefixLen - 1) /* + ";\n") */;
1991 * Returns total constant pool entry count.
1993 public int getCpoolCount() {
1998 * Returns minor version of class file.
2000 public int getMinor_version() {
2001 return minor_version;
2005 * Returns major version of class file.
2007 public int getMajor_version() {
2008 return major_version;
2011 private boolean isJavaIdentifierStart(int cp) {
2012 return ('a' <= cp && cp <= 'z') || ('A' <= cp && cp <= 'Z');
2015 private boolean isJavaIdentifierPart(int cp) {
2016 return isJavaIdentifierStart(cp) || ('0' <= cp && cp <= '9');
2019 public String[] getNameAndType(int indx) {
2020 return getNameAndType(indx, 0, new String[2]);
2023 private String[] getNameAndType(int indx, int at, String[] arr) {
2024 CPX2 c2 = getCpoolEntry(indx);
2025 arr[at] = StringValue(c2.cpx1);
2026 arr[at + 1] = StringValue(c2.cpx2);
2030 public String[] getFieldInfoName(int indx) {
2031 CPX2 c2 = getCpoolEntry(indx);
2032 String[] arr = new String[3];
2033 arr[0] = getClassName(c2.cpx1);
2034 return getNameAndType(c2.cpx2, 1, arr);
2037 static byte[] findAttr(String n, AttrData[] attrs) {
2038 for (AttrData ad : attrs) {
2039 if (n.equals(ad.getAttrName())) {
2040 return ad.getData();
2048 * Strores field data informastion.
2050 * @author Sucheta Dambalkar (Adopted code from jdis)
2052 static class FieldData {
2057 int descriptor_index;
2058 int attributes_count;
2060 boolean isSynthetic = false;
2061 boolean isDeprecated = false;
2064 public FieldData(ClassData cls) {
2069 * Read and store field info.
2071 public void read(DataInputStream in) throws IOException {
2072 access = in.readUnsignedShort();
2073 name_index = in.readUnsignedShort();
2074 descriptor_index = in.readUnsignedShort();
2075 // Read the attributes
2076 int attributes_count = in.readUnsignedShort();
2077 attrs = new Vector(attributes_count);
2078 for (int i = 0; i < attributes_count; i++) {
2079 int attr_name_index = in.readUnsignedShort();
2080 if (cls.getTag(attr_name_index) != CONSTANT_UTF8) {
2083 String attr_name = cls.getString(attr_name_index);
2084 if (attr_name.equals("ConstantValue")) {
2085 if (in.readInt() != 2) {
2086 throw new ClassFormatError("invalid ConstantValue attr length");
2088 value_cpx = in.readUnsignedShort();
2089 AttrData attr = new AttrData(cls);
2090 attr.read(attr_name_index);
2091 attrs.addElement(attr);
2092 } else if (attr_name.equals("Synthetic")) {
2093 if (in.readInt() != 0) {
2094 throw new ClassFormatError("invalid Synthetic attr length");
2097 AttrData attr = new AttrData(cls);
2098 attr.read(attr_name_index);
2099 attrs.addElement(attr);
2100 } else if (attr_name.equals("Deprecated")) {
2101 if (in.readInt() != 0) {
2102 throw new ClassFormatError("invalid Synthetic attr length");
2104 isDeprecated = true;
2105 AttrData attr = new AttrData(cls);
2106 attr.read(attr_name_index);
2107 attrs.addElement(attr);
2109 AttrData attr = new AttrData(cls);
2110 attr.read(attr_name_index, in);
2111 attrs.addElement(attr);
2117 public boolean isStatic() {
2118 return (access & ACC_STATIC) != 0;
2122 * Returns access of a field.
2124 public String[] getAccess() {
2125 Vector v = new Vector();
2126 if ((access & ACC_PUBLIC) != 0) {
2127 v.addElement("public");
2129 if ((access & ACC_PRIVATE) != 0) {
2130 v.addElement("private");
2132 if ((access & ACC_PROTECTED) != 0) {
2133 v.addElement("protected");
2135 if ((access & ACC_STATIC) != 0) {
2136 v.addElement("static");
2138 if ((access & ACC_FINAL) != 0) {
2139 v.addElement("final");
2141 if ((access & ACC_VOLATILE) != 0) {
2142 v.addElement("volatile");
2144 if ((access & ACC_TRANSIENT) != 0) {
2145 v.addElement("transient");
2147 String[] accflags = new String[v.size()];
2148 v.copyInto(accflags);
2153 * Returns name of a field.
2155 public String getName() {
2156 return cls.getStringValue(name_index);
2160 * Returns internal signature of a field
2162 public String getInternalSig() {
2163 return cls.getStringValue(descriptor_index);
2167 * Returns true if field is synthetic.
2169 public boolean isSynthetic() {
2174 * Returns true if field is deprecated.
2176 public boolean isDeprecated() {
2177 return isDeprecated;
2181 * Returns index of constant value in cpool.
2183 public int getConstantValueIndex() {
2188 * Returns list of attributes of field.
2190 public Vector getAttributes() {
2194 public byte[] findAnnotationData(boolean classRetention) {
2195 String n = classRetention
2196 ? "RuntimeInvisibleAnnotations" : // NOI18N
2197 "RuntimeVisibleAnnotations"; // NOI18N
2198 AttrData[] arr = new AttrData[attrs.size()];
2199 attrs.copyInto(arr);
2200 return ClassData.findAttr(n, arr);
2205 * A JavaScript optimized replacement for Hashtable.
2207 * @author Jaroslav Tulach <jtulach@netbeans.org>
2209 private static final class Hashtable {
2211 private Object[] keys;
2212 private Object[] values;
2218 Hashtable(int i, double d) {
2225 synchronized void put(Object key, Object val) {
2226 int[] where = {-1, -1};
2227 Object found = get(key, where);
2228 if (where[0] != -1) {
2230 values[where[0]] = val;
2232 if (where[1] != -1) {
2234 keys[where[1]] = key;
2235 values[where[1]] = val;
2238 keys = new Object[11];
2239 values = new Object[11];
2243 Object[] newKeys = new Object[keys.length * 2];
2244 Object[] newValues = new Object[values.length * 2];
2245 for (int i = 0; i < keys.length; i++) {
2246 newKeys[i] = keys[i];
2247 newValues[i] = values[i];
2249 newKeys[keys.length] = key;
2250 newValues[keys.length] = val;
2258 Object get(Object key) {
2259 return get(key, null);
2262 private synchronized Object get(Object key, int[] foundAndNull) {
2266 for (int i = 0; i < keys.length; i++) {
2267 if (keys[i] == null) {
2268 if (foundAndNull != null) {
2269 foundAndNull[1] = i;
2271 } else if (keys[i].equals(key)) {
2272 if (foundAndNull != null) {
2273 foundAndNull[0] = i;
2283 * Strores InnerClass data informastion.
2285 * @author Sucheta Dambalkar (Adopted code from jdis)
2287 private static class InnerClassData {
2290 int inner_class_info_index, outer_class_info_index, inner_name_index, access;
2292 public InnerClassData(ClassData cls) {
2298 * Read Innerclass attribute data.
2300 public void read(DataInputStream in) throws IOException {
2301 inner_class_info_index = in.readUnsignedShort();
2302 outer_class_info_index = in.readUnsignedShort();
2303 inner_name_index = in.readUnsignedShort();
2304 access = in.readUnsignedShort();
2308 * Returns the access of this class or interface.
2310 public String[] getAccess() {
2311 Vector v = new Vector();
2312 if ((access & ACC_PUBLIC) != 0) {
2313 v.addElement("public");
2315 if ((access & ACC_FINAL) != 0) {
2316 v.addElement("final");
2318 if ((access & ACC_ABSTRACT) != 0) {
2319 v.addElement("abstract");
2321 String[] accflags = new String[v.size()];
2322 v.copyInto(accflags);
2325 } // end InnerClassData
2328 * Strores LineNumberTable data information.
2330 * @author Sucheta Dambalkar (Adopted code from jdis)
2332 private static class LineNumData {
2334 short start_pc, line_number;
2336 public LineNumData() {
2340 * Read LineNumberTable attribute.
2342 public LineNumData(DataInputStream in) throws IOException {
2343 start_pc = in.readShort();
2344 line_number = in.readShort();
2350 * Strores LocalVariableTable data information.
2352 * @author Sucheta Dambalkar (Adopted code from jdis)
2354 private static class LocVarData {
2356 short start_pc, length, name_cpx, sig_cpx, slot;
2358 public LocVarData() {
2362 * Read LocalVariableTable attribute.
2364 public LocVarData(DataInputStream in) throws IOException {
2365 start_pc = in.readShort();
2366 length = in.readShort();
2367 name_cpx = in.readShort();
2368 sig_cpx = in.readShort();
2369 slot = in.readShort();
2374 * Strores method data informastion.
2376 * @author Sucheta Dambalkar (Adopted code from jdis)
2378 static class MethodData {
2383 int descriptor_index;
2384 int attributes_count;
2386 Vector exception_table = new Vector(0);
2387 Vector lin_num_tb = new Vector(0);
2388 Vector loc_var_tb = new Vector(0);
2389 StackMapTableData[] stackMapTable;
2390 StackMapData[] stackMap;
2391 int[] exc_index_table = null;
2392 Vector attrs = new Vector(0);
2393 Vector code_attrs = new Vector(0);
2394 int max_stack, max_locals;
2395 boolean isSynthetic = false;
2396 boolean isDeprecated = false;
2398 public MethodData(ClassData cls) {
2405 public void read(DataInputStream in) throws IOException {
2406 access = in.readUnsignedShort();
2407 name_index = in.readUnsignedShort();
2408 descriptor_index = in.readUnsignedShort();
2409 int attributes_count = in.readUnsignedShort();
2410 for (int i = 0; i < attributes_count; i++) {
2411 int attr_name_index = in.readUnsignedShort();
2415 if (cls.getTag(attr_name_index) == CONSTANT_UTF8) {
2416 String attr_name = cls.getString(attr_name_index);
2417 if (attr_name.equals("Code")) {
2419 AttrData attr = new AttrData(cls);
2420 attr.read(attr_name_index);
2421 attrs.addElement(attr);
2423 } else if (attr_name.equals("Exceptions")) {
2425 AttrData attr = new AttrData(cls);
2426 attr.read(attr_name_index);
2427 attrs.addElement(attr);
2429 } else if (attr_name.equals("Synthetic")) {
2430 if (in.readInt() != 0) {
2431 throw new ClassFormatError("invalid Synthetic attr length");
2434 AttrData attr = new AttrData(cls);
2435 attr.read(attr_name_index);
2436 attrs.addElement(attr);
2438 } else if (attr_name.equals("Deprecated")) {
2439 if (in.readInt() != 0) {
2440 throw new ClassFormatError("invalid Synthetic attr length");
2442 isDeprecated = true;
2443 AttrData attr = new AttrData(cls);
2444 attr.read(attr_name_index);
2445 attrs.addElement(attr);
2449 AttrData attr = new AttrData(cls);
2450 attr.read(attr_name_index, in);
2451 attrs.addElement(attr);
2457 * Read code attribute info.
2459 public void readCode(DataInputStream in) throws IOException {
2461 int attr_length = in.readInt();
2462 max_stack = in.readUnsignedShort();
2463 max_locals = in.readUnsignedShort();
2464 int codelen = in.readInt();
2466 code = new byte[codelen];
2468 while (totalread < codelen) {
2469 totalread += in.read(code, totalread, codelen - totalread);
2471 // in.read(code, 0, codelen);
2473 readExceptionTable(in);
2474 int code_attributes_count = in.readUnsignedShort();
2476 for (int k = 0; k < code_attributes_count; k++) {
2477 int table_name_index = in.readUnsignedShort();
2478 int table_name_tag = cls.getTag(table_name_index);
2479 AttrData attr = new AttrData(cls);
2480 if (table_name_tag == CONSTANT_UTF8) {
2481 String table_name_tstr = cls.getString(table_name_index);
2482 if (table_name_tstr.equals("LineNumberTable")) {
2483 readLineNumTable(in);
2484 attr.read(table_name_index);
2485 } else if (table_name_tstr.equals("LocalVariableTable")) {
2486 readLocVarTable(in);
2487 attr.read(table_name_index);
2488 } else if (table_name_tstr.equals("StackMapTable")) {
2489 readStackMapTable(in);
2490 attr.read(table_name_index);
2491 } else if (table_name_tstr.equals("StackMap")) {
2493 attr.read(table_name_index);
2495 attr.read(table_name_index, in);
2497 code_attrs.addElement(attr);
2501 attr.read(table_name_index, in);
2502 code_attrs.addElement(attr);
2507 * Read exception table info.
2509 void readExceptionTable(DataInputStream in) throws IOException {
2510 int exception_table_len = in.readUnsignedShort();
2511 exception_table = new Vector(exception_table_len);
2512 for (int l = 0; l < exception_table_len; l++) {
2513 exception_table.addElement(new TrapData(in, l));
2518 * Read LineNumberTable attribute info.
2520 void readLineNumTable(DataInputStream in) throws IOException {
2521 int attr_len = in.readInt(); // attr_length
2522 int lin_num_tb_len = in.readUnsignedShort();
2523 lin_num_tb = new Vector(lin_num_tb_len);
2524 for (int l = 0; l < lin_num_tb_len; l++) {
2525 lin_num_tb.addElement(new LineNumData(in));
2530 * Read LocalVariableTable attribute info.
2532 void readLocVarTable(DataInputStream in) throws IOException {
2533 int attr_len = in.readInt(); // attr_length
2534 int loc_var_tb_len = in.readUnsignedShort();
2535 loc_var_tb = new Vector(loc_var_tb_len);
2536 for (int l = 0; l < loc_var_tb_len; l++) {
2537 loc_var_tb.addElement(new LocVarData(in));
2542 * Read Exception attribute info.
2544 public void readExceptions(DataInputStream in) throws IOException {
2545 int attr_len = in.readInt(); // attr_length in prog
2546 int num_exceptions = in.readUnsignedShort();
2547 exc_index_table = new int[num_exceptions];
2548 for (int l = 0; l < num_exceptions; l++) {
2549 int exc = in.readShort();
2550 exc_index_table[l] = exc;
2555 * Read StackMapTable attribute info.
2557 void readStackMapTable(DataInputStream in) throws IOException {
2558 int attr_len = in.readInt(); //attr_length
2559 int stack_map_tb_len = in.readUnsignedShort();
2560 stackMapTable = new StackMapTableData[stack_map_tb_len];
2561 for (int i = 0; i < stack_map_tb_len; i++) {
2562 stackMapTable[i] = StackMapTableData.getInstance(in, this);
2567 * Read StackMap attribute info.
2569 void readStackMap(DataInputStream in) throws IOException {
2570 int attr_len = in.readInt(); //attr_length
2571 int stack_map_len = in.readUnsignedShort();
2572 stackMap = new StackMapData[stack_map_len];
2573 for (int i = 0; i < stack_map_len; i++) {
2574 stackMap[i] = new StackMapData(in, this);
2579 * Return access of the method.
2581 public int getAccess() {
2586 * Return name of the method.
2588 public String getName() {
2589 return cls.getStringValue(name_index);
2593 * Return internal siganature of the method.
2595 public String getInternalSig() {
2596 return cls.getStringValue(descriptor_index);
2600 * Return code attribute data of a method.
2602 public byte[] getCode() {
2607 * Return LineNumberTable size.
2609 public int getnumlines() {
2610 return lin_num_tb.size();
2614 * Return LineNumberTable
2616 public Vector getlin_num_tb() {
2621 * Return LocalVariableTable size.
2623 public int getloc_var_tbsize() {
2624 return loc_var_tb.size();
2628 * Return LocalVariableTable.
2630 public Vector getloc_var_tb() {
2637 public StackMapData[] getStackMap() {
2642 * Return StackMapTable.
2644 public StackMapTableData[] getStackMapTable() {
2645 return stackMapTable;
2648 public StackMapIterator createStackMapIterator() {
2649 return new StackMapIterator(this);
2653 * Return true if method is static
2655 public boolean isStatic() {
2656 if ((access & ACC_STATIC) != 0) {
2663 * Return max depth of operand stack.
2665 public int getMaxStack() {
2670 * Return number of local variables.
2672 public int getMaxLocals() {
2677 * Return exception index table in Exception attribute.
2679 public int[] get_exc_index_table() {
2680 return exc_index_table;
2684 * Return exception table in code attributre.
2686 public TrapDataIterator getTrapDataIterator() {
2687 return new TrapDataIterator(exception_table);
2691 * Return method attributes.
2693 public Vector getAttributes() {
2698 * Return code attributes.
2700 public Vector getCodeAttributes() {
2705 * Return true if method id synthetic.
2707 public boolean isSynthetic() {
2712 * Return true if method is deprecated.
2714 public boolean isDeprecated() {
2715 return isDeprecated;
2718 public byte[] findAnnotationData(boolean classRetention) {
2719 String n = classRetention
2720 ? "RuntimeInvisibleAnnotations" : // NOI18N
2721 "RuntimeVisibleAnnotations"; // NOI18N
2722 AttrData[] arr = new AttrData[attrs.size()];
2723 attrs.copyInto(arr);
2724 return ClassData.findAttr(n, arr);
2727 public boolean isConstructor() {
2728 return "<init>".equals(getName());
2732 /* represents one entry of StackMap attribute
2734 private static class StackMapData {
2740 StackMapData(int offset, int[] locals, int[] stack) {
2741 this.offset = offset;
2742 this.locals = locals;
2746 StackMapData(DataInputStream in, MethodData method) throws IOException {
2747 offset = in.readUnsignedShort();
2748 int local_size = in.readUnsignedShort();
2749 locals = readTypeArray(in, local_size, method);
2750 int stack_size = in.readUnsignedShort();
2751 stack = readTypeArray(in, stack_size, method);
2754 static final int[] readTypeArray(DataInputStream in, int length, MethodData method) throws IOException {
2755 int[] types = new int[length];
2756 for (int i = 0; i < length; i++) {
2757 types[i] = readType(in, method);
2762 static final int readType(DataInputStream in, MethodData method) throws IOException {
2763 int type = in.readUnsignedByte();
2764 if (type == ITEM_Object || type == ITEM_NewObject) {
2765 type = type | (in.readUnsignedShort() << 8);
2771 static final class StackMapIterator {
2773 private final StackMapTableData[] stackMapTable;
2774 private final TypeArray argTypes;
2775 private final TypeArray localTypes;
2776 private final TypeArray stackTypes;
2777 private int nextFrameIndex;
2778 private int lastFrameByteCodeOffset;
2779 private int byteCodeOffset;
2781 StackMapIterator(final MethodData methodData) {
2782 this(methodData.getStackMapTable(),
2783 methodData.getInternalSig(),
2784 methodData.isStatic());
2787 StackMapIterator(final StackMapTableData[] stackMapTable,
2788 final String methodSignature,
2789 final boolean isStaticMethod) {
2790 this.stackMapTable = (stackMapTable != null)
2792 : new StackMapTableData[0];
2794 argTypes = getArgTypes(methodSignature, isStaticMethod);
2795 localTypes = new TypeArray();
2796 stackTypes = new TypeArray();
2798 localTypes.addAll(argTypes);
2800 lastFrameByteCodeOffset = -1;
2804 public String getFrameAsString() {
2805 return (nextFrameIndex == 0)
2806 ? StackMapTableData.toString("INITIAL", 0, null, null)
2807 : stackMapTable[nextFrameIndex - 1].toString();
2810 public int getFrameIndex() {
2811 return nextFrameIndex;
2814 public TypeArray getFrameStack() {
2818 public TypeArray getFrameLocals() {
2822 public TypeArray getArguments() {
2826 public void advanceBy(final int numByteCodes) {
2827 if (numByteCodes < 0) {
2828 throw new IllegalStateException("Forward only iterator");
2831 byteCodeOffset += numByteCodes;
2832 while ((nextFrameIndex < stackMapTable.length)
2833 && ((byteCodeOffset - lastFrameByteCodeOffset)
2834 >= (stackMapTable[nextFrameIndex].offsetDelta
2836 final StackMapTableData nextFrame = stackMapTable[nextFrameIndex];
2838 lastFrameByteCodeOffset += nextFrame.offsetDelta + 1;
2839 nextFrame.applyTo(localTypes, stackTypes);
2845 public void advanceTo(final int nextByteCodeOffset) {
2846 advanceBy(nextByteCodeOffset - byteCodeOffset);
2849 private static TypeArray getArgTypes(final String methodSignature,
2850 final boolean isStaticMethod) {
2851 final TypeArray argTypes = new TypeArray();
2853 if (!isStaticMethod) {
2854 argTypes.add(ITEM_Object);
2857 if (methodSignature.charAt(0) != '(') {
2858 throw new IllegalArgumentException("Invalid method signature");
2861 final int length = methodSignature.length();
2862 boolean skipType = false;
2864 for (int i = 1; i < length; ++i) {
2865 switch (methodSignature.charAt(i)) {
2871 argType = ITEM_Integer;
2874 argType = ITEM_Long;
2877 argType = ITEM_Float;
2880 argType = ITEM_Double;
2883 i = methodSignature.indexOf(';', i + 1);
2885 throw new IllegalArgumentException(
2886 "Invalid method signature");
2888 argType = ITEM_Object;
2892 // not interested in the return value type
2896 argTypes.add(ITEM_Object);
2902 throw new IllegalArgumentException(
2903 "Invalid method signature");
2907 argTypes.add(argType);
2916 /* represents one entry of StackMapTable attribute
2919 private static abstract class StackMapTableData {
2921 final int frameType;
2924 StackMapTableData(int frameType) {
2925 this.frameType = frameType;
2928 abstract void applyTo(TypeArray localTypes, TypeArray stackTypes);
2930 protected static String toString(
2931 final String frameType,
2933 final int[] localTypes,
2934 final int[] stackTypes) {
2935 final StringBuilder sb = new StringBuilder(frameType);
2937 sb.append("(off: +").append(offset);
2938 if (localTypes != null) {
2939 sb.append(", locals: ");
2940 appendTypes(sb, localTypes);
2942 if (stackTypes != null) {
2943 sb.append(", stack: ");
2944 appendTypes(sb, stackTypes);
2948 return sb.toString();
2951 private static void appendTypes(final StringBuilder sb, final int[] types) {
2953 if (types.length > 0) {
2954 sb.append(TypeArray.typeString(types[0]));
2955 for (int i = 1; i < types.length; ++i) {
2957 sb.append(TypeArray.typeString(types[i]));
2963 private static class SameFrame extends StackMapTableData {
2965 SameFrame(int frameType, int offsetDelta) {
2967 this.offsetDelta = offsetDelta;
2971 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
2976 public String toString() {
2977 return toString("SAME" + ((frameType == SAME_FRAME_EXTENDED)
2978 ? "_FRAME_EXTENDED" : ""),
2984 private static class SameLocals1StackItem extends StackMapTableData {
2988 SameLocals1StackItem(int frameType, int offsetDelta, int[] stack) {
2990 this.offsetDelta = offsetDelta;
2995 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
2996 stackTypes.setAll(stack);
3000 public String toString() {
3002 "SAME_LOCALS_1_STACK_ITEM"
3003 + ((frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED)
3004 ? "_EXTENDED" : ""),
3010 private static class ChopFrame extends StackMapTableData {
3012 ChopFrame(int frameType, int offsetDelta) {
3014 this.offsetDelta = offsetDelta;
3018 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
3019 localTypes.setSize(localTypes.getSize()
3020 - (SAME_FRAME_EXTENDED - frameType));
3025 public String toString() {
3026 return toString("CHOP", offsetDelta, null, null);
3030 private static class AppendFrame extends StackMapTableData {
3034 AppendFrame(int frameType, int offsetDelta, int[] locals) {
3036 this.offsetDelta = offsetDelta;
3037 this.locals = locals;
3041 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
3042 localTypes.addAll(locals);
3047 public String toString() {
3048 return toString("APPEND", offsetDelta, locals, null);
3052 private static class FullFrame extends StackMapTableData {
3057 FullFrame(int offsetDelta, int[] locals, int[] stack) {
3059 this.offsetDelta = offsetDelta;
3060 this.locals = locals;
3065 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
3066 localTypes.setAll(locals);
3067 stackTypes.setAll(stack);
3071 public String toString() {
3072 return toString("FULL", offsetDelta, locals, stack);
3076 static StackMapTableData getInstance(DataInputStream in, MethodData method)
3077 throws IOException {
3078 int frameType = in.readUnsignedByte();
3080 if (frameType < SAME_FRAME_BOUND) {
3082 return new SameFrame(frameType, frameType);
3083 } else if (SAME_FRAME_BOUND <= frameType && frameType < SAME_LOCALS_1_STACK_ITEM_BOUND) {
3084 // same_locals_1_stack_item_frame
3085 // read additional single stack element
3086 return new SameLocals1StackItem(frameType,
3087 (frameType - SAME_FRAME_BOUND),
3088 StackMapData.readTypeArray(in, 1, method));
3089 } else if (frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
3090 // same_locals_1_stack_item_extended
3091 return new SameLocals1StackItem(frameType,
3092 in.readUnsignedShort(),
3093 StackMapData.readTypeArray(in, 1, method));
3094 } else if (SAME_LOCALS_1_STACK_ITEM_EXTENDED < frameType && frameType < SAME_FRAME_EXTENDED) {
3095 // chop_frame or same_frame_extended
3096 return new ChopFrame(frameType, in.readUnsignedShort());
3097 } else if (frameType == SAME_FRAME_EXTENDED) {
3098 // chop_frame or same_frame_extended
3099 return new SameFrame(frameType, in.readUnsignedShort());
3100 } else if (SAME_FRAME_EXTENDED < frameType && frameType < FULL_FRAME) {
3102 return new AppendFrame(frameType, in.readUnsignedShort(),
3103 StackMapData.readTypeArray(in, frameType - SAME_FRAME_EXTENDED, method));
3104 } else if (frameType == FULL_FRAME) {
3106 int offsetDelta = in.readUnsignedShort();
3107 int locals_size = in.readUnsignedShort();
3108 int[] locals = StackMapData.readTypeArray(in, locals_size, method);
3109 int stack_size = in.readUnsignedShort();
3110 int[] stack = StackMapData.readTypeArray(in, stack_size, method);
3111 return new FullFrame(offsetDelta, locals, stack);
3113 throw new ClassFormatError("unrecognized frame_type in StackMapTable");
3119 * Stores exception table data in code attribute.
3121 * @author Sucheta Dambalkar (Adopted code from jdis)
3123 static final class TrapData {
3125 public final short start_pc;
3126 public final short end_pc;
3127 public final short handler_pc;
3128 public final short catch_cpx;
3132 * Read and store exception table data in code attribute.
3134 TrapData(DataInputStream in, int num) throws IOException {
3136 start_pc = in.readShort();
3137 end_pc = in.readShort();
3138 handler_pc = in.readShort();
3139 catch_cpx = in.readShort();
3143 * returns recommended identifier
3145 public String ident() {
3151 * @author Jaroslav Tulach <jtulach@netbeans.org>
3153 static final class TrapDataIterator {
3155 private final Hashtable exStart = new Hashtable();
3156 private final Hashtable exStop = new Hashtable();
3157 private TrapData[] current = new TrapData[10];
3158 private int currentCount;
3160 TrapDataIterator(Vector exceptionTable) {
3161 for (int i = 0; i < exceptionTable.size(); i++) {
3162 final TrapData td = (TrapData) exceptionTable.elementAt(i);
3163 put(exStart, td.start_pc, td);
3164 put(exStop, td.end_pc, td);
3168 private static void put(Hashtable h, short key, TrapData td) {
3169 Short s = Short.valueOf((short) key);
3170 Vector v = (Vector) h.get(s);
3178 private boolean processAll(Hashtable h, Short key, boolean add) {
3179 boolean change = false;
3180 Vector v = (Vector) h.get(key);
3183 for (int i = 0; i < s; i++) {
3184 TrapData td = (TrapData) v.elementAt(i);
3197 public boolean advanceTo(int i) {
3198 Short s = Short.valueOf((short) i);
3199 boolean ch1 = processAll(exStart, s, true);
3200 boolean ch2 = processAll(exStop, s, false);
3204 public boolean useTry() {
3205 return currentCount > 0;
3208 public TrapData[] current() {
3209 TrapData[] copy = new TrapData[currentCount];
3210 for (int i = 0; i < currentCount; i++) {
3211 copy[i] = current[i];
3216 private void add(TrapData e) {
3217 if (currentCount == current.length) {
3218 TrapData[] data = new TrapData[currentCount * 2];
3219 for (int i = 0; i < currentCount; i++) {
3220 data[i] = current[i];
3224 current[currentCount++] = e;
3227 private void remove(TrapData e) {
3228 if (currentCount == 0) {
3232 while (from < currentCount) {
3233 if (e == current[from++]) {
3237 while (from < currentCount) {
3238 current[from - 1] = current[from];
3239 current[from] = null;
3245 static final class TypeArray {
3247 private static final int CAPACITY_INCREMENT = 16;
3248 private int[] types;
3251 public TypeArray() {
3254 public TypeArray(final TypeArray initialTypes) {
3255 setAll(initialTypes);
3258 public void add(final int newType) {
3259 ensureCapacity(size + 1);
3260 types[size++] = newType;
3263 public void addAll(final TypeArray newTypes) {
3264 addAll(newTypes.types, 0, newTypes.size);
3267 public void addAll(final int[] newTypes) {
3268 addAll(newTypes, 0, newTypes.length);
3271 public void addAll(final int[] newTypes,
3275 ensureCapacity(size + count);
3276 arraycopy(newTypes, offset, types, size, count);
3281 public void set(final int index, final int newType) {
3282 types[index] = newType;
3285 public void setAll(final TypeArray newTypes) {
3286 setAll(newTypes.types, 0, newTypes.size);
3289 public void setAll(final int[] newTypes) {
3290 setAll(newTypes, 0, newTypes.length);
3293 public void setAll(final int[] newTypes,
3297 ensureCapacity(count);
3298 arraycopy(newTypes, offset, types, 0, count);
3305 public void setSize(final int newSize) {
3306 if (size != newSize) {
3307 ensureCapacity(newSize);
3309 for (int i = size; i < newSize; ++i) {
3316 public void clear() {
3320 public int getSize() {
3324 public int get(final int index) {
3325 return types[index];
3328 public static String typeString(final int type) {
3329 switch (type & 0xff) {
3342 case ITEM_InitObject: // UninitializedThis
3346 case ITEM_NewObject: // Uninitialized
3349 throw new IllegalArgumentException("Unknown type");
3354 public String toString() {
3355 final StringBuilder sb = new StringBuilder("[");
3357 sb.append(typeString(types[0]));
3358 for (int i = 1; i < size; ++i) {
3360 sb.append(typeString(types[i]));
3364 return sb.append(']').toString();
3367 private void ensureCapacity(final int minCapacity) {
3368 if ((minCapacity == 0)
3369 || (types != null) && (minCapacity <= types.length)) {
3373 final int newCapacity =
3374 ((minCapacity + CAPACITY_INCREMENT - 1) / CAPACITY_INCREMENT)
3375 * CAPACITY_INCREMENT;
3376 final int[] newTypes = new int[newCapacity];
3379 arraycopy(types, 0, newTypes, 0, size);
3385 // no System.arraycopy
3386 private void arraycopy(final int[] src, final int srcPos,
3387 final int[] dest, final int destPos,
3389 for (int i = 0; i < length; ++i) {
3390 dest[destPos + i] = src[srcPos + i];
3395 * A JavaScript ready replacement for java.util.Vector
3397 * @author Jaroslav Tulach <jtulach@netbeans.org>
3399 @JavaScriptPrototype(prototype = "new Array")
3400 private static final class Vector {
3402 private Object[] arr;
3410 void add(Object objectType) {
3411 addElement(objectType);
3414 @JavaScriptBody(args = {"obj"}, body =
3416 void addElement(Object obj) {
3417 final int s = size();
3419 setElementAt(obj, s);
3422 @JavaScriptBody(args = {}, body =
3423 "return this.length;")
3425 return arr == null ? 0 : arr.length;
3428 @JavaScriptBody(args = {"newArr"}, body =
3429 "for (var i = 0; i < this.length; i++) {\n"
3430 + " newArr[i] = this[i];\n"
3432 void copyInto(Object[] newArr) {
3436 int min = Math.min(newArr.length, arr.length);
3437 for (int i = 0; i < min; i++) {
3442 @JavaScriptBody(args = {"index"}, body =
3443 "return this[index];")
3444 Object elementAt(int index) {
3448 private void setSize(int len) {
3449 Object[] newArr = new Object[len];
3454 @JavaScriptBody(args = {"val", "index"}, body =
3455 "this[index] = val;")
3456 void setElementAt(Object val, int index) {