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('\"');
1849 sb.append("\\u2028");
1852 sb.append("\\u2029");
1858 return sb.toString();
1860 case CONSTANT_DOUBLE: {
1861 Double d = (Double) x;
1862 String sd = d.toString();
1868 case CONSTANT_FLOAT: {
1869 Float f = (Float) x;
1870 String sf = (f).toString();
1876 case CONSTANT_LONG: {
1879 return ln.toString();
1881 return ln.toString() + 'l';
1883 case CONSTANT_INTEGER: {
1884 Integer in = (Integer) x;
1885 return in.toString();
1887 case CONSTANT_CLASS:
1888 String jn = getClassName(cpx);
1895 return javaName(jn);
1896 case CONSTANT_STRING:
1897 String sv = stringValue(((CPX) x).cpx, textual);
1899 return '"' + sv + '"';
1903 case CONSTANT_FIELD:
1904 case CONSTANT_METHOD:
1905 case CONSTANT_INTERFACEMETHOD:
1906 //return getShortClassName(((CPX2)x).cpx1)+"."+StringValue(((CPX2)x).cpx2);
1907 return javaName(getClassName(((CPX2) x).cpx1)) + "." + StringValue(((CPX2) x).cpx2);
1909 case CONSTANT_NAMEANDTYPE:
1910 return getName(((CPX2) x).cpx1) + ":" + StringValue(((CPX2) x).cpx2);
1912 return "UnknownTag"; //TBD
1917 * Returns resolved java type name.
1919 public String javaName(String name) {
1923 int len = name.length();
1931 for (int k = 0; k < len; k += Character.charCount(cp)) {
1932 cp = name.codePointAt(k);
1934 if (!isJavaIdentifierStart(cp)) {
1937 } else if (cp != '/') {
1938 if (!isJavaIdentifierPart(cp)) {
1946 return "\"" + name + "\"";
1949 public String getName(int cpx) {
1952 return javaName((String) cpool[cpx]); //.replace('/','.');
1953 } catch (ArrayIndexOutOfBoundsException e) {
1954 return "<invalid constant pool index:" + cpx + ">";
1955 } catch (ClassCastException e) {
1956 return "<invalid constant pool ref:" + cpx + ">";
1961 * Returns unqualified class name.
1963 public String getShortClassName(int cpx) {
1964 String classname = javaName(getClassName(cpx));
1965 pkgPrefixLen = classname.lastIndexOf("/") + 1;
1966 if (pkgPrefixLen != 0) {
1967 pkgPrefix = classname.substring(0, pkgPrefixLen);
1968 if (classname.startsWith(pkgPrefix)) {
1969 return classname.substring(pkgPrefixLen);
1976 * Returns source file name.
1978 public String getSourceName() {
1979 return getName(source_cpx);
1983 * Returns package name.
1985 public String getPkgName() {
1986 String classname = getClassName(this_class);
1987 pkgPrefixLen = classname.lastIndexOf("/") + 1;
1988 if (pkgPrefixLen != 0) {
1989 pkgPrefix = classname.substring(0, pkgPrefixLen);
1990 return ("package " + pkgPrefix.substring(0, pkgPrefixLen - 1) + ";\n");
1997 * Returns total constant pool entry count.
1999 public int getCpoolCount() {
2004 * Returns minor version of class file.
2006 public int getMinor_version() {
2007 return minor_version;
2011 * Returns major version of class file.
2013 public int getMajor_version() {
2014 return major_version;
2017 private boolean isJavaIdentifierStart(int cp) {
2018 return ('a' <= cp && cp <= 'z') || ('A' <= cp && cp <= 'Z');
2021 private boolean isJavaIdentifierPart(int cp) {
2022 return isJavaIdentifierStart(cp) || ('0' <= cp && cp <= '9');
2025 public String[] getNameAndType(int indx) {
2026 return getNameAndType(indx, 0, new String[2]);
2029 private String[] getNameAndType(int indx, int at, String[] arr) {
2030 CPX2 c2 = getCpoolEntry(indx);
2031 arr[at] = StringValue(c2.cpx1);
2032 arr[at + 1] = StringValue(c2.cpx2);
2036 public String[] getFieldInfoName(int indx) {
2037 CPX2 c2 = getCpoolEntry(indx);
2038 String[] arr = new String[3];
2039 arr[0] = getClassName(c2.cpx1);
2040 return getNameAndType(c2.cpx2, 1, arr);
2043 static byte[] findAttr(String n, AttrData[] attrs) {
2044 for (AttrData ad : attrs) {
2045 if (n.equals(ad.getAttrName())) {
2046 return ad.getData();
2054 * Strores field data informastion.
2056 * @author Sucheta Dambalkar (Adopted code from jdis)
2058 static class FieldData {
2063 int descriptor_index;
2064 int attributes_count;
2066 boolean isSynthetic = false;
2067 boolean isDeprecated = false;
2070 public FieldData(ClassData cls) {
2075 * Read and store field info.
2077 public void read(DataInputStream in) throws IOException {
2078 access = in.readUnsignedShort();
2079 name_index = in.readUnsignedShort();
2080 descriptor_index = in.readUnsignedShort();
2081 // Read the attributes
2082 int attributes_count = in.readUnsignedShort();
2083 attrs = new Vector(attributes_count);
2084 for (int i = 0; i < attributes_count; i++) {
2085 int attr_name_index = in.readUnsignedShort();
2086 if (cls.getTag(attr_name_index) != CONSTANT_UTF8) {
2089 String attr_name = cls.getString(attr_name_index);
2090 if (attr_name.equals("ConstantValue")) {
2091 if (in.readInt() != 2) {
2092 throw new ClassFormatError("invalid ConstantValue attr length");
2094 value_cpx = in.readUnsignedShort();
2095 AttrData attr = new AttrData(cls);
2096 attr.read(attr_name_index);
2097 attrs.addElement(attr);
2098 } else if (attr_name.equals("Synthetic")) {
2099 if (in.readInt() != 0) {
2100 throw new ClassFormatError("invalid Synthetic attr length");
2103 AttrData attr = new AttrData(cls);
2104 attr.read(attr_name_index);
2105 attrs.addElement(attr);
2106 } else if (attr_name.equals("Deprecated")) {
2107 if (in.readInt() != 0) {
2108 throw new ClassFormatError("invalid Synthetic attr length");
2110 isDeprecated = true;
2111 AttrData attr = new AttrData(cls);
2112 attr.read(attr_name_index);
2113 attrs.addElement(attr);
2115 AttrData attr = new AttrData(cls);
2116 attr.read(attr_name_index, in);
2117 attrs.addElement(attr);
2123 public boolean isStatic() {
2124 return (access & ACC_STATIC) != 0;
2128 * Returns access of a field.
2130 public String[] getAccess() {
2131 Vector v = new Vector();
2132 if ((access & ACC_PUBLIC) != 0) {
2133 v.addElement("public");
2135 if ((access & ACC_PRIVATE) != 0) {
2136 v.addElement("private");
2138 if ((access & ACC_PROTECTED) != 0) {
2139 v.addElement("protected");
2141 if ((access & ACC_STATIC) != 0) {
2142 v.addElement("static");
2144 if ((access & ACC_FINAL) != 0) {
2145 v.addElement("final");
2147 if ((access & ACC_VOLATILE) != 0) {
2148 v.addElement("volatile");
2150 if ((access & ACC_TRANSIENT) != 0) {
2151 v.addElement("transient");
2153 String[] accflags = new String[v.size()];
2154 v.copyInto(accflags);
2159 * Returns name of a field.
2161 public String getName() {
2162 return cls.getStringValue(name_index);
2166 * Returns internal signature of a field
2168 public String getInternalSig() {
2169 return cls.getStringValue(descriptor_index);
2173 * Returns true if field is synthetic.
2175 public boolean isSynthetic() {
2180 * Returns true if field is deprecated.
2182 public boolean isDeprecated() {
2183 return isDeprecated;
2187 * Returns index of constant value in cpool.
2189 public int getConstantValueIndex() {
2194 * Returns list of attributes of field.
2196 public Vector getAttributes() {
2200 public byte[] findAnnotationData(boolean classRetention) {
2201 String n = classRetention
2202 ? "RuntimeInvisibleAnnotations" : // NOI18N
2203 "RuntimeVisibleAnnotations"; // NOI18N
2204 AttrData[] arr = new AttrData[attrs.size()];
2205 attrs.copyInto(arr);
2206 return ClassData.findAttr(n, arr);
2211 * A JavaScript optimized replacement for Hashtable.
2213 * @author Jaroslav Tulach <jtulach@netbeans.org>
2215 private static final class Hashtable {
2217 private Object[] keys;
2218 private Object[] values;
2224 Hashtable(int i, double d) {
2231 synchronized void put(Object key, Object val) {
2232 int[] where = {-1, -1};
2233 Object found = get(key, where);
2234 if (where[0] != -1) {
2236 values[where[0]] = val;
2238 if (where[1] != -1) {
2240 keys[where[1]] = key;
2241 values[where[1]] = val;
2244 keys = new Object[11];
2245 values = new Object[11];
2249 Object[] newKeys = new Object[keys.length * 2];
2250 Object[] newValues = new Object[values.length * 2];
2251 for (int i = 0; i < keys.length; i++) {
2252 newKeys[i] = keys[i];
2253 newValues[i] = values[i];
2255 newKeys[keys.length] = key;
2256 newValues[keys.length] = val;
2264 Object get(Object key) {
2265 return get(key, null);
2268 private synchronized Object get(Object key, int[] foundAndNull) {
2272 for (int i = 0; i < keys.length; i++) {
2273 if (keys[i] == null) {
2274 if (foundAndNull != null) {
2275 foundAndNull[1] = i;
2277 } else if (keys[i].equals(key)) {
2278 if (foundAndNull != null) {
2279 foundAndNull[0] = i;
2289 * Strores InnerClass data informastion.
2291 * @author Sucheta Dambalkar (Adopted code from jdis)
2293 private static class InnerClassData {
2296 int inner_class_info_index, outer_class_info_index, inner_name_index, access;
2298 public InnerClassData(ClassData cls) {
2304 * Read Innerclass attribute data.
2306 public void read(DataInputStream in) throws IOException {
2307 inner_class_info_index = in.readUnsignedShort();
2308 outer_class_info_index = in.readUnsignedShort();
2309 inner_name_index = in.readUnsignedShort();
2310 access = in.readUnsignedShort();
2314 * Returns the access of this class or interface.
2316 public String[] getAccess() {
2317 Vector v = new Vector();
2318 if ((access & ACC_PUBLIC) != 0) {
2319 v.addElement("public");
2321 if ((access & ACC_FINAL) != 0) {
2322 v.addElement("final");
2324 if ((access & ACC_ABSTRACT) != 0) {
2325 v.addElement("abstract");
2327 String[] accflags = new String[v.size()];
2328 v.copyInto(accflags);
2331 } // end InnerClassData
2334 * Strores LineNumberTable data information.
2336 * @author Sucheta Dambalkar (Adopted code from jdis)
2338 private static class LineNumData {
2340 short start_pc, line_number;
2342 public LineNumData() {
2346 * Read LineNumberTable attribute.
2348 public LineNumData(DataInputStream in) throws IOException {
2349 start_pc = in.readShort();
2350 line_number = in.readShort();
2356 * Strores LocalVariableTable data information.
2358 * @author Sucheta Dambalkar (Adopted code from jdis)
2360 private static class LocVarData {
2362 short start_pc, length, name_cpx, sig_cpx, slot;
2364 public LocVarData() {
2368 * Read LocalVariableTable attribute.
2370 public LocVarData(DataInputStream in) throws IOException {
2371 start_pc = in.readShort();
2372 length = in.readShort();
2373 name_cpx = in.readShort();
2374 sig_cpx = in.readShort();
2375 slot = in.readShort();
2380 * Strores method data informastion.
2382 * @author Sucheta Dambalkar (Adopted code from jdis)
2384 static class MethodData {
2389 int descriptor_index;
2390 int attributes_count;
2392 Vector exception_table = new Vector(0);
2393 Vector lin_num_tb = new Vector(0);
2394 Vector loc_var_tb = new Vector(0);
2395 StackMapTableData[] stackMapTable;
2396 StackMapData[] stackMap;
2397 int[] exc_index_table = null;
2398 Vector attrs = new Vector(0);
2399 Vector code_attrs = new Vector(0);
2400 int max_stack, max_locals;
2401 boolean isSynthetic = false;
2402 boolean isDeprecated = false;
2404 public MethodData(ClassData cls) {
2411 public void read(DataInputStream in) throws IOException {
2412 access = in.readUnsignedShort();
2413 name_index = in.readUnsignedShort();
2414 descriptor_index = in.readUnsignedShort();
2415 int attributes_count = in.readUnsignedShort();
2416 for (int i = 0; i < attributes_count; i++) {
2417 int attr_name_index = in.readUnsignedShort();
2421 if (cls.getTag(attr_name_index) == CONSTANT_UTF8) {
2422 String attr_name = cls.getString(attr_name_index);
2423 if (attr_name.equals("Code")) {
2425 AttrData attr = new AttrData(cls);
2426 attr.read(attr_name_index);
2427 attrs.addElement(attr);
2429 } else if (attr_name.equals("Exceptions")) {
2431 AttrData attr = new AttrData(cls);
2432 attr.read(attr_name_index);
2433 attrs.addElement(attr);
2435 } else if (attr_name.equals("Synthetic")) {
2436 if (in.readInt() != 0) {
2437 throw new ClassFormatError("invalid Synthetic attr length");
2440 AttrData attr = new AttrData(cls);
2441 attr.read(attr_name_index);
2442 attrs.addElement(attr);
2444 } else if (attr_name.equals("Deprecated")) {
2445 if (in.readInt() != 0) {
2446 throw new ClassFormatError("invalid Synthetic attr length");
2448 isDeprecated = true;
2449 AttrData attr = new AttrData(cls);
2450 attr.read(attr_name_index);
2451 attrs.addElement(attr);
2455 AttrData attr = new AttrData(cls);
2456 attr.read(attr_name_index, in);
2457 attrs.addElement(attr);
2463 * Read code attribute info.
2465 public void readCode(DataInputStream in) throws IOException {
2467 int attr_length = in.readInt();
2468 max_stack = in.readUnsignedShort();
2469 max_locals = in.readUnsignedShort();
2470 int codelen = in.readInt();
2472 code = new byte[codelen];
2474 while (totalread < codelen) {
2475 totalread += in.read(code, totalread, codelen - totalread);
2477 // in.read(code, 0, codelen);
2479 readExceptionTable(in);
2480 int code_attributes_count = in.readUnsignedShort();
2482 for (int k = 0; k < code_attributes_count; k++) {
2483 int table_name_index = in.readUnsignedShort();
2484 int table_name_tag = cls.getTag(table_name_index);
2485 AttrData attr = new AttrData(cls);
2486 if (table_name_tag == CONSTANT_UTF8) {
2487 String table_name_tstr = cls.getString(table_name_index);
2488 if (table_name_tstr.equals("LineNumberTable")) {
2489 readLineNumTable(in);
2490 attr.read(table_name_index);
2491 } else if (table_name_tstr.equals("LocalVariableTable")) {
2492 readLocVarTable(in);
2493 attr.read(table_name_index);
2494 } else if (table_name_tstr.equals("StackMapTable")) {
2495 readStackMapTable(in);
2496 attr.read(table_name_index);
2497 } else if (table_name_tstr.equals("StackMap")) {
2499 attr.read(table_name_index);
2501 attr.read(table_name_index, in);
2503 code_attrs.addElement(attr);
2507 attr.read(table_name_index, in);
2508 code_attrs.addElement(attr);
2513 * Read exception table info.
2515 void readExceptionTable(DataInputStream in) throws IOException {
2516 int exception_table_len = in.readUnsignedShort();
2517 exception_table = new Vector(exception_table_len);
2518 for (int l = 0; l < exception_table_len; l++) {
2519 exception_table.addElement(new TrapData(in, l));
2524 * Read LineNumberTable attribute info.
2526 void readLineNumTable(DataInputStream in) throws IOException {
2527 int attr_len = in.readInt(); // attr_length
2528 int lin_num_tb_len = in.readUnsignedShort();
2529 lin_num_tb = new Vector(lin_num_tb_len);
2530 for (int l = 0; l < lin_num_tb_len; l++) {
2531 lin_num_tb.addElement(new LineNumData(in));
2536 * Read LocalVariableTable attribute info.
2538 void readLocVarTable(DataInputStream in) throws IOException {
2539 int attr_len = in.readInt(); // attr_length
2540 int loc_var_tb_len = in.readUnsignedShort();
2541 loc_var_tb = new Vector(loc_var_tb_len);
2542 for (int l = 0; l < loc_var_tb_len; l++) {
2543 loc_var_tb.addElement(new LocVarData(in));
2548 * Read Exception attribute info.
2550 public void readExceptions(DataInputStream in) throws IOException {
2551 int attr_len = in.readInt(); // attr_length in prog
2552 int num_exceptions = in.readUnsignedShort();
2553 exc_index_table = new int[num_exceptions];
2554 for (int l = 0; l < num_exceptions; l++) {
2555 int exc = in.readShort();
2556 exc_index_table[l] = exc;
2561 * Read StackMapTable attribute info.
2563 void readStackMapTable(DataInputStream in) throws IOException {
2564 int attr_len = in.readInt(); //attr_length
2565 int stack_map_tb_len = in.readUnsignedShort();
2566 stackMapTable = new StackMapTableData[stack_map_tb_len];
2567 for (int i = 0; i < stack_map_tb_len; i++) {
2568 stackMapTable[i] = StackMapTableData.getInstance(in, this);
2573 * Read StackMap attribute info.
2575 void readStackMap(DataInputStream in) throws IOException {
2576 int attr_len = in.readInt(); //attr_length
2577 int stack_map_len = in.readUnsignedShort();
2578 stackMap = new StackMapData[stack_map_len];
2579 for (int i = 0; i < stack_map_len; i++) {
2580 stackMap[i] = new StackMapData(in, this);
2585 * Return access of the method.
2587 public int getAccess() {
2592 * Return name of the method.
2594 public String getName() {
2595 return cls.getStringValue(name_index);
2599 * Return internal siganature of the method.
2601 public String getInternalSig() {
2602 return cls.getStringValue(descriptor_index);
2606 * Return code attribute data of a method.
2608 public byte[] getCode() {
2613 * Return LineNumberTable size.
2615 public int getnumlines() {
2616 return lin_num_tb.size();
2620 * Return LineNumberTable
2622 public Vector getlin_num_tb() {
2627 * Return LocalVariableTable size.
2629 public int getloc_var_tbsize() {
2630 return loc_var_tb.size();
2634 * Return LocalVariableTable.
2636 public Vector getloc_var_tb() {
2643 public StackMapData[] getStackMap() {
2648 * Return StackMapTable.
2650 public StackMapTableData[] getStackMapTable() {
2651 return stackMapTable;
2654 public StackMapIterator createStackMapIterator() {
2655 return new StackMapIterator(this);
2659 * Return true if method is static
2661 public boolean isStatic() {
2662 if ((access & ACC_STATIC) != 0) {
2669 * Return max depth of operand stack.
2671 public int getMaxStack() {
2676 * Return number of local variables.
2678 public int getMaxLocals() {
2683 * Return exception index table in Exception attribute.
2685 public int[] get_exc_index_table() {
2686 return exc_index_table;
2690 * Return exception table in code attributre.
2692 public TrapDataIterator getTrapDataIterator() {
2693 return new TrapDataIterator(exception_table);
2697 * Return method attributes.
2699 public Vector getAttributes() {
2704 * Return code attributes.
2706 public Vector getCodeAttributes() {
2711 * Return true if method id synthetic.
2713 public boolean isSynthetic() {
2718 * Return true if method is deprecated.
2720 public boolean isDeprecated() {
2721 return isDeprecated;
2724 public byte[] findAnnotationData(boolean classRetention) {
2725 String n = classRetention
2726 ? "RuntimeInvisibleAnnotations" : // NOI18N
2727 "RuntimeVisibleAnnotations"; // NOI18N
2728 AttrData[] arr = new AttrData[attrs.size()];
2729 attrs.copyInto(arr);
2730 return ClassData.findAttr(n, arr);
2733 public boolean isConstructor() {
2734 return "<init>".equals(getName());
2738 /* represents one entry of StackMap attribute
2740 private static class StackMapData {
2746 StackMapData(int offset, int[] locals, int[] stack) {
2747 this.offset = offset;
2748 this.locals = locals;
2752 StackMapData(DataInputStream in, MethodData method) throws IOException {
2753 offset = in.readUnsignedShort();
2754 int local_size = in.readUnsignedShort();
2755 locals = readTypeArray(in, local_size, method);
2756 int stack_size = in.readUnsignedShort();
2757 stack = readTypeArray(in, stack_size, method);
2760 static final int[] readTypeArray(DataInputStream in, int length, MethodData method) throws IOException {
2761 int[] types = new int[length];
2762 for (int i = 0; i < length; i++) {
2763 types[i] = readType(in, method);
2768 static final int readType(DataInputStream in, MethodData method) throws IOException {
2769 int type = in.readUnsignedByte();
2770 if (type == ITEM_Object || type == ITEM_NewObject) {
2771 type = type | (in.readUnsignedShort() << 8);
2777 static final class StackMapIterator {
2779 private final StackMapTableData[] stackMapTable;
2780 private final TypeArray argTypes;
2781 private final TypeArray localTypes;
2782 private final TypeArray stackTypes;
2783 private int nextFrameIndex;
2784 private int lastFrameByteCodeOffset;
2785 private int byteCodeOffset;
2787 StackMapIterator(final MethodData methodData) {
2788 this(methodData.getStackMapTable(),
2789 methodData.getInternalSig(),
2790 methodData.isStatic());
2793 StackMapIterator(final StackMapTableData[] stackMapTable,
2794 final String methodSignature,
2795 final boolean isStaticMethod) {
2796 this.stackMapTable = (stackMapTable != null)
2798 : new StackMapTableData[0];
2800 argTypes = getArgTypes(methodSignature, isStaticMethod);
2801 localTypes = new TypeArray();
2802 stackTypes = new TypeArray();
2804 localTypes.addAll(argTypes);
2806 lastFrameByteCodeOffset = -1;
2810 public String getFrameAsString() {
2811 return (nextFrameIndex == 0)
2812 ? StackMapTableData.toString("INITIAL", 0, null, null)
2813 : stackMapTable[nextFrameIndex - 1].toString();
2816 public int getFrameIndex() {
2817 return nextFrameIndex;
2820 public TypeArray getFrameStack() {
2824 public TypeArray getFrameLocals() {
2828 public TypeArray getArguments() {
2832 public void advanceBy(final int numByteCodes) {
2833 if (numByteCodes < 0) {
2834 throw new IllegalStateException("Forward only iterator");
2837 byteCodeOffset += numByteCodes;
2838 while ((nextFrameIndex < stackMapTable.length)
2839 && ((byteCodeOffset - lastFrameByteCodeOffset)
2840 >= (stackMapTable[nextFrameIndex].offsetDelta
2842 final StackMapTableData nextFrame = stackMapTable[nextFrameIndex];
2844 lastFrameByteCodeOffset += nextFrame.offsetDelta + 1;
2845 nextFrame.applyTo(localTypes, stackTypes);
2851 public void advanceTo(final int nextByteCodeOffset) {
2852 advanceBy(nextByteCodeOffset - byteCodeOffset);
2855 private static TypeArray getArgTypes(final String methodSignature,
2856 final boolean isStaticMethod) {
2857 final TypeArray argTypes = new TypeArray();
2859 if (!isStaticMethod) {
2860 argTypes.add(ITEM_Object);
2863 if (methodSignature.charAt(0) != '(') {
2864 throw new IllegalArgumentException("Invalid method signature");
2867 final int length = methodSignature.length();
2868 boolean skipType = false;
2870 for (int i = 1; i < length; ++i) {
2871 switch (methodSignature.charAt(i)) {
2877 argType = ITEM_Integer;
2880 argType = ITEM_Long;
2883 argType = ITEM_Float;
2886 argType = ITEM_Double;
2889 i = methodSignature.indexOf(';', i + 1);
2891 throw new IllegalArgumentException(
2892 "Invalid method signature");
2894 argType = ITEM_Object;
2898 // not interested in the return value type
2902 argTypes.add(ITEM_Object);
2908 throw new IllegalArgumentException(
2909 "Invalid method signature");
2913 argTypes.add(argType);
2922 /* represents one entry of StackMapTable attribute
2925 private static abstract class StackMapTableData {
2927 final int frameType;
2930 StackMapTableData(int frameType) {
2931 this.frameType = frameType;
2934 abstract void applyTo(TypeArray localTypes, TypeArray stackTypes);
2936 protected static String toString(
2937 final String frameType,
2939 final int[] localTypes,
2940 final int[] stackTypes) {
2941 final StringBuilder sb = new StringBuilder(frameType);
2943 sb.append("(off: +").append(offset);
2944 if (localTypes != null) {
2945 sb.append(", locals: ");
2946 appendTypes(sb, localTypes);
2948 if (stackTypes != null) {
2949 sb.append(", stack: ");
2950 appendTypes(sb, stackTypes);
2954 return sb.toString();
2957 private static void appendTypes(final StringBuilder sb, final int[] types) {
2959 if (types.length > 0) {
2960 sb.append(TypeArray.typeString(types[0]));
2961 for (int i = 1; i < types.length; ++i) {
2963 sb.append(TypeArray.typeString(types[i]));
2969 private static class SameFrame extends StackMapTableData {
2971 SameFrame(int frameType, int offsetDelta) {
2973 this.offsetDelta = offsetDelta;
2977 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
2982 public String toString() {
2983 return toString("SAME" + ((frameType == SAME_FRAME_EXTENDED)
2984 ? "_FRAME_EXTENDED" : ""),
2990 private static class SameLocals1StackItem extends StackMapTableData {
2994 SameLocals1StackItem(int frameType, int offsetDelta, int[] stack) {
2996 this.offsetDelta = offsetDelta;
3001 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
3002 stackTypes.setAll(stack);
3006 public String toString() {
3008 "SAME_LOCALS_1_STACK_ITEM"
3009 + ((frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED)
3010 ? "_EXTENDED" : ""),
3016 private static class ChopFrame extends StackMapTableData {
3018 ChopFrame(int frameType, int offsetDelta) {
3020 this.offsetDelta = offsetDelta;
3024 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
3025 localTypes.setSize(localTypes.getSize()
3026 - (SAME_FRAME_EXTENDED - frameType));
3031 public String toString() {
3032 return toString("CHOP", offsetDelta, null, null);
3036 private static class AppendFrame extends StackMapTableData {
3040 AppendFrame(int frameType, int offsetDelta, int[] locals) {
3042 this.offsetDelta = offsetDelta;
3043 this.locals = locals;
3047 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
3048 localTypes.addAll(locals);
3053 public String toString() {
3054 return toString("APPEND", offsetDelta, locals, null);
3058 private static class FullFrame extends StackMapTableData {
3063 FullFrame(int offsetDelta, int[] locals, int[] stack) {
3065 this.offsetDelta = offsetDelta;
3066 this.locals = locals;
3071 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
3072 localTypes.setAll(locals);
3073 stackTypes.setAll(stack);
3077 public String toString() {
3078 return toString("FULL", offsetDelta, locals, stack);
3082 static StackMapTableData getInstance(DataInputStream in, MethodData method)
3083 throws IOException {
3084 int frameType = in.readUnsignedByte();
3086 if (frameType < SAME_FRAME_BOUND) {
3088 return new SameFrame(frameType, frameType);
3089 } else if (SAME_FRAME_BOUND <= frameType && frameType < SAME_LOCALS_1_STACK_ITEM_BOUND) {
3090 // same_locals_1_stack_item_frame
3091 // read additional single stack element
3092 return new SameLocals1StackItem(frameType,
3093 (frameType - SAME_FRAME_BOUND),
3094 StackMapData.readTypeArray(in, 1, method));
3095 } else if (frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
3096 // same_locals_1_stack_item_extended
3097 return new SameLocals1StackItem(frameType,
3098 in.readUnsignedShort(),
3099 StackMapData.readTypeArray(in, 1, method));
3100 } else if (SAME_LOCALS_1_STACK_ITEM_EXTENDED < frameType && frameType < SAME_FRAME_EXTENDED) {
3101 // chop_frame or same_frame_extended
3102 return new ChopFrame(frameType, in.readUnsignedShort());
3103 } else if (frameType == SAME_FRAME_EXTENDED) {
3104 // chop_frame or same_frame_extended
3105 return new SameFrame(frameType, in.readUnsignedShort());
3106 } else if (SAME_FRAME_EXTENDED < frameType && frameType < FULL_FRAME) {
3108 return new AppendFrame(frameType, in.readUnsignedShort(),
3109 StackMapData.readTypeArray(in, frameType - SAME_FRAME_EXTENDED, method));
3110 } else if (frameType == FULL_FRAME) {
3112 int offsetDelta = in.readUnsignedShort();
3113 int locals_size = in.readUnsignedShort();
3114 int[] locals = StackMapData.readTypeArray(in, locals_size, method);
3115 int stack_size = in.readUnsignedShort();
3116 int[] stack = StackMapData.readTypeArray(in, stack_size, method);
3117 return new FullFrame(offsetDelta, locals, stack);
3119 throw new ClassFormatError("unrecognized frame_type in StackMapTable");
3125 * Stores exception table data in code attribute.
3127 * @author Sucheta Dambalkar (Adopted code from jdis)
3129 static final class TrapData {
3131 public final short start_pc;
3132 public final short end_pc;
3133 public final short handler_pc;
3134 public final short catch_cpx;
3138 * Read and store exception table data in code attribute.
3140 TrapData(DataInputStream in, int num) throws IOException {
3142 start_pc = in.readShort();
3143 end_pc = in.readShort();
3144 handler_pc = in.readShort();
3145 catch_cpx = in.readShort();
3149 * returns recommended identifier
3151 public String ident() {
3157 * @author Jaroslav Tulach <jtulach@netbeans.org>
3159 static final class TrapDataIterator {
3161 private final Hashtable exStart = new Hashtable();
3162 private final Hashtable exStop = new Hashtable();
3163 private TrapData[] current = new TrapData[10];
3164 private int currentCount;
3166 TrapDataIterator(Vector exceptionTable) {
3167 for (int i = 0; i < exceptionTable.size(); i++) {
3168 final TrapData td = (TrapData) exceptionTable.elementAt(i);
3169 put(exStart, td.start_pc, td);
3170 put(exStop, td.end_pc, td);
3174 private static void put(Hashtable h, short key, TrapData td) {
3175 Short s = Short.valueOf((short) key);
3176 Vector v = (Vector) h.get(s);
3184 private boolean processAll(Hashtable h, Short key, boolean add) {
3185 boolean change = false;
3186 Vector v = (Vector) h.get(key);
3189 for (int i = 0; i < s; i++) {
3190 TrapData td = (TrapData) v.elementAt(i);
3203 public boolean advanceTo(int i) {
3204 Short s = Short.valueOf((short) i);
3205 boolean ch1 = processAll(exStart, s, true);
3206 boolean ch2 = processAll(exStop, s, false);
3210 public boolean useTry() {
3211 return currentCount > 0;
3214 public TrapData[] current() {
3215 TrapData[] copy = new TrapData[currentCount];
3216 for (int i = 0; i < currentCount; i++) {
3217 copy[i] = current[i];
3222 private void add(TrapData e) {
3223 if (currentCount == current.length) {
3224 TrapData[] data = new TrapData[currentCount * 2];
3225 for (int i = 0; i < currentCount; i++) {
3226 data[i] = current[i];
3230 current[currentCount++] = e;
3233 private void remove(TrapData e) {
3234 if (currentCount == 0) {
3238 while (from < currentCount) {
3239 if (e == current[from++]) {
3243 while (from < currentCount) {
3244 current[from - 1] = current[from];
3245 current[from] = null;
3251 static final class TypeArray {
3253 private static final int CAPACITY_INCREMENT = 16;
3254 private int[] types;
3257 public TypeArray() {
3260 public TypeArray(final TypeArray initialTypes) {
3261 setAll(initialTypes);
3264 public void add(final int newType) {
3265 ensureCapacity(size + 1);
3266 types[size++] = newType;
3269 public void addAll(final TypeArray newTypes) {
3270 addAll(newTypes.types, 0, newTypes.size);
3273 public void addAll(final int[] newTypes) {
3274 addAll(newTypes, 0, newTypes.length);
3277 public void addAll(final int[] newTypes,
3281 ensureCapacity(size + count);
3282 arraycopy(newTypes, offset, types, size, count);
3287 public void set(final int index, final int newType) {
3288 types[index] = newType;
3291 public void setAll(final TypeArray newTypes) {
3292 setAll(newTypes.types, 0, newTypes.size);
3295 public void setAll(final int[] newTypes) {
3296 setAll(newTypes, 0, newTypes.length);
3299 public void setAll(final int[] newTypes,
3303 ensureCapacity(count);
3304 arraycopy(newTypes, offset, types, 0, count);
3311 public void setSize(final int newSize) {
3312 if (size != newSize) {
3313 ensureCapacity(newSize);
3315 for (int i = size; i < newSize; ++i) {
3322 public void clear() {
3326 public int getSize() {
3330 public int get(final int index) {
3331 return types[index];
3334 public static String typeString(final int type) {
3335 switch (type & 0xff) {
3348 case ITEM_InitObject: // UninitializedThis
3352 case ITEM_NewObject: // Uninitialized
3355 throw new IllegalArgumentException("Unknown type");
3360 public String toString() {
3361 final StringBuilder sb = new StringBuilder("[");
3363 sb.append(typeString(types[0]));
3364 for (int i = 1; i < size; ++i) {
3366 sb.append(typeString(types[i]));
3370 return sb.append(']').toString();
3373 private void ensureCapacity(final int minCapacity) {
3374 if ((minCapacity == 0)
3375 || (types != null) && (minCapacity <= types.length)) {
3379 final int newCapacity =
3380 ((minCapacity + CAPACITY_INCREMENT - 1) / CAPACITY_INCREMENT)
3381 * CAPACITY_INCREMENT;
3382 final int[] newTypes = new int[newCapacity];
3385 arraycopy(types, 0, newTypes, 0, size);
3391 // no System.arraycopy
3392 private void arraycopy(final int[] src, final int srcPos,
3393 final int[] dest, final int destPos,
3395 for (int i = 0; i < length; ++i) {
3396 dest[destPos + i] = src[srcPos + i];
3401 * A JavaScript ready replacement for java.util.Vector
3403 * @author Jaroslav Tulach <jtulach@netbeans.org>
3405 @JavaScriptPrototype(prototype = "new Array")
3406 private static final class Vector {
3408 private Object[] arr;
3416 void add(Object objectType) {
3417 addElement(objectType);
3420 @JavaScriptBody(args = {"obj"}, body =
3422 void addElement(Object obj) {
3423 final int s = size();
3425 setElementAt(obj, s);
3428 @JavaScriptBody(args = {}, body =
3429 "return this.length;")
3431 return arr == null ? 0 : arr.length;
3434 @JavaScriptBody(args = {"newArr"}, body =
3435 "for (var i = 0; i < this.length; i++) {\n"
3436 + " newArr[i] = this[i];\n"
3438 void copyInto(Object[] newArr) {
3442 int min = Math.min(newArr.length, arr.length);
3443 for (int i = 0; i < min; i++) {
3448 @JavaScriptBody(args = {"index"}, body =
3449 "return this[index];")
3450 Object elementAt(int index) {
3454 private void setSize(int len) {
3455 Object[] newArr = new Object[len];
3460 @JavaScriptBody(args = {"val", "index"}, body =
3461 "this[index] = val;")
3462 void setElementAt(Object val, int index) {