1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeParser.java Mon Mar 04 19:20:40 2013 +0100
1.3 @@ -0,0 +1,3461 @@
1.4 +/*
1.5 + * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +package org.apidesign.vm4brwsr;
1.29 +
1.30 +import java.io.ByteArrayInputStream;
1.31 +import java.io.DataInputStream;
1.32 +import java.io.IOException;
1.33 +import java.io.InputStream;
1.34 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
1.35 +import org.apidesign.bck2brwsr.core.JavaScriptPrototype;
1.36 +
1.37 +/** This is a byte code parser heavily based on original code of JavaP utility.
1.38 + * As such I decided to keep the original Oracle's GPLv2 header.
1.39 + *
1.40 + * @author Jaroslav Tulach <jtulach@netbeans.org>
1.41 + */
1.42 +final class ByteCodeParser {
1.43 + private ByteCodeParser() {
1.44 + }
1.45 + /* Signature Characters */
1.46 + public static final char SIGC_VOID = 'V';
1.47 + public static final String SIG_VOID = "V";
1.48 + public static final char SIGC_BOOLEAN = 'Z';
1.49 + public static final String SIG_BOOLEAN = "Z";
1.50 + public static final char SIGC_BYTE = 'B';
1.51 + public static final String SIG_BYTE = "B";
1.52 + public static final char SIGC_CHAR = 'C';
1.53 + public static final String SIG_CHAR = "C";
1.54 + public static final char SIGC_SHORT = 'S';
1.55 + public static final String SIG_SHORT = "S";
1.56 + public static final char SIGC_INT = 'I';
1.57 + public static final String SIG_INT = "I";
1.58 + public static final char SIGC_LONG = 'J';
1.59 + public static final String SIG_LONG = "J";
1.60 + public static final char SIGC_FLOAT = 'F';
1.61 + public static final String SIG_FLOAT = "F";
1.62 + public static final char SIGC_DOUBLE = 'D';
1.63 + public static final String SIG_DOUBLE = "D";
1.64 + public static final char SIGC_ARRAY = '[';
1.65 + public static final String SIG_ARRAY = "[";
1.66 + public static final char SIGC_CLASS = 'L';
1.67 + public static final String SIG_CLASS = "L";
1.68 + public static final char SIGC_METHOD = '(';
1.69 + public static final String SIG_METHOD = "(";
1.70 + public static final char SIGC_ENDCLASS = ';';
1.71 + public static final String SIG_ENDCLASS = ";";
1.72 + public static final char SIGC_ENDMETHOD = ')';
1.73 + public static final String SIG_ENDMETHOD = ")";
1.74 + public static final char SIGC_PACKAGE = '/';
1.75 + public static final String SIG_PACKAGE = "/";
1.76 +
1.77 + /* Class File Constants */
1.78 + public static final int JAVA_MAGIC = 0xcafebabe;
1.79 + public static final int JAVA_VERSION = 45;
1.80 + public static final int JAVA_MINOR_VERSION = 3;
1.81 +
1.82 + /* Constant table */
1.83 + public static final int CONSTANT_UTF8 = 1;
1.84 + public static final int CONSTANT_UNICODE = 2;
1.85 + public static final int CONSTANT_INTEGER = 3;
1.86 + public static final int CONSTANT_FLOAT = 4;
1.87 + public static final int CONSTANT_LONG = 5;
1.88 + public static final int CONSTANT_DOUBLE = 6;
1.89 + public static final int CONSTANT_CLASS = 7;
1.90 + public static final int CONSTANT_STRING = 8;
1.91 + public static final int CONSTANT_FIELD = 9;
1.92 + public static final int CONSTANT_METHOD = 10;
1.93 + public static final int CONSTANT_INTERFACEMETHOD = 11;
1.94 + public static final int CONSTANT_NAMEANDTYPE = 12;
1.95 +
1.96 + /* Access Flags */
1.97 + public static final int ACC_PUBLIC = 0x00000001;
1.98 + public static final int ACC_PRIVATE = 0x00000002;
1.99 + public static final int ACC_PROTECTED = 0x00000004;
1.100 + public static final int ACC_STATIC = 0x00000008;
1.101 + public static final int ACC_FINAL = 0x00000010;
1.102 + public static final int ACC_SYNCHRONIZED = 0x00000020;
1.103 + public static final int ACC_SUPER = 0x00000020;
1.104 + public static final int ACC_VOLATILE = 0x00000040;
1.105 + public static final int ACC_TRANSIENT = 0x00000080;
1.106 + public static final int ACC_NATIVE = 0x00000100;
1.107 + public static final int ACC_INTERFACE = 0x00000200;
1.108 + public static final int ACC_ABSTRACT = 0x00000400;
1.109 + public static final int ACC_STRICT = 0x00000800;
1.110 + public static final int ACC_EXPLICIT = 0x00001000;
1.111 + public static final int ACC_SYNTHETIC = 0x00010000; // actually, this is an attribute
1.112 +
1.113 + /* Type codes */
1.114 + public static final int T_CLASS = 0x00000002;
1.115 + public static final int T_BOOLEAN = 0x00000004;
1.116 + public static final int T_CHAR = 0x00000005;
1.117 + public static final int T_FLOAT = 0x00000006;
1.118 + public static final int T_DOUBLE = 0x00000007;
1.119 + public static final int T_BYTE = 0x00000008;
1.120 + public static final int T_SHORT = 0x00000009;
1.121 + public static final int T_INT = 0x0000000a;
1.122 + public static final int T_LONG = 0x0000000b;
1.123 +
1.124 + /* Type codes for StackMap attribute */
1.125 + public static final int ITEM_Bogus =0; // an unknown or uninitialized value
1.126 + public static final int ITEM_Integer =1; // a 32-bit integer
1.127 + public static final int ITEM_Float =2; // not used
1.128 + public static final int ITEM_Double =3; // not used
1.129 + public static final int ITEM_Long =4; // a 64-bit integer
1.130 + public static final int ITEM_Null =5; // the type of null
1.131 + public static final int ITEM_InitObject =6; // "this" in constructor
1.132 + public static final int ITEM_Object =7; // followed by 2-byte index of class name
1.133 + public static final int ITEM_NewObject =8; // followed by 2-byte ref to "new"
1.134 +
1.135 + /* Constants used in StackMapTable attribute */
1.136 + public static final int SAME_FRAME_BOUND = 64;
1.137 + public static final int SAME_LOCALS_1_STACK_ITEM_BOUND = 128;
1.138 + public static final int SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247;
1.139 + public static final int SAME_FRAME_EXTENDED = 251;
1.140 + public static final int FULL_FRAME = 255;
1.141 +
1.142 + /* Opcodes */
1.143 + public static final int opc_dead = -2;
1.144 + public static final int opc_label = -1;
1.145 + public static final int opc_nop = 0;
1.146 + public static final int opc_aconst_null = 1;
1.147 + public static final int opc_iconst_m1 = 2;
1.148 + public static final int opc_iconst_0 = 3;
1.149 + public static final int opc_iconst_1 = 4;
1.150 + public static final int opc_iconst_2 = 5;
1.151 + public static final int opc_iconst_3 = 6;
1.152 + public static final int opc_iconst_4 = 7;
1.153 + public static final int opc_iconst_5 = 8;
1.154 + public static final int opc_lconst_0 = 9;
1.155 + public static final int opc_lconst_1 = 10;
1.156 + public static final int opc_fconst_0 = 11;
1.157 + public static final int opc_fconst_1 = 12;
1.158 + public static final int opc_fconst_2 = 13;
1.159 + public static final int opc_dconst_0 = 14;
1.160 + public static final int opc_dconst_1 = 15;
1.161 + public static final int opc_bipush = 16;
1.162 + public static final int opc_sipush = 17;
1.163 + public static final int opc_ldc = 18;
1.164 + public static final int opc_ldc_w = 19;
1.165 + public static final int opc_ldc2_w = 20;
1.166 + public static final int opc_iload = 21;
1.167 + public static final int opc_lload = 22;
1.168 + public static final int opc_fload = 23;
1.169 + public static final int opc_dload = 24;
1.170 + public static final int opc_aload = 25;
1.171 + public static final int opc_iload_0 = 26;
1.172 + public static final int opc_iload_1 = 27;
1.173 + public static final int opc_iload_2 = 28;
1.174 + public static final int opc_iload_3 = 29;
1.175 + public static final int opc_lload_0 = 30;
1.176 + public static final int opc_lload_1 = 31;
1.177 + public static final int opc_lload_2 = 32;
1.178 + public static final int opc_lload_3 = 33;
1.179 + public static final int opc_fload_0 = 34;
1.180 + public static final int opc_fload_1 = 35;
1.181 + public static final int opc_fload_2 = 36;
1.182 + public static final int opc_fload_3 = 37;
1.183 + public static final int opc_dload_0 = 38;
1.184 + public static final int opc_dload_1 = 39;
1.185 + public static final int opc_dload_2 = 40;
1.186 + public static final int opc_dload_3 = 41;
1.187 + public static final int opc_aload_0 = 42;
1.188 + public static final int opc_aload_1 = 43;
1.189 + public static final int opc_aload_2 = 44;
1.190 + public static final int opc_aload_3 = 45;
1.191 + public static final int opc_iaload = 46;
1.192 + public static final int opc_laload = 47;
1.193 + public static final int opc_faload = 48;
1.194 + public static final int opc_daload = 49;
1.195 + public static final int opc_aaload = 50;
1.196 + public static final int opc_baload = 51;
1.197 + public static final int opc_caload = 52;
1.198 + public static final int opc_saload = 53;
1.199 + public static final int opc_istore = 54;
1.200 + public static final int opc_lstore = 55;
1.201 + public static final int opc_fstore = 56;
1.202 + public static final int opc_dstore = 57;
1.203 + public static final int opc_astore = 58;
1.204 + public static final int opc_istore_0 = 59;
1.205 + public static final int opc_istore_1 = 60;
1.206 + public static final int opc_istore_2 = 61;
1.207 + public static final int opc_istore_3 = 62;
1.208 + public static final int opc_lstore_0 = 63;
1.209 + public static final int opc_lstore_1 = 64;
1.210 + public static final int opc_lstore_2 = 65;
1.211 + public static final int opc_lstore_3 = 66;
1.212 + public static final int opc_fstore_0 = 67;
1.213 + public static final int opc_fstore_1 = 68;
1.214 + public static final int opc_fstore_2 = 69;
1.215 + public static final int opc_fstore_3 = 70;
1.216 + public static final int opc_dstore_0 = 71;
1.217 + public static final int opc_dstore_1 = 72;
1.218 + public static final int opc_dstore_2 = 73;
1.219 + public static final int opc_dstore_3 = 74;
1.220 + public static final int opc_astore_0 = 75;
1.221 + public static final int opc_astore_1 = 76;
1.222 + public static final int opc_astore_2 = 77;
1.223 + public static final int opc_astore_3 = 78;
1.224 + public static final int opc_iastore = 79;
1.225 + public static final int opc_lastore = 80;
1.226 + public static final int opc_fastore = 81;
1.227 + public static final int opc_dastore = 82;
1.228 + public static final int opc_aastore = 83;
1.229 + public static final int opc_bastore = 84;
1.230 + public static final int opc_castore = 85;
1.231 + public static final int opc_sastore = 86;
1.232 + public static final int opc_pop = 87;
1.233 + public static final int opc_pop2 = 88;
1.234 + public static final int opc_dup = 89;
1.235 + public static final int opc_dup_x1 = 90;
1.236 + public static final int opc_dup_x2 = 91;
1.237 + public static final int opc_dup2 = 92;
1.238 + public static final int opc_dup2_x1 = 93;
1.239 + public static final int opc_dup2_x2 = 94;
1.240 + public static final int opc_swap = 95;
1.241 + public static final int opc_iadd = 96;
1.242 + public static final int opc_ladd = 97;
1.243 + public static final int opc_fadd = 98;
1.244 + public static final int opc_dadd = 99;
1.245 + public static final int opc_isub = 100;
1.246 + public static final int opc_lsub = 101;
1.247 + public static final int opc_fsub = 102;
1.248 + public static final int opc_dsub = 103;
1.249 + public static final int opc_imul = 104;
1.250 + public static final int opc_lmul = 105;
1.251 + public static final int opc_fmul = 106;
1.252 + public static final int opc_dmul = 107;
1.253 + public static final int opc_idiv = 108;
1.254 + public static final int opc_ldiv = 109;
1.255 + public static final int opc_fdiv = 110;
1.256 + public static final int opc_ddiv = 111;
1.257 + public static final int opc_irem = 112;
1.258 + public static final int opc_lrem = 113;
1.259 + public static final int opc_frem = 114;
1.260 + public static final int opc_drem = 115;
1.261 + public static final int opc_ineg = 116;
1.262 + public static final int opc_lneg = 117;
1.263 + public static final int opc_fneg = 118;
1.264 + public static final int opc_dneg = 119;
1.265 + public static final int opc_ishl = 120;
1.266 + public static final int opc_lshl = 121;
1.267 + public static final int opc_ishr = 122;
1.268 + public static final int opc_lshr = 123;
1.269 + public static final int opc_iushr = 124;
1.270 + public static final int opc_lushr = 125;
1.271 + public static final int opc_iand = 126;
1.272 + public static final int opc_land = 127;
1.273 + public static final int opc_ior = 128;
1.274 + public static final int opc_lor = 129;
1.275 + public static final int opc_ixor = 130;
1.276 + public static final int opc_lxor = 131;
1.277 + public static final int opc_iinc = 132;
1.278 + public static final int opc_i2l = 133;
1.279 + public static final int opc_i2f = 134;
1.280 + public static final int opc_i2d = 135;
1.281 + public static final int opc_l2i = 136;
1.282 + public static final int opc_l2f = 137;
1.283 + public static final int opc_l2d = 138;
1.284 + public static final int opc_f2i = 139;
1.285 + public static final int opc_f2l = 140;
1.286 + public static final int opc_f2d = 141;
1.287 + public static final int opc_d2i = 142;
1.288 + public static final int opc_d2l = 143;
1.289 + public static final int opc_d2f = 144;
1.290 + public static final int opc_i2b = 145;
1.291 + public static final int opc_int2byte = 145;
1.292 + public static final int opc_i2c = 146;
1.293 + public static final int opc_int2char = 146;
1.294 + public static final int opc_i2s = 147;
1.295 + public static final int opc_int2short = 147;
1.296 + public static final int opc_lcmp = 148;
1.297 + public static final int opc_fcmpl = 149;
1.298 + public static final int opc_fcmpg = 150;
1.299 + public static final int opc_dcmpl = 151;
1.300 + public static final int opc_dcmpg = 152;
1.301 + public static final int opc_ifeq = 153;
1.302 + public static final int opc_ifne = 154;
1.303 + public static final int opc_iflt = 155;
1.304 + public static final int opc_ifge = 156;
1.305 + public static final int opc_ifgt = 157;
1.306 + public static final int opc_ifle = 158;
1.307 + public static final int opc_if_icmpeq = 159;
1.308 + public static final int opc_if_icmpne = 160;
1.309 + public static final int opc_if_icmplt = 161;
1.310 + public static final int opc_if_icmpge = 162;
1.311 + public static final int opc_if_icmpgt = 163;
1.312 + public static final int opc_if_icmple = 164;
1.313 + public static final int opc_if_acmpeq = 165;
1.314 + public static final int opc_if_acmpne = 166;
1.315 + public static final int opc_goto = 167;
1.316 + public static final int opc_jsr = 168;
1.317 + public static final int opc_ret = 169;
1.318 + public static final int opc_tableswitch = 170;
1.319 + public static final int opc_lookupswitch = 171;
1.320 + public static final int opc_ireturn = 172;
1.321 + public static final int opc_lreturn = 173;
1.322 + public static final int opc_freturn = 174;
1.323 + public static final int opc_dreturn = 175;
1.324 + public static final int opc_areturn = 176;
1.325 + public static final int opc_return = 177;
1.326 + public static final int opc_getstatic = 178;
1.327 + public static final int opc_putstatic = 179;
1.328 + public static final int opc_getfield = 180;
1.329 + public static final int opc_putfield = 181;
1.330 + public static final int opc_invokevirtual = 182;
1.331 + public static final int opc_invokenonvirtual = 183;
1.332 + public static final int opc_invokespecial = 183;
1.333 + public static final int opc_invokestatic = 184;
1.334 + public static final int opc_invokeinterface = 185;
1.335 +// public static final int opc_xxxunusedxxx = 186;
1.336 + public static final int opc_new = 187;
1.337 + public static final int opc_newarray = 188;
1.338 + public static final int opc_anewarray = 189;
1.339 + public static final int opc_arraylength = 190;
1.340 + public static final int opc_athrow = 191;
1.341 + public static final int opc_checkcast = 192;
1.342 + public static final int opc_instanceof = 193;
1.343 + public static final int opc_monitorenter = 194;
1.344 + public static final int opc_monitorexit = 195;
1.345 + public static final int opc_wide = 196;
1.346 + public static final int opc_multianewarray = 197;
1.347 + public static final int opc_ifnull = 198;
1.348 + public static final int opc_ifnonnull = 199;
1.349 + public static final int opc_goto_w = 200;
1.350 + public static final int opc_jsr_w = 201;
1.351 + /* Pseudo-instructions */
1.352 + public static final int opc_bytecode = 203;
1.353 + public static final int opc_try = 204;
1.354 + public static final int opc_endtry = 205;
1.355 + public static final int opc_catch = 206;
1.356 + public static final int opc_var = 207;
1.357 + public static final int opc_endvar = 208;
1.358 + public static final int opc_localsmap = 209;
1.359 + public static final int opc_stackmap = 210;
1.360 + /* PicoJava prefixes */
1.361 + public static final int opc_nonpriv = 254;
1.362 + public static final int opc_priv = 255;
1.363 +
1.364 + /* Wide instructions */
1.365 + public static final int opc_iload_w = (opc_wide<<8)|opc_iload;
1.366 + public static final int opc_lload_w = (opc_wide<<8)|opc_lload;
1.367 + public static final int opc_fload_w = (opc_wide<<8)|opc_fload;
1.368 + public static final int opc_dload_w = (opc_wide<<8)|opc_dload;
1.369 + public static final int opc_aload_w = (opc_wide<<8)|opc_aload;
1.370 + public static final int opc_istore_w = (opc_wide<<8)|opc_istore;
1.371 + public static final int opc_lstore_w = (opc_wide<<8)|opc_lstore;
1.372 + public static final int opc_fstore_w = (opc_wide<<8)|opc_fstore;
1.373 + public static final int opc_dstore_w = (opc_wide<<8)|opc_dstore;
1.374 + public static final int opc_astore_w = (opc_wide<<8)|opc_astore;
1.375 + public static final int opc_ret_w = (opc_wide<<8)|opc_ret;
1.376 + public static final int opc_iinc_w = (opc_wide<<8)|opc_iinc;
1.377 +
1.378 + /* Opcode Names */
1.379 + public static final String opcNamesTab[] = {
1.380 + "nop",
1.381 + "aconst_null",
1.382 + "iconst_m1",
1.383 + "iconst_0",
1.384 + "iconst_1",
1.385 + "iconst_2",
1.386 + "iconst_3",
1.387 + "iconst_4",
1.388 + "iconst_5",
1.389 + "lconst_0",
1.390 + "lconst_1",
1.391 + "fconst_0",
1.392 + "fconst_1",
1.393 + "fconst_2",
1.394 + "dconst_0",
1.395 + "dconst_1",
1.396 + "bipush",
1.397 + "sipush",
1.398 + "ldc",
1.399 + "ldc_w",
1.400 + "ldc2_w",
1.401 + "iload",
1.402 + "lload",
1.403 + "fload",
1.404 + "dload",
1.405 + "aload",
1.406 + "iload_0",
1.407 + "iload_1",
1.408 + "iload_2",
1.409 + "iload_3",
1.410 + "lload_0",
1.411 + "lload_1",
1.412 + "lload_2",
1.413 + "lload_3",
1.414 + "fload_0",
1.415 + "fload_1",
1.416 + "fload_2",
1.417 + "fload_3",
1.418 + "dload_0",
1.419 + "dload_1",
1.420 + "dload_2",
1.421 + "dload_3",
1.422 + "aload_0",
1.423 + "aload_1",
1.424 + "aload_2",
1.425 + "aload_3",
1.426 + "iaload",
1.427 + "laload",
1.428 + "faload",
1.429 + "daload",
1.430 + "aaload",
1.431 + "baload",
1.432 + "caload",
1.433 + "saload",
1.434 + "istore",
1.435 + "lstore",
1.436 + "fstore",
1.437 + "dstore",
1.438 + "astore",
1.439 + "istore_0",
1.440 + "istore_1",
1.441 + "istore_2",
1.442 + "istore_3",
1.443 + "lstore_0",
1.444 + "lstore_1",
1.445 + "lstore_2",
1.446 + "lstore_3",
1.447 + "fstore_0",
1.448 + "fstore_1",
1.449 + "fstore_2",
1.450 + "fstore_3",
1.451 + "dstore_0",
1.452 + "dstore_1",
1.453 + "dstore_2",
1.454 + "dstore_3",
1.455 + "astore_0",
1.456 + "astore_1",
1.457 + "astore_2",
1.458 + "astore_3",
1.459 + "iastore",
1.460 + "lastore",
1.461 + "fastore",
1.462 + "dastore",
1.463 + "aastore",
1.464 + "bastore",
1.465 + "castore",
1.466 + "sastore",
1.467 + "pop",
1.468 + "pop2",
1.469 + "dup",
1.470 + "dup_x1",
1.471 + "dup_x2",
1.472 + "dup2",
1.473 + "dup2_x1",
1.474 + "dup2_x2",
1.475 + "swap",
1.476 + "iadd",
1.477 + "ladd",
1.478 + "fadd",
1.479 + "dadd",
1.480 + "isub",
1.481 + "lsub",
1.482 + "fsub",
1.483 + "dsub",
1.484 + "imul",
1.485 + "lmul",
1.486 + "fmul",
1.487 + "dmul",
1.488 + "idiv",
1.489 + "ldiv",
1.490 + "fdiv",
1.491 + "ddiv",
1.492 + "irem",
1.493 + "lrem",
1.494 + "frem",
1.495 + "drem",
1.496 + "ineg",
1.497 + "lneg",
1.498 + "fneg",
1.499 + "dneg",
1.500 + "ishl",
1.501 + "lshl",
1.502 + "ishr",
1.503 + "lshr",
1.504 + "iushr",
1.505 + "lushr",
1.506 + "iand",
1.507 + "land",
1.508 + "ior",
1.509 + "lor",
1.510 + "ixor",
1.511 + "lxor",
1.512 + "iinc",
1.513 + "i2l",
1.514 + "i2f",
1.515 + "i2d",
1.516 + "l2i",
1.517 + "l2f",
1.518 + "l2d",
1.519 + "f2i",
1.520 + "f2l",
1.521 + "f2d",
1.522 + "d2i",
1.523 + "d2l",
1.524 + "d2f",
1.525 + "i2b",
1.526 + "i2c",
1.527 + "i2s",
1.528 + "lcmp",
1.529 + "fcmpl",
1.530 + "fcmpg",
1.531 + "dcmpl",
1.532 + "dcmpg",
1.533 + "ifeq",
1.534 + "ifne",
1.535 + "iflt",
1.536 + "ifge",
1.537 + "ifgt",
1.538 + "ifle",
1.539 + "if_icmpeq",
1.540 + "if_icmpne",
1.541 + "if_icmplt",
1.542 + "if_icmpge",
1.543 + "if_icmpgt",
1.544 + "if_icmple",
1.545 + "if_acmpeq",
1.546 + "if_acmpne",
1.547 + "goto",
1.548 + "jsr",
1.549 + "ret",
1.550 + "tableswitch",
1.551 + "lookupswitch",
1.552 + "ireturn",
1.553 + "lreturn",
1.554 + "freturn",
1.555 + "dreturn",
1.556 + "areturn",
1.557 + "return",
1.558 + "getstatic",
1.559 + "putstatic",
1.560 + "getfield",
1.561 + "putfield",
1.562 + "invokevirtual",
1.563 + "invokespecial", // was "invokenonvirtual",
1.564 + "invokestatic",
1.565 + "invokeinterface",
1.566 + "bytecode 186", //"xxxunusedxxx",
1.567 + "new",
1.568 + "newarray",
1.569 + "anewarray",
1.570 + "arraylength",
1.571 + "athrow",
1.572 + "checkcast",
1.573 + "instanceof",
1.574 + "monitorenter",
1.575 + "monitorexit",
1.576 + null, // "wide",
1.577 + "multianewarray",
1.578 + "ifnull",
1.579 + "ifnonnull",
1.580 + "goto_w",
1.581 + "jsr_w",
1.582 + "bytecode 202", // "breakpoint",
1.583 + "bytecode",
1.584 + "try",
1.585 + "endtry",
1.586 + "catch",
1.587 + "var",
1.588 + "endvar",
1.589 + "locals_map",
1.590 + "stack_map"
1.591 + };
1.592 +
1.593 + /* Opcode Lengths */
1.594 + public static final int opcLengthsTab[] = {
1.595 + 1,
1.596 + 1,
1.597 + 1,
1.598 + 1,
1.599 + 1,
1.600 + 1,
1.601 + 1,
1.602 + 1,
1.603 + 1,
1.604 + 1,
1.605 + 1,
1.606 + 1,
1.607 + 1,
1.608 + 1,
1.609 + 1,
1.610 + 1,
1.611 + 2,
1.612 + 3,
1.613 + 2,
1.614 + 3,
1.615 + 3,
1.616 + 2,
1.617 + 2,
1.618 + 2,
1.619 + 2,
1.620 + 2,
1.621 + 1,
1.622 + 1,
1.623 + 1,
1.624 + 1,
1.625 + 1,
1.626 + 1,
1.627 + 1,
1.628 + 1,
1.629 + 1,
1.630 + 1,
1.631 + 1,
1.632 + 1,
1.633 + 1,
1.634 + 1,
1.635 + 1,
1.636 + 1,
1.637 + 1,
1.638 + 1,
1.639 + 1,
1.640 + 1,
1.641 + 1,
1.642 + 1,
1.643 + 1,
1.644 + 1,
1.645 + 1,
1.646 + 1,
1.647 + 1,
1.648 + 1,
1.649 + 2,
1.650 + 2,
1.651 + 2,
1.652 + 2,
1.653 + 2,
1.654 + 1,
1.655 + 1,
1.656 + 1,
1.657 + 1,
1.658 + 1,
1.659 + 1,
1.660 + 1,
1.661 + 1,
1.662 + 1,
1.663 + 1,
1.664 + 1,
1.665 + 1,
1.666 + 1,
1.667 + 1,
1.668 + 1,
1.669 + 1,
1.670 + 1,
1.671 + 1,
1.672 + 1,
1.673 + 1,
1.674 + 1,
1.675 + 1,
1.676 + 1,
1.677 + 1,
1.678 + 1,
1.679 + 1,
1.680 + 1,
1.681 + 1,
1.682 + 1,
1.683 + 1,
1.684 + 1,
1.685 + 1,
1.686 + 1,
1.687 + 1,
1.688 + 1,
1.689 + 1,
1.690 + 1,
1.691 + 1,
1.692 + 1,
1.693 + 1,
1.694 + 1,
1.695 + 1,
1.696 + 1,
1.697 + 1,
1.698 + 1,
1.699 + 1,
1.700 + 1,
1.701 + 1,
1.702 + 1,
1.703 + 1,
1.704 + 1,
1.705 + 1,
1.706 + 1,
1.707 + 1,
1.708 + 1,
1.709 + 1,
1.710 + 1,
1.711 + 1,
1.712 + 1,
1.713 + 1,
1.714 + 1,
1.715 + 1,
1.716 + 1,
1.717 + 1,
1.718 + 1,
1.719 + 1,
1.720 + 1,
1.721 + 1,
1.722 + 1,
1.723 + 1,
1.724 + 1,
1.725 + 1,
1.726 + 1,
1.727 + 3,
1.728 + 1,
1.729 + 1,
1.730 + 1,
1.731 + 1,
1.732 + 1,
1.733 + 1,
1.734 + 1,
1.735 + 1,
1.736 + 1,
1.737 + 1,
1.738 + 1,
1.739 + 1,
1.740 + 1,
1.741 + 1,
1.742 + 1,
1.743 + 1,
1.744 + 1,
1.745 + 1,
1.746 + 1,
1.747 + 1,
1.748 + 3,
1.749 + 3,
1.750 + 3,
1.751 + 3,
1.752 + 3,
1.753 + 3,
1.754 + 3,
1.755 + 3,
1.756 + 3,
1.757 + 3,
1.758 + 3,
1.759 + 3,
1.760 + 3,
1.761 + 3,
1.762 + 3,
1.763 + 3,
1.764 + 2,
1.765 + 99,
1.766 + 99,
1.767 + 1,
1.768 + 1,
1.769 + 1,
1.770 + 1,
1.771 + 1,
1.772 + 1,
1.773 + 3,
1.774 + 3,
1.775 + 3,
1.776 + 3,
1.777 + 3,
1.778 + 3,
1.779 + 3,
1.780 + 5,
1.781 + 0,
1.782 + 3,
1.783 + 2,
1.784 + 3,
1.785 + 1,
1.786 + 1,
1.787 + 3,
1.788 + 3,
1.789 + 1,
1.790 + 1,
1.791 + 0, // wide
1.792 + 4,
1.793 + 3,
1.794 + 3,
1.795 + 5,
1.796 + 5,
1.797 + 1,
1.798 + 1, 0, 0, 0, 0, 0 // pseudo
1.799 + };
1.800 +
1.801 + /**
1.802 + * End of input
1.803 + */
1.804 + public static final int EOF = -1;
1.805 +
1.806 + /*
1.807 + * Flags
1.808 + */
1.809 + public static final int F_VERBOSE = 1 << 0;
1.810 + public static final int F_DUMP = 1 << 1;
1.811 + public static final int F_WARNINGS = 1 << 2;
1.812 + public static final int F_DEBUG = 1 << 3;
1.813 + public static final int F_OPTIMIZE = 1 << 4;
1.814 + public static final int F_DEPENDENCIES = 1 << 5;
1.815 +
1.816 + /*
1.817 + * Type codes
1.818 + */
1.819 + public static final int TC_BOOLEAN = 0;
1.820 + public static final int TC_BYTE = 1;
1.821 + public static final int TC_CHAR = 2;
1.822 + public static final int TC_SHORT = 3;
1.823 + public static final int TC_INT = 4;
1.824 + public static final int TC_LONG = 5;
1.825 + public static final int TC_FLOAT = 6;
1.826 + public static final int TC_DOUBLE = 7;
1.827 + public static final int TC_NULL = 8;
1.828 + public static final int TC_ARRAY = 9;
1.829 + public static final int TC_CLASS = 10;
1.830 + public static final int TC_VOID = 11;
1.831 + public static final int TC_METHOD = 12;
1.832 + public static final int TC_ERROR = 13;
1.833 +
1.834 + /*
1.835 + * Type Masks
1.836 + */
1.837 + public static final int TM_NULL = 1 << TC_NULL;
1.838 + public static final int TM_VOID = 1 << TC_VOID;
1.839 + public static final int TM_BOOLEAN = 1 << TC_BOOLEAN;
1.840 + public static final int TM_BYTE = 1 << TC_BYTE;
1.841 + public static final int TM_CHAR = 1 << TC_CHAR;
1.842 + public static final int TM_SHORT = 1 << TC_SHORT;
1.843 + public static final int TM_INT = 1 << TC_INT;
1.844 + public static final int TM_LONG = 1 << TC_LONG;
1.845 + public static final int TM_FLOAT = 1 << TC_FLOAT;
1.846 + public static final int TM_DOUBLE = 1 << TC_DOUBLE;
1.847 + public static final int TM_ARRAY = 1 << TC_ARRAY;
1.848 + public static final int TM_CLASS = 1 << TC_CLASS;
1.849 + public static final int TM_METHOD = 1 << TC_METHOD;
1.850 + public static final int TM_ERROR = 1 << TC_ERROR;
1.851 +
1.852 + public static final int TM_INT32 = TM_BYTE | TM_SHORT | TM_CHAR | TM_INT;
1.853 + public static final int TM_NUM32 = TM_INT32 | TM_FLOAT;
1.854 + public static final int TM_NUM64 = TM_LONG | TM_DOUBLE;
1.855 + public static final int TM_INTEGER = TM_INT32 | TM_LONG;
1.856 + public static final int TM_REAL = TM_FLOAT | TM_DOUBLE;
1.857 + public static final int TM_NUMBER = TM_INTEGER | TM_REAL;
1.858 + public static final int TM_REFERENCE = TM_ARRAY | TM_CLASS | TM_NULL;
1.859 +
1.860 + /*
1.861 + * Class status
1.862 + */
1.863 + public static final int CS_UNDEFINED = 0;
1.864 + public static final int CS_UNDECIDED = 1;
1.865 + public static final int CS_BINARY = 2;
1.866 + public static final int CS_SOURCE = 3;
1.867 + public static final int CS_PARSED = 4;
1.868 + public static final int CS_COMPILED = 5;
1.869 + public static final int CS_NOTFOUND = 6;
1.870 +
1.871 + /*
1.872 + * Attributes
1.873 + */
1.874 + public static final int ATT_ALL = -1;
1.875 + public static final int ATT_CODE = 1;
1.876 +
1.877 + /*
1.878 + * Number of bits used in file offsets
1.879 + */
1.880 + public static final int OFFSETBITS = 19;
1.881 + public static final int MAXFILESIZE = (1 << OFFSETBITS) - 1;
1.882 + public static final int MAXLINENUMBER = (1 << (32 - OFFSETBITS)) - 1;
1.883 +
1.884 + /*
1.885 + * Operators
1.886 + */
1.887 + public final int COMMA = 0;
1.888 + public final int ASSIGN = 1;
1.889 +
1.890 + public final int ASGMUL = 2;
1.891 + public final int ASGDIV = 3;
1.892 + public final int ASGREM = 4;
1.893 + public final int ASGADD = 5;
1.894 + public final int ASGSUB = 6;
1.895 + public final int ASGLSHIFT = 7;
1.896 + public final int ASGRSHIFT = 8;
1.897 + public final int ASGURSHIFT = 9;
1.898 + public final int ASGBITAND = 10;
1.899 + public final int ASGBITOR = 11;
1.900 + public final int ASGBITXOR = 12;
1.901 +
1.902 + public final int COND = 13;
1.903 + public final int OR = 14;
1.904 + public final int AND = 15;
1.905 + public final int BITOR = 16;
1.906 + public final int BITXOR = 17;
1.907 + public final int BITAND = 18;
1.908 + public final int NE = 19;
1.909 + public final int EQ = 20;
1.910 + public final int GE = 21;
1.911 + public final int GT = 22;
1.912 + public final int LE = 23;
1.913 + public final int LT = 24;
1.914 + public final int INSTANCEOF = 25;
1.915 + public final int LSHIFT = 26;
1.916 + public final int RSHIFT = 27;
1.917 + public final int URSHIFT = 28;
1.918 + public final int ADD = 29;
1.919 + public final int SUB = 30;
1.920 + public final int DIV = 31;
1.921 + public final int REM = 32;
1.922 + public final int MUL = 33;
1.923 + public final int CAST = 34; // (x)y
1.924 + public final int POS = 35; // +x
1.925 + public final int NEG = 36; // -x
1.926 + public final int NOT = 37;
1.927 + public final int BITNOT = 38;
1.928 + public final int PREINC = 39; // ++x
1.929 + public final int PREDEC = 40; // --x
1.930 + public final int NEWARRAY = 41;
1.931 + public final int NEWINSTANCE = 42;
1.932 + public final int NEWFROMNAME = 43;
1.933 + public final int POSTINC = 44; // x++
1.934 + public final int POSTDEC = 45; // x--
1.935 + public final int FIELD = 46;
1.936 + public final int METHOD = 47; // x(y)
1.937 + public final int ARRAYACCESS = 48; // x[y]
1.938 + public final int NEW = 49;
1.939 + public final int INC = 50;
1.940 + public final int DEC = 51;
1.941 +
1.942 + public final int CONVERT = 55; // implicit conversion
1.943 + public final int EXPR = 56; // (x)
1.944 + public final int ARRAY = 57; // {x, y, ...}
1.945 + public final int GOTO = 58;
1.946 +
1.947 + /*
1.948 + * Value tokens
1.949 + */
1.950 + public final int IDENT = 60;
1.951 + public final int BOOLEANVAL = 61;
1.952 + public final int BYTEVAL = 62;
1.953 + public final int CHARVAL = 63;
1.954 + public final int SHORTVAL = 64;
1.955 + public final int INTVAL = 65;
1.956 + public final int LONGVAL = 66;
1.957 + public final int FLOATVAL = 67;
1.958 + public final int DOUBLEVAL = 68;
1.959 + public final int STRINGVAL = 69;
1.960 +
1.961 + /*
1.962 + * Type keywords
1.963 + */
1.964 + public final int BYTE = 70;
1.965 + public final int CHAR = 71;
1.966 + public final int SHORT = 72;
1.967 + public final int INT = 73;
1.968 + public final int LONG = 74;
1.969 + public final int FLOAT = 75;
1.970 + public final int DOUBLE = 76;
1.971 + public final int VOID = 77;
1.972 + public final int BOOLEAN = 78;
1.973 +
1.974 + /*
1.975 + * Expression keywords
1.976 + */
1.977 + public final int TRUE = 80;
1.978 + public final int FALSE = 81;
1.979 + public final int THIS = 82;
1.980 + public final int SUPER = 83;
1.981 + public final int NULL = 84;
1.982 +
1.983 + /*
1.984 + * Statement keywords
1.985 + */
1.986 + public final int IF = 90;
1.987 + public final int ELSE = 91;
1.988 + public final int FOR = 92;
1.989 + public final int WHILE = 93;
1.990 + public final int DO = 94;
1.991 + public final int SWITCH = 95;
1.992 + public final int CASE = 96;
1.993 + public final int DEFAULT = 97;
1.994 + public final int BREAK = 98;
1.995 + public final int CONTINUE = 99;
1.996 + public final int RETURN = 100;
1.997 + public final int TRY = 101;
1.998 + public final int CATCH = 102;
1.999 + public final int FINALLY = 103;
1.1000 + public final int THROW = 104;
1.1001 + public final int STAT = 105;
1.1002 + public final int EXPRESSION = 106;
1.1003 + public final int DECLARATION = 107;
1.1004 + public final int VARDECLARATION = 108;
1.1005 +
1.1006 + /*
1.1007 + * Declaration keywords
1.1008 + */
1.1009 + public final int IMPORT = 110;
1.1010 + public final int CLASS = 111;
1.1011 + public final int EXTENDS = 112;
1.1012 + public final int IMPLEMENTS = 113;
1.1013 + public final int INTERFACE = 114;
1.1014 + public final int PACKAGE = 115;
1.1015 +
1.1016 + /*
1.1017 + * Modifier keywords
1.1018 + */
1.1019 + public final int PRIVATE = 120;
1.1020 + public final int PUBLIC = 121;
1.1021 + public final int PROTECTED = 122;
1.1022 + public final int CONST = 123;
1.1023 + public final int STATIC = 124;
1.1024 + public final int TRANSIENT = 125;
1.1025 + public final int SYNCHRONIZED = 126;
1.1026 + public final int NATIVE = 127;
1.1027 + public final int FINAL = 128;
1.1028 + public final int VOLATILE = 129;
1.1029 + public final int ABSTRACT = 130;
1.1030 + public final int STRICT = 165;
1.1031 +
1.1032 + /*
1.1033 + * Punctuation
1.1034 + */
1.1035 + public final int SEMICOLON = 135;
1.1036 + public final int COLON = 136;
1.1037 + public final int QUESTIONMARK = 137;
1.1038 + public final int LBRACE = 138;
1.1039 + public final int RBRACE = 139;
1.1040 + public final int LPAREN = 140;
1.1041 + public final int RPAREN = 141;
1.1042 + public final int LSQBRACKET = 142;
1.1043 + public final int RSQBRACKET = 143;
1.1044 + public final int THROWS = 144;
1.1045 +
1.1046 + /*
1.1047 + * Special tokens
1.1048 + */
1.1049 + public final int ERROR = 145; // an error
1.1050 + public final int COMMENT = 146; // not used anymore.
1.1051 + public final int TYPE = 147;
1.1052 + public final int LENGTH = 148;
1.1053 + public final int INLINERETURN = 149;
1.1054 + public final int INLINEMETHOD = 150;
1.1055 + public final int INLINENEWINSTANCE = 151;
1.1056 +
1.1057 + /*
1.1058 + * Added for jasm
1.1059 + */
1.1060 + public final int METHODREF = 152;
1.1061 + public final int FIELDREF = 153;
1.1062 + public final int STACK = 154;
1.1063 + public final int LOCAL = 155;
1.1064 + public final int CPINDEX = 156;
1.1065 + public final int CPNAME = 157;
1.1066 + public final int SIGN = 158;
1.1067 + public final int BITS = 159;
1.1068 + public final int INF = 160;
1.1069 + public final int NAN = 161;
1.1070 + public final int INNERCLASS = 162;
1.1071 + public final int OF = 163;
1.1072 + public final int SYNTHETIC = 164;
1.1073 +// last used=165;
1.1074 +
1.1075 + /*
1.1076 + * Operator precedence
1.1077 + */
1.1078 + public static final int opPrecedence[] = {
1.1079 + 10, 11, 11, 11, 11, 11, 11, 11, 11, 11,
1.1080 + 11, 11, 11, 12, 13, 14, 15, 16, 17, 18,
1.1081 + 18, 19, 19, 19, 19, 19, 20, 20, 20, 21,
1.1082 + 21, 22, 22, 22, 23, 24, 24, 24, 24, 24,
1.1083 + 24, 25, 25, 26, 26, 26, 26, 26, 26
1.1084 + };
1.1085 +
1.1086 + /*
1.1087 + * Operator names
1.1088 + */
1.1089 + public static final String opNames[] = {
1.1090 + ",", "=", "*=", "/=", "%=",
1.1091 + "+=", "-=", "<<=", ">>=", "<<<=",
1.1092 + "&=", "|=", "^=", "?:", "||",
1.1093 + "&&", "|", "^", "&", "!=",
1.1094 + "==", ">=", ">", "<=", "<",
1.1095 + "instanceof", "<<", ">>", "<<<", "+",
1.1096 + "-", "/", "%", "*", "cast",
1.1097 + "+", "-", "!", "~", "++",
1.1098 + "--", "new", "new", "new", "++",
1.1099 + "--", "field", "method", "[]", "new",
1.1100 + "++", "--", null, null, null,
1.1101 +
1.1102 + "convert", "expr", "array", "goto", null,
1.1103 +
1.1104 + "Identifier", "Boolean", "Byte", "Char", "Short",
1.1105 + "Integer", "Long", "Float", "Double", "String",
1.1106 +
1.1107 + "byte", "char", "short", "int", "long",
1.1108 + "float", "double", "void", "boolean", null,
1.1109 +
1.1110 + "true", "false", "this", "super", "null",
1.1111 + null, null, null, null, null,
1.1112 +
1.1113 + "if", "else", "for", "while", "do",
1.1114 + "switch", "case", "default", "break", "continue",
1.1115 + "return", "try", "catch", "finally", "throw",
1.1116 + "stat", "expression", "declaration", "declaration", null,
1.1117 +
1.1118 + "import", "class", "extends", "implements", "interface",
1.1119 + "package", null, null, null, null,
1.1120 +
1.1121 + "private", "public", "protected", "const", "static",
1.1122 + "transient", "synchronized", "native", "final", "volatile",
1.1123 + "abstract", null, null, null, null,
1.1124 +
1.1125 + ";", ":", "?", "{", "}",
1.1126 + "(", ")", "[", "]", "throws",
1.1127 + "error", "comment", "type", "length", "inline-return",
1.1128 + "inline-method", "inline-new",
1.1129 + "method", "field", "stack", "locals", "CPINDEX", "CPName", "SIGN",
1.1130 + "bits", "INF", "NaN", "InnerClass", "of", "synthetic"
1.1131 + };
1.1132 +
1.1133 + static class AnnotationParser {
1.1134 +
1.1135 + private final boolean textual;
1.1136 + private final boolean iterateArray;
1.1137 +
1.1138 + protected AnnotationParser(boolean textual, boolean iterateArray) {
1.1139 + this.textual = textual;
1.1140 + this.iterateArray = iterateArray;
1.1141 + }
1.1142 +
1.1143 + protected void visitAnnotationStart(String type, boolean top) throws IOException {
1.1144 + }
1.1145 +
1.1146 + protected void visitAnnotationEnd(String type, boolean top) throws IOException {
1.1147 + }
1.1148 +
1.1149 + protected void visitValueStart(String attrName, char type) throws IOException {
1.1150 + }
1.1151 +
1.1152 + protected void visitValueEnd(String attrName, char type) throws IOException {
1.1153 + }
1.1154 +
1.1155 + protected void visitAttr(
1.1156 + String annoType, String attr, String attrType, String value) throws IOException {
1.1157 + }
1.1158 +
1.1159 + protected void visitEnumAttr(
1.1160 + String annoType, String attr, String attrType, String value) throws IOException {
1.1161 + visitAttr(annoType, attr, attrType, value);
1.1162 + }
1.1163 +
1.1164 + /**
1.1165 + * Initialize the parsing with constant pool from
1.1166 + * <code>cd</code>.
1.1167 + *
1.1168 + * @param attr the attribute defining annotations
1.1169 + * @param cd constant pool
1.1170 + * @throws IOException in case I/O fails
1.1171 + */
1.1172 + public final void parse(byte[] attr, ClassData cd) throws IOException {
1.1173 + ByteArrayInputStream is = new ByteArrayInputStream(attr);
1.1174 + DataInputStream dis = new DataInputStream(is);
1.1175 + try {
1.1176 + read(dis, cd);
1.1177 + } finally {
1.1178 + is.close();
1.1179 + }
1.1180 + }
1.1181 +
1.1182 + private void read(DataInputStream dis, ClassData cd) throws IOException {
1.1183 + int cnt = dis.readUnsignedShort();
1.1184 + for (int i = 0; i < cnt; i++) {
1.1185 + readAnno(dis, cd, true);
1.1186 + }
1.1187 + }
1.1188 +
1.1189 + private void readAnno(DataInputStream dis, ClassData cd, boolean top) throws IOException {
1.1190 + int type = dis.readUnsignedShort();
1.1191 + String typeName = cd.StringValue(type);
1.1192 + visitAnnotationStart(typeName, top);
1.1193 + int cnt = dis.readUnsignedShort();
1.1194 + for (int i = 0; i < cnt; i++) {
1.1195 + String attrName = cd.StringValue(dis.readUnsignedShort());
1.1196 + readValue(dis, cd, typeName, attrName);
1.1197 + }
1.1198 + visitAnnotationEnd(typeName, top);
1.1199 + if (cnt == 0) {
1.1200 + visitAttr(typeName, null, null, null);
1.1201 + }
1.1202 + }
1.1203 +
1.1204 + private void readValue(
1.1205 + DataInputStream dis, ClassData cd, String typeName, String attrName) throws IOException {
1.1206 + char type = (char) dis.readByte();
1.1207 + visitValueStart(attrName, type);
1.1208 + if (type == '@') {
1.1209 + readAnno(dis, cd, false);
1.1210 + } else if ("CFJZsSIDB".indexOf(type) >= 0) { // NOI18N
1.1211 + int primitive = dis.readUnsignedShort();
1.1212 + String val = cd.stringValue(primitive, textual);
1.1213 + String attrType;
1.1214 + if (type == 's') {
1.1215 + attrType = "Ljava_lang_String_2";
1.1216 + if (textual) {
1.1217 + val = '"' + val + '"';
1.1218 + }
1.1219 + } else {
1.1220 + attrType = "" + type;
1.1221 + }
1.1222 + visitAttr(typeName, attrName, attrType, val);
1.1223 + } else if (type == 'c') {
1.1224 + int cls = dis.readUnsignedShort();
1.1225 + } else if (type == '[') {
1.1226 + int cnt = dis.readUnsignedShort();
1.1227 + for (int i = 0; i < cnt; i++) {
1.1228 + readValue(dis, cd, typeName, iterateArray ? attrName : null);
1.1229 + }
1.1230 + } else if (type == 'e') {
1.1231 + int enumT = dis.readUnsignedShort();
1.1232 + String attrType = cd.stringValue(enumT, textual);
1.1233 + int enumN = dis.readUnsignedShort();
1.1234 + String val = cd.stringValue(enumN, textual);
1.1235 + visitEnumAttr(typeName, attrName, attrType, val);
1.1236 + } else {
1.1237 + throw new IOException("Unknown type " + type);
1.1238 + }
1.1239 + visitValueEnd(attrName, type);
1.1240 + }
1.1241 + }
1.1242 +
1.1243 + /**
1.1244 + * Reads and stores attribute information.
1.1245 + *
1.1246 + * @author Sucheta Dambalkar (Adopted code from jdis)
1.1247 + */
1.1248 + private static class AttrData {
1.1249 +
1.1250 + ClassData cls;
1.1251 + int name_cpx;
1.1252 + int datalen;
1.1253 + byte data[];
1.1254 +
1.1255 + public AttrData(ClassData cls) {
1.1256 + this.cls = cls;
1.1257 + }
1.1258 +
1.1259 + /**
1.1260 + * Reads unknown attribute.
1.1261 + */
1.1262 + public void read(int name_cpx, DataInputStream in) throws IOException {
1.1263 + this.name_cpx = name_cpx;
1.1264 + datalen = in.readInt();
1.1265 + data = new byte[datalen];
1.1266 + in.readFully(data);
1.1267 + }
1.1268 +
1.1269 + /**
1.1270 + * Reads just the name of known attribute.
1.1271 + */
1.1272 + public void read(int name_cpx) {
1.1273 + this.name_cpx = name_cpx;
1.1274 + }
1.1275 +
1.1276 + /**
1.1277 + * Returns attribute name.
1.1278 + */
1.1279 + public String getAttrName() {
1.1280 + return cls.getString(name_cpx);
1.1281 + }
1.1282 +
1.1283 + /**
1.1284 + * Returns attribute data.
1.1285 + */
1.1286 + public byte[] getData() {
1.1287 + return data;
1.1288 + }
1.1289 + }
1.1290 +
1.1291 + /**
1.1292 + * Stores constant pool entry information with one field.
1.1293 + *
1.1294 + * @author Sucheta Dambalkar (Adopted code from jdis)
1.1295 + */
1.1296 + private static class CPX {
1.1297 +
1.1298 + int cpx;
1.1299 +
1.1300 + CPX(int cpx) {
1.1301 + this.cpx = cpx;
1.1302 + }
1.1303 + }
1.1304 +
1.1305 + /**
1.1306 + * Stores constant pool entry information with two fields.
1.1307 + *
1.1308 + * @author Sucheta Dambalkar (Adopted code from jdis)
1.1309 + */
1.1310 + private static class CPX2 {
1.1311 +
1.1312 + int cpx1, cpx2;
1.1313 +
1.1314 + CPX2(int cpx1, int cpx2) {
1.1315 + this.cpx1 = cpx1;
1.1316 + this.cpx2 = cpx2;
1.1317 + }
1.1318 + }
1.1319 +
1.1320 + /**
1.1321 + * Central data repository of the Java Disassembler. Stores all the
1.1322 + * information in java class file.
1.1323 + *
1.1324 + * @author Sucheta Dambalkar (Adopted code from jdis)
1.1325 + */
1.1326 + static final class ClassData {
1.1327 +
1.1328 + private int magic;
1.1329 + private int minor_version;
1.1330 + private int major_version;
1.1331 + private int cpool_count;
1.1332 + private Object cpool[];
1.1333 + private int access;
1.1334 + private int this_class = 0;
1.1335 + private int super_class;
1.1336 + private int interfaces_count;
1.1337 + private int[] interfaces = new int[0];
1.1338 + private int fields_count;
1.1339 + private FieldData[] fields;
1.1340 + private int methods_count;
1.1341 + private MethodData[] methods;
1.1342 + private InnerClassData[] innerClasses;
1.1343 + private int attributes_count;
1.1344 + private AttrData[] attrs;
1.1345 + private String classname;
1.1346 + private String superclassname;
1.1347 + private int source_cpx = 0;
1.1348 + private byte tags[];
1.1349 + private Hashtable indexHashAscii = new Hashtable();
1.1350 + private String pkgPrefix = "";
1.1351 + private int pkgPrefixLen = 0;
1.1352 +
1.1353 + /**
1.1354 + * Read classfile to disassemble.
1.1355 + */
1.1356 + public ClassData(InputStream infile) throws IOException {
1.1357 + this.read(new DataInputStream(infile));
1.1358 + }
1.1359 +
1.1360 + /**
1.1361 + * Reads and stores class file information.
1.1362 + */
1.1363 + public void read(DataInputStream in) throws IOException {
1.1364 + // Read the header
1.1365 + magic = in.readInt();
1.1366 + if (magic != JAVA_MAGIC) {
1.1367 + throw new ClassFormatError("wrong magic: "
1.1368 + + toHex(magic) + ", expected "
1.1369 + + toHex(JAVA_MAGIC));
1.1370 + }
1.1371 + minor_version = in.readShort();
1.1372 + major_version = in.readShort();
1.1373 + if (major_version != JAVA_VERSION) {
1.1374 + }
1.1375 +
1.1376 + // Read the constant pool
1.1377 + readCP(in);
1.1378 + access = in.readUnsignedShort();
1.1379 + this_class = in.readUnsignedShort();
1.1380 + super_class = in.readUnsignedShort();
1.1381 +
1.1382 + //Read interfaces.
1.1383 + interfaces_count = in.readUnsignedShort();
1.1384 + if (interfaces_count > 0) {
1.1385 + interfaces = new int[interfaces_count];
1.1386 + }
1.1387 + for (int i = 0; i < interfaces_count; i++) {
1.1388 + interfaces[i] = in.readShort();
1.1389 + }
1.1390 +
1.1391 + // Read the fields
1.1392 + readFields(in);
1.1393 +
1.1394 + // Read the methods
1.1395 + readMethods(in);
1.1396 +
1.1397 + // Read the attributes
1.1398 + attributes_count = in.readUnsignedShort();
1.1399 + attrs = new AttrData[attributes_count];
1.1400 + for (int k = 0; k < attributes_count; k++) {
1.1401 + int name_cpx = in.readUnsignedShort();
1.1402 + if (getTag(name_cpx) == CONSTANT_UTF8
1.1403 + && getString(name_cpx).equals("SourceFile")) {
1.1404 + if (in.readInt() != 2) {
1.1405 + throw new ClassFormatError("invalid attr length");
1.1406 + }
1.1407 + source_cpx = in.readUnsignedShort();
1.1408 + AttrData attr = new AttrData(this);
1.1409 + attr.read(name_cpx);
1.1410 + attrs[k] = attr;
1.1411 +
1.1412 + } else if (getTag(name_cpx) == CONSTANT_UTF8
1.1413 + && getString(name_cpx).equals("InnerClasses")) {
1.1414 + int length = in.readInt();
1.1415 + int num = in.readUnsignedShort();
1.1416 + if (2 + num * 8 != length) {
1.1417 + throw new ClassFormatError("invalid attr length");
1.1418 + }
1.1419 + innerClasses = new InnerClassData[num];
1.1420 + for (int j = 0; j < num; j++) {
1.1421 + InnerClassData innerClass = new InnerClassData(this);
1.1422 + innerClass.read(in);
1.1423 + innerClasses[j] = innerClass;
1.1424 + }
1.1425 + AttrData attr = new AttrData(this);
1.1426 + attr.read(name_cpx);
1.1427 + attrs[k] = attr;
1.1428 + } else {
1.1429 + AttrData attr = new AttrData(this);
1.1430 + attr.read(name_cpx, in);
1.1431 + attrs[k] = attr;
1.1432 + }
1.1433 + }
1.1434 + in.close();
1.1435 + } // end ClassData.read()
1.1436 +
1.1437 + /**
1.1438 + * Reads and stores constant pool info.
1.1439 + */
1.1440 + void readCP(DataInputStream in) throws IOException {
1.1441 + cpool_count = in.readUnsignedShort();
1.1442 + tags = new byte[cpool_count];
1.1443 + cpool = new Object[cpool_count];
1.1444 + for (int i = 1; i < cpool_count; i++) {
1.1445 + byte tag = in.readByte();
1.1446 +
1.1447 + switch (tags[i] = tag) {
1.1448 + case CONSTANT_UTF8:
1.1449 + String str = in.readUTF();
1.1450 + indexHashAscii.put(cpool[i] = str, new Integer(i));
1.1451 + break;
1.1452 + case CONSTANT_INTEGER:
1.1453 + cpool[i] = new Integer(in.readInt());
1.1454 + break;
1.1455 + case CONSTANT_FLOAT:
1.1456 + cpool[i] = new Float(in.readFloat());
1.1457 + break;
1.1458 + case CONSTANT_LONG:
1.1459 + cpool[i++] = new Long(in.readLong());
1.1460 + break;
1.1461 + case CONSTANT_DOUBLE:
1.1462 + cpool[i++] = new Double(in.readDouble());
1.1463 + break;
1.1464 + case CONSTANT_CLASS:
1.1465 + case CONSTANT_STRING:
1.1466 + cpool[i] = new CPX(in.readUnsignedShort());
1.1467 + break;
1.1468 +
1.1469 + case CONSTANT_FIELD:
1.1470 + case CONSTANT_METHOD:
1.1471 + case CONSTANT_INTERFACEMETHOD:
1.1472 + case CONSTANT_NAMEANDTYPE:
1.1473 + cpool[i] = new CPX2(in.readUnsignedShort(), in.readUnsignedShort());
1.1474 + break;
1.1475 +
1.1476 + case 0:
1.1477 + default:
1.1478 + throw new ClassFormatError("invalid constant type: " + (int) tags[i]);
1.1479 + }
1.1480 + }
1.1481 + }
1.1482 +
1.1483 + /**
1.1484 + * Reads and strores field info.
1.1485 + */
1.1486 + protected void readFields(DataInputStream in) throws IOException {
1.1487 + int fields_count = in.readUnsignedShort();
1.1488 + fields = new FieldData[fields_count];
1.1489 + for (int k = 0; k < fields_count; k++) {
1.1490 + FieldData field = new FieldData(this);
1.1491 + field.read(in);
1.1492 + fields[k] = field;
1.1493 + }
1.1494 + }
1.1495 +
1.1496 + /**
1.1497 + * Reads and strores Method info.
1.1498 + */
1.1499 + protected void readMethods(DataInputStream in) throws IOException {
1.1500 + int methods_count = in.readUnsignedShort();
1.1501 + methods = new MethodData[methods_count];
1.1502 + for (int k = 0; k < methods_count; k++) {
1.1503 + MethodData method = new MethodData(this);
1.1504 + method.read(in);
1.1505 + methods[k] = method;
1.1506 + }
1.1507 + }
1.1508 +
1.1509 + /**
1.1510 + * get a string
1.1511 + */
1.1512 + public String getString(int n) {
1.1513 + if (n == 0) {
1.1514 + return null;
1.1515 + } else {
1.1516 + return (String) cpool[n];
1.1517 + }
1.1518 + }
1.1519 +
1.1520 + /**
1.1521 + * get the type of constant given an index
1.1522 + */
1.1523 + public byte getTag(int n) {
1.1524 + try {
1.1525 + return tags[n];
1.1526 + } catch (ArrayIndexOutOfBoundsException e) {
1.1527 + return (byte) 100;
1.1528 + }
1.1529 + }
1.1530 + static final String hexString = "0123456789ABCDEF";
1.1531 + public static char hexTable[] = hexString.toCharArray();
1.1532 +
1.1533 + static String toHex(long val, int width) {
1.1534 + StringBuffer s = new StringBuffer();
1.1535 + for (int i = width - 1; i >= 0; i--) {
1.1536 + s.append(hexTable[((int) (val >> (4 * i))) & 0xF]);
1.1537 + }
1.1538 + return "0x" + s.toString();
1.1539 + }
1.1540 +
1.1541 + static String toHex(long val) {
1.1542 + int width;
1.1543 + for (width = 16; width > 0; width--) {
1.1544 + if ((val >> (width - 1) * 4) != 0) {
1.1545 + break;
1.1546 + }
1.1547 + }
1.1548 + return toHex(val, width);
1.1549 + }
1.1550 +
1.1551 + static String toHex(int val) {
1.1552 + int width;
1.1553 + for (width = 8; width > 0; width--) {
1.1554 + if ((val >> (width - 1) * 4) != 0) {
1.1555 + break;
1.1556 + }
1.1557 + }
1.1558 + return toHex(val, width);
1.1559 + }
1.1560 +
1.1561 + /**
1.1562 + * Returns the name of this class.
1.1563 + */
1.1564 + public String getClassName() {
1.1565 + String res = null;
1.1566 + if (this_class == 0) {
1.1567 + return res;
1.1568 + }
1.1569 + int tcpx;
1.1570 + try {
1.1571 + if (tags[this_class] != CONSTANT_CLASS) {
1.1572 + return res; //"<CP["+cpx+"] is not a Class> ";
1.1573 + }
1.1574 + tcpx = ((CPX) cpool[this_class]).cpx;
1.1575 + } catch (ArrayIndexOutOfBoundsException e) {
1.1576 + return res; // "#"+cpx+"// invalid constant pool index";
1.1577 + } catch (Throwable e) {
1.1578 + return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
1.1579 + }
1.1580 +
1.1581 + try {
1.1582 + return (String) (cpool[tcpx]);
1.1583 + } catch (ArrayIndexOutOfBoundsException e) {
1.1584 + return res; // "class #"+scpx+"// invalid constant pool index";
1.1585 + } catch (ClassCastException e) {
1.1586 + return res; // "class #"+scpx+"// invalid constant pool reference";
1.1587 + } catch (Throwable e) {
1.1588 + return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
1.1589 + }
1.1590 +
1.1591 + }
1.1592 +
1.1593 + /**
1.1594 + * Returns the name of class at perticular index.
1.1595 + */
1.1596 + public String getClassName(int cpx) {
1.1597 + String res = "#" + cpx;
1.1598 + if (cpx == 0) {
1.1599 + return res;
1.1600 + }
1.1601 + int scpx;
1.1602 + try {
1.1603 + if (tags[cpx] != CONSTANT_CLASS) {
1.1604 + return res; //"<CP["+cpx+"] is not a Class> ";
1.1605 + }
1.1606 + scpx = ((CPX) cpool[cpx]).cpx;
1.1607 + } catch (ArrayIndexOutOfBoundsException e) {
1.1608 + return res; // "#"+cpx+"// invalid constant pool index";
1.1609 + } catch (Throwable e) {
1.1610 + return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
1.1611 + }
1.1612 + res = "#" + scpx;
1.1613 + try {
1.1614 + return (String) (cpool[scpx]);
1.1615 + } catch (ArrayIndexOutOfBoundsException e) {
1.1616 + return res; // "class #"+scpx+"// invalid constant pool index";
1.1617 + } catch (ClassCastException e) {
1.1618 + return res; // "class #"+scpx+"// invalid constant pool reference";
1.1619 + } catch (Throwable e) {
1.1620 + return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
1.1621 + }
1.1622 + }
1.1623 +
1.1624 + public int getAccessFlags() {
1.1625 + return access;
1.1626 + }
1.1627 +
1.1628 + /**
1.1629 + * Returns true if it is a class
1.1630 + */
1.1631 + public boolean isClass() {
1.1632 + if ((access & ACC_INTERFACE) == 0) {
1.1633 + return true;
1.1634 + }
1.1635 + return false;
1.1636 + }
1.1637 +
1.1638 + /**
1.1639 + * Returns true if it is a interface.
1.1640 + */
1.1641 + public boolean isInterface() {
1.1642 + if ((access & ACC_INTERFACE) != 0) {
1.1643 + return true;
1.1644 + }
1.1645 + return false;
1.1646 + }
1.1647 +
1.1648 + /**
1.1649 + * Returns true if this member is public, false otherwise.
1.1650 + */
1.1651 + public boolean isPublic() {
1.1652 + return (access & ACC_PUBLIC) != 0;
1.1653 + }
1.1654 +
1.1655 + /**
1.1656 + * Returns the access of this class or interface.
1.1657 + */
1.1658 + public String[] getAccess() {
1.1659 + Vector v = new Vector();
1.1660 + if ((access & ACC_PUBLIC) != 0) {
1.1661 + v.addElement("public");
1.1662 + }
1.1663 + if ((access & ACC_FINAL) != 0) {
1.1664 + v.addElement("final");
1.1665 + }
1.1666 + if ((access & ACC_ABSTRACT) != 0) {
1.1667 + v.addElement("abstract");
1.1668 + }
1.1669 + String[] accflags = new String[v.size()];
1.1670 + v.copyInto(accflags);
1.1671 + return accflags;
1.1672 + }
1.1673 +
1.1674 + /**
1.1675 + * Returns list of innerclasses.
1.1676 + */
1.1677 + public InnerClassData[] getInnerClasses() {
1.1678 + return innerClasses;
1.1679 + }
1.1680 +
1.1681 + /**
1.1682 + * Returns list of attributes.
1.1683 + */
1.1684 + final AttrData[] getAttributes() {
1.1685 + return attrs;
1.1686 + }
1.1687 +
1.1688 + public byte[] findAnnotationData(boolean classRetention) {
1.1689 + String n = classRetention
1.1690 + ? "RuntimeInvisibleAnnotations" : // NOI18N
1.1691 + "RuntimeVisibleAnnotations"; // NOI18N
1.1692 + return findAttr(n, attrs);
1.1693 + }
1.1694 +
1.1695 + /**
1.1696 + * Returns true if superbit is set.
1.1697 + */
1.1698 + public boolean isSuperSet() {
1.1699 + if ((access & ACC_SUPER) != 0) {
1.1700 + return true;
1.1701 + }
1.1702 + return false;
1.1703 + }
1.1704 +
1.1705 + /**
1.1706 + * Returns super class name.
1.1707 + */
1.1708 + public String getSuperClassName() {
1.1709 + String res = null;
1.1710 + if (super_class == 0) {
1.1711 + return res;
1.1712 + }
1.1713 + int scpx;
1.1714 + try {
1.1715 + if (tags[super_class] != CONSTANT_CLASS) {
1.1716 + return res; //"<CP["+cpx+"] is not a Class> ";
1.1717 + }
1.1718 + scpx = ((CPX) cpool[super_class]).cpx;
1.1719 + } catch (ArrayIndexOutOfBoundsException e) {
1.1720 + return res; // "#"+cpx+"// invalid constant pool index";
1.1721 + } catch (Throwable e) {
1.1722 + return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
1.1723 + }
1.1724 +
1.1725 + try {
1.1726 + return (String) (cpool[scpx]);
1.1727 + } catch (ArrayIndexOutOfBoundsException e) {
1.1728 + return res; // "class #"+scpx+"// invalid constant pool index";
1.1729 + } catch (ClassCastException e) {
1.1730 + return res; // "class #"+scpx+"// invalid constant pool reference";
1.1731 + } catch (Throwable e) {
1.1732 + return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
1.1733 + }
1.1734 + }
1.1735 +
1.1736 + /**
1.1737 + * Returns list of super interfaces.
1.1738 + */
1.1739 + public String[] getSuperInterfaces() {
1.1740 + String interfacenames[] = new String[interfaces.length];
1.1741 + int interfacecpx = -1;
1.1742 + for (int i = 0; i < interfaces.length; i++) {
1.1743 + interfacecpx = ((CPX) cpool[interfaces[i]]).cpx;
1.1744 + interfacenames[i] = (String) (cpool[interfacecpx]);
1.1745 + }
1.1746 + return interfacenames;
1.1747 + }
1.1748 +
1.1749 + /**
1.1750 + * Returns string at prticular constant pool index.
1.1751 + */
1.1752 + public String getStringValue(int cpoolx) {
1.1753 + try {
1.1754 + return ((String) cpool[cpoolx]);
1.1755 + } catch (ArrayIndexOutOfBoundsException e) {
1.1756 + return "//invalid constant pool index:" + cpoolx;
1.1757 + } catch (ClassCastException e) {
1.1758 + return "//invalid constant pool ref:" + cpoolx;
1.1759 + }
1.1760 + }
1.1761 +
1.1762 + /**
1.1763 + * Returns list of field info.
1.1764 + */
1.1765 + public FieldData[] getFields() {
1.1766 + return fields;
1.1767 + }
1.1768 +
1.1769 + /**
1.1770 + * Returns list of method info.
1.1771 + */
1.1772 + public MethodData[] getMethods() {
1.1773 + return methods;
1.1774 + }
1.1775 +
1.1776 + /**
1.1777 + * Returns constant pool entry at that index.
1.1778 + */
1.1779 + public CPX2 getCpoolEntry(int cpx) {
1.1780 + return ((CPX2) (cpool[cpx]));
1.1781 + }
1.1782 +
1.1783 + public Object getCpoolEntryobj(int cpx) {
1.1784 + return (cpool[cpx]);
1.1785 + }
1.1786 +
1.1787 + /**
1.1788 + * Returns index of this class.
1.1789 + */
1.1790 + public int getthis_cpx() {
1.1791 + return this_class;
1.1792 + }
1.1793 +
1.1794 + /**
1.1795 + * Returns string at that index.
1.1796 + */
1.1797 + public String StringValue(int cpx) {
1.1798 + return stringValue(cpx, false);
1.1799 + }
1.1800 +
1.1801 + public String stringValue(int cpx, boolean textual) {
1.1802 + return stringValue(cpx, textual, null);
1.1803 + }
1.1804 +
1.1805 + public String stringValue(int cpx, String[] classRefs) {
1.1806 + return stringValue(cpx, true, classRefs);
1.1807 + }
1.1808 +
1.1809 + private String stringValue(int cpx, boolean textual, String[] refs) {
1.1810 + if (cpx == 0) {
1.1811 + return "#0";
1.1812 + }
1.1813 + int tag;
1.1814 + Object x;
1.1815 + String suffix = "";
1.1816 + try {
1.1817 + tag = tags[cpx];
1.1818 + x = cpool[cpx];
1.1819 + } catch (IndexOutOfBoundsException e) {
1.1820 + return "<Incorrect CP index:" + cpx + ">";
1.1821 + }
1.1822 +
1.1823 + if (x == null) {
1.1824 + return "<NULL>";
1.1825 + }
1.1826 + switch (tag) {
1.1827 + case CONSTANT_UTF8: {
1.1828 + if (!textual) {
1.1829 + return (String) x;
1.1830 + }
1.1831 + StringBuilder sb = new StringBuilder();
1.1832 + String s = (String) x;
1.1833 + for (int k = 0; k < s.length(); k++) {
1.1834 + char c = s.charAt(k);
1.1835 + switch (c) {
1.1836 + case '\\':
1.1837 + sb.append('\\').append('\\');
1.1838 + break;
1.1839 + case '\t':
1.1840 + sb.append('\\').append('t');
1.1841 + break;
1.1842 + case '\n':
1.1843 + sb.append('\\').append('n');
1.1844 + break;
1.1845 + case '\r':
1.1846 + sb.append('\\').append('r');
1.1847 + break;
1.1848 + case '\"':
1.1849 + sb.append('\\').append('\"');
1.1850 + break;
1.1851 + default:
1.1852 + sb.append(c);
1.1853 + }
1.1854 + }
1.1855 + return sb.toString();
1.1856 + }
1.1857 + case CONSTANT_DOUBLE: {
1.1858 + Double d = (Double) x;
1.1859 + String sd = d.toString();
1.1860 + if (textual) {
1.1861 + return sd;
1.1862 + }
1.1863 + return sd + "d";
1.1864 + }
1.1865 + case CONSTANT_FLOAT: {
1.1866 + Float f = (Float) x;
1.1867 + String sf = (f).toString();
1.1868 + if (textual) {
1.1869 + return sf;
1.1870 + }
1.1871 + return sf + "f";
1.1872 + }
1.1873 + case CONSTANT_LONG: {
1.1874 + Long ln = (Long) x;
1.1875 + if (textual) {
1.1876 + return ln.toString();
1.1877 + }
1.1878 + return ln.toString() + 'l';
1.1879 + }
1.1880 + case CONSTANT_INTEGER: {
1.1881 + Integer in = (Integer) x;
1.1882 + return in.toString();
1.1883 + }
1.1884 + case CONSTANT_CLASS:
1.1885 + String jn = getClassName(cpx);
1.1886 + if (textual) {
1.1887 + if (refs != null) {
1.1888 + refs[0] = jn;
1.1889 + }
1.1890 + return jn;
1.1891 + }
1.1892 + return javaName(jn);
1.1893 + case CONSTANT_STRING:
1.1894 + String sv = stringValue(((CPX) x).cpx, textual);
1.1895 + if (textual) {
1.1896 + return '"' + sv + '"';
1.1897 + } else {
1.1898 + return sv;
1.1899 + }
1.1900 + case CONSTANT_FIELD:
1.1901 + case CONSTANT_METHOD:
1.1902 + case CONSTANT_INTERFACEMETHOD:
1.1903 + //return getShortClassName(((CPX2)x).cpx1)+"."+StringValue(((CPX2)x).cpx2);
1.1904 + return javaName(getClassName(((CPX2) x).cpx1)) + "." + StringValue(((CPX2) x).cpx2);
1.1905 +
1.1906 + case CONSTANT_NAMEANDTYPE:
1.1907 + return getName(((CPX2) x).cpx1) + ":" + StringValue(((CPX2) x).cpx2);
1.1908 + default:
1.1909 + return "UnknownTag"; //TBD
1.1910 + }
1.1911 + }
1.1912 +
1.1913 + /**
1.1914 + * Returns resolved java type name.
1.1915 + */
1.1916 + public String javaName(String name) {
1.1917 + if (name == null) {
1.1918 + return "null";
1.1919 + }
1.1920 + int len = name.length();
1.1921 + if (len == 0) {
1.1922 + return "\"\"";
1.1923 + }
1.1924 + int cc = '/';
1.1925 + fullname:
1.1926 + { // xxx/yyy/zzz
1.1927 + int cp;
1.1928 + for (int k = 0; k < len; k += Character.charCount(cp)) {
1.1929 + cp = name.codePointAt(k);
1.1930 + if (cc == '/') {
1.1931 + if (!isJavaIdentifierStart(cp)) {
1.1932 + break fullname;
1.1933 + }
1.1934 + } else if (cp != '/') {
1.1935 + if (!isJavaIdentifierPart(cp)) {
1.1936 + break fullname;
1.1937 + }
1.1938 + }
1.1939 + cc = cp;
1.1940 + }
1.1941 + return name;
1.1942 + }
1.1943 + return "\"" + name + "\"";
1.1944 + }
1.1945 +
1.1946 + public String getName(int cpx) {
1.1947 + String res;
1.1948 + try {
1.1949 + return javaName((String) cpool[cpx]); //.replace('/','.');
1.1950 + } catch (ArrayIndexOutOfBoundsException e) {
1.1951 + return "<invalid constant pool index:" + cpx + ">";
1.1952 + } catch (ClassCastException e) {
1.1953 + return "<invalid constant pool ref:" + cpx + ">";
1.1954 + }
1.1955 + }
1.1956 +
1.1957 + /**
1.1958 + * Returns unqualified class name.
1.1959 + */
1.1960 + public String getShortClassName(int cpx) {
1.1961 + String classname = javaName(getClassName(cpx));
1.1962 + pkgPrefixLen = classname.lastIndexOf("/") + 1;
1.1963 + if (pkgPrefixLen != 0) {
1.1964 + pkgPrefix = classname.substring(0, pkgPrefixLen);
1.1965 + if (classname.startsWith(pkgPrefix)) {
1.1966 + return classname.substring(pkgPrefixLen);
1.1967 + }
1.1968 + }
1.1969 + return classname;
1.1970 + }
1.1971 +
1.1972 + /**
1.1973 + * Returns source file name.
1.1974 + */
1.1975 + public String getSourceName() {
1.1976 + return getName(source_cpx);
1.1977 + }
1.1978 +
1.1979 + /**
1.1980 + * Returns package name.
1.1981 + */
1.1982 + public String getPkgName() {
1.1983 + String classname = getClassName(this_class);
1.1984 + pkgPrefixLen = classname.lastIndexOf("/") + 1;
1.1985 + if (pkgPrefixLen != 0) {
1.1986 + pkgPrefix = classname.substring(0, pkgPrefixLen);
1.1987 + return ("package " + pkgPrefix.substring(0, pkgPrefixLen - 1) + ";\n");
1.1988 + } else {
1.1989 + return null;
1.1990 + }
1.1991 + }
1.1992 +
1.1993 + /**
1.1994 + * Returns total constant pool entry count.
1.1995 + */
1.1996 + public int getCpoolCount() {
1.1997 + return cpool_count;
1.1998 + }
1.1999 +
1.2000 + /**
1.2001 + * Returns minor version of class file.
1.2002 + */
1.2003 + public int getMinor_version() {
1.2004 + return minor_version;
1.2005 + }
1.2006 +
1.2007 + /**
1.2008 + * Returns major version of class file.
1.2009 + */
1.2010 + public int getMajor_version() {
1.2011 + return major_version;
1.2012 + }
1.2013 +
1.2014 + private boolean isJavaIdentifierStart(int cp) {
1.2015 + return ('a' <= cp && cp <= 'z') || ('A' <= cp && cp <= 'Z');
1.2016 + }
1.2017 +
1.2018 + private boolean isJavaIdentifierPart(int cp) {
1.2019 + return isJavaIdentifierStart(cp) || ('0' <= cp && cp <= '9');
1.2020 + }
1.2021 +
1.2022 + public String[] getNameAndType(int indx) {
1.2023 + return getNameAndType(indx, 0, new String[2]);
1.2024 + }
1.2025 +
1.2026 + private String[] getNameAndType(int indx, int at, String[] arr) {
1.2027 + CPX2 c2 = getCpoolEntry(indx);
1.2028 + arr[at] = StringValue(c2.cpx1);
1.2029 + arr[at + 1] = StringValue(c2.cpx2);
1.2030 + return arr;
1.2031 + }
1.2032 +
1.2033 + public String[] getFieldInfoName(int indx) {
1.2034 + CPX2 c2 = getCpoolEntry(indx);
1.2035 + String[] arr = new String[3];
1.2036 + arr[0] = getClassName(c2.cpx1);
1.2037 + return getNameAndType(c2.cpx2, 1, arr);
1.2038 + }
1.2039 +
1.2040 + static byte[] findAttr(String n, AttrData[] attrs) {
1.2041 + for (AttrData ad : attrs) {
1.2042 + if (n.equals(ad.getAttrName())) {
1.2043 + return ad.getData();
1.2044 + }
1.2045 + }
1.2046 + return null;
1.2047 + }
1.2048 + }
1.2049 +
1.2050 + /**
1.2051 + * Strores field data informastion.
1.2052 + *
1.2053 + * @author Sucheta Dambalkar (Adopted code from jdis)
1.2054 + */
1.2055 + static class FieldData {
1.2056 +
1.2057 + ClassData cls;
1.2058 + int access;
1.2059 + int name_index;
1.2060 + int descriptor_index;
1.2061 + int attributes_count;
1.2062 + int value_cpx = 0;
1.2063 + boolean isSynthetic = false;
1.2064 + boolean isDeprecated = false;
1.2065 + Vector attrs;
1.2066 +
1.2067 + public FieldData(ClassData cls) {
1.2068 + this.cls = cls;
1.2069 + }
1.2070 +
1.2071 + /**
1.2072 + * Read and store field info.
1.2073 + */
1.2074 + public void read(DataInputStream in) throws IOException {
1.2075 + access = in.readUnsignedShort();
1.2076 + name_index = in.readUnsignedShort();
1.2077 + descriptor_index = in.readUnsignedShort();
1.2078 + // Read the attributes
1.2079 + int attributes_count = in.readUnsignedShort();
1.2080 + attrs = new Vector(attributes_count);
1.2081 + for (int i = 0; i < attributes_count; i++) {
1.2082 + int attr_name_index = in.readUnsignedShort();
1.2083 + if (cls.getTag(attr_name_index) != CONSTANT_UTF8) {
1.2084 + continue;
1.2085 + }
1.2086 + String attr_name = cls.getString(attr_name_index);
1.2087 + if (attr_name.equals("ConstantValue")) {
1.2088 + if (in.readInt() != 2) {
1.2089 + throw new ClassFormatError("invalid ConstantValue attr length");
1.2090 + }
1.2091 + value_cpx = in.readUnsignedShort();
1.2092 + AttrData attr = new AttrData(cls);
1.2093 + attr.read(attr_name_index);
1.2094 + attrs.addElement(attr);
1.2095 + } else if (attr_name.equals("Synthetic")) {
1.2096 + if (in.readInt() != 0) {
1.2097 + throw new ClassFormatError("invalid Synthetic attr length");
1.2098 + }
1.2099 + isSynthetic = true;
1.2100 + AttrData attr = new AttrData(cls);
1.2101 + attr.read(attr_name_index);
1.2102 + attrs.addElement(attr);
1.2103 + } else if (attr_name.equals("Deprecated")) {
1.2104 + if (in.readInt() != 0) {
1.2105 + throw new ClassFormatError("invalid Synthetic attr length");
1.2106 + }
1.2107 + isDeprecated = true;
1.2108 + AttrData attr = new AttrData(cls);
1.2109 + attr.read(attr_name_index);
1.2110 + attrs.addElement(attr);
1.2111 + } else {
1.2112 + AttrData attr = new AttrData(cls);
1.2113 + attr.read(attr_name_index, in);
1.2114 + attrs.addElement(attr);
1.2115 + }
1.2116 + }
1.2117 +
1.2118 + } // end read
1.2119 +
1.2120 + public boolean isStatic() {
1.2121 + return (access & ACC_STATIC) != 0;
1.2122 + }
1.2123 +
1.2124 + /**
1.2125 + * Returns access of a field.
1.2126 + */
1.2127 + public String[] getAccess() {
1.2128 + Vector v = new Vector();
1.2129 + if ((access & ACC_PUBLIC) != 0) {
1.2130 + v.addElement("public");
1.2131 + }
1.2132 + if ((access & ACC_PRIVATE) != 0) {
1.2133 + v.addElement("private");
1.2134 + }
1.2135 + if ((access & ACC_PROTECTED) != 0) {
1.2136 + v.addElement("protected");
1.2137 + }
1.2138 + if ((access & ACC_STATIC) != 0) {
1.2139 + v.addElement("static");
1.2140 + }
1.2141 + if ((access & ACC_FINAL) != 0) {
1.2142 + v.addElement("final");
1.2143 + }
1.2144 + if ((access & ACC_VOLATILE) != 0) {
1.2145 + v.addElement("volatile");
1.2146 + }
1.2147 + if ((access & ACC_TRANSIENT) != 0) {
1.2148 + v.addElement("transient");
1.2149 + }
1.2150 + String[] accflags = new String[v.size()];
1.2151 + v.copyInto(accflags);
1.2152 + return accflags;
1.2153 + }
1.2154 +
1.2155 + /**
1.2156 + * Returns name of a field.
1.2157 + */
1.2158 + public String getName() {
1.2159 + return cls.getStringValue(name_index);
1.2160 + }
1.2161 +
1.2162 + /**
1.2163 + * Returns internal signature of a field
1.2164 + */
1.2165 + public String getInternalSig() {
1.2166 + return cls.getStringValue(descriptor_index);
1.2167 + }
1.2168 +
1.2169 + /**
1.2170 + * Returns true if field is synthetic.
1.2171 + */
1.2172 + public boolean isSynthetic() {
1.2173 + return isSynthetic;
1.2174 + }
1.2175 +
1.2176 + /**
1.2177 + * Returns true if field is deprecated.
1.2178 + */
1.2179 + public boolean isDeprecated() {
1.2180 + return isDeprecated;
1.2181 + }
1.2182 +
1.2183 + /**
1.2184 + * Returns index of constant value in cpool.
1.2185 + */
1.2186 + public int getConstantValueIndex() {
1.2187 + return (value_cpx);
1.2188 + }
1.2189 +
1.2190 + /**
1.2191 + * Returns list of attributes of field.
1.2192 + */
1.2193 + public Vector getAttributes() {
1.2194 + return attrs;
1.2195 + }
1.2196 +
1.2197 + public byte[] findAnnotationData(boolean classRetention) {
1.2198 + String n = classRetention
1.2199 + ? "RuntimeInvisibleAnnotations" : // NOI18N
1.2200 + "RuntimeVisibleAnnotations"; // NOI18N
1.2201 + AttrData[] arr = new AttrData[attrs.size()];
1.2202 + attrs.copyInto(arr);
1.2203 + return ClassData.findAttr(n, arr);
1.2204 + }
1.2205 + }
1.2206 +
1.2207 + /**
1.2208 + * A JavaScript optimized replacement for Hashtable.
1.2209 + *
1.2210 + * @author Jaroslav Tulach <jtulach@netbeans.org>
1.2211 + */
1.2212 + private static final class Hashtable {
1.2213 +
1.2214 + private Object[] keys;
1.2215 + private Object[] values;
1.2216 +
1.2217 + Hashtable(int i) {
1.2218 + this();
1.2219 + }
1.2220 +
1.2221 + Hashtable(int i, double d) {
1.2222 + this();
1.2223 + }
1.2224 +
1.2225 + Hashtable() {
1.2226 + }
1.2227 +
1.2228 + synchronized void put(Object key, Object val) {
1.2229 + int[] where = {-1, -1};
1.2230 + Object found = get(key, where);
1.2231 + if (where[0] != -1) {
1.2232 + // key exists
1.2233 + values[where[0]] = val;
1.2234 + } else {
1.2235 + if (where[1] != -1) {
1.2236 + // null found
1.2237 + keys[where[1]] = key;
1.2238 + values[where[1]] = val;
1.2239 + } else {
1.2240 + if (keys == null) {
1.2241 + keys = new Object[11];
1.2242 + values = new Object[11];
1.2243 + keys[0] = key;
1.2244 + values[0] = val;
1.2245 + } else {
1.2246 + Object[] newKeys = new Object[keys.length * 2];
1.2247 + Object[] newValues = new Object[values.length * 2];
1.2248 + for (int i = 0; i < keys.length; i++) {
1.2249 + newKeys[i] = keys[i];
1.2250 + newValues[i] = values[i];
1.2251 + }
1.2252 + newKeys[keys.length] = key;
1.2253 + newValues[keys.length] = val;
1.2254 + keys = newKeys;
1.2255 + values = newValues;
1.2256 + }
1.2257 + }
1.2258 + }
1.2259 + }
1.2260 +
1.2261 + Object get(Object key) {
1.2262 + return get(key, null);
1.2263 + }
1.2264 +
1.2265 + private synchronized Object get(Object key, int[] foundAndNull) {
1.2266 + if (keys == null) {
1.2267 + return null;
1.2268 + }
1.2269 + for (int i = 0; i < keys.length; i++) {
1.2270 + if (keys[i] == null) {
1.2271 + if (foundAndNull != null) {
1.2272 + foundAndNull[1] = i;
1.2273 + }
1.2274 + } else if (keys[i].equals(key)) {
1.2275 + if (foundAndNull != null) {
1.2276 + foundAndNull[0] = i;
1.2277 + }
1.2278 + return values[i];
1.2279 + }
1.2280 + }
1.2281 + return null;
1.2282 + }
1.2283 + }
1.2284 +
1.2285 + /**
1.2286 + * Strores InnerClass data informastion.
1.2287 + *
1.2288 + * @author Sucheta Dambalkar (Adopted code from jdis)
1.2289 + */
1.2290 + private static class InnerClassData {
1.2291 +
1.2292 + ClassData cls;
1.2293 + int inner_class_info_index, outer_class_info_index, inner_name_index, access;
1.2294 +
1.2295 + public InnerClassData(ClassData cls) {
1.2296 + this.cls = cls;
1.2297 +
1.2298 + }
1.2299 +
1.2300 + /**
1.2301 + * Read Innerclass attribute data.
1.2302 + */
1.2303 + public void read(DataInputStream in) throws IOException {
1.2304 + inner_class_info_index = in.readUnsignedShort();
1.2305 + outer_class_info_index = in.readUnsignedShort();
1.2306 + inner_name_index = in.readUnsignedShort();
1.2307 + access = in.readUnsignedShort();
1.2308 + } // end read
1.2309 +
1.2310 + /**
1.2311 + * Returns the access of this class or interface.
1.2312 + */
1.2313 + public String[] getAccess() {
1.2314 + Vector v = new Vector();
1.2315 + if ((access & ACC_PUBLIC) != 0) {
1.2316 + v.addElement("public");
1.2317 + }
1.2318 + if ((access & ACC_FINAL) != 0) {
1.2319 + v.addElement("final");
1.2320 + }
1.2321 + if ((access & ACC_ABSTRACT) != 0) {
1.2322 + v.addElement("abstract");
1.2323 + }
1.2324 + String[] accflags = new String[v.size()];
1.2325 + v.copyInto(accflags);
1.2326 + return accflags;
1.2327 + }
1.2328 + } // end InnerClassData
1.2329 +
1.2330 + /**
1.2331 + * Strores LineNumberTable data information.
1.2332 + *
1.2333 + * @author Sucheta Dambalkar (Adopted code from jdis)
1.2334 + */
1.2335 + private static class LineNumData {
1.2336 +
1.2337 + short start_pc, line_number;
1.2338 +
1.2339 + public LineNumData() {
1.2340 + }
1.2341 +
1.2342 + /**
1.2343 + * Read LineNumberTable attribute.
1.2344 + */
1.2345 + public LineNumData(DataInputStream in) throws IOException {
1.2346 + start_pc = in.readShort();
1.2347 + line_number = in.readShort();
1.2348 +
1.2349 + }
1.2350 + }
1.2351 +
1.2352 + /**
1.2353 + * Strores LocalVariableTable data information.
1.2354 + *
1.2355 + * @author Sucheta Dambalkar (Adopted code from jdis)
1.2356 + */
1.2357 + private static class LocVarData {
1.2358 +
1.2359 + short start_pc, length, name_cpx, sig_cpx, slot;
1.2360 +
1.2361 + public LocVarData() {
1.2362 + }
1.2363 +
1.2364 + /**
1.2365 + * Read LocalVariableTable attribute.
1.2366 + */
1.2367 + public LocVarData(DataInputStream in) throws IOException {
1.2368 + start_pc = in.readShort();
1.2369 + length = in.readShort();
1.2370 + name_cpx = in.readShort();
1.2371 + sig_cpx = in.readShort();
1.2372 + slot = in.readShort();
1.2373 +
1.2374 + }
1.2375 + }
1.2376 + /**
1.2377 + * Strores method data informastion.
1.2378 + *
1.2379 + * @author Sucheta Dambalkar (Adopted code from jdis)
1.2380 + */
1.2381 + static class MethodData {
1.2382 +
1.2383 + ClassData cls;
1.2384 + int access;
1.2385 + int name_index;
1.2386 + int descriptor_index;
1.2387 + int attributes_count;
1.2388 + byte[] code;
1.2389 + Vector exception_table = new Vector(0);
1.2390 + Vector lin_num_tb = new Vector(0);
1.2391 + Vector loc_var_tb = new Vector(0);
1.2392 + StackMapTableData[] stackMapTable;
1.2393 + StackMapData[] stackMap;
1.2394 + int[] exc_index_table = null;
1.2395 + Vector attrs = new Vector(0);
1.2396 + Vector code_attrs = new Vector(0);
1.2397 + int max_stack, max_locals;
1.2398 + boolean isSynthetic = false;
1.2399 + boolean isDeprecated = false;
1.2400 +
1.2401 + public MethodData(ClassData cls) {
1.2402 + this.cls = cls;
1.2403 + }
1.2404 +
1.2405 + /**
1.2406 + * Read method info.
1.2407 + */
1.2408 + public void read(DataInputStream in) throws IOException {
1.2409 + access = in.readUnsignedShort();
1.2410 + name_index = in.readUnsignedShort();
1.2411 + descriptor_index = in.readUnsignedShort();
1.2412 + int attributes_count = in.readUnsignedShort();
1.2413 + for (int i = 0; i < attributes_count; i++) {
1.2414 + int attr_name_index = in.readUnsignedShort();
1.2415 +
1.2416 + readAttr:
1.2417 + {
1.2418 + if (cls.getTag(attr_name_index) == CONSTANT_UTF8) {
1.2419 + String attr_name = cls.getString(attr_name_index);
1.2420 + if (attr_name.equals("Code")) {
1.2421 + readCode(in);
1.2422 + AttrData attr = new AttrData(cls);
1.2423 + attr.read(attr_name_index);
1.2424 + attrs.addElement(attr);
1.2425 + break readAttr;
1.2426 + } else if (attr_name.equals("Exceptions")) {
1.2427 + readExceptions(in);
1.2428 + AttrData attr = new AttrData(cls);
1.2429 + attr.read(attr_name_index);
1.2430 + attrs.addElement(attr);
1.2431 + break readAttr;
1.2432 + } else if (attr_name.equals("Synthetic")) {
1.2433 + if (in.readInt() != 0) {
1.2434 + throw new ClassFormatError("invalid Synthetic attr length");
1.2435 + }
1.2436 + isSynthetic = true;
1.2437 + AttrData attr = new AttrData(cls);
1.2438 + attr.read(attr_name_index);
1.2439 + attrs.addElement(attr);
1.2440 + break readAttr;
1.2441 + } else if (attr_name.equals("Deprecated")) {
1.2442 + if (in.readInt() != 0) {
1.2443 + throw new ClassFormatError("invalid Synthetic attr length");
1.2444 + }
1.2445 + isDeprecated = true;
1.2446 + AttrData attr = new AttrData(cls);
1.2447 + attr.read(attr_name_index);
1.2448 + attrs.addElement(attr);
1.2449 + break readAttr;
1.2450 + }
1.2451 + }
1.2452 + AttrData attr = new AttrData(cls);
1.2453 + attr.read(attr_name_index, in);
1.2454 + attrs.addElement(attr);
1.2455 + }
1.2456 + }
1.2457 + }
1.2458 +
1.2459 + /**
1.2460 + * Read code attribute info.
1.2461 + */
1.2462 + public void readCode(DataInputStream in) throws IOException {
1.2463 +
1.2464 + int attr_length = in.readInt();
1.2465 + max_stack = in.readUnsignedShort();
1.2466 + max_locals = in.readUnsignedShort();
1.2467 + int codelen = in.readInt();
1.2468 +
1.2469 + code = new byte[codelen];
1.2470 + int totalread = 0;
1.2471 + while (totalread < codelen) {
1.2472 + totalread += in.read(code, totalread, codelen - totalread);
1.2473 + }
1.2474 + // in.read(code, 0, codelen);
1.2475 + int clen = 0;
1.2476 + readExceptionTable(in);
1.2477 + int code_attributes_count = in.readUnsignedShort();
1.2478 +
1.2479 + for (int k = 0; k < code_attributes_count; k++) {
1.2480 + int table_name_index = in.readUnsignedShort();
1.2481 + int table_name_tag = cls.getTag(table_name_index);
1.2482 + AttrData attr = new AttrData(cls);
1.2483 + if (table_name_tag == CONSTANT_UTF8) {
1.2484 + String table_name_tstr = cls.getString(table_name_index);
1.2485 + if (table_name_tstr.equals("LineNumberTable")) {
1.2486 + readLineNumTable(in);
1.2487 + attr.read(table_name_index);
1.2488 + } else if (table_name_tstr.equals("LocalVariableTable")) {
1.2489 + readLocVarTable(in);
1.2490 + attr.read(table_name_index);
1.2491 + } else if (table_name_tstr.equals("StackMapTable")) {
1.2492 + readStackMapTable(in);
1.2493 + attr.read(table_name_index);
1.2494 + } else if (table_name_tstr.equals("StackMap")) {
1.2495 + readStackMap(in);
1.2496 + attr.read(table_name_index);
1.2497 + } else {
1.2498 + attr.read(table_name_index, in);
1.2499 + }
1.2500 + code_attrs.addElement(attr);
1.2501 + continue;
1.2502 + }
1.2503 +
1.2504 + attr.read(table_name_index, in);
1.2505 + code_attrs.addElement(attr);
1.2506 + }
1.2507 + }
1.2508 +
1.2509 + /**
1.2510 + * Read exception table info.
1.2511 + */
1.2512 + void readExceptionTable(DataInputStream in) throws IOException {
1.2513 + int exception_table_len = in.readUnsignedShort();
1.2514 + exception_table = new Vector(exception_table_len);
1.2515 + for (int l = 0; l < exception_table_len; l++) {
1.2516 + exception_table.addElement(new TrapData(in, l));
1.2517 + }
1.2518 + }
1.2519 +
1.2520 + /**
1.2521 + * Read LineNumberTable attribute info.
1.2522 + */
1.2523 + void readLineNumTable(DataInputStream in) throws IOException {
1.2524 + int attr_len = in.readInt(); // attr_length
1.2525 + int lin_num_tb_len = in.readUnsignedShort();
1.2526 + lin_num_tb = new Vector(lin_num_tb_len);
1.2527 + for (int l = 0; l < lin_num_tb_len; l++) {
1.2528 + lin_num_tb.addElement(new LineNumData(in));
1.2529 + }
1.2530 + }
1.2531 +
1.2532 + /**
1.2533 + * Read LocalVariableTable attribute info.
1.2534 + */
1.2535 + void readLocVarTable(DataInputStream in) throws IOException {
1.2536 + int attr_len = in.readInt(); // attr_length
1.2537 + int loc_var_tb_len = in.readUnsignedShort();
1.2538 + loc_var_tb = new Vector(loc_var_tb_len);
1.2539 + for (int l = 0; l < loc_var_tb_len; l++) {
1.2540 + loc_var_tb.addElement(new LocVarData(in));
1.2541 + }
1.2542 + }
1.2543 +
1.2544 + /**
1.2545 + * Read Exception attribute info.
1.2546 + */
1.2547 + public void readExceptions(DataInputStream in) throws IOException {
1.2548 + int attr_len = in.readInt(); // attr_length in prog
1.2549 + int num_exceptions = in.readUnsignedShort();
1.2550 + exc_index_table = new int[num_exceptions];
1.2551 + for (int l = 0; l < num_exceptions; l++) {
1.2552 + int exc = in.readShort();
1.2553 + exc_index_table[l] = exc;
1.2554 + }
1.2555 + }
1.2556 +
1.2557 + /**
1.2558 + * Read StackMapTable attribute info.
1.2559 + */
1.2560 + void readStackMapTable(DataInputStream in) throws IOException {
1.2561 + int attr_len = in.readInt(); //attr_length
1.2562 + int stack_map_tb_len = in.readUnsignedShort();
1.2563 + stackMapTable = new StackMapTableData[stack_map_tb_len];
1.2564 + for (int i = 0; i < stack_map_tb_len; i++) {
1.2565 + stackMapTable[i] = StackMapTableData.getInstance(in, this);
1.2566 + }
1.2567 + }
1.2568 +
1.2569 + /**
1.2570 + * Read StackMap attribute info.
1.2571 + */
1.2572 + void readStackMap(DataInputStream in) throws IOException {
1.2573 + int attr_len = in.readInt(); //attr_length
1.2574 + int stack_map_len = in.readUnsignedShort();
1.2575 + stackMap = new StackMapData[stack_map_len];
1.2576 + for (int i = 0; i < stack_map_len; i++) {
1.2577 + stackMap[i] = new StackMapData(in, this);
1.2578 + }
1.2579 + }
1.2580 +
1.2581 + /**
1.2582 + * Return access of the method.
1.2583 + */
1.2584 + public int getAccess() {
1.2585 + return access;
1.2586 + }
1.2587 +
1.2588 + /**
1.2589 + * Return name of the method.
1.2590 + */
1.2591 + public String getName() {
1.2592 + return cls.getStringValue(name_index);
1.2593 + }
1.2594 +
1.2595 + /**
1.2596 + * Return internal siganature of the method.
1.2597 + */
1.2598 + public String getInternalSig() {
1.2599 + return cls.getStringValue(descriptor_index);
1.2600 + }
1.2601 +
1.2602 + /**
1.2603 + * Return code attribute data of a method.
1.2604 + */
1.2605 + public byte[] getCode() {
1.2606 + return code;
1.2607 + }
1.2608 +
1.2609 + /**
1.2610 + * Return LineNumberTable size.
1.2611 + */
1.2612 + public int getnumlines() {
1.2613 + return lin_num_tb.size();
1.2614 + }
1.2615 +
1.2616 + /**
1.2617 + * Return LineNumberTable
1.2618 + */
1.2619 + public Vector getlin_num_tb() {
1.2620 + return lin_num_tb;
1.2621 + }
1.2622 +
1.2623 + /**
1.2624 + * Return LocalVariableTable size.
1.2625 + */
1.2626 + public int getloc_var_tbsize() {
1.2627 + return loc_var_tb.size();
1.2628 + }
1.2629 +
1.2630 + /**
1.2631 + * Return LocalVariableTable.
1.2632 + */
1.2633 + public Vector getloc_var_tb() {
1.2634 + return loc_var_tb;
1.2635 + }
1.2636 +
1.2637 + /**
1.2638 + * Return StackMap.
1.2639 + */
1.2640 + public StackMapData[] getStackMap() {
1.2641 + return stackMap;
1.2642 + }
1.2643 +
1.2644 + /**
1.2645 + * Return StackMapTable.
1.2646 + */
1.2647 + public StackMapTableData[] getStackMapTable() {
1.2648 + return stackMapTable;
1.2649 + }
1.2650 +
1.2651 + public StackMapIterator createStackMapIterator() {
1.2652 + return new StackMapIterator(this);
1.2653 + }
1.2654 +
1.2655 + /**
1.2656 + * Return true if method is static
1.2657 + */
1.2658 + public boolean isStatic() {
1.2659 + if ((access & ACC_STATIC) != 0) {
1.2660 + return true;
1.2661 + }
1.2662 + return false;
1.2663 + }
1.2664 +
1.2665 + /**
1.2666 + * Return max depth of operand stack.
1.2667 + */
1.2668 + public int getMaxStack() {
1.2669 + return max_stack;
1.2670 + }
1.2671 +
1.2672 + /**
1.2673 + * Return number of local variables.
1.2674 + */
1.2675 + public int getMaxLocals() {
1.2676 + return max_locals;
1.2677 + }
1.2678 +
1.2679 + /**
1.2680 + * Return exception index table in Exception attribute.
1.2681 + */
1.2682 + public int[] get_exc_index_table() {
1.2683 + return exc_index_table;
1.2684 + }
1.2685 +
1.2686 + /**
1.2687 + * Return exception table in code attributre.
1.2688 + */
1.2689 + public TrapDataIterator getTrapDataIterator() {
1.2690 + return new TrapDataIterator(exception_table);
1.2691 + }
1.2692 +
1.2693 + /**
1.2694 + * Return method attributes.
1.2695 + */
1.2696 + public Vector getAttributes() {
1.2697 + return attrs;
1.2698 + }
1.2699 +
1.2700 + /**
1.2701 + * Return code attributes.
1.2702 + */
1.2703 + public Vector getCodeAttributes() {
1.2704 + return code_attrs;
1.2705 + }
1.2706 +
1.2707 + /**
1.2708 + * Return true if method id synthetic.
1.2709 + */
1.2710 + public boolean isSynthetic() {
1.2711 + return isSynthetic;
1.2712 + }
1.2713 +
1.2714 + /**
1.2715 + * Return true if method is deprecated.
1.2716 + */
1.2717 + public boolean isDeprecated() {
1.2718 + return isDeprecated;
1.2719 + }
1.2720 +
1.2721 + public byte[] findAnnotationData(boolean classRetention) {
1.2722 + String n = classRetention
1.2723 + ? "RuntimeInvisibleAnnotations" : // NOI18N
1.2724 + "RuntimeVisibleAnnotations"; // NOI18N
1.2725 + AttrData[] arr = new AttrData[attrs.size()];
1.2726 + attrs.copyInto(arr);
1.2727 + return ClassData.findAttr(n, arr);
1.2728 + }
1.2729 +
1.2730 + public boolean isConstructor() {
1.2731 + return "<init>".equals(getName());
1.2732 + }
1.2733 + }
1.2734 +
1.2735 + /* represents one entry of StackMap attribute
1.2736 + */
1.2737 + private static class StackMapData {
1.2738 +
1.2739 + final int offset;
1.2740 + final int[] locals;
1.2741 + final int[] stack;
1.2742 +
1.2743 + StackMapData(int offset, int[] locals, int[] stack) {
1.2744 + this.offset = offset;
1.2745 + this.locals = locals;
1.2746 + this.stack = stack;
1.2747 + }
1.2748 +
1.2749 + StackMapData(DataInputStream in, MethodData method) throws IOException {
1.2750 + offset = in.readUnsignedShort();
1.2751 + int local_size = in.readUnsignedShort();
1.2752 + locals = readTypeArray(in, local_size, method);
1.2753 + int stack_size = in.readUnsignedShort();
1.2754 + stack = readTypeArray(in, stack_size, method);
1.2755 + }
1.2756 +
1.2757 + static final int[] readTypeArray(DataInputStream in, int length, MethodData method) throws IOException {
1.2758 + int[] types = new int[length];
1.2759 + for (int i = 0; i < length; i++) {
1.2760 + types[i] = readType(in, method);
1.2761 + }
1.2762 + return types;
1.2763 + }
1.2764 +
1.2765 + static final int readType(DataInputStream in, MethodData method) throws IOException {
1.2766 + int type = in.readUnsignedByte();
1.2767 + if (type == ITEM_Object || type == ITEM_NewObject) {
1.2768 + type = type | (in.readUnsignedShort() << 8);
1.2769 + }
1.2770 + return type;
1.2771 + }
1.2772 + }
1.2773 +
1.2774 + static final class StackMapIterator {
1.2775 +
1.2776 + private final StackMapTableData[] stackMapTable;
1.2777 + private final TypeArray argTypes;
1.2778 + private final TypeArray localTypes;
1.2779 + private final TypeArray stackTypes;
1.2780 + private int nextFrameIndex;
1.2781 + private int lastFrameByteCodeOffset;
1.2782 + private int byteCodeOffset;
1.2783 +
1.2784 + StackMapIterator(final MethodData methodData) {
1.2785 + this(methodData.getStackMapTable(),
1.2786 + methodData.getInternalSig(),
1.2787 + methodData.isStatic());
1.2788 + }
1.2789 +
1.2790 + StackMapIterator(final StackMapTableData[] stackMapTable,
1.2791 + final String methodSignature,
1.2792 + final boolean isStaticMethod) {
1.2793 + this.stackMapTable = (stackMapTable != null)
1.2794 + ? stackMapTable
1.2795 + : new StackMapTableData[0];
1.2796 +
1.2797 + argTypes = getArgTypes(methodSignature, isStaticMethod);
1.2798 + localTypes = new TypeArray();
1.2799 + stackTypes = new TypeArray();
1.2800 +
1.2801 + localTypes.addAll(argTypes);
1.2802 +
1.2803 + lastFrameByteCodeOffset = -1;
1.2804 + advanceBy(0);
1.2805 + }
1.2806 +
1.2807 + public String getFrameAsString() {
1.2808 + return (nextFrameIndex == 0)
1.2809 + ? StackMapTableData.toString("INITIAL", 0, null, null)
1.2810 + : stackMapTable[nextFrameIndex - 1].toString();
1.2811 + }
1.2812 +
1.2813 + public int getFrameIndex() {
1.2814 + return nextFrameIndex;
1.2815 + }
1.2816 +
1.2817 + public TypeArray getFrameStack() {
1.2818 + return stackTypes;
1.2819 + }
1.2820 +
1.2821 + public TypeArray getFrameLocals() {
1.2822 + return localTypes;
1.2823 + }
1.2824 +
1.2825 + public TypeArray getArguments() {
1.2826 + return argTypes;
1.2827 + }
1.2828 +
1.2829 + public void advanceBy(final int numByteCodes) {
1.2830 + if (numByteCodes < 0) {
1.2831 + throw new IllegalStateException("Forward only iterator");
1.2832 + }
1.2833 +
1.2834 + byteCodeOffset += numByteCodes;
1.2835 + while ((nextFrameIndex < stackMapTable.length)
1.2836 + && ((byteCodeOffset - lastFrameByteCodeOffset)
1.2837 + >= (stackMapTable[nextFrameIndex].offsetDelta
1.2838 + + 1))) {
1.2839 + final StackMapTableData nextFrame = stackMapTable[nextFrameIndex];
1.2840 +
1.2841 + lastFrameByteCodeOffset += nextFrame.offsetDelta + 1;
1.2842 + nextFrame.applyTo(localTypes, stackTypes);
1.2843 +
1.2844 + ++nextFrameIndex;
1.2845 + }
1.2846 + }
1.2847 +
1.2848 + public void advanceTo(final int nextByteCodeOffset) {
1.2849 + advanceBy(nextByteCodeOffset - byteCodeOffset);
1.2850 + }
1.2851 +
1.2852 + private static TypeArray getArgTypes(final String methodSignature,
1.2853 + final boolean isStaticMethod) {
1.2854 + final TypeArray argTypes = new TypeArray();
1.2855 +
1.2856 + if (!isStaticMethod) {
1.2857 + argTypes.add(ITEM_Object);
1.2858 + }
1.2859 +
1.2860 + if (methodSignature.charAt(0) != '(') {
1.2861 + throw new IllegalArgumentException("Invalid method signature");
1.2862 + }
1.2863 +
1.2864 + final int length = methodSignature.length();
1.2865 + boolean skipType = false;
1.2866 + int argType;
1.2867 + for (int i = 1; i < length; ++i) {
1.2868 + switch (methodSignature.charAt(i)) {
1.2869 + case 'B':
1.2870 + case 'C':
1.2871 + case 'S':
1.2872 + case 'Z':
1.2873 + case 'I':
1.2874 + argType = ITEM_Integer;
1.2875 + break;
1.2876 + case 'J':
1.2877 + argType = ITEM_Long;
1.2878 + break;
1.2879 + case 'F':
1.2880 + argType = ITEM_Float;
1.2881 + break;
1.2882 + case 'D':
1.2883 + argType = ITEM_Double;
1.2884 + break;
1.2885 + case 'L': {
1.2886 + i = methodSignature.indexOf(';', i + 1);
1.2887 + if (i == -1) {
1.2888 + throw new IllegalArgumentException(
1.2889 + "Invalid method signature");
1.2890 + }
1.2891 + argType = ITEM_Object;
1.2892 + break;
1.2893 + }
1.2894 + case ')':
1.2895 + // not interested in the return value type
1.2896 + return argTypes;
1.2897 + case '[':
1.2898 + if (!skipType) {
1.2899 + argTypes.add(ITEM_Object);
1.2900 + skipType = true;
1.2901 + }
1.2902 + continue;
1.2903 +
1.2904 + default:
1.2905 + throw new IllegalArgumentException(
1.2906 + "Invalid method signature");
1.2907 + }
1.2908 +
1.2909 + if (!skipType) {
1.2910 + argTypes.add(argType);
1.2911 + } else {
1.2912 + skipType = false;
1.2913 + }
1.2914 + }
1.2915 +
1.2916 + return argTypes;
1.2917 + }
1.2918 + }
1.2919 + /* represents one entry of StackMapTable attribute
1.2920 + */
1.2921 +
1.2922 + private static abstract class StackMapTableData {
1.2923 +
1.2924 + final int frameType;
1.2925 + int offsetDelta;
1.2926 +
1.2927 + StackMapTableData(int frameType) {
1.2928 + this.frameType = frameType;
1.2929 + }
1.2930 +
1.2931 + abstract void applyTo(TypeArray localTypes, TypeArray stackTypes);
1.2932 +
1.2933 + protected static String toString(
1.2934 + final String frameType,
1.2935 + final int offset,
1.2936 + final int[] localTypes,
1.2937 + final int[] stackTypes) {
1.2938 + final StringBuilder sb = new StringBuilder(frameType);
1.2939 +
1.2940 + sb.append("(off: +").append(offset);
1.2941 + if (localTypes != null) {
1.2942 + sb.append(", locals: ");
1.2943 + appendTypes(sb, localTypes);
1.2944 + }
1.2945 + if (stackTypes != null) {
1.2946 + sb.append(", stack: ");
1.2947 + appendTypes(sb, stackTypes);
1.2948 + }
1.2949 + sb.append(')');
1.2950 +
1.2951 + return sb.toString();
1.2952 + }
1.2953 +
1.2954 + private static void appendTypes(final StringBuilder sb, final int[] types) {
1.2955 + sb.append('[');
1.2956 + if (types.length > 0) {
1.2957 + sb.append(TypeArray.typeString(types[0]));
1.2958 + for (int i = 1; i < types.length; ++i) {
1.2959 + sb.append(", ");
1.2960 + sb.append(TypeArray.typeString(types[i]));
1.2961 + }
1.2962 + }
1.2963 + sb.append(']');
1.2964 + }
1.2965 +
1.2966 + private static class SameFrame extends StackMapTableData {
1.2967 +
1.2968 + SameFrame(int frameType, int offsetDelta) {
1.2969 + super(frameType);
1.2970 + this.offsetDelta = offsetDelta;
1.2971 + }
1.2972 +
1.2973 + @Override
1.2974 + void applyTo(TypeArray localTypes, TypeArray stackTypes) {
1.2975 + stackTypes.clear();
1.2976 + }
1.2977 +
1.2978 + @Override
1.2979 + public String toString() {
1.2980 + return toString("SAME" + ((frameType == SAME_FRAME_EXTENDED)
1.2981 + ? "_FRAME_EXTENDED" : ""),
1.2982 + offsetDelta,
1.2983 + null, null);
1.2984 + }
1.2985 + }
1.2986 +
1.2987 + private static class SameLocals1StackItem extends StackMapTableData {
1.2988 +
1.2989 + final int[] stack;
1.2990 +
1.2991 + SameLocals1StackItem(int frameType, int offsetDelta, int[] stack) {
1.2992 + super(frameType);
1.2993 + this.offsetDelta = offsetDelta;
1.2994 + this.stack = stack;
1.2995 + }
1.2996 +
1.2997 + @Override
1.2998 + void applyTo(TypeArray localTypes, TypeArray stackTypes) {
1.2999 + stackTypes.setAll(stack);
1.3000 + }
1.3001 +
1.3002 + @Override
1.3003 + public String toString() {
1.3004 + return toString(
1.3005 + "SAME_LOCALS_1_STACK_ITEM"
1.3006 + + ((frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED)
1.3007 + ? "_EXTENDED" : ""),
1.3008 + offsetDelta,
1.3009 + null, stack);
1.3010 + }
1.3011 + }
1.3012 +
1.3013 + private static class ChopFrame extends StackMapTableData {
1.3014 +
1.3015 + ChopFrame(int frameType, int offsetDelta) {
1.3016 + super(frameType);
1.3017 + this.offsetDelta = offsetDelta;
1.3018 + }
1.3019 +
1.3020 + @Override
1.3021 + void applyTo(TypeArray localTypes, TypeArray stackTypes) {
1.3022 + localTypes.setSize(localTypes.getSize()
1.3023 + - (SAME_FRAME_EXTENDED - frameType));
1.3024 + stackTypes.clear();
1.3025 + }
1.3026 +
1.3027 + @Override
1.3028 + public String toString() {
1.3029 + return toString("CHOP", offsetDelta, null, null);
1.3030 + }
1.3031 + }
1.3032 +
1.3033 + private static class AppendFrame extends StackMapTableData {
1.3034 +
1.3035 + final int[] locals;
1.3036 +
1.3037 + AppendFrame(int frameType, int offsetDelta, int[] locals) {
1.3038 + super(frameType);
1.3039 + this.offsetDelta = offsetDelta;
1.3040 + this.locals = locals;
1.3041 + }
1.3042 +
1.3043 + @Override
1.3044 + void applyTo(TypeArray localTypes, TypeArray stackTypes) {
1.3045 + localTypes.addAll(locals);
1.3046 + stackTypes.clear();
1.3047 + }
1.3048 +
1.3049 + @Override
1.3050 + public String toString() {
1.3051 + return toString("APPEND", offsetDelta, locals, null);
1.3052 + }
1.3053 + }
1.3054 +
1.3055 + private static class FullFrame extends StackMapTableData {
1.3056 +
1.3057 + final int[] locals;
1.3058 + final int[] stack;
1.3059 +
1.3060 + FullFrame(int offsetDelta, int[] locals, int[] stack) {
1.3061 + super(FULL_FRAME);
1.3062 + this.offsetDelta = offsetDelta;
1.3063 + this.locals = locals;
1.3064 + this.stack = stack;
1.3065 + }
1.3066 +
1.3067 + @Override
1.3068 + void applyTo(TypeArray localTypes, TypeArray stackTypes) {
1.3069 + localTypes.setAll(locals);
1.3070 + stackTypes.setAll(stack);
1.3071 + }
1.3072 +
1.3073 + @Override
1.3074 + public String toString() {
1.3075 + return toString("FULL", offsetDelta, locals, stack);
1.3076 + }
1.3077 + }
1.3078 +
1.3079 + static StackMapTableData getInstance(DataInputStream in, MethodData method)
1.3080 + throws IOException {
1.3081 + int frameType = in.readUnsignedByte();
1.3082 +
1.3083 + if (frameType < SAME_FRAME_BOUND) {
1.3084 + // same_frame
1.3085 + return new SameFrame(frameType, frameType);
1.3086 + } else if (SAME_FRAME_BOUND <= frameType && frameType < SAME_LOCALS_1_STACK_ITEM_BOUND) {
1.3087 + // same_locals_1_stack_item_frame
1.3088 + // read additional single stack element
1.3089 + return new SameLocals1StackItem(frameType,
1.3090 + (frameType - SAME_FRAME_BOUND),
1.3091 + StackMapData.readTypeArray(in, 1, method));
1.3092 + } else if (frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
1.3093 + // same_locals_1_stack_item_extended
1.3094 + return new SameLocals1StackItem(frameType,
1.3095 + in.readUnsignedShort(),
1.3096 + StackMapData.readTypeArray(in, 1, method));
1.3097 + } else if (SAME_LOCALS_1_STACK_ITEM_EXTENDED < frameType && frameType < SAME_FRAME_EXTENDED) {
1.3098 + // chop_frame or same_frame_extended
1.3099 + return new ChopFrame(frameType, in.readUnsignedShort());
1.3100 + } else if (frameType == SAME_FRAME_EXTENDED) {
1.3101 + // chop_frame or same_frame_extended
1.3102 + return new SameFrame(frameType, in.readUnsignedShort());
1.3103 + } else if (SAME_FRAME_EXTENDED < frameType && frameType < FULL_FRAME) {
1.3104 + // append_frame
1.3105 + return new AppendFrame(frameType, in.readUnsignedShort(),
1.3106 + StackMapData.readTypeArray(in, frameType - SAME_FRAME_EXTENDED, method));
1.3107 + } else if (frameType == FULL_FRAME) {
1.3108 + // full_frame
1.3109 + int offsetDelta = in.readUnsignedShort();
1.3110 + int locals_size = in.readUnsignedShort();
1.3111 + int[] locals = StackMapData.readTypeArray(in, locals_size, method);
1.3112 + int stack_size = in.readUnsignedShort();
1.3113 + int[] stack = StackMapData.readTypeArray(in, stack_size, method);
1.3114 + return new FullFrame(offsetDelta, locals, stack);
1.3115 + } else {
1.3116 + throw new ClassFormatError("unrecognized frame_type in StackMapTable");
1.3117 + }
1.3118 + }
1.3119 + }
1.3120 +
1.3121 + /**
1.3122 + * Stores exception table data in code attribute.
1.3123 + *
1.3124 + * @author Sucheta Dambalkar (Adopted code from jdis)
1.3125 + */
1.3126 + static final class TrapData {
1.3127 +
1.3128 + public final short start_pc;
1.3129 + public final short end_pc;
1.3130 + public final short handler_pc;
1.3131 + public final short catch_cpx;
1.3132 + final int num;
1.3133 +
1.3134 + /**
1.3135 + * Read and store exception table data in code attribute.
1.3136 + */
1.3137 + TrapData(DataInputStream in, int num) throws IOException {
1.3138 + this.num = num;
1.3139 + start_pc = in.readShort();
1.3140 + end_pc = in.readShort();
1.3141 + handler_pc = in.readShort();
1.3142 + catch_cpx = in.readShort();
1.3143 + }
1.3144 +
1.3145 + /**
1.3146 + * returns recommended identifier
1.3147 + */
1.3148 + public String ident() {
1.3149 + return "t" + num;
1.3150 + }
1.3151 + }
1.3152 + /**
1.3153 + *
1.3154 + * @author Jaroslav Tulach <jtulach@netbeans.org>
1.3155 + */
1.3156 + static final class TrapDataIterator {
1.3157 +
1.3158 + private final Hashtable exStart = new Hashtable();
1.3159 + private final Hashtable exStop = new Hashtable();
1.3160 + private TrapData[] current = new TrapData[10];
1.3161 + private int currentCount;
1.3162 +
1.3163 + TrapDataIterator(Vector exceptionTable) {
1.3164 + for (int i = 0; i < exceptionTable.size(); i++) {
1.3165 + final TrapData td = (TrapData) exceptionTable.elementAt(i);
1.3166 + put(exStart, td.start_pc, td);
1.3167 + put(exStop, td.end_pc, td);
1.3168 + }
1.3169 + }
1.3170 +
1.3171 + private static void put(Hashtable h, short key, TrapData td) {
1.3172 + Short s = Short.valueOf((short) key);
1.3173 + Vector v = (Vector) h.get(s);
1.3174 + if (v == null) {
1.3175 + v = new Vector(1);
1.3176 + h.put(s, v);
1.3177 + }
1.3178 + v.add(td);
1.3179 + }
1.3180 +
1.3181 + private boolean processAll(Hashtable h, Short key, boolean add) {
1.3182 + boolean change = false;
1.3183 + Vector v = (Vector) h.get(key);
1.3184 + if (v != null) {
1.3185 + int s = v.size();
1.3186 + for (int i = 0; i < s; i++) {
1.3187 + TrapData td = (TrapData) v.elementAt(i);
1.3188 + if (add) {
1.3189 + add(td);
1.3190 + change = true;
1.3191 + } else {
1.3192 + remove(td);
1.3193 + change = true;
1.3194 + }
1.3195 + }
1.3196 + }
1.3197 + return change;
1.3198 + }
1.3199 +
1.3200 + public boolean advanceTo(int i) {
1.3201 + Short s = Short.valueOf((short) i);
1.3202 + boolean ch1 = processAll(exStart, s, true);
1.3203 + boolean ch2 = processAll(exStop, s, false);
1.3204 + return ch1 || ch2;
1.3205 + }
1.3206 +
1.3207 + public boolean useTry() {
1.3208 + return currentCount > 0;
1.3209 + }
1.3210 +
1.3211 + public TrapData[] current() {
1.3212 + TrapData[] copy = new TrapData[currentCount];
1.3213 + for (int i = 0; i < currentCount; i++) {
1.3214 + copy[i] = current[i];
1.3215 + }
1.3216 + return copy;
1.3217 + }
1.3218 +
1.3219 + private void add(TrapData e) {
1.3220 + if (currentCount == current.length) {
1.3221 + TrapData[] data = new TrapData[currentCount * 2];
1.3222 + for (int i = 0; i < currentCount; i++) {
1.3223 + data[i] = current[i];
1.3224 + }
1.3225 + current = data;
1.3226 + }
1.3227 + current[currentCount++] = e;
1.3228 + }
1.3229 +
1.3230 + private void remove(TrapData e) {
1.3231 + if (currentCount == 0) {
1.3232 + return;
1.3233 + }
1.3234 + int from = 0;
1.3235 + while (from < currentCount) {
1.3236 + if (e == current[from++]) {
1.3237 + break;
1.3238 + }
1.3239 + }
1.3240 + while (from < currentCount) {
1.3241 + current[from - 1] = current[from];
1.3242 + current[from] = null;
1.3243 + from++;
1.3244 + }
1.3245 + currentCount--;
1.3246 + }
1.3247 + }
1.3248 + static final class TypeArray {
1.3249 +
1.3250 + private static final int CAPACITY_INCREMENT = 16;
1.3251 + private int[] types;
1.3252 + private int size;
1.3253 +
1.3254 + public TypeArray() {
1.3255 + }
1.3256 +
1.3257 + public TypeArray(final TypeArray initialTypes) {
1.3258 + setAll(initialTypes);
1.3259 + }
1.3260 +
1.3261 + public void add(final int newType) {
1.3262 + ensureCapacity(size + 1);
1.3263 + types[size++] = newType;
1.3264 + }
1.3265 +
1.3266 + public void addAll(final TypeArray newTypes) {
1.3267 + addAll(newTypes.types, 0, newTypes.size);
1.3268 + }
1.3269 +
1.3270 + public void addAll(final int[] newTypes) {
1.3271 + addAll(newTypes, 0, newTypes.length);
1.3272 + }
1.3273 +
1.3274 + public void addAll(final int[] newTypes,
1.3275 + final int offset,
1.3276 + final int count) {
1.3277 + if (count > 0) {
1.3278 + ensureCapacity(size + count);
1.3279 + arraycopy(newTypes, offset, types, size, count);
1.3280 + size += count;
1.3281 + }
1.3282 + }
1.3283 +
1.3284 + public void set(final int index, final int newType) {
1.3285 + types[index] = newType;
1.3286 + }
1.3287 +
1.3288 + public void setAll(final TypeArray newTypes) {
1.3289 + setAll(newTypes.types, 0, newTypes.size);
1.3290 + }
1.3291 +
1.3292 + public void setAll(final int[] newTypes) {
1.3293 + setAll(newTypes, 0, newTypes.length);
1.3294 + }
1.3295 +
1.3296 + public void setAll(final int[] newTypes,
1.3297 + final int offset,
1.3298 + final int count) {
1.3299 + if (count > 0) {
1.3300 + ensureCapacity(count);
1.3301 + arraycopy(newTypes, offset, types, 0, count);
1.3302 + size = count;
1.3303 + } else {
1.3304 + clear();
1.3305 + }
1.3306 + }
1.3307 +
1.3308 + public void setSize(final int newSize) {
1.3309 + if (size != newSize) {
1.3310 + ensureCapacity(newSize);
1.3311 +
1.3312 + for (int i = size; i < newSize; ++i) {
1.3313 + types[i] = 0;
1.3314 + }
1.3315 + size = newSize;
1.3316 + }
1.3317 + }
1.3318 +
1.3319 + public void clear() {
1.3320 + size = 0;
1.3321 + }
1.3322 +
1.3323 + public int getSize() {
1.3324 + return size;
1.3325 + }
1.3326 +
1.3327 + public int get(final int index) {
1.3328 + return types[index];
1.3329 + }
1.3330 +
1.3331 + public static String typeString(final int type) {
1.3332 + switch (type & 0xff) {
1.3333 + case ITEM_Bogus:
1.3334 + return "_top_";
1.3335 + case ITEM_Integer:
1.3336 + return "_int_";
1.3337 + case ITEM_Float:
1.3338 + return "_float_";
1.3339 + case ITEM_Double:
1.3340 + return "_double_";
1.3341 + case ITEM_Long:
1.3342 + return "_long_";
1.3343 + case ITEM_Null:
1.3344 + return "_null_";
1.3345 + case ITEM_InitObject: // UninitializedThis
1.3346 + return "_init_";
1.3347 + case ITEM_Object:
1.3348 + return "_object_";
1.3349 + case ITEM_NewObject: // Uninitialized
1.3350 + return "_new_";
1.3351 + default:
1.3352 + throw new IllegalArgumentException("Unknown type");
1.3353 + }
1.3354 + }
1.3355 +
1.3356 + @Override
1.3357 + public String toString() {
1.3358 + final StringBuilder sb = new StringBuilder("[");
1.3359 + if (size > 0) {
1.3360 + sb.append(typeString(types[0]));
1.3361 + for (int i = 1; i < size; ++i) {
1.3362 + sb.append(", ");
1.3363 + sb.append(typeString(types[i]));
1.3364 + }
1.3365 + }
1.3366 +
1.3367 + return sb.append(']').toString();
1.3368 + }
1.3369 +
1.3370 + private void ensureCapacity(final int minCapacity) {
1.3371 + if ((minCapacity == 0)
1.3372 + || (types != null) && (minCapacity <= types.length)) {
1.3373 + return;
1.3374 + }
1.3375 +
1.3376 + final int newCapacity =
1.3377 + ((minCapacity + CAPACITY_INCREMENT - 1) / CAPACITY_INCREMENT)
1.3378 + * CAPACITY_INCREMENT;
1.3379 + final int[] newTypes = new int[newCapacity];
1.3380 +
1.3381 + if (size > 0) {
1.3382 + arraycopy(types, 0, newTypes, 0, size);
1.3383 + }
1.3384 +
1.3385 + types = newTypes;
1.3386 + }
1.3387 +
1.3388 + // no System.arraycopy
1.3389 + private void arraycopy(final int[] src, final int srcPos,
1.3390 + final int[] dest, final int destPos,
1.3391 + final int length) {
1.3392 + for (int i = 0; i < length; ++i) {
1.3393 + dest[destPos + i] = src[srcPos + i];
1.3394 + }
1.3395 + }
1.3396 + }
1.3397 + /**
1.3398 + * A JavaScript ready replacement for java.util.Vector
1.3399 + *
1.3400 + * @author Jaroslav Tulach <jtulach@netbeans.org>
1.3401 + */
1.3402 + @JavaScriptPrototype(prototype = "new Array")
1.3403 + private static final class Vector {
1.3404 +
1.3405 + private Object[] arr;
1.3406 +
1.3407 + Vector() {
1.3408 + }
1.3409 +
1.3410 + Vector(int i) {
1.3411 + }
1.3412 +
1.3413 + void add(Object objectType) {
1.3414 + addElement(objectType);
1.3415 + }
1.3416 +
1.3417 + @JavaScriptBody(args = {"obj"}, body =
1.3418 + "this.push(obj);")
1.3419 + void addElement(Object obj) {
1.3420 + final int s = size();
1.3421 + setSize(s + 1);
1.3422 + setElementAt(obj, s);
1.3423 + }
1.3424 +
1.3425 + @JavaScriptBody(args = {}, body =
1.3426 + "return this.length;")
1.3427 + int size() {
1.3428 + return arr == null ? 0 : arr.length;
1.3429 + }
1.3430 +
1.3431 + @JavaScriptBody(args = {"newArr"}, body =
1.3432 + "for (var i = 0; i < this.length; i++) {\n"
1.3433 + + " newArr[i] = this[i];\n"
1.3434 + + "}\n")
1.3435 + void copyInto(Object[] newArr) {
1.3436 + if (arr == null) {
1.3437 + return;
1.3438 + }
1.3439 + int min = Math.min(newArr.length, arr.length);
1.3440 + for (int i = 0; i < min; i++) {
1.3441 + newArr[i] = arr[i];
1.3442 + }
1.3443 + }
1.3444 +
1.3445 + @JavaScriptBody(args = {"index"}, body =
1.3446 + "return this[index];")
1.3447 + Object elementAt(int index) {
1.3448 + return arr[index];
1.3449 + }
1.3450 +
1.3451 + private void setSize(int len) {
1.3452 + Object[] newArr = new Object[len];
1.3453 + copyInto(newArr);
1.3454 + arr = newArr;
1.3455 + }
1.3456 +
1.3457 + @JavaScriptBody(args = {"val", "index"}, body =
1.3458 + "this[index] = val;")
1.3459 + void setElementAt(Object val, int index) {
1.3460 + arr[index] = val;
1.3461 + }
1.3462 + }
1.3463 +
1.3464 +}