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 public MethodData findMethod(String name, String signature) {
2038 for (MethodData md: methods) {
2039 if (md.getName().equals(name)
2040 && md.getInternalSig().equals(signature)) {
2049 public FieldData findField(String name, String signature) {
2050 for (FieldData fd: fields) {
2051 if (fd.getName().equals(name)
2052 && fd.getInternalSig().equals(signature)) {
2061 static byte[] findAttr(String n, AttrData[] attrs) {
2062 for (AttrData ad : attrs) {
2063 if (n.equals(ad.getAttrName())) {
2064 return ad.getData();
2072 * Strores field data informastion.
2074 * @author Sucheta Dambalkar (Adopted code from jdis)
2076 static class FieldData {
2081 int descriptor_index;
2082 int attributes_count;
2084 boolean isSynthetic = false;
2085 boolean isDeprecated = false;
2088 public FieldData(ClassData cls) {
2093 * Read and store field info.
2095 public void read(DataInputStream in) throws IOException {
2096 access = in.readUnsignedShort();
2097 name_index = in.readUnsignedShort();
2098 descriptor_index = in.readUnsignedShort();
2099 // Read the attributes
2100 int attributes_count = in.readUnsignedShort();
2101 attrs = new Vector(attributes_count);
2102 for (int i = 0; i < attributes_count; i++) {
2103 int attr_name_index = in.readUnsignedShort();
2104 if (cls.getTag(attr_name_index) != CONSTANT_UTF8) {
2107 String attr_name = cls.getString(attr_name_index);
2108 if (attr_name.equals("ConstantValue")) {
2109 if (in.readInt() != 2) {
2110 throw new ClassFormatError("invalid ConstantValue attr length");
2112 value_cpx = in.readUnsignedShort();
2113 AttrData attr = new AttrData(cls);
2114 attr.read(attr_name_index);
2115 attrs.addElement(attr);
2116 } else if (attr_name.equals("Synthetic")) {
2117 if (in.readInt() != 0) {
2118 throw new ClassFormatError("invalid Synthetic attr length");
2121 AttrData attr = new AttrData(cls);
2122 attr.read(attr_name_index);
2123 attrs.addElement(attr);
2124 } else if (attr_name.equals("Deprecated")) {
2125 if (in.readInt() != 0) {
2126 throw new ClassFormatError("invalid Synthetic attr length");
2128 isDeprecated = true;
2129 AttrData attr = new AttrData(cls);
2130 attr.read(attr_name_index);
2131 attrs.addElement(attr);
2133 AttrData attr = new AttrData(cls);
2134 attr.read(attr_name_index, in);
2135 attrs.addElement(attr);
2141 public boolean isStatic() {
2142 return (access & ACC_STATIC) != 0;
2146 * Returns access of a field.
2148 public String[] getAccess() {
2149 Vector v = new Vector();
2150 if ((access & ACC_PUBLIC) != 0) {
2151 v.addElement("public");
2153 if ((access & ACC_PRIVATE) != 0) {
2154 v.addElement("private");
2156 if ((access & ACC_PROTECTED) != 0) {
2157 v.addElement("protected");
2159 if ((access & ACC_STATIC) != 0) {
2160 v.addElement("static");
2162 if ((access & ACC_FINAL) != 0) {
2163 v.addElement("final");
2165 if ((access & ACC_VOLATILE) != 0) {
2166 v.addElement("volatile");
2168 if ((access & ACC_TRANSIENT) != 0) {
2169 v.addElement("transient");
2171 String[] accflags = new String[v.size()];
2172 v.copyInto(accflags);
2177 * Returns name of a field.
2179 public String getName() {
2180 return cls.getStringValue(name_index);
2184 * Returns internal signature of a field
2186 public String getInternalSig() {
2187 return cls.getStringValue(descriptor_index);
2191 * Returns true if field is synthetic.
2193 public boolean isSynthetic() {
2198 * Returns true if field is deprecated.
2200 public boolean isDeprecated() {
2201 return isDeprecated;
2205 * Returns index of constant value in cpool.
2207 public int getConstantValueIndex() {
2212 * Returns list of attributes of field.
2214 public Vector getAttributes() {
2218 public byte[] findAnnotationData(boolean classRetention) {
2219 String n = classRetention
2220 ? "RuntimeInvisibleAnnotations" : // NOI18N
2221 "RuntimeVisibleAnnotations"; // NOI18N
2222 AttrData[] arr = new AttrData[attrs.size()];
2223 attrs.copyInto(arr);
2224 return ClassData.findAttr(n, arr);
2229 * A JavaScript optimized replacement for Hashtable.
2231 * @author Jaroslav Tulach <jtulach@netbeans.org>
2233 private static final class Hashtable {
2235 private Object[] keys;
2236 private Object[] values;
2242 Hashtable(int i, double d) {
2249 synchronized void put(Object key, Object val) {
2250 int[] where = {-1, -1};
2251 Object found = get(key, where);
2252 if (where[0] != -1) {
2254 values[where[0]] = val;
2256 if (where[1] != -1) {
2258 keys[where[1]] = key;
2259 values[where[1]] = val;
2262 keys = new Object[11];
2263 values = new Object[11];
2267 Object[] newKeys = new Object[keys.length * 2];
2268 Object[] newValues = new Object[values.length * 2];
2269 for (int i = 0; i < keys.length; i++) {
2270 newKeys[i] = keys[i];
2271 newValues[i] = values[i];
2273 newKeys[keys.length] = key;
2274 newValues[keys.length] = val;
2282 Object get(Object key) {
2283 return get(key, null);
2286 private synchronized Object get(Object key, int[] foundAndNull) {
2290 for (int i = 0; i < keys.length; i++) {
2291 if (keys[i] == null) {
2292 if (foundAndNull != null) {
2293 foundAndNull[1] = i;
2295 } else if (keys[i].equals(key)) {
2296 if (foundAndNull != null) {
2297 foundAndNull[0] = i;
2307 * Strores InnerClass data informastion.
2309 * @author Sucheta Dambalkar (Adopted code from jdis)
2311 private static class InnerClassData {
2314 int inner_class_info_index, outer_class_info_index, inner_name_index, access;
2316 public InnerClassData(ClassData cls) {
2322 * Read Innerclass attribute data.
2324 public void read(DataInputStream in) throws IOException {
2325 inner_class_info_index = in.readUnsignedShort();
2326 outer_class_info_index = in.readUnsignedShort();
2327 inner_name_index = in.readUnsignedShort();
2328 access = in.readUnsignedShort();
2332 * Returns the access of this class or interface.
2334 public String[] getAccess() {
2335 Vector v = new Vector();
2336 if ((access & ACC_PUBLIC) != 0) {
2337 v.addElement("public");
2339 if ((access & ACC_FINAL) != 0) {
2340 v.addElement("final");
2342 if ((access & ACC_ABSTRACT) != 0) {
2343 v.addElement("abstract");
2345 String[] accflags = new String[v.size()];
2346 v.copyInto(accflags);
2349 } // end InnerClassData
2352 * Strores LineNumberTable data information.
2354 * @author Sucheta Dambalkar (Adopted code from jdis)
2356 private static class LineNumData {
2358 short start_pc, line_number;
2360 public LineNumData() {
2364 * Read LineNumberTable attribute.
2366 public LineNumData(DataInputStream in) throws IOException {
2367 start_pc = in.readShort();
2368 line_number = in.readShort();
2374 * Strores LocalVariableTable data information.
2376 * @author Sucheta Dambalkar (Adopted code from jdis)
2378 private static class LocVarData {
2380 short start_pc, length, name_cpx, sig_cpx, slot;
2382 public LocVarData() {
2386 * Read LocalVariableTable attribute.
2388 public LocVarData(DataInputStream in) throws IOException {
2389 start_pc = in.readShort();
2390 length = in.readShort();
2391 name_cpx = in.readShort();
2392 sig_cpx = in.readShort();
2393 slot = in.readShort();
2398 * Strores method data informastion.
2400 * @author Sucheta Dambalkar (Adopted code from jdis)
2402 static class MethodData {
2407 int descriptor_index;
2408 int attributes_count;
2410 Vector exception_table = new Vector(0);
2411 Vector lin_num_tb = new Vector(0);
2412 Vector loc_var_tb = new Vector(0);
2413 StackMapTableData[] stackMapTable;
2414 StackMapData[] stackMap;
2415 int[] exc_index_table = null;
2416 Vector attrs = new Vector(0);
2417 Vector code_attrs = new Vector(0);
2418 int max_stack, max_locals;
2419 boolean isSynthetic = false;
2420 boolean isDeprecated = false;
2422 public MethodData(ClassData cls) {
2429 public void read(DataInputStream in) throws IOException {
2430 access = in.readUnsignedShort();
2431 name_index = in.readUnsignedShort();
2432 descriptor_index = in.readUnsignedShort();
2433 int attributes_count = in.readUnsignedShort();
2434 for (int i = 0; i < attributes_count; i++) {
2435 int attr_name_index = in.readUnsignedShort();
2439 if (cls.getTag(attr_name_index) == CONSTANT_UTF8) {
2440 String attr_name = cls.getString(attr_name_index);
2441 if (attr_name.equals("Code")) {
2443 AttrData attr = new AttrData(cls);
2444 attr.read(attr_name_index);
2445 attrs.addElement(attr);
2447 } else if (attr_name.equals("Exceptions")) {
2449 AttrData attr = new AttrData(cls);
2450 attr.read(attr_name_index);
2451 attrs.addElement(attr);
2453 } else if (attr_name.equals("Synthetic")) {
2454 if (in.readInt() != 0) {
2455 throw new ClassFormatError("invalid Synthetic attr length");
2458 AttrData attr = new AttrData(cls);
2459 attr.read(attr_name_index);
2460 attrs.addElement(attr);
2462 } else if (attr_name.equals("Deprecated")) {
2463 if (in.readInt() != 0) {
2464 throw new ClassFormatError("invalid Synthetic attr length");
2466 isDeprecated = true;
2467 AttrData attr = new AttrData(cls);
2468 attr.read(attr_name_index);
2469 attrs.addElement(attr);
2473 AttrData attr = new AttrData(cls);
2474 attr.read(attr_name_index, in);
2475 attrs.addElement(attr);
2481 * Read code attribute info.
2483 public void readCode(DataInputStream in) throws IOException {
2485 int attr_length = in.readInt();
2486 max_stack = in.readUnsignedShort();
2487 max_locals = in.readUnsignedShort();
2488 int codelen = in.readInt();
2490 code = new byte[codelen];
2492 while (totalread < codelen) {
2493 totalread += in.read(code, totalread, codelen - totalread);
2495 // in.read(code, 0, codelen);
2497 readExceptionTable(in);
2498 int code_attributes_count = in.readUnsignedShort();
2500 for (int k = 0; k < code_attributes_count; k++) {
2501 int table_name_index = in.readUnsignedShort();
2502 int table_name_tag = cls.getTag(table_name_index);
2503 AttrData attr = new AttrData(cls);
2504 if (table_name_tag == CONSTANT_UTF8) {
2505 String table_name_tstr = cls.getString(table_name_index);
2506 if (table_name_tstr.equals("LineNumberTable")) {
2507 readLineNumTable(in);
2508 attr.read(table_name_index);
2509 } else if (table_name_tstr.equals("LocalVariableTable")) {
2510 readLocVarTable(in);
2511 attr.read(table_name_index);
2512 } else if (table_name_tstr.equals("StackMapTable")) {
2513 readStackMapTable(in);
2514 attr.read(table_name_index);
2515 } else if (table_name_tstr.equals("StackMap")) {
2517 attr.read(table_name_index);
2519 attr.read(table_name_index, in);
2521 code_attrs.addElement(attr);
2525 attr.read(table_name_index, in);
2526 code_attrs.addElement(attr);
2531 * Read exception table info.
2533 void readExceptionTable(DataInputStream in) throws IOException {
2534 int exception_table_len = in.readUnsignedShort();
2535 exception_table = new Vector(exception_table_len);
2536 for (int l = 0; l < exception_table_len; l++) {
2537 exception_table.addElement(new TrapData(in, l));
2542 * Read LineNumberTable attribute info.
2544 void readLineNumTable(DataInputStream in) throws IOException {
2545 int attr_len = in.readInt(); // attr_length
2546 int lin_num_tb_len = in.readUnsignedShort();
2547 lin_num_tb = new Vector(lin_num_tb_len);
2548 for (int l = 0; l < lin_num_tb_len; l++) {
2549 lin_num_tb.addElement(new LineNumData(in));
2554 * Read LocalVariableTable attribute info.
2556 void readLocVarTable(DataInputStream in) throws IOException {
2557 int attr_len = in.readInt(); // attr_length
2558 int loc_var_tb_len = in.readUnsignedShort();
2559 loc_var_tb = new Vector(loc_var_tb_len);
2560 for (int l = 0; l < loc_var_tb_len; l++) {
2561 loc_var_tb.addElement(new LocVarData(in));
2566 * Read Exception attribute info.
2568 public void readExceptions(DataInputStream in) throws IOException {
2569 int attr_len = in.readInt(); // attr_length in prog
2570 int num_exceptions = in.readUnsignedShort();
2571 exc_index_table = new int[num_exceptions];
2572 for (int l = 0; l < num_exceptions; l++) {
2573 int exc = in.readShort();
2574 exc_index_table[l] = exc;
2579 * Read StackMapTable attribute info.
2581 void readStackMapTable(DataInputStream in) throws IOException {
2582 int attr_len = in.readInt(); //attr_length
2583 int stack_map_tb_len = in.readUnsignedShort();
2584 stackMapTable = new StackMapTableData[stack_map_tb_len];
2585 for (int i = 0; i < stack_map_tb_len; i++) {
2586 stackMapTable[i] = StackMapTableData.getInstance(in, this);
2591 * Read StackMap attribute info.
2593 void readStackMap(DataInputStream in) throws IOException {
2594 int attr_len = in.readInt(); //attr_length
2595 int stack_map_len = in.readUnsignedShort();
2596 stackMap = new StackMapData[stack_map_len];
2597 for (int i = 0; i < stack_map_len; i++) {
2598 stackMap[i] = new StackMapData(in, this);
2603 * Return access of the method.
2605 public int getAccess() {
2610 * Return name of the method.
2612 public String getName() {
2613 return cls.getStringValue(name_index);
2617 * Return internal siganature of the method.
2619 public String getInternalSig() {
2620 return cls.getStringValue(descriptor_index);
2624 * Return code attribute data of a method.
2626 public byte[] getCode() {
2631 * Return LineNumberTable size.
2633 public int getnumlines() {
2634 return lin_num_tb.size();
2638 * Return LineNumberTable
2640 public Vector getlin_num_tb() {
2645 * Return LocalVariableTable size.
2647 public int getloc_var_tbsize() {
2648 return loc_var_tb.size();
2652 * Return LocalVariableTable.
2654 public Vector getloc_var_tb() {
2661 public StackMapData[] getStackMap() {
2666 * Return StackMapTable.
2668 public StackMapTableData[] getStackMapTable() {
2669 return stackMapTable;
2672 public StackMapIterator createStackMapIterator() {
2673 return new StackMapIterator(this);
2677 * Return true if method is static
2679 public boolean isStatic() {
2680 if ((access & ACC_STATIC) != 0) {
2687 * Return max depth of operand stack.
2689 public int getMaxStack() {
2694 * Return number of local variables.
2696 public int getMaxLocals() {
2701 * Return exception index table in Exception attribute.
2703 public int[] get_exc_index_table() {
2704 return exc_index_table;
2708 * Return exception table in code attributre.
2710 public TrapDataIterator getTrapDataIterator() {
2711 return new TrapDataIterator(exception_table);
2715 * Return method attributes.
2717 public Vector getAttributes() {
2722 * Return code attributes.
2724 public Vector getCodeAttributes() {
2729 * Return true if method id synthetic.
2731 public boolean isSynthetic() {
2736 * Return true if method is deprecated.
2738 public boolean isDeprecated() {
2739 return isDeprecated;
2742 public byte[] findAnnotationData(boolean classRetention) {
2743 String n = classRetention
2744 ? "RuntimeInvisibleAnnotations" : // NOI18N
2745 "RuntimeVisibleAnnotations"; // NOI18N
2746 AttrData[] arr = new AttrData[attrs.size()];
2747 attrs.copyInto(arr);
2748 return ClassData.findAttr(n, arr);
2751 public boolean isConstructor() {
2752 return "<init>".equals(getName());
2756 /* represents one entry of StackMap attribute
2758 private static class StackMapData {
2764 StackMapData(int offset, int[] locals, int[] stack) {
2765 this.offset = offset;
2766 this.locals = locals;
2770 StackMapData(DataInputStream in, MethodData method) throws IOException {
2771 offset = in.readUnsignedShort();
2772 int local_size = in.readUnsignedShort();
2773 locals = readTypeArray(in, local_size, method);
2774 int stack_size = in.readUnsignedShort();
2775 stack = readTypeArray(in, stack_size, method);
2778 static final int[] readTypeArray(DataInputStream in, int length, MethodData method) throws IOException {
2779 int[] types = new int[length];
2780 for (int i = 0; i < length; i++) {
2781 types[i] = readType(in, method);
2786 static final int readType(DataInputStream in, MethodData method) throws IOException {
2787 int type = in.readUnsignedByte();
2788 if (type == ITEM_Object || type == ITEM_NewObject) {
2789 type = type | (in.readUnsignedShort() << 8);
2795 static final class StackMapIterator {
2797 private final StackMapTableData[] stackMapTable;
2798 private final TypeArray argTypes;
2799 private final TypeArray localTypes;
2800 private final TypeArray stackTypes;
2801 private int nextFrameIndex;
2802 private int lastFrameByteCodeOffset;
2803 private int byteCodeOffset;
2805 StackMapIterator(final MethodData methodData) {
2806 this(methodData.getStackMapTable(),
2807 methodData.getInternalSig(),
2808 methodData.isStatic());
2811 StackMapIterator(final StackMapTableData[] stackMapTable,
2812 final String methodSignature,
2813 final boolean isStaticMethod) {
2814 this.stackMapTable = (stackMapTable != null)
2816 : new StackMapTableData[0];
2818 argTypes = getArgTypes(methodSignature, isStaticMethod);
2819 localTypes = new TypeArray();
2820 stackTypes = new TypeArray();
2822 localTypes.addAll(argTypes);
2824 lastFrameByteCodeOffset = -1;
2828 public String getFrameAsString() {
2829 return (nextFrameIndex == 0)
2830 ? StackMapTableData.toString("INITIAL", 0, null, null)
2831 : stackMapTable[nextFrameIndex - 1].toString();
2834 public int getFrameIndex() {
2835 return nextFrameIndex;
2838 public TypeArray getFrameStack() {
2842 public TypeArray getFrameLocals() {
2846 public TypeArray getArguments() {
2850 public void advanceBy(final int numByteCodes) {
2851 if (numByteCodes < 0) {
2852 throw new IllegalStateException("Forward only iterator");
2855 byteCodeOffset += numByteCodes;
2856 while ((nextFrameIndex < stackMapTable.length)
2857 && ((byteCodeOffset - lastFrameByteCodeOffset)
2858 >= (stackMapTable[nextFrameIndex].offsetDelta
2860 final StackMapTableData nextFrame = stackMapTable[nextFrameIndex];
2862 lastFrameByteCodeOffset += nextFrame.offsetDelta + 1;
2863 nextFrame.applyTo(localTypes, stackTypes);
2869 public void advanceTo(final int nextByteCodeOffset) {
2870 advanceBy(nextByteCodeOffset - byteCodeOffset);
2873 private static TypeArray getArgTypes(final String methodSignature,
2874 final boolean isStaticMethod) {
2875 final TypeArray argTypes = new TypeArray();
2877 if (!isStaticMethod) {
2878 argTypes.add(ITEM_Object);
2881 if (methodSignature.charAt(0) != '(') {
2882 throw new IllegalArgumentException("Invalid method signature");
2885 final int length = methodSignature.length();
2886 boolean skipType = false;
2888 for (int i = 1; i < length; ++i) {
2889 switch (methodSignature.charAt(i)) {
2895 argType = ITEM_Integer;
2898 argType = ITEM_Long;
2901 argType = ITEM_Float;
2904 argType = ITEM_Double;
2907 i = methodSignature.indexOf(';', i + 1);
2909 throw new IllegalArgumentException(
2910 "Invalid method signature");
2912 argType = ITEM_Object;
2916 // not interested in the return value type
2920 argTypes.add(ITEM_Object);
2926 throw new IllegalArgumentException(
2927 "Invalid method signature");
2931 argTypes.add(argType);
2940 /* represents one entry of StackMapTable attribute
2943 private static abstract class StackMapTableData {
2945 final int frameType;
2948 StackMapTableData(int frameType) {
2949 this.frameType = frameType;
2952 abstract void applyTo(TypeArray localTypes, TypeArray stackTypes);
2954 protected static String toString(
2955 final String frameType,
2957 final int[] localTypes,
2958 final int[] stackTypes) {
2959 final StringBuilder sb = new StringBuilder(frameType);
2961 sb.append("(off: +").append(offset);
2962 if (localTypes != null) {
2963 sb.append(", locals: ");
2964 appendTypes(sb, localTypes);
2966 if (stackTypes != null) {
2967 sb.append(", stack: ");
2968 appendTypes(sb, stackTypes);
2972 return sb.toString();
2975 private static void appendTypes(final StringBuilder sb, final int[] types) {
2977 if (types.length > 0) {
2978 sb.append(TypeArray.typeString(types[0]));
2979 for (int i = 1; i < types.length; ++i) {
2981 sb.append(TypeArray.typeString(types[i]));
2987 private static class SameFrame extends StackMapTableData {
2989 SameFrame(int frameType, int offsetDelta) {
2991 this.offsetDelta = offsetDelta;
2995 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
3000 public String toString() {
3001 return toString("SAME" + ((frameType == SAME_FRAME_EXTENDED)
3002 ? "_FRAME_EXTENDED" : ""),
3008 private static class SameLocals1StackItem extends StackMapTableData {
3012 SameLocals1StackItem(int frameType, int offsetDelta, int[] stack) {
3014 this.offsetDelta = offsetDelta;
3019 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
3020 stackTypes.setAll(stack);
3024 public String toString() {
3026 "SAME_LOCALS_1_STACK_ITEM"
3027 + ((frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED)
3028 ? "_EXTENDED" : ""),
3034 private static class ChopFrame extends StackMapTableData {
3036 ChopFrame(int frameType, int offsetDelta) {
3038 this.offsetDelta = offsetDelta;
3042 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
3043 localTypes.setSize(localTypes.getSize()
3044 - (SAME_FRAME_EXTENDED - frameType));
3049 public String toString() {
3050 return toString("CHOP", offsetDelta, null, null);
3054 private static class AppendFrame extends StackMapTableData {
3058 AppendFrame(int frameType, int offsetDelta, int[] locals) {
3060 this.offsetDelta = offsetDelta;
3061 this.locals = locals;
3065 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
3066 localTypes.addAll(locals);
3071 public String toString() {
3072 return toString("APPEND", offsetDelta, locals, null);
3076 private static class FullFrame extends StackMapTableData {
3081 FullFrame(int offsetDelta, int[] locals, int[] stack) {
3083 this.offsetDelta = offsetDelta;
3084 this.locals = locals;
3089 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
3090 localTypes.setAll(locals);
3091 stackTypes.setAll(stack);
3095 public String toString() {
3096 return toString("FULL", offsetDelta, locals, stack);
3100 static StackMapTableData getInstance(DataInputStream in, MethodData method)
3101 throws IOException {
3102 int frameType = in.readUnsignedByte();
3104 if (frameType < SAME_FRAME_BOUND) {
3106 return new SameFrame(frameType, frameType);
3107 } else if (SAME_FRAME_BOUND <= frameType && frameType < SAME_LOCALS_1_STACK_ITEM_BOUND) {
3108 // same_locals_1_stack_item_frame
3109 // read additional single stack element
3110 return new SameLocals1StackItem(frameType,
3111 (frameType - SAME_FRAME_BOUND),
3112 StackMapData.readTypeArray(in, 1, method));
3113 } else if (frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
3114 // same_locals_1_stack_item_extended
3115 return new SameLocals1StackItem(frameType,
3116 in.readUnsignedShort(),
3117 StackMapData.readTypeArray(in, 1, method));
3118 } else if (SAME_LOCALS_1_STACK_ITEM_EXTENDED < frameType && frameType < SAME_FRAME_EXTENDED) {
3119 // chop_frame or same_frame_extended
3120 return new ChopFrame(frameType, in.readUnsignedShort());
3121 } else if (frameType == SAME_FRAME_EXTENDED) {
3122 // chop_frame or same_frame_extended
3123 return new SameFrame(frameType, in.readUnsignedShort());
3124 } else if (SAME_FRAME_EXTENDED < frameType && frameType < FULL_FRAME) {
3126 return new AppendFrame(frameType, in.readUnsignedShort(),
3127 StackMapData.readTypeArray(in, frameType - SAME_FRAME_EXTENDED, method));
3128 } else if (frameType == FULL_FRAME) {
3130 int offsetDelta = in.readUnsignedShort();
3131 int locals_size = in.readUnsignedShort();
3132 int[] locals = StackMapData.readTypeArray(in, locals_size, method);
3133 int stack_size = in.readUnsignedShort();
3134 int[] stack = StackMapData.readTypeArray(in, stack_size, method);
3135 return new FullFrame(offsetDelta, locals, stack);
3137 throw new ClassFormatError("unrecognized frame_type in StackMapTable");
3143 * Stores exception table data in code attribute.
3145 * @author Sucheta Dambalkar (Adopted code from jdis)
3147 static final class TrapData {
3149 public final short start_pc;
3150 public final short end_pc;
3151 public final short handler_pc;
3152 public final short catch_cpx;
3156 * Read and store exception table data in code attribute.
3158 TrapData(DataInputStream in, int num) throws IOException {
3160 start_pc = in.readShort();
3161 end_pc = in.readShort();
3162 handler_pc = in.readShort();
3163 catch_cpx = in.readShort();
3167 * returns recommended identifier
3169 public String ident() {
3175 * @author Jaroslav Tulach <jtulach@netbeans.org>
3177 static final class TrapDataIterator {
3179 private final Hashtable exStart = new Hashtable();
3180 private final Hashtable exStop = new Hashtable();
3181 private TrapData[] current = new TrapData[10];
3182 private int currentCount;
3184 TrapDataIterator(Vector exceptionTable) {
3185 for (int i = 0; i < exceptionTable.size(); i++) {
3186 final TrapData td = (TrapData) exceptionTable.elementAt(i);
3187 put(exStart, td.start_pc, td);
3188 put(exStop, td.end_pc, td);
3192 private static void put(Hashtable h, short key, TrapData td) {
3193 Short s = Short.valueOf((short) key);
3194 Vector v = (Vector) h.get(s);
3202 private boolean processAll(Hashtable h, Short key, boolean add) {
3203 boolean change = false;
3204 Vector v = (Vector) h.get(key);
3207 for (int i = 0; i < s; i++) {
3208 TrapData td = (TrapData) v.elementAt(i);
3221 public boolean advanceTo(int i) {
3222 Short s = Short.valueOf((short) i);
3223 boolean ch1 = processAll(exStart, s, true);
3224 boolean ch2 = processAll(exStop, s, false);
3228 public boolean useTry() {
3229 return currentCount > 0;
3232 public TrapData[] current() {
3233 TrapData[] copy = new TrapData[currentCount];
3234 for (int i = 0; i < currentCount; i++) {
3235 copy[i] = current[i];
3240 private void add(TrapData e) {
3241 if (currentCount == current.length) {
3242 TrapData[] data = new TrapData[currentCount * 2];
3243 for (int i = 0; i < currentCount; i++) {
3244 data[i] = current[i];
3248 current[currentCount++] = e;
3251 private void remove(TrapData e) {
3252 if (currentCount == 0) {
3256 while (from < currentCount) {
3257 if (e == current[from++]) {
3261 while (from < currentCount) {
3262 current[from - 1] = current[from];
3263 current[from] = null;
3269 static final class TypeArray {
3271 private static final int CAPACITY_INCREMENT = 16;
3272 private int[] types;
3275 public TypeArray() {
3278 public TypeArray(final TypeArray initialTypes) {
3279 setAll(initialTypes);
3282 public void add(final int newType) {
3283 ensureCapacity(size + 1);
3284 types[size++] = newType;
3287 public void addAll(final TypeArray newTypes) {
3288 addAll(newTypes.types, 0, newTypes.size);
3291 public void addAll(final int[] newTypes) {
3292 addAll(newTypes, 0, newTypes.length);
3295 public void addAll(final int[] newTypes,
3299 ensureCapacity(size + count);
3300 arraycopy(newTypes, offset, types, size, count);
3305 public void set(final int index, final int newType) {
3306 types[index] = newType;
3309 public void setAll(final TypeArray newTypes) {
3310 setAll(newTypes.types, 0, newTypes.size);
3313 public void setAll(final int[] newTypes) {
3314 setAll(newTypes, 0, newTypes.length);
3317 public void setAll(final int[] newTypes,
3321 ensureCapacity(count);
3322 arraycopy(newTypes, offset, types, 0, count);
3329 public void setSize(final int newSize) {
3330 if (size != newSize) {
3331 ensureCapacity(newSize);
3333 for (int i = size; i < newSize; ++i) {
3340 public void clear() {
3344 public int getSize() {
3348 public int get(final int index) {
3349 return types[index];
3352 public static String typeString(final int type) {
3353 switch (type & 0xff) {
3366 case ITEM_InitObject: // UninitializedThis
3370 case ITEM_NewObject: // Uninitialized
3373 throw new IllegalArgumentException("Unknown type");
3378 public String toString() {
3379 final StringBuilder sb = new StringBuilder("[");
3381 sb.append(typeString(types[0]));
3382 for (int i = 1; i < size; ++i) {
3384 sb.append(typeString(types[i]));
3388 return sb.append(']').toString();
3391 private void ensureCapacity(final int minCapacity) {
3392 if ((minCapacity == 0)
3393 || (types != null) && (minCapacity <= types.length)) {
3397 final int newCapacity =
3398 ((minCapacity + CAPACITY_INCREMENT - 1) / CAPACITY_INCREMENT)
3399 * CAPACITY_INCREMENT;
3400 final int[] newTypes = new int[newCapacity];
3403 arraycopy(types, 0, newTypes, 0, size);
3409 // no System.arraycopy
3410 private void arraycopy(final int[] src, final int srcPos,
3411 final int[] dest, final int destPos,
3413 for (int i = 0; i < length; ++i) {
3414 dest[destPos + i] = src[srcPos + i];
3419 * A JavaScript ready replacement for java.util.Vector
3421 * @author Jaroslav Tulach <jtulach@netbeans.org>
3423 @JavaScriptPrototype(prototype = "new Array")
3424 private static final class Vector {
3426 private Object[] arr;
3434 void add(Object objectType) {
3435 addElement(objectType);
3438 @JavaScriptBody(args = {"obj"}, body =
3440 void addElement(Object obj) {
3441 final int s = size();
3443 setElementAt(obj, s);
3446 @JavaScriptBody(args = {}, body =
3447 "return this.length;")
3449 return arr == null ? 0 : arr.length;
3452 @JavaScriptBody(args = {"newArr"}, body =
3453 "for (var i = 0; i < this.length; i++) {\n"
3454 + " newArr[i] = this[i];\n"
3456 void copyInto(Object[] newArr) {
3460 int min = Math.min(newArr.length, arr.length);
3461 for (int i = 0; i < min; i++) {
3466 @JavaScriptBody(args = {"index"}, body =
3467 "return this[index];")
3468 Object elementAt(int index) {
3472 private void setSize(int len) {
3473 Object[] newArr = new Object[len];
3478 @JavaScriptBody(args = {"val", "index"}, body =
3479 "this[index] = val;")
3480 void setElementAt(Object val, int index) {