rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeParser.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 09 Oct 2013 16:53:45 +0200
changeset 1354 43f89d9f7238
parent 810 9eb750594b15
child 1469 f57fa856ffc4
permissions -rw-r--r--
Unicode has some special new line characters that need to be encoded too
jaroslav@810
     1
/*
jaroslav@810
     2
 * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved.
jaroslav@810
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jaroslav@810
     4
 *
jaroslav@810
     5
 * This code is free software; you can redistribute it and/or modify it
jaroslav@810
     6
 * under the terms of the GNU General Public License version 2 only, as
jaroslav@810
     7
 * published by the Free Software Foundation.  Oracle designates this
jaroslav@810
     8
 * particular file as subject to the "Classpath" exception as provided
jaroslav@810
     9
 * by Oracle in the LICENSE file that accompanied this code.
jaroslav@810
    10
 *
jaroslav@810
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
jaroslav@810
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jaroslav@810
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
jaroslav@810
    14
 * version 2 for more details (a copy is included in the LICENSE file that
jaroslav@810
    15
 * accompanied this code).
jaroslav@810
    16
 *
jaroslav@810
    17
 * You should have received a copy of the GNU General Public License version
jaroslav@810
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
jaroslav@810
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jaroslav@810
    20
 *
jaroslav@810
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jaroslav@810
    22
 * or visit www.oracle.com if you need additional information or have any
jaroslav@810
    23
 * questions.
jaroslav@810
    24
 */
jaroslav@810
    25
package org.apidesign.vm4brwsr;
jaroslav@810
    26
jaroslav@810
    27
import java.io.ByteArrayInputStream;
jaroslav@810
    28
import java.io.DataInputStream;
jaroslav@810
    29
import java.io.IOException;
jaroslav@810
    30
import java.io.InputStream;
jaroslav@810
    31
import org.apidesign.bck2brwsr.core.JavaScriptBody;
jaroslav@810
    32
import org.apidesign.bck2brwsr.core.JavaScriptPrototype;
jaroslav@810
    33
jaroslav@810
    34
/** This is a byte code parser heavily based on original code of JavaP utility.
jaroslav@810
    35
 * As such I decided to keep the original Oracle's GPLv2 header.
jaroslav@810
    36
 *
jaroslav@810
    37
 * @author Jaroslav Tulach <jtulach@netbeans.org>
jaroslav@810
    38
 */
jaroslav@810
    39
final class ByteCodeParser {
jaroslav@810
    40
    private ByteCodeParser() {
jaroslav@810
    41
    }
jaroslav@810
    42
    /* Signature Characters */
jaroslav@810
    43
    public static final char   SIGC_VOID                  = 'V';
jaroslav@810
    44
    public static final String SIG_VOID                   = "V";
jaroslav@810
    45
    public static final char   SIGC_BOOLEAN               = 'Z';
jaroslav@810
    46
    public static final String SIG_BOOLEAN                = "Z";
jaroslav@810
    47
    public static final char   SIGC_BYTE                  = 'B';
jaroslav@810
    48
    public static final String SIG_BYTE                   = "B";
jaroslav@810
    49
    public static final char   SIGC_CHAR                  = 'C';
jaroslav@810
    50
    public static final String SIG_CHAR                   = "C";
jaroslav@810
    51
    public static final char   SIGC_SHORT                 = 'S';
jaroslav@810
    52
    public static final String SIG_SHORT                  = "S";
jaroslav@810
    53
    public static final char   SIGC_INT                   = 'I';
jaroslav@810
    54
    public static final String SIG_INT                    = "I";
jaroslav@810
    55
    public static final char   SIGC_LONG                  = 'J';
jaroslav@810
    56
    public static final String SIG_LONG                   = "J";
jaroslav@810
    57
    public static final char   SIGC_FLOAT                 = 'F';
jaroslav@810
    58
    public static final String SIG_FLOAT                  = "F";
jaroslav@810
    59
    public static final char   SIGC_DOUBLE                = 'D';
jaroslav@810
    60
    public static final String SIG_DOUBLE                 = "D";
jaroslav@810
    61
    public static final char   SIGC_ARRAY                 = '[';
jaroslav@810
    62
    public static final String SIG_ARRAY                  = "[";
jaroslav@810
    63
    public static final char   SIGC_CLASS                 = 'L';
jaroslav@810
    64
    public static final String SIG_CLASS                  = "L";
jaroslav@810
    65
    public static final char   SIGC_METHOD                = '(';
jaroslav@810
    66
    public static final String SIG_METHOD                 = "(";
jaroslav@810
    67
    public static final char   SIGC_ENDCLASS              = ';';
jaroslav@810
    68
    public static final String SIG_ENDCLASS               = ";";
jaroslav@810
    69
    public static final char   SIGC_ENDMETHOD             = ')';
jaroslav@810
    70
    public static final String SIG_ENDMETHOD              = ")";
jaroslav@810
    71
    public static final char   SIGC_PACKAGE               = '/';
jaroslav@810
    72
    public static final String SIG_PACKAGE                = "/";
jaroslav@810
    73
jaroslav@810
    74
    /* Class File Constants */
jaroslav@810
    75
    public static final int JAVA_MAGIC                   = 0xcafebabe;
jaroslav@810
    76
    public static final int JAVA_VERSION                 = 45;
jaroslav@810
    77
    public static final int JAVA_MINOR_VERSION           = 3;
jaroslav@810
    78
jaroslav@810
    79
    /* Constant table */
jaroslav@810
    80
    public static final int CONSTANT_UTF8                = 1;
jaroslav@810
    81
    public static final int CONSTANT_UNICODE             = 2;
jaroslav@810
    82
    public static final int CONSTANT_INTEGER             = 3;
jaroslav@810
    83
    public static final int CONSTANT_FLOAT               = 4;
jaroslav@810
    84
    public static final int CONSTANT_LONG                = 5;
jaroslav@810
    85
    public static final int CONSTANT_DOUBLE              = 6;
jaroslav@810
    86
    public static final int CONSTANT_CLASS               = 7;
jaroslav@810
    87
    public static final int CONSTANT_STRING              = 8;
jaroslav@810
    88
    public static final int CONSTANT_FIELD               = 9;
jaroslav@810
    89
    public static final int CONSTANT_METHOD              = 10;
jaroslav@810
    90
    public static final int CONSTANT_INTERFACEMETHOD     = 11;
jaroslav@810
    91
    public static final int CONSTANT_NAMEANDTYPE         = 12;
jaroslav@810
    92
jaroslav@810
    93
    /* Access Flags */
jaroslav@810
    94
    public static final int ACC_PUBLIC                   = 0x00000001;
jaroslav@810
    95
    public static final int ACC_PRIVATE                  = 0x00000002;
jaroslav@810
    96
    public static final int ACC_PROTECTED                = 0x00000004;
jaroslav@810
    97
    public static final int ACC_STATIC                   = 0x00000008;
jaroslav@810
    98
    public static final int ACC_FINAL                    = 0x00000010;
jaroslav@810
    99
    public static final int ACC_SYNCHRONIZED             = 0x00000020;
jaroslav@810
   100
    public static final int ACC_SUPER                        = 0x00000020;
jaroslav@810
   101
    public static final int ACC_VOLATILE                 = 0x00000040;
jaroslav@810
   102
    public static final int ACC_TRANSIENT                = 0x00000080;
jaroslav@810
   103
    public static final int ACC_NATIVE                   = 0x00000100;
jaroslav@810
   104
    public static final int ACC_INTERFACE                = 0x00000200;
jaroslav@810
   105
    public static final int ACC_ABSTRACT                 = 0x00000400;
jaroslav@810
   106
    public static final int ACC_STRICT                   = 0x00000800;
jaroslav@810
   107
    public static final int ACC_EXPLICIT                 = 0x00001000;
jaroslav@810
   108
    public static final int ACC_SYNTHETIC                = 0x00010000; // actually, this is an attribute
jaroslav@810
   109
jaroslav@810
   110
    /* Type codes */
jaroslav@810
   111
    public static final int T_CLASS                      = 0x00000002;
jaroslav@810
   112
    public static final int T_BOOLEAN                    = 0x00000004;
jaroslav@810
   113
    public static final int T_CHAR                       = 0x00000005;
jaroslav@810
   114
    public static final int T_FLOAT                      = 0x00000006;
jaroslav@810
   115
    public static final int T_DOUBLE                     = 0x00000007;
jaroslav@810
   116
    public static final int T_BYTE                       = 0x00000008;
jaroslav@810
   117
    public static final int T_SHORT                      = 0x00000009;
jaroslav@810
   118
    public static final int T_INT                        = 0x0000000a;
jaroslav@810
   119
    public static final int T_LONG                       = 0x0000000b;
jaroslav@810
   120
jaroslav@810
   121
    /* Type codes for StackMap attribute */
jaroslav@810
   122
    public static final int ITEM_Bogus      =0; // an unknown or uninitialized value
jaroslav@810
   123
    public static final int ITEM_Integer    =1; // a 32-bit integer
jaroslav@810
   124
    public static final int ITEM_Float      =2; // not used
jaroslav@810
   125
    public static final int ITEM_Double     =3; // not used
jaroslav@810
   126
    public static final int ITEM_Long       =4; // a 64-bit integer
jaroslav@810
   127
    public static final int ITEM_Null       =5; // the type of null
jaroslav@810
   128
    public static final int ITEM_InitObject =6; // "this" in constructor
jaroslav@810
   129
    public static final int ITEM_Object     =7; // followed by 2-byte index of class name
jaroslav@810
   130
    public static final int ITEM_NewObject  =8; // followed by 2-byte ref to "new"
jaroslav@810
   131
jaroslav@810
   132
    /* Constants used in StackMapTable attribute */
jaroslav@810
   133
    public static final int SAME_FRAME_BOUND                  = 64;
jaroslav@810
   134
    public static final int SAME_LOCALS_1_STACK_ITEM_BOUND    = 128;
jaroslav@810
   135
    public static final int SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247;
jaroslav@810
   136
    public static final int SAME_FRAME_EXTENDED               = 251;
jaroslav@810
   137
    public static final int FULL_FRAME                        = 255;
jaroslav@810
   138
jaroslav@810
   139
    /* Opcodes */
jaroslav@810
   140
    public static final int opc_dead                     = -2;
jaroslav@810
   141
    public static final int opc_label                    = -1;
jaroslav@810
   142
    public static final int opc_nop                      = 0;
jaroslav@810
   143
    public static final int opc_aconst_null              = 1;
jaroslav@810
   144
    public static final int opc_iconst_m1                = 2;
jaroslav@810
   145
    public static final int opc_iconst_0                 = 3;
jaroslav@810
   146
    public static final int opc_iconst_1                 = 4;
jaroslav@810
   147
    public static final int opc_iconst_2                 = 5;
jaroslav@810
   148
    public static final int opc_iconst_3                 = 6;
jaroslav@810
   149
    public static final int opc_iconst_4                 = 7;
jaroslav@810
   150
    public static final int opc_iconst_5                 = 8;
jaroslav@810
   151
    public static final int opc_lconst_0                 = 9;
jaroslav@810
   152
    public static final int opc_lconst_1                 = 10;
jaroslav@810
   153
    public static final int opc_fconst_0                 = 11;
jaroslav@810
   154
    public static final int opc_fconst_1                 = 12;
jaroslav@810
   155
    public static final int opc_fconst_2                 = 13;
jaroslav@810
   156
    public static final int opc_dconst_0                 = 14;
jaroslav@810
   157
    public static final int opc_dconst_1                 = 15;
jaroslav@810
   158
    public static final int opc_bipush                   = 16;
jaroslav@810
   159
    public static final int opc_sipush                   = 17;
jaroslav@810
   160
    public static final int opc_ldc                      = 18;
jaroslav@810
   161
    public static final int opc_ldc_w                    = 19;
jaroslav@810
   162
    public static final int opc_ldc2_w                   = 20;
jaroslav@810
   163
    public static final int opc_iload                    = 21;
jaroslav@810
   164
    public static final int opc_lload                    = 22;
jaroslav@810
   165
    public static final int opc_fload                    = 23;
jaroslav@810
   166
    public static final int opc_dload                    = 24;
jaroslav@810
   167
    public static final int opc_aload                    = 25;
jaroslav@810
   168
    public static final int opc_iload_0                  = 26;
jaroslav@810
   169
    public static final int opc_iload_1                  = 27;
jaroslav@810
   170
    public static final int opc_iload_2                  = 28;
jaroslav@810
   171
    public static final int opc_iload_3                  = 29;
jaroslav@810
   172
    public static final int opc_lload_0                  = 30;
jaroslav@810
   173
    public static final int opc_lload_1                  = 31;
jaroslav@810
   174
    public static final int opc_lload_2                  = 32;
jaroslav@810
   175
    public static final int opc_lload_3                  = 33;
jaroslav@810
   176
    public static final int opc_fload_0                  = 34;
jaroslav@810
   177
    public static final int opc_fload_1                  = 35;
jaroslav@810
   178
    public static final int opc_fload_2                  = 36;
jaroslav@810
   179
    public static final int opc_fload_3                  = 37;
jaroslav@810
   180
    public static final int opc_dload_0                  = 38;
jaroslav@810
   181
    public static final int opc_dload_1                  = 39;
jaroslav@810
   182
    public static final int opc_dload_2                  = 40;
jaroslav@810
   183
    public static final int opc_dload_3                  = 41;
jaroslav@810
   184
    public static final int opc_aload_0                  = 42;
jaroslav@810
   185
    public static final int opc_aload_1                  = 43;
jaroslav@810
   186
    public static final int opc_aload_2                  = 44;
jaroslav@810
   187
    public static final int opc_aload_3                  = 45;
jaroslav@810
   188
    public static final int opc_iaload                   = 46;
jaroslav@810
   189
    public static final int opc_laload                   = 47;
jaroslav@810
   190
    public static final int opc_faload                   = 48;
jaroslav@810
   191
    public static final int opc_daload                   = 49;
jaroslav@810
   192
    public static final int opc_aaload                   = 50;
jaroslav@810
   193
    public static final int opc_baload                   = 51;
jaroslav@810
   194
    public static final int opc_caload                   = 52;
jaroslav@810
   195
    public static final int opc_saload                   = 53;
jaroslav@810
   196
    public static final int opc_istore                   = 54;
jaroslav@810
   197
    public static final int opc_lstore                   = 55;
jaroslav@810
   198
    public static final int opc_fstore                   = 56;
jaroslav@810
   199
    public static final int opc_dstore                   = 57;
jaroslav@810
   200
    public static final int opc_astore                   = 58;
jaroslav@810
   201
    public static final int opc_istore_0                 = 59;
jaroslav@810
   202
    public static final int opc_istore_1                 = 60;
jaroslav@810
   203
    public static final int opc_istore_2                 = 61;
jaroslav@810
   204
    public static final int opc_istore_3                 = 62;
jaroslav@810
   205
    public static final int opc_lstore_0                 = 63;
jaroslav@810
   206
    public static final int opc_lstore_1                 = 64;
jaroslav@810
   207
    public static final int opc_lstore_2                 = 65;
jaroslav@810
   208
    public static final int opc_lstore_3                 = 66;
jaroslav@810
   209
    public static final int opc_fstore_0                 = 67;
jaroslav@810
   210
    public static final int opc_fstore_1                 = 68;
jaroslav@810
   211
    public static final int opc_fstore_2                 = 69;
jaroslav@810
   212
    public static final int opc_fstore_3                 = 70;
jaroslav@810
   213
    public static final int opc_dstore_0                 = 71;
jaroslav@810
   214
    public static final int opc_dstore_1                 = 72;
jaroslav@810
   215
    public static final int opc_dstore_2                 = 73;
jaroslav@810
   216
    public static final int opc_dstore_3                 = 74;
jaroslav@810
   217
    public static final int opc_astore_0                 = 75;
jaroslav@810
   218
    public static final int opc_astore_1                 = 76;
jaroslav@810
   219
    public static final int opc_astore_2                 = 77;
jaroslav@810
   220
    public static final int opc_astore_3                 = 78;
jaroslav@810
   221
    public static final int opc_iastore                  = 79;
jaroslav@810
   222
    public static final int opc_lastore                  = 80;
jaroslav@810
   223
    public static final int opc_fastore                  = 81;
jaroslav@810
   224
    public static final int opc_dastore                  = 82;
jaroslav@810
   225
    public static final int opc_aastore                  = 83;
jaroslav@810
   226
    public static final int opc_bastore                  = 84;
jaroslav@810
   227
    public static final int opc_castore                  = 85;
jaroslav@810
   228
    public static final int opc_sastore                  = 86;
jaroslav@810
   229
    public static final int opc_pop                      = 87;
jaroslav@810
   230
    public static final int opc_pop2                     = 88;
jaroslav@810
   231
    public static final int opc_dup                      = 89;
jaroslav@810
   232
    public static final int opc_dup_x1                   = 90;
jaroslav@810
   233
    public static final int opc_dup_x2                   = 91;
jaroslav@810
   234
    public static final int opc_dup2                     = 92;
jaroslav@810
   235
    public static final int opc_dup2_x1                  = 93;
jaroslav@810
   236
    public static final int opc_dup2_x2                  = 94;
jaroslav@810
   237
    public static final int opc_swap                     = 95;
jaroslav@810
   238
    public static final int opc_iadd                     = 96;
jaroslav@810
   239
    public static final int opc_ladd                     = 97;
jaroslav@810
   240
    public static final int opc_fadd                     = 98;
jaroslav@810
   241
    public static final int opc_dadd                     = 99;
jaroslav@810
   242
    public static final int opc_isub                     = 100;
jaroslav@810
   243
    public static final int opc_lsub                     = 101;
jaroslav@810
   244
    public static final int opc_fsub                     = 102;
jaroslav@810
   245
    public static final int opc_dsub                     = 103;
jaroslav@810
   246
    public static final int opc_imul                     = 104;
jaroslav@810
   247
    public static final int opc_lmul                     = 105;
jaroslav@810
   248
    public static final int opc_fmul                     = 106;
jaroslav@810
   249
    public static final int opc_dmul                     = 107;
jaroslav@810
   250
    public static final int opc_idiv                     = 108;
jaroslav@810
   251
    public static final int opc_ldiv                     = 109;
jaroslav@810
   252
    public static final int opc_fdiv                     = 110;
jaroslav@810
   253
    public static final int opc_ddiv                     = 111;
jaroslav@810
   254
    public static final int opc_irem                     = 112;
jaroslav@810
   255
    public static final int opc_lrem                     = 113;
jaroslav@810
   256
    public static final int opc_frem                     = 114;
jaroslav@810
   257
    public static final int opc_drem                     = 115;
jaroslav@810
   258
    public static final int opc_ineg                     = 116;
jaroslav@810
   259
    public static final int opc_lneg                     = 117;
jaroslav@810
   260
    public static final int opc_fneg                     = 118;
jaroslav@810
   261
    public static final int opc_dneg                     = 119;
jaroslav@810
   262
    public static final int opc_ishl                     = 120;
jaroslav@810
   263
    public static final int opc_lshl                     = 121;
jaroslav@810
   264
    public static final int opc_ishr                     = 122;
jaroslav@810
   265
    public static final int opc_lshr                     = 123;
jaroslav@810
   266
    public static final int opc_iushr                    = 124;
jaroslav@810
   267
    public static final int opc_lushr                    = 125;
jaroslav@810
   268
    public static final int opc_iand                     = 126;
jaroslav@810
   269
    public static final int opc_land                     = 127;
jaroslav@810
   270
    public static final int opc_ior                      = 128;
jaroslav@810
   271
    public static final int opc_lor                      = 129;
jaroslav@810
   272
    public static final int opc_ixor                     = 130;
jaroslav@810
   273
    public static final int opc_lxor                     = 131;
jaroslav@810
   274
    public static final int opc_iinc                     = 132;
jaroslav@810
   275
    public static final int opc_i2l                      = 133;
jaroslav@810
   276
    public static final int opc_i2f                      = 134;
jaroslav@810
   277
    public static final int opc_i2d                      = 135;
jaroslav@810
   278
    public static final int opc_l2i                      = 136;
jaroslav@810
   279
    public static final int opc_l2f                      = 137;
jaroslav@810
   280
    public static final int opc_l2d                      = 138;
jaroslav@810
   281
    public static final int opc_f2i                      = 139;
jaroslav@810
   282
    public static final int opc_f2l                      = 140;
jaroslav@810
   283
    public static final int opc_f2d                      = 141;
jaroslav@810
   284
    public static final int opc_d2i                      = 142;
jaroslav@810
   285
    public static final int opc_d2l                      = 143;
jaroslav@810
   286
    public static final int opc_d2f                      = 144;
jaroslav@810
   287
    public static final int opc_i2b                      = 145;
jaroslav@810
   288
    public static final int opc_int2byte                 = 145;
jaroslav@810
   289
    public static final int opc_i2c                      = 146;
jaroslav@810
   290
    public static final int opc_int2char                 = 146;
jaroslav@810
   291
    public static final int opc_i2s                      = 147;
jaroslav@810
   292
    public static final int opc_int2short                = 147;
jaroslav@810
   293
    public static final int opc_lcmp                     = 148;
jaroslav@810
   294
    public static final int opc_fcmpl                    = 149;
jaroslav@810
   295
    public static final int opc_fcmpg                    = 150;
jaroslav@810
   296
    public static final int opc_dcmpl                    = 151;
jaroslav@810
   297
    public static final int opc_dcmpg                    = 152;
jaroslav@810
   298
    public static final int opc_ifeq                     = 153;
jaroslav@810
   299
    public static final int opc_ifne                     = 154;
jaroslav@810
   300
    public static final int opc_iflt                     = 155;
jaroslav@810
   301
    public static final int opc_ifge                     = 156;
jaroslav@810
   302
    public static final int opc_ifgt                     = 157;
jaroslav@810
   303
    public static final int opc_ifle                     = 158;
jaroslav@810
   304
    public static final int opc_if_icmpeq                = 159;
jaroslav@810
   305
    public static final int opc_if_icmpne                = 160;
jaroslav@810
   306
    public static final int opc_if_icmplt                = 161;
jaroslav@810
   307
    public static final int opc_if_icmpge                = 162;
jaroslav@810
   308
    public static final int opc_if_icmpgt                = 163;
jaroslav@810
   309
    public static final int opc_if_icmple                = 164;
jaroslav@810
   310
    public static final int opc_if_acmpeq                = 165;
jaroslav@810
   311
    public static final int opc_if_acmpne                = 166;
jaroslav@810
   312
    public static final int opc_goto                     = 167;
jaroslav@810
   313
    public static final int opc_jsr                      = 168;
jaroslav@810
   314
    public static final int opc_ret                      = 169;
jaroslav@810
   315
    public static final int opc_tableswitch              = 170;
jaroslav@810
   316
    public static final int opc_lookupswitch             = 171;
jaroslav@810
   317
    public static final int opc_ireturn                  = 172;
jaroslav@810
   318
    public static final int opc_lreturn                  = 173;
jaroslav@810
   319
    public static final int opc_freturn                  = 174;
jaroslav@810
   320
    public static final int opc_dreturn                  = 175;
jaroslav@810
   321
    public static final int opc_areturn                  = 176;
jaroslav@810
   322
    public static final int opc_return                   = 177;
jaroslav@810
   323
    public static final int opc_getstatic                = 178;
jaroslav@810
   324
    public static final int opc_putstatic                = 179;
jaroslav@810
   325
    public static final int opc_getfield                 = 180;
jaroslav@810
   326
    public static final int opc_putfield                 = 181;
jaroslav@810
   327
    public static final int opc_invokevirtual            = 182;
jaroslav@810
   328
    public static final int opc_invokenonvirtual         = 183;
jaroslav@810
   329
    public static final int opc_invokespecial            = 183;
jaroslav@810
   330
    public static final int opc_invokestatic             = 184;
jaroslav@810
   331
    public static final int opc_invokeinterface          = 185;
jaroslav@810
   332
//    public static final int opc_xxxunusedxxx             = 186;
jaroslav@810
   333
    public static final int opc_new                      = 187;
jaroslav@810
   334
    public static final int opc_newarray                 = 188;
jaroslav@810
   335
    public static final int opc_anewarray                = 189;
jaroslav@810
   336
    public static final int opc_arraylength              = 190;
jaroslav@810
   337
    public static final int opc_athrow                   = 191;
jaroslav@810
   338
    public static final int opc_checkcast                = 192;
jaroslav@810
   339
    public static final int opc_instanceof               = 193;
jaroslav@810
   340
    public static final int opc_monitorenter             = 194;
jaroslav@810
   341
    public static final int opc_monitorexit              = 195;
jaroslav@810
   342
    public static final int opc_wide                     = 196;
jaroslav@810
   343
    public static final int opc_multianewarray           = 197;
jaroslav@810
   344
    public static final int opc_ifnull                   = 198;
jaroslav@810
   345
    public static final int opc_ifnonnull                = 199;
jaroslav@810
   346
    public static final int opc_goto_w                   = 200;
jaroslav@810
   347
    public static final int opc_jsr_w                    = 201;
jaroslav@810
   348
        /* Pseudo-instructions */
jaroslav@810
   349
    public static final int opc_bytecode                 = 203;
jaroslav@810
   350
    public static final int opc_try                      = 204;
jaroslav@810
   351
    public static final int opc_endtry                   = 205;
jaroslav@810
   352
    public static final int opc_catch                    = 206;
jaroslav@810
   353
    public static final int opc_var                      = 207;
jaroslav@810
   354
    public static final int opc_endvar                   = 208;
jaroslav@810
   355
    public static final int opc_localsmap                = 209;
jaroslav@810
   356
    public static final int opc_stackmap                 = 210;
jaroslav@810
   357
        /* PicoJava prefixes */
jaroslav@810
   358
    public static final int opc_nonpriv                  = 254;
jaroslav@810
   359
    public static final int opc_priv                     = 255;
jaroslav@810
   360
jaroslav@810
   361
        /* Wide instructions */
jaroslav@810
   362
    public static final int opc_iload_w         = (opc_wide<<8)|opc_iload;
jaroslav@810
   363
    public static final int opc_lload_w         = (opc_wide<<8)|opc_lload;
jaroslav@810
   364
    public static final int opc_fload_w         = (opc_wide<<8)|opc_fload;
jaroslav@810
   365
    public static final int opc_dload_w         = (opc_wide<<8)|opc_dload;
jaroslav@810
   366
    public static final int opc_aload_w         = (opc_wide<<8)|opc_aload;
jaroslav@810
   367
    public static final int opc_istore_w        = (opc_wide<<8)|opc_istore;
jaroslav@810
   368
    public static final int opc_lstore_w        = (opc_wide<<8)|opc_lstore;
jaroslav@810
   369
    public static final int opc_fstore_w        = (opc_wide<<8)|opc_fstore;
jaroslav@810
   370
    public static final int opc_dstore_w        = (opc_wide<<8)|opc_dstore;
jaroslav@810
   371
    public static final int opc_astore_w        = (opc_wide<<8)|opc_astore;
jaroslav@810
   372
    public static final int opc_ret_w           = (opc_wide<<8)|opc_ret;
jaroslav@810
   373
    public static final int opc_iinc_w          = (opc_wide<<8)|opc_iinc;
jaroslav@810
   374
jaroslav@810
   375
    /* Opcode Names */
jaroslav@810
   376
  public static final String opcNamesTab[] = {
jaroslav@810
   377
        "nop",
jaroslav@810
   378
        "aconst_null",
jaroslav@810
   379
        "iconst_m1",
jaroslav@810
   380
        "iconst_0",
jaroslav@810
   381
        "iconst_1",
jaroslav@810
   382
        "iconst_2",
jaroslav@810
   383
        "iconst_3",
jaroslav@810
   384
        "iconst_4",
jaroslav@810
   385
        "iconst_5",
jaroslav@810
   386
        "lconst_0",
jaroslav@810
   387
        "lconst_1",
jaroslav@810
   388
        "fconst_0",
jaroslav@810
   389
        "fconst_1",
jaroslav@810
   390
        "fconst_2",
jaroslav@810
   391
        "dconst_0",
jaroslav@810
   392
        "dconst_1",
jaroslav@810
   393
        "bipush",
jaroslav@810
   394
        "sipush",
jaroslav@810
   395
        "ldc",
jaroslav@810
   396
        "ldc_w",
jaroslav@810
   397
        "ldc2_w",
jaroslav@810
   398
        "iload",
jaroslav@810
   399
        "lload",
jaroslav@810
   400
        "fload",
jaroslav@810
   401
        "dload",
jaroslav@810
   402
        "aload",
jaroslav@810
   403
        "iload_0",
jaroslav@810
   404
        "iload_1",
jaroslav@810
   405
        "iload_2",
jaroslav@810
   406
        "iload_3",
jaroslav@810
   407
        "lload_0",
jaroslav@810
   408
        "lload_1",
jaroslav@810
   409
        "lload_2",
jaroslav@810
   410
        "lload_3",
jaroslav@810
   411
        "fload_0",
jaroslav@810
   412
        "fload_1",
jaroslav@810
   413
        "fload_2",
jaroslav@810
   414
        "fload_3",
jaroslav@810
   415
        "dload_0",
jaroslav@810
   416
        "dload_1",
jaroslav@810
   417
        "dload_2",
jaroslav@810
   418
        "dload_3",
jaroslav@810
   419
        "aload_0",
jaroslav@810
   420
        "aload_1",
jaroslav@810
   421
        "aload_2",
jaroslav@810
   422
        "aload_3",
jaroslav@810
   423
        "iaload",
jaroslav@810
   424
        "laload",
jaroslav@810
   425
        "faload",
jaroslav@810
   426
        "daload",
jaroslav@810
   427
        "aaload",
jaroslav@810
   428
        "baload",
jaroslav@810
   429
        "caload",
jaroslav@810
   430
        "saload",
jaroslav@810
   431
        "istore",
jaroslav@810
   432
        "lstore",
jaroslav@810
   433
        "fstore",
jaroslav@810
   434
        "dstore",
jaroslav@810
   435
        "astore",
jaroslav@810
   436
        "istore_0",
jaroslav@810
   437
        "istore_1",
jaroslav@810
   438
        "istore_2",
jaroslav@810
   439
        "istore_3",
jaroslav@810
   440
        "lstore_0",
jaroslav@810
   441
        "lstore_1",
jaroslav@810
   442
        "lstore_2",
jaroslav@810
   443
        "lstore_3",
jaroslav@810
   444
        "fstore_0",
jaroslav@810
   445
        "fstore_1",
jaroslav@810
   446
        "fstore_2",
jaroslav@810
   447
        "fstore_3",
jaroslav@810
   448
        "dstore_0",
jaroslav@810
   449
        "dstore_1",
jaroslav@810
   450
        "dstore_2",
jaroslav@810
   451
        "dstore_3",
jaroslav@810
   452
        "astore_0",
jaroslav@810
   453
        "astore_1",
jaroslav@810
   454
        "astore_2",
jaroslav@810
   455
        "astore_3",
jaroslav@810
   456
        "iastore",
jaroslav@810
   457
        "lastore",
jaroslav@810
   458
        "fastore",
jaroslav@810
   459
        "dastore",
jaroslav@810
   460
        "aastore",
jaroslav@810
   461
        "bastore",
jaroslav@810
   462
        "castore",
jaroslav@810
   463
        "sastore",
jaroslav@810
   464
        "pop",
jaroslav@810
   465
        "pop2",
jaroslav@810
   466
        "dup",
jaroslav@810
   467
        "dup_x1",
jaroslav@810
   468
        "dup_x2",
jaroslav@810
   469
        "dup2",
jaroslav@810
   470
        "dup2_x1",
jaroslav@810
   471
        "dup2_x2",
jaroslav@810
   472
        "swap",
jaroslav@810
   473
        "iadd",
jaroslav@810
   474
        "ladd",
jaroslav@810
   475
        "fadd",
jaroslav@810
   476
        "dadd",
jaroslav@810
   477
        "isub",
jaroslav@810
   478
        "lsub",
jaroslav@810
   479
        "fsub",
jaroslav@810
   480
        "dsub",
jaroslav@810
   481
        "imul",
jaroslav@810
   482
        "lmul",
jaroslav@810
   483
        "fmul",
jaroslav@810
   484
        "dmul",
jaroslav@810
   485
        "idiv",
jaroslav@810
   486
        "ldiv",
jaroslav@810
   487
        "fdiv",
jaroslav@810
   488
        "ddiv",
jaroslav@810
   489
        "irem",
jaroslav@810
   490
        "lrem",
jaroslav@810
   491
        "frem",
jaroslav@810
   492
        "drem",
jaroslav@810
   493
        "ineg",
jaroslav@810
   494
        "lneg",
jaroslav@810
   495
        "fneg",
jaroslav@810
   496
        "dneg",
jaroslav@810
   497
        "ishl",
jaroslav@810
   498
        "lshl",
jaroslav@810
   499
        "ishr",
jaroslav@810
   500
        "lshr",
jaroslav@810
   501
        "iushr",
jaroslav@810
   502
        "lushr",
jaroslav@810
   503
        "iand",
jaroslav@810
   504
        "land",
jaroslav@810
   505
        "ior",
jaroslav@810
   506
        "lor",
jaroslav@810
   507
        "ixor",
jaroslav@810
   508
        "lxor",
jaroslav@810
   509
        "iinc",
jaroslav@810
   510
        "i2l",
jaroslav@810
   511
        "i2f",
jaroslav@810
   512
        "i2d",
jaroslav@810
   513
        "l2i",
jaroslav@810
   514
        "l2f",
jaroslav@810
   515
        "l2d",
jaroslav@810
   516
        "f2i",
jaroslav@810
   517
        "f2l",
jaroslav@810
   518
        "f2d",
jaroslav@810
   519
        "d2i",
jaroslav@810
   520
        "d2l",
jaroslav@810
   521
        "d2f",
jaroslav@810
   522
        "i2b",
jaroslav@810
   523
        "i2c",
jaroslav@810
   524
        "i2s",
jaroslav@810
   525
        "lcmp",
jaroslav@810
   526
        "fcmpl",
jaroslav@810
   527
        "fcmpg",
jaroslav@810
   528
        "dcmpl",
jaroslav@810
   529
        "dcmpg",
jaroslav@810
   530
        "ifeq",
jaroslav@810
   531
        "ifne",
jaroslav@810
   532
        "iflt",
jaroslav@810
   533
        "ifge",
jaroslav@810
   534
        "ifgt",
jaroslav@810
   535
        "ifle",
jaroslav@810
   536
        "if_icmpeq",
jaroslav@810
   537
        "if_icmpne",
jaroslav@810
   538
        "if_icmplt",
jaroslav@810
   539
        "if_icmpge",
jaroslav@810
   540
        "if_icmpgt",
jaroslav@810
   541
        "if_icmple",
jaroslav@810
   542
        "if_acmpeq",
jaroslav@810
   543
        "if_acmpne",
jaroslav@810
   544
        "goto",
jaroslav@810
   545
        "jsr",
jaroslav@810
   546
        "ret",
jaroslav@810
   547
        "tableswitch",
jaroslav@810
   548
        "lookupswitch",
jaroslav@810
   549
        "ireturn",
jaroslav@810
   550
        "lreturn",
jaroslav@810
   551
        "freturn",
jaroslav@810
   552
        "dreturn",
jaroslav@810
   553
        "areturn",
jaroslav@810
   554
        "return",
jaroslav@810
   555
        "getstatic",
jaroslav@810
   556
        "putstatic",
jaroslav@810
   557
        "getfield",
jaroslav@810
   558
        "putfield",
jaroslav@810
   559
        "invokevirtual",
jaroslav@810
   560
        "invokespecial", //     was "invokenonvirtual",
jaroslav@810
   561
        "invokestatic",
jaroslav@810
   562
        "invokeinterface",
jaroslav@810
   563
        "bytecode 186", //"xxxunusedxxx",
jaroslav@810
   564
        "new",
jaroslav@810
   565
        "newarray",
jaroslav@810
   566
        "anewarray",
jaroslav@810
   567
        "arraylength",
jaroslav@810
   568
        "athrow",
jaroslav@810
   569
        "checkcast",
jaroslav@810
   570
        "instanceof",
jaroslav@810
   571
        "monitorenter",
jaroslav@810
   572
        "monitorexit",
jaroslav@810
   573
         null, // "wide",
jaroslav@810
   574
        "multianewarray",
jaroslav@810
   575
        "ifnull",
jaroslav@810
   576
        "ifnonnull",
jaroslav@810
   577
        "goto_w",
jaroslav@810
   578
        "jsr_w",
jaroslav@810
   579
        "bytecode 202", // "breakpoint",
jaroslav@810
   580
        "bytecode",
jaroslav@810
   581
        "try",
jaroslav@810
   582
        "endtry",
jaroslav@810
   583
        "catch",
jaroslav@810
   584
        "var",
jaroslav@810
   585
        "endvar",
jaroslav@810
   586
        "locals_map",
jaroslav@810
   587
        "stack_map"
jaroslav@810
   588
  };
jaroslav@810
   589
jaroslav@810
   590
    /* Opcode Lengths */
jaroslav@810
   591
  public static final int opcLengthsTab[] = {
jaroslav@810
   592
        1,
jaroslav@810
   593
        1,
jaroslav@810
   594
        1,
jaroslav@810
   595
        1,
jaroslav@810
   596
        1,
jaroslav@810
   597
        1,
jaroslav@810
   598
        1,
jaroslav@810
   599
        1,
jaroslav@810
   600
        1,
jaroslav@810
   601
        1,
jaroslav@810
   602
        1,
jaroslav@810
   603
        1,
jaroslav@810
   604
        1,
jaroslav@810
   605
        1,
jaroslav@810
   606
        1,
jaroslav@810
   607
        1,
jaroslav@810
   608
        2,
jaroslav@810
   609
        3,
jaroslav@810
   610
        2,
jaroslav@810
   611
        3,
jaroslav@810
   612
        3,
jaroslav@810
   613
        2,
jaroslav@810
   614
        2,
jaroslav@810
   615
        2,
jaroslav@810
   616
        2,
jaroslav@810
   617
        2,
jaroslav@810
   618
        1,
jaroslav@810
   619
        1,
jaroslav@810
   620
        1,
jaroslav@810
   621
        1,
jaroslav@810
   622
        1,
jaroslav@810
   623
        1,
jaroslav@810
   624
        1,
jaroslav@810
   625
        1,
jaroslav@810
   626
        1,
jaroslav@810
   627
        1,
jaroslav@810
   628
        1,
jaroslav@810
   629
        1,
jaroslav@810
   630
        1,
jaroslav@810
   631
        1,
jaroslav@810
   632
        1,
jaroslav@810
   633
        1,
jaroslav@810
   634
        1,
jaroslav@810
   635
        1,
jaroslav@810
   636
        1,
jaroslav@810
   637
        1,
jaroslav@810
   638
        1,
jaroslav@810
   639
        1,
jaroslav@810
   640
        1,
jaroslav@810
   641
        1,
jaroslav@810
   642
        1,
jaroslav@810
   643
        1,
jaroslav@810
   644
        1,
jaroslav@810
   645
        1,
jaroslav@810
   646
        2,
jaroslav@810
   647
        2,
jaroslav@810
   648
        2,
jaroslav@810
   649
        2,
jaroslav@810
   650
        2,
jaroslav@810
   651
        1,
jaroslav@810
   652
        1,
jaroslav@810
   653
        1,
jaroslav@810
   654
        1,
jaroslav@810
   655
        1,
jaroslav@810
   656
        1,
jaroslav@810
   657
        1,
jaroslav@810
   658
        1,
jaroslav@810
   659
        1,
jaroslav@810
   660
        1,
jaroslav@810
   661
        1,
jaroslav@810
   662
        1,
jaroslav@810
   663
        1,
jaroslav@810
   664
        1,
jaroslav@810
   665
        1,
jaroslav@810
   666
        1,
jaroslav@810
   667
        1,
jaroslav@810
   668
        1,
jaroslav@810
   669
        1,
jaroslav@810
   670
        1,
jaroslav@810
   671
        1,
jaroslav@810
   672
        1,
jaroslav@810
   673
        1,
jaroslav@810
   674
        1,
jaroslav@810
   675
        1,
jaroslav@810
   676
        1,
jaroslav@810
   677
        1,
jaroslav@810
   678
        1,
jaroslav@810
   679
        1,
jaroslav@810
   680
        1,
jaroslav@810
   681
        1,
jaroslav@810
   682
        1,
jaroslav@810
   683
        1,
jaroslav@810
   684
        1,
jaroslav@810
   685
        1,
jaroslav@810
   686
        1,
jaroslav@810
   687
        1,
jaroslav@810
   688
        1,
jaroslav@810
   689
        1,
jaroslav@810
   690
        1,
jaroslav@810
   691
        1,
jaroslav@810
   692
        1,
jaroslav@810
   693
        1,
jaroslav@810
   694
        1,
jaroslav@810
   695
        1,
jaroslav@810
   696
        1,
jaroslav@810
   697
        1,
jaroslav@810
   698
        1,
jaroslav@810
   699
        1,
jaroslav@810
   700
        1,
jaroslav@810
   701
        1,
jaroslav@810
   702
        1,
jaroslav@810
   703
        1,
jaroslav@810
   704
        1,
jaroslav@810
   705
        1,
jaroslav@810
   706
        1,
jaroslav@810
   707
        1,
jaroslav@810
   708
        1,
jaroslav@810
   709
        1,
jaroslav@810
   710
        1,
jaroslav@810
   711
        1,
jaroslav@810
   712
        1,
jaroslav@810
   713
        1,
jaroslav@810
   714
        1,
jaroslav@810
   715
        1,
jaroslav@810
   716
        1,
jaroslav@810
   717
        1,
jaroslav@810
   718
        1,
jaroslav@810
   719
        1,
jaroslav@810
   720
        1,
jaroslav@810
   721
        1,
jaroslav@810
   722
        1,
jaroslav@810
   723
        1,
jaroslav@810
   724
        3,
jaroslav@810
   725
        1,
jaroslav@810
   726
        1,
jaroslav@810
   727
        1,
jaroslav@810
   728
        1,
jaroslav@810
   729
        1,
jaroslav@810
   730
        1,
jaroslav@810
   731
        1,
jaroslav@810
   732
        1,
jaroslav@810
   733
        1,
jaroslav@810
   734
        1,
jaroslav@810
   735
        1,
jaroslav@810
   736
        1,
jaroslav@810
   737
        1,
jaroslav@810
   738
        1,
jaroslav@810
   739
        1,
jaroslav@810
   740
        1,
jaroslav@810
   741
        1,
jaroslav@810
   742
        1,
jaroslav@810
   743
        1,
jaroslav@810
   744
        1,
jaroslav@810
   745
        3,
jaroslav@810
   746
        3,
jaroslav@810
   747
        3,
jaroslav@810
   748
        3,
jaroslav@810
   749
        3,
jaroslav@810
   750
        3,
jaroslav@810
   751
        3,
jaroslav@810
   752
        3,
jaroslav@810
   753
        3,
jaroslav@810
   754
        3,
jaroslav@810
   755
        3,
jaroslav@810
   756
        3,
jaroslav@810
   757
        3,
jaroslav@810
   758
        3,
jaroslav@810
   759
        3,
jaroslav@810
   760
        3,
jaroslav@810
   761
        2,
jaroslav@810
   762
        99,
jaroslav@810
   763
        99,
jaroslav@810
   764
        1,
jaroslav@810
   765
        1,
jaroslav@810
   766
        1,
jaroslav@810
   767
        1,
jaroslav@810
   768
        1,
jaroslav@810
   769
        1,
jaroslav@810
   770
        3,
jaroslav@810
   771
        3,
jaroslav@810
   772
        3,
jaroslav@810
   773
        3,
jaroslav@810
   774
        3,
jaroslav@810
   775
        3,
jaroslav@810
   776
        3,
jaroslav@810
   777
        5,
jaroslav@810
   778
        0,
jaroslav@810
   779
        3,
jaroslav@810
   780
        2,
jaroslav@810
   781
        3,
jaroslav@810
   782
        1,
jaroslav@810
   783
        1,
jaroslav@810
   784
        3,
jaroslav@810
   785
        3,
jaroslav@810
   786
        1,
jaroslav@810
   787
        1,
jaroslav@810
   788
        0, // wide
jaroslav@810
   789
        4,
jaroslav@810
   790
        3,
jaroslav@810
   791
        3,
jaroslav@810
   792
        5,
jaroslav@810
   793
        5,
jaroslav@810
   794
        1,
jaroslav@810
   795
        1, 0, 0, 0, 0, 0 // pseudo
jaroslav@810
   796
  };
jaroslav@810
   797
jaroslav@810
   798
     /**
jaroslav@810
   799
     * End of input
jaroslav@810
   800
     */
jaroslav@810
   801
    public static final int EOF = -1;
jaroslav@810
   802
jaroslav@810
   803
   /*
jaroslav@810
   804
     * Flags
jaroslav@810
   805
     */
jaroslav@810
   806
    public static final int F_VERBOSE           = 1 << 0;
jaroslav@810
   807
    public static final int F_DUMP              = 1 << 1;
jaroslav@810
   808
    public static final int F_WARNINGS          = 1 << 2;
jaroslav@810
   809
    public static final int F_DEBUG             = 1 << 3;
jaroslav@810
   810
    public static final int F_OPTIMIZE          = 1 << 4;
jaroslav@810
   811
    public static final int F_DEPENDENCIES      = 1 << 5;
jaroslav@810
   812
jaroslav@810
   813
    /*
jaroslav@810
   814
     * Type codes
jaroslav@810
   815
     */
jaroslav@810
   816
    public static final int TC_BOOLEAN   = 0;
jaroslav@810
   817
    public static final int TC_BYTE      = 1;
jaroslav@810
   818
    public static final int TC_CHAR      = 2;
jaroslav@810
   819
    public static final int TC_SHORT     = 3;
jaroslav@810
   820
    public static final int TC_INT       = 4;
jaroslav@810
   821
    public static final int TC_LONG      = 5;
jaroslav@810
   822
    public static final int TC_FLOAT     = 6;
jaroslav@810
   823
    public static final int TC_DOUBLE    = 7;
jaroslav@810
   824
    public static final int TC_NULL      = 8;
jaroslav@810
   825
    public static final int TC_ARRAY     = 9;
jaroslav@810
   826
    public static final int TC_CLASS     = 10;
jaroslav@810
   827
    public static final int TC_VOID      = 11;
jaroslav@810
   828
    public static final int TC_METHOD    = 12;
jaroslav@810
   829
    public static final int TC_ERROR     = 13;
jaroslav@810
   830
jaroslav@810
   831
    /*
jaroslav@810
   832
     * Type Masks
jaroslav@810
   833
     */
jaroslav@810
   834
    public static final int TM_NULL      = 1 << TC_NULL;
jaroslav@810
   835
    public static final int TM_VOID      = 1 << TC_VOID;
jaroslav@810
   836
    public static final int TM_BOOLEAN   = 1 << TC_BOOLEAN;
jaroslav@810
   837
    public static final int TM_BYTE      = 1 << TC_BYTE;
jaroslav@810
   838
    public static final int TM_CHAR      = 1 << TC_CHAR;
jaroslav@810
   839
    public static final int TM_SHORT     = 1 << TC_SHORT;
jaroslav@810
   840
    public static final int TM_INT       = 1 << TC_INT;
jaroslav@810
   841
    public static final int TM_LONG      = 1 << TC_LONG;
jaroslav@810
   842
    public static final int TM_FLOAT     = 1 << TC_FLOAT;
jaroslav@810
   843
    public static final int TM_DOUBLE    = 1 << TC_DOUBLE;
jaroslav@810
   844
    public static final int TM_ARRAY     = 1 << TC_ARRAY;
jaroslav@810
   845
    public static final int TM_CLASS     = 1 << TC_CLASS;
jaroslav@810
   846
    public static final int TM_METHOD    = 1 << TC_METHOD;
jaroslav@810
   847
    public static final int TM_ERROR     = 1 << TC_ERROR;
jaroslav@810
   848
jaroslav@810
   849
    public static final int TM_INT32     = TM_BYTE | TM_SHORT | TM_CHAR | TM_INT;
jaroslav@810
   850
    public static final int TM_NUM32     = TM_INT32 | TM_FLOAT;
jaroslav@810
   851
    public static final int TM_NUM64     = TM_LONG | TM_DOUBLE;
jaroslav@810
   852
    public static final int TM_INTEGER   = TM_INT32 | TM_LONG;
jaroslav@810
   853
    public static final int TM_REAL      = TM_FLOAT | TM_DOUBLE;
jaroslav@810
   854
    public static final int TM_NUMBER    = TM_INTEGER | TM_REAL;
jaroslav@810
   855
    public static final int TM_REFERENCE = TM_ARRAY | TM_CLASS | TM_NULL;
jaroslav@810
   856
jaroslav@810
   857
    /*
jaroslav@810
   858
     * Class status
jaroslav@810
   859
     */
jaroslav@810
   860
    public static final int CS_UNDEFINED        = 0;
jaroslav@810
   861
    public static final int CS_UNDECIDED        = 1;
jaroslav@810
   862
    public static final int CS_BINARY           = 2;
jaroslav@810
   863
    public static final int CS_SOURCE           = 3;
jaroslav@810
   864
    public static final int CS_PARSED           = 4;
jaroslav@810
   865
    public static final int CS_COMPILED         = 5;
jaroslav@810
   866
    public static final int CS_NOTFOUND         = 6;
jaroslav@810
   867
jaroslav@810
   868
    /*
jaroslav@810
   869
     * Attributes
jaroslav@810
   870
     */
jaroslav@810
   871
    public static final int ATT_ALL             = -1;
jaroslav@810
   872
    public static final int ATT_CODE            = 1;
jaroslav@810
   873
jaroslav@810
   874
    /*
jaroslav@810
   875
     * Number of bits used in file offsets
jaroslav@810
   876
     */
jaroslav@810
   877
    public static final int OFFSETBITS          = 19;
jaroslav@810
   878
    public static final int MAXFILESIZE         = (1 << OFFSETBITS) - 1;
jaroslav@810
   879
    public static final int MAXLINENUMBER       = (1 << (32 - OFFSETBITS)) - 1;
jaroslav@810
   880
jaroslav@810
   881
    /*
jaroslav@810
   882
     * Operators
jaroslav@810
   883
     */
jaroslav@810
   884
    public final int COMMA              = 0;
jaroslav@810
   885
    public final int ASSIGN             = 1;
jaroslav@810
   886
jaroslav@810
   887
    public final int ASGMUL             = 2;
jaroslav@810
   888
    public final int ASGDIV             = 3;
jaroslav@810
   889
    public final int ASGREM             = 4;
jaroslav@810
   890
    public final int ASGADD             = 5;
jaroslav@810
   891
    public final int ASGSUB             = 6;
jaroslav@810
   892
    public final int ASGLSHIFT          = 7;
jaroslav@810
   893
    public final int ASGRSHIFT          = 8;
jaroslav@810
   894
    public final int ASGURSHIFT         = 9;
jaroslav@810
   895
    public final int ASGBITAND          = 10;
jaroslav@810
   896
    public final int ASGBITOR           = 11;
jaroslav@810
   897
    public final int ASGBITXOR          = 12;
jaroslav@810
   898
jaroslav@810
   899
    public final int COND               = 13;
jaroslav@810
   900
    public final int OR                 = 14;
jaroslav@810
   901
    public final int AND                = 15;
jaroslav@810
   902
    public final int BITOR              = 16;
jaroslav@810
   903
    public final int BITXOR             = 17;
jaroslav@810
   904
    public final int BITAND             = 18;
jaroslav@810
   905
    public final int NE                 = 19;
jaroslav@810
   906
    public final int EQ                 = 20;
jaroslav@810
   907
    public final int GE                 = 21;
jaroslav@810
   908
    public final int GT                 = 22;
jaroslav@810
   909
    public final int LE                 = 23;
jaroslav@810
   910
    public final int LT                 = 24;
jaroslav@810
   911
    public final int INSTANCEOF         = 25;
jaroslav@810
   912
    public final int LSHIFT             = 26;
jaroslav@810
   913
    public final int RSHIFT             = 27;
jaroslav@810
   914
    public final int URSHIFT            = 28;
jaroslav@810
   915
    public final int ADD                = 29;
jaroslav@810
   916
    public final int SUB                = 30;
jaroslav@810
   917
    public final int DIV                = 31;
jaroslav@810
   918
    public final int REM                = 32;
jaroslav@810
   919
    public final int MUL                = 33;
jaroslav@810
   920
    public final int CAST               = 34;           // (x)y
jaroslav@810
   921
    public final int POS                = 35;           // +x
jaroslav@810
   922
    public final int NEG                = 36;           // -x
jaroslav@810
   923
    public final int NOT                = 37;
jaroslav@810
   924
    public final int BITNOT             = 38;
jaroslav@810
   925
    public final int PREINC             = 39;           // ++x
jaroslav@810
   926
    public final int PREDEC             = 40;           // --x
jaroslav@810
   927
    public final int NEWARRAY           = 41;
jaroslav@810
   928
    public final int NEWINSTANCE        = 42;
jaroslav@810
   929
    public final int NEWFROMNAME        = 43;
jaroslav@810
   930
    public final int POSTINC            = 44;           // x++
jaroslav@810
   931
    public final int POSTDEC            = 45;           // x--
jaroslav@810
   932
    public final int FIELD              = 46;
jaroslav@810
   933
    public final int METHOD             = 47;           // x(y)
jaroslav@810
   934
    public final int ARRAYACCESS        = 48;           // x[y]
jaroslav@810
   935
    public final int NEW                = 49;
jaroslav@810
   936
    public final int INC                = 50;
jaroslav@810
   937
    public final int DEC                = 51;
jaroslav@810
   938
jaroslav@810
   939
    public final int CONVERT            = 55;           // implicit conversion
jaroslav@810
   940
    public final int EXPR               = 56;           // (x)
jaroslav@810
   941
    public final int ARRAY              = 57;           // {x, y, ...}
jaroslav@810
   942
    public final int GOTO               = 58;
jaroslav@810
   943
jaroslav@810
   944
    /*
jaroslav@810
   945
     * Value tokens
jaroslav@810
   946
     */
jaroslav@810
   947
    public final int IDENT              = 60;
jaroslav@810
   948
    public final int BOOLEANVAL         = 61;
jaroslav@810
   949
    public final int BYTEVAL            = 62;
jaroslav@810
   950
    public final int CHARVAL            = 63;
jaroslav@810
   951
    public final int SHORTVAL           = 64;
jaroslav@810
   952
    public final int INTVAL                     = 65;
jaroslav@810
   953
    public final int LONGVAL            = 66;
jaroslav@810
   954
    public final int FLOATVAL           = 67;
jaroslav@810
   955
    public final int DOUBLEVAL          = 68;
jaroslav@810
   956
    public final int STRINGVAL          = 69;
jaroslav@810
   957
jaroslav@810
   958
    /*
jaroslav@810
   959
     * Type keywords
jaroslav@810
   960
     */
jaroslav@810
   961
    public final int BYTE               = 70;
jaroslav@810
   962
    public final int CHAR               = 71;
jaroslav@810
   963
    public final int SHORT              = 72;
jaroslav@810
   964
    public final int INT                = 73;
jaroslav@810
   965
    public final int LONG               = 74;
jaroslav@810
   966
    public final int FLOAT              = 75;
jaroslav@810
   967
    public final int DOUBLE             = 76;
jaroslav@810
   968
    public final int VOID               = 77;
jaroslav@810
   969
    public final int BOOLEAN            = 78;
jaroslav@810
   970
jaroslav@810
   971
    /*
jaroslav@810
   972
     * Expression keywords
jaroslav@810
   973
     */
jaroslav@810
   974
    public final int TRUE               = 80;
jaroslav@810
   975
    public final int FALSE              = 81;
jaroslav@810
   976
    public final int THIS               = 82;
jaroslav@810
   977
    public final int SUPER              = 83;
jaroslav@810
   978
    public final int NULL               = 84;
jaroslav@810
   979
jaroslav@810
   980
    /*
jaroslav@810
   981
     * Statement keywords
jaroslav@810
   982
     */
jaroslav@810
   983
    public final int IF                 = 90;
jaroslav@810
   984
    public final int ELSE               = 91;
jaroslav@810
   985
    public final int FOR                = 92;
jaroslav@810
   986
    public final int WHILE              = 93;
jaroslav@810
   987
    public final int DO                 = 94;
jaroslav@810
   988
    public final int SWITCH             = 95;
jaroslav@810
   989
    public final int CASE               = 96;
jaroslav@810
   990
    public final int DEFAULT            = 97;
jaroslav@810
   991
    public final int BREAK              = 98;
jaroslav@810
   992
    public final int CONTINUE           = 99;
jaroslav@810
   993
    public final int RETURN             = 100;
jaroslav@810
   994
    public final int TRY                = 101;
jaroslav@810
   995
    public final int CATCH              = 102;
jaroslav@810
   996
    public final int FINALLY            = 103;
jaroslav@810
   997
    public final int THROW              = 104;
jaroslav@810
   998
    public final int STAT               = 105;
jaroslav@810
   999
    public final int EXPRESSION         = 106;
jaroslav@810
  1000
    public final int DECLARATION        = 107;
jaroslav@810
  1001
    public final int VARDECLARATION     = 108;
jaroslav@810
  1002
jaroslav@810
  1003
    /*
jaroslav@810
  1004
     * Declaration keywords
jaroslav@810
  1005
     */
jaroslav@810
  1006
    public final int IMPORT             = 110;
jaroslav@810
  1007
    public final int CLASS              = 111;
jaroslav@810
  1008
    public final int EXTENDS            = 112;
jaroslav@810
  1009
    public final int IMPLEMENTS         = 113;
jaroslav@810
  1010
    public final int INTERFACE          = 114;
jaroslav@810
  1011
    public final int PACKAGE            = 115;
jaroslav@810
  1012
jaroslav@810
  1013
    /*
jaroslav@810
  1014
     * Modifier keywords
jaroslav@810
  1015
     */
jaroslav@810
  1016
    public final int PRIVATE    = 120;
jaroslav@810
  1017
    public final int PUBLIC             = 121;
jaroslav@810
  1018
    public final int PROTECTED  = 122;
jaroslav@810
  1019
    public final int CONST              = 123;
jaroslav@810
  1020
    public final int STATIC             = 124;
jaroslav@810
  1021
    public final int TRANSIENT          = 125;
jaroslav@810
  1022
    public final int SYNCHRONIZED       = 126;
jaroslav@810
  1023
    public final int NATIVE             = 127;
jaroslav@810
  1024
    public final int FINAL              = 128;
jaroslav@810
  1025
    public final int VOLATILE   = 129;
jaroslav@810
  1026
    public final int ABSTRACT   = 130;
jaroslav@810
  1027
    public final int STRICT             = 165;
jaroslav@810
  1028
jaroslav@810
  1029
    /*
jaroslav@810
  1030
     * Punctuation
jaroslav@810
  1031
     */
jaroslav@810
  1032
    public final int SEMICOLON  = 135;
jaroslav@810
  1033
    public final int COLON              = 136;
jaroslav@810
  1034
    public final int QUESTIONMARK       = 137;
jaroslav@810
  1035
    public final int LBRACE             = 138;
jaroslav@810
  1036
    public final int RBRACE             = 139;
jaroslav@810
  1037
    public final int LPAREN             = 140;
jaroslav@810
  1038
    public final int RPAREN             = 141;
jaroslav@810
  1039
    public final int LSQBRACKET = 142;
jaroslav@810
  1040
    public final int RSQBRACKET = 143;
jaroslav@810
  1041
    public final int THROWS     = 144;
jaroslav@810
  1042
jaroslav@810
  1043
    /*
jaroslav@810
  1044
     * Special tokens
jaroslav@810
  1045
     */
jaroslav@810
  1046
    public final int ERROR              = 145;          // an error
jaroslav@810
  1047
    public final int COMMENT    = 146;          // not used anymore.
jaroslav@810
  1048
    public final int TYPE               = 147;
jaroslav@810
  1049
    public final int LENGTH             = 148;
jaroslav@810
  1050
    public final int INLINERETURN       = 149;
jaroslav@810
  1051
    public final int INLINEMETHOD       = 150;
jaroslav@810
  1052
    public final int INLINENEWINSTANCE  = 151;
jaroslav@810
  1053
jaroslav@810
  1054
    /*
jaroslav@810
  1055
     * Added for jasm
jaroslav@810
  1056
     */
jaroslav@810
  1057
        public final int METHODREF      = 152;
jaroslav@810
  1058
        public final int FIELDREF       = 153;
jaroslav@810
  1059
    public final int STACK              = 154;
jaroslav@810
  1060
    public final int LOCAL              = 155;
jaroslav@810
  1061
    public final int CPINDEX    = 156;
jaroslav@810
  1062
    public final int CPNAME             = 157;
jaroslav@810
  1063
    public final int SIGN               = 158;
jaroslav@810
  1064
    public final int BITS               = 159;
jaroslav@810
  1065
    public final int INF                = 160;
jaroslav@810
  1066
    public final int NAN                = 161;
jaroslav@810
  1067
    public final int INNERCLASS = 162;
jaroslav@810
  1068
    public final int OF         = 163;
jaroslav@810
  1069
    public final int SYNTHETIC          = 164;
jaroslav@810
  1070
// last used=165;
jaroslav@810
  1071
jaroslav@810
  1072
   /*
jaroslav@810
  1073
     * Operator precedence
jaroslav@810
  1074
     */
jaroslav@810
  1075
    public static final int opPrecedence[] = {
jaroslav@810
  1076
        10,     11,     11,     11,     11,     11,     11,     11,     11,     11,
jaroslav@810
  1077
        11,     11,     11,     12,     13,     14,     15,     16,     17,     18,
jaroslav@810
  1078
        18,     19,     19,     19,     19,     19,     20,     20,     20,     21,
jaroslav@810
  1079
        21,     22,     22,     22,     23,     24,     24,     24,     24,     24,
jaroslav@810
  1080
        24,     25,     25,     26,     26,     26,     26,     26,     26
jaroslav@810
  1081
    };
jaroslav@810
  1082
jaroslav@810
  1083
    /*
jaroslav@810
  1084
     * Operator names
jaroslav@810
  1085
     */
jaroslav@810
  1086
    public static final String opNames[] = {
jaroslav@810
  1087
        ",",            "=",            "*=",           "/=",           "%=",
jaroslav@810
  1088
        "+=",           "-=",           "<<=",          ">>=",          "<<<=",
jaroslav@810
  1089
        "&=",           "|=",           "^=",           "?:",           "||",
jaroslav@810
  1090
        "&&",           "|",            "^",            "&",            "!=",
jaroslav@810
  1091
        "==",           ">=",           ">",            "<=",           "<",
jaroslav@810
  1092
        "instanceof",   "<<",           ">>",           "<<<",          "+",
jaroslav@810
  1093
        "-",            "/",            "%",            "*",            "cast",
jaroslav@810
  1094
        "+",            "-",            "!",            "~",            "++",
jaroslav@810
  1095
        "--",           "new",          "new",          "new",          "++",
jaroslav@810
  1096
        "--",           "field",        "method",       "[]",           "new",
jaroslav@810
  1097
        "++",           "--",           null,           null,           null,
jaroslav@810
  1098
jaroslav@810
  1099
        "convert",      "expr",         "array",        "goto",         null,
jaroslav@810
  1100
jaroslav@810
  1101
        "Identifier",   "Boolean",      "Byte",         "Char",         "Short",
jaroslav@810
  1102
        "Integer",              "Long",         "Float",        "Double",       "String",
jaroslav@810
  1103
jaroslav@810
  1104
        "byte",         "char",         "short",        "int",          "long",
jaroslav@810
  1105
        "float",        "double",       "void",         "boolean",      null,
jaroslav@810
  1106
jaroslav@810
  1107
        "true",         "false",        "this",         "super",        "null",
jaroslav@810
  1108
        null,           null,           null,           null,           null,
jaroslav@810
  1109
jaroslav@810
  1110
        "if",           "else",         "for",          "while",        "do",
jaroslav@810
  1111
        "switch",       "case",         "default",      "break",        "continue",
jaroslav@810
  1112
        "return",       "try",          "catch",        "finally",      "throw",
jaroslav@810
  1113
        "stat",         "expression",   "declaration",  "declaration",  null,
jaroslav@810
  1114
jaroslav@810
  1115
        "import",       "class",        "extends",      "implements",   "interface",
jaroslav@810
  1116
        "package",      null,           null,           null,           null,
jaroslav@810
  1117
jaroslav@810
  1118
        "private",      "public",       "protected",    "const",        "static",
jaroslav@810
  1119
        "transient",    "synchronized", "native",       "final",        "volatile",
jaroslav@810
  1120
        "abstract",     null,           null,           null,           null,
jaroslav@810
  1121
jaroslav@810
  1122
        ";",            ":",            "?",            "{",            "}",
jaroslav@810
  1123
        "(",            ")",            "[",            "]",            "throws",
jaroslav@810
  1124
        "error",        "comment",      "type",         "length",       "inline-return",
jaroslav@810
  1125
        "inline-method", "inline-new",
jaroslav@810
  1126
        "method", "field", "stack", "locals", "CPINDEX", "CPName", "SIGN",
jaroslav@810
  1127
        "bits", "INF", "NaN", "InnerClass", "of", "synthetic"
jaroslav@810
  1128
    };
jaroslav@810
  1129
    
jaroslav@810
  1130
    static class AnnotationParser {
jaroslav@810
  1131
jaroslav@810
  1132
        private final boolean textual;
jaroslav@810
  1133
        private final boolean iterateArray;
jaroslav@810
  1134
jaroslav@810
  1135
        protected AnnotationParser(boolean textual, boolean iterateArray) {
jaroslav@810
  1136
            this.textual = textual;
jaroslav@810
  1137
            this.iterateArray = iterateArray;
jaroslav@810
  1138
        }
jaroslav@810
  1139
jaroslav@810
  1140
        protected void visitAnnotationStart(String type, boolean top) throws IOException {
jaroslav@810
  1141
        }
jaroslav@810
  1142
jaroslav@810
  1143
        protected void visitAnnotationEnd(String type, boolean top) throws IOException {
jaroslav@810
  1144
        }
jaroslav@810
  1145
jaroslav@810
  1146
        protected void visitValueStart(String attrName, char type) throws IOException {
jaroslav@810
  1147
        }
jaroslav@810
  1148
jaroslav@810
  1149
        protected void visitValueEnd(String attrName, char type) throws IOException {
jaroslav@810
  1150
        }
jaroslav@810
  1151
jaroslav@810
  1152
        protected void visitAttr(
jaroslav@810
  1153
            String annoType, String attr, String attrType, String value) throws IOException {
jaroslav@810
  1154
        }
jaroslav@810
  1155
jaroslav@810
  1156
        protected void visitEnumAttr(
jaroslav@810
  1157
            String annoType, String attr, String attrType, String value) throws IOException {
jaroslav@810
  1158
            visitAttr(annoType, attr, attrType, value);
jaroslav@810
  1159
        }
jaroslav@810
  1160
jaroslav@810
  1161
        /**
jaroslav@810
  1162
         * Initialize the parsing with constant pool from
jaroslav@810
  1163
         * <code>cd</code>.
jaroslav@810
  1164
         *
jaroslav@810
  1165
         * @param attr the attribute defining annotations
jaroslav@810
  1166
         * @param cd constant pool
jaroslav@810
  1167
         * @throws IOException in case I/O fails
jaroslav@810
  1168
         */
jaroslav@810
  1169
        public final void parse(byte[] attr, ClassData cd) throws IOException {
jaroslav@810
  1170
            ByteArrayInputStream is = new ByteArrayInputStream(attr);
jaroslav@810
  1171
            DataInputStream dis = new DataInputStream(is);
jaroslav@810
  1172
            try {
jaroslav@810
  1173
                read(dis, cd);
jaroslav@810
  1174
            } finally {
jaroslav@810
  1175
                is.close();
jaroslav@810
  1176
            }
jaroslav@810
  1177
        }
jaroslav@810
  1178
jaroslav@810
  1179
        private void read(DataInputStream dis, ClassData cd) throws IOException {
jaroslav@810
  1180
            int cnt = dis.readUnsignedShort();
jaroslav@810
  1181
            for (int i = 0; i < cnt; i++) {
jaroslav@810
  1182
                readAnno(dis, cd, true);
jaroslav@810
  1183
            }
jaroslav@810
  1184
        }
jaroslav@810
  1185
jaroslav@810
  1186
        private void readAnno(DataInputStream dis, ClassData cd, boolean top) throws IOException {
jaroslav@810
  1187
            int type = dis.readUnsignedShort();
jaroslav@810
  1188
            String typeName = cd.StringValue(type);
jaroslav@810
  1189
            visitAnnotationStart(typeName, top);
jaroslav@810
  1190
            int cnt = dis.readUnsignedShort();
jaroslav@810
  1191
            for (int i = 0; i < cnt; i++) {
jaroslav@810
  1192
                String attrName = cd.StringValue(dis.readUnsignedShort());
jaroslav@810
  1193
                readValue(dis, cd, typeName, attrName);
jaroslav@810
  1194
            }
jaroslav@810
  1195
            visitAnnotationEnd(typeName, top);
jaroslav@810
  1196
            if (cnt == 0) {
jaroslav@810
  1197
                visitAttr(typeName, null, null, null);
jaroslav@810
  1198
            }
jaroslav@810
  1199
        }
jaroslav@810
  1200
jaroslav@810
  1201
        private void readValue(
jaroslav@810
  1202
            DataInputStream dis, ClassData cd, String typeName, String attrName) throws IOException {
jaroslav@810
  1203
            char type = (char) dis.readByte();
jaroslav@810
  1204
            visitValueStart(attrName, type);
jaroslav@810
  1205
            if (type == '@') {
jaroslav@810
  1206
                readAnno(dis, cd, false);
jaroslav@810
  1207
            } else if ("CFJZsSIDB".indexOf(type) >= 0) { // NOI18N
jaroslav@810
  1208
                int primitive = dis.readUnsignedShort();
jaroslav@810
  1209
                String val = cd.stringValue(primitive, textual);
jaroslav@810
  1210
                String attrType;
jaroslav@810
  1211
                if (type == 's') {
jaroslav@810
  1212
                    attrType = "Ljava_lang_String_2";
jaroslav@810
  1213
                    if (textual) {
jaroslav@810
  1214
                        val = '"' + val + '"';
jaroslav@810
  1215
                    }
jaroslav@810
  1216
                } else {
jaroslav@810
  1217
                    attrType = "" + type;
jaroslav@810
  1218
                }
jaroslav@810
  1219
                visitAttr(typeName, attrName, attrType, val);
jaroslav@810
  1220
            } else if (type == 'c') {
jaroslav@810
  1221
                int cls = dis.readUnsignedShort();
jaroslav@810
  1222
            } else if (type == '[') {
jaroslav@810
  1223
                int cnt = dis.readUnsignedShort();
jaroslav@810
  1224
                for (int i = 0; i < cnt; i++) {
jaroslav@810
  1225
                    readValue(dis, cd, typeName, iterateArray ? attrName : null);
jaroslav@810
  1226
                }
jaroslav@810
  1227
            } else if (type == 'e') {
jaroslav@810
  1228
                int enumT = dis.readUnsignedShort();
jaroslav@810
  1229
                String attrType = cd.stringValue(enumT, textual);
jaroslav@810
  1230
                int enumN = dis.readUnsignedShort();
jaroslav@810
  1231
                String val = cd.stringValue(enumN, textual);
jaroslav@810
  1232
                visitEnumAttr(typeName, attrName, attrType, val);
jaroslav@810
  1233
            } else {
jaroslav@810
  1234
                throw new IOException("Unknown type " + type);
jaroslav@810
  1235
            }
jaroslav@810
  1236
            visitValueEnd(attrName, type);
jaroslav@810
  1237
        }
jaroslav@810
  1238
    }
jaroslav@810
  1239
    
jaroslav@810
  1240
    /**
jaroslav@810
  1241
     * Reads and stores attribute information.
jaroslav@810
  1242
     *
jaroslav@810
  1243
     * @author Sucheta Dambalkar (Adopted code from jdis)
jaroslav@810
  1244
     */
jaroslav@810
  1245
    private static class AttrData {
jaroslav@810
  1246
jaroslav@810
  1247
        ClassData cls;
jaroslav@810
  1248
        int name_cpx;
jaroslav@810
  1249
        int datalen;
jaroslav@810
  1250
        byte data[];
jaroslav@810
  1251
jaroslav@810
  1252
        public AttrData(ClassData cls) {
jaroslav@810
  1253
            this.cls = cls;
jaroslav@810
  1254
        }
jaroslav@810
  1255
jaroslav@810
  1256
        /**
jaroslav@810
  1257
         * Reads unknown attribute.
jaroslav@810
  1258
         */
jaroslav@810
  1259
        public void read(int name_cpx, DataInputStream in) throws IOException {
jaroslav@810
  1260
            this.name_cpx = name_cpx;
jaroslav@810
  1261
            datalen = in.readInt();
jaroslav@810
  1262
            data = new byte[datalen];
jaroslav@810
  1263
            in.readFully(data);
jaroslav@810
  1264
        }
jaroslav@810
  1265
jaroslav@810
  1266
        /**
jaroslav@810
  1267
         * Reads just the name of known attribute.
jaroslav@810
  1268
         */
jaroslav@810
  1269
        public void read(int name_cpx) {
jaroslav@810
  1270
            this.name_cpx = name_cpx;
jaroslav@810
  1271
        }
jaroslav@810
  1272
jaroslav@810
  1273
        /**
jaroslav@810
  1274
         * Returns attribute name.
jaroslav@810
  1275
         */
jaroslav@810
  1276
        public String getAttrName() {
jaroslav@810
  1277
            return cls.getString(name_cpx);
jaroslav@810
  1278
        }
jaroslav@810
  1279
jaroslav@810
  1280
        /**
jaroslav@810
  1281
         * Returns attribute data.
jaroslav@810
  1282
         */
jaroslav@810
  1283
        public byte[] getData() {
jaroslav@810
  1284
            return data;
jaroslav@810
  1285
        }
jaroslav@810
  1286
    }
jaroslav@810
  1287
jaroslav@810
  1288
    /**
jaroslav@810
  1289
     * Stores constant pool entry information with one field.
jaroslav@810
  1290
     *
jaroslav@810
  1291
     * @author Sucheta Dambalkar (Adopted code from jdis)
jaroslav@810
  1292
     */
jaroslav@810
  1293
    private static class CPX {
jaroslav@810
  1294
jaroslav@810
  1295
        int cpx;
jaroslav@810
  1296
jaroslav@810
  1297
        CPX(int cpx) {
jaroslav@810
  1298
            this.cpx = cpx;
jaroslav@810
  1299
        }
jaroslav@810
  1300
    }
jaroslav@810
  1301
jaroslav@810
  1302
    /**
jaroslav@810
  1303
     * Stores constant pool entry information with two fields.
jaroslav@810
  1304
     *
jaroslav@810
  1305
     * @author Sucheta Dambalkar (Adopted code from jdis)
jaroslav@810
  1306
     */
jaroslav@810
  1307
    private static class CPX2 {
jaroslav@810
  1308
jaroslav@810
  1309
        int cpx1, cpx2;
jaroslav@810
  1310
jaroslav@810
  1311
        CPX2(int cpx1, int cpx2) {
jaroslav@810
  1312
            this.cpx1 = cpx1;
jaroslav@810
  1313
            this.cpx2 = cpx2;
jaroslav@810
  1314
        }
jaroslav@810
  1315
    }
jaroslav@810
  1316
jaroslav@810
  1317
    /**
jaroslav@810
  1318
     * Central data repository of the Java Disassembler. Stores all the
jaroslav@810
  1319
     * information in java class file.
jaroslav@810
  1320
     *
jaroslav@810
  1321
     * @author Sucheta Dambalkar (Adopted code from jdis)
jaroslav@810
  1322
     */
jaroslav@810
  1323
    static final class ClassData {
jaroslav@810
  1324
jaroslav@810
  1325
        private int magic;
jaroslav@810
  1326
        private int minor_version;
jaroslav@810
  1327
        private int major_version;
jaroslav@810
  1328
        private int cpool_count;
jaroslav@810
  1329
        private Object cpool[];
jaroslav@810
  1330
        private int access;
jaroslav@810
  1331
        private int this_class = 0;
jaroslav@810
  1332
        private int super_class;
jaroslav@810
  1333
        private int interfaces_count;
jaroslav@810
  1334
        private int[] interfaces = new int[0];
jaroslav@810
  1335
        private int fields_count;
jaroslav@810
  1336
        private FieldData[] fields;
jaroslav@810
  1337
        private int methods_count;
jaroslav@810
  1338
        private MethodData[] methods;
jaroslav@810
  1339
        private InnerClassData[] innerClasses;
jaroslav@810
  1340
        private int attributes_count;
jaroslav@810
  1341
        private AttrData[] attrs;
jaroslav@810
  1342
        private String classname;
jaroslav@810
  1343
        private String superclassname;
jaroslav@810
  1344
        private int source_cpx = 0;
jaroslav@810
  1345
        private byte tags[];
jaroslav@810
  1346
        private Hashtable indexHashAscii = new Hashtable();
jaroslav@810
  1347
        private String pkgPrefix = "";
jaroslav@810
  1348
        private int pkgPrefixLen = 0;
jaroslav@810
  1349
jaroslav@810
  1350
        /**
jaroslav@810
  1351
         * Read classfile to disassemble.
jaroslav@810
  1352
         */
jaroslav@810
  1353
        public ClassData(InputStream infile) throws IOException {
jaroslav@810
  1354
            this.read(new DataInputStream(infile));
jaroslav@810
  1355
        }
jaroslav@810
  1356
jaroslav@810
  1357
        /**
jaroslav@810
  1358
         * Reads and stores class file information.
jaroslav@810
  1359
         */
jaroslav@810
  1360
        public void read(DataInputStream in) throws IOException {
jaroslav@810
  1361
            // Read the header
jaroslav@810
  1362
            magic = in.readInt();
jaroslav@810
  1363
            if (magic != JAVA_MAGIC) {
jaroslav@810
  1364
                throw new ClassFormatError("wrong magic: "
jaroslav@810
  1365
                    + toHex(magic) + ", expected "
jaroslav@810
  1366
                    + toHex(JAVA_MAGIC));
jaroslav@810
  1367
            }
jaroslav@810
  1368
            minor_version = in.readShort();
jaroslav@810
  1369
            major_version = in.readShort();
jaroslav@810
  1370
            if (major_version != JAVA_VERSION) {
jaroslav@810
  1371
            }
jaroslav@810
  1372
jaroslav@810
  1373
            // Read the constant pool
jaroslav@810
  1374
            readCP(in);
jaroslav@810
  1375
            access = in.readUnsignedShort();
jaroslav@810
  1376
            this_class = in.readUnsignedShort();
jaroslav@810
  1377
            super_class = in.readUnsignedShort();
jaroslav@810
  1378
jaroslav@810
  1379
            //Read interfaces.
jaroslav@810
  1380
            interfaces_count = in.readUnsignedShort();
jaroslav@810
  1381
            if (interfaces_count > 0) {
jaroslav@810
  1382
                interfaces = new int[interfaces_count];
jaroslav@810
  1383
            }
jaroslav@810
  1384
            for (int i = 0; i < interfaces_count; i++) {
jaroslav@810
  1385
                interfaces[i] = in.readShort();
jaroslav@810
  1386
            }
jaroslav@810
  1387
jaroslav@810
  1388
            // Read the fields
jaroslav@810
  1389
            readFields(in);
jaroslav@810
  1390
jaroslav@810
  1391
            // Read the methods
jaroslav@810
  1392
            readMethods(in);
jaroslav@810
  1393
jaroslav@810
  1394
            // Read the attributes
jaroslav@810
  1395
            attributes_count = in.readUnsignedShort();
jaroslav@810
  1396
            attrs = new AttrData[attributes_count];
jaroslav@810
  1397
            for (int k = 0; k < attributes_count; k++) {
jaroslav@810
  1398
                int name_cpx = in.readUnsignedShort();
jaroslav@810
  1399
                if (getTag(name_cpx) == CONSTANT_UTF8
jaroslav@810
  1400
                    && getString(name_cpx).equals("SourceFile")) {
jaroslav@810
  1401
                    if (in.readInt() != 2) {
jaroslav@810
  1402
                        throw new ClassFormatError("invalid attr length");
jaroslav@810
  1403
                    }
jaroslav@810
  1404
                    source_cpx = in.readUnsignedShort();
jaroslav@810
  1405
                    AttrData attr = new AttrData(this);
jaroslav@810
  1406
                    attr.read(name_cpx);
jaroslav@810
  1407
                    attrs[k] = attr;
jaroslav@810
  1408
jaroslav@810
  1409
                } else if (getTag(name_cpx) == CONSTANT_UTF8
jaroslav@810
  1410
                    && getString(name_cpx).equals("InnerClasses")) {
jaroslav@810
  1411
                    int length = in.readInt();
jaroslav@810
  1412
                    int num = in.readUnsignedShort();
jaroslav@810
  1413
                    if (2 + num * 8 != length) {
jaroslav@810
  1414
                        throw new ClassFormatError("invalid attr length");
jaroslav@810
  1415
                    }
jaroslav@810
  1416
                    innerClasses = new InnerClassData[num];
jaroslav@810
  1417
                    for (int j = 0; j < num; j++) {
jaroslav@810
  1418
                        InnerClassData innerClass = new InnerClassData(this);
jaroslav@810
  1419
                        innerClass.read(in);
jaroslav@810
  1420
                        innerClasses[j] = innerClass;
jaroslav@810
  1421
                    }
jaroslav@810
  1422
                    AttrData attr = new AttrData(this);
jaroslav@810
  1423
                    attr.read(name_cpx);
jaroslav@810
  1424
                    attrs[k] = attr;
jaroslav@810
  1425
                } else {
jaroslav@810
  1426
                    AttrData attr = new AttrData(this);
jaroslav@810
  1427
                    attr.read(name_cpx, in);
jaroslav@810
  1428
                    attrs[k] = attr;
jaroslav@810
  1429
                }
jaroslav@810
  1430
            }
jaroslav@810
  1431
            in.close();
jaroslav@810
  1432
        } // end ClassData.read()
jaroslav@810
  1433
jaroslav@810
  1434
        /**
jaroslav@810
  1435
         * Reads and stores constant pool info.
jaroslav@810
  1436
         */
jaroslav@810
  1437
        void readCP(DataInputStream in) throws IOException {
jaroslav@810
  1438
            cpool_count = in.readUnsignedShort();
jaroslav@810
  1439
            tags = new byte[cpool_count];
jaroslav@810
  1440
            cpool = new Object[cpool_count];
jaroslav@810
  1441
            for (int i = 1; i < cpool_count; i++) {
jaroslav@810
  1442
                byte tag = in.readByte();
jaroslav@810
  1443
jaroslav@810
  1444
                switch (tags[i] = tag) {
jaroslav@810
  1445
                    case CONSTANT_UTF8:
jaroslav@810
  1446
                        String str = in.readUTF();
jaroslav@810
  1447
                        indexHashAscii.put(cpool[i] = str, new Integer(i));
jaroslav@810
  1448
                        break;
jaroslav@810
  1449
                    case CONSTANT_INTEGER:
jaroslav@810
  1450
                        cpool[i] = new Integer(in.readInt());
jaroslav@810
  1451
                        break;
jaroslav@810
  1452
                    case CONSTANT_FLOAT:
jaroslav@810
  1453
                        cpool[i] = new Float(in.readFloat());
jaroslav@810
  1454
                        break;
jaroslav@810
  1455
                    case CONSTANT_LONG:
jaroslav@810
  1456
                        cpool[i++] = new Long(in.readLong());
jaroslav@810
  1457
                        break;
jaroslav@810
  1458
                    case CONSTANT_DOUBLE:
jaroslav@810
  1459
                        cpool[i++] = new Double(in.readDouble());
jaroslav@810
  1460
                        break;
jaroslav@810
  1461
                    case CONSTANT_CLASS:
jaroslav@810
  1462
                    case CONSTANT_STRING:
jaroslav@810
  1463
                        cpool[i] = new CPX(in.readUnsignedShort());
jaroslav@810
  1464
                        break;
jaroslav@810
  1465
jaroslav@810
  1466
                    case CONSTANT_FIELD:
jaroslav@810
  1467
                    case CONSTANT_METHOD:
jaroslav@810
  1468
                    case CONSTANT_INTERFACEMETHOD:
jaroslav@810
  1469
                    case CONSTANT_NAMEANDTYPE:
jaroslav@810
  1470
                        cpool[i] = new CPX2(in.readUnsignedShort(), in.readUnsignedShort());
jaroslav@810
  1471
                        break;
jaroslav@810
  1472
jaroslav@810
  1473
                    case 0:
jaroslav@810
  1474
                    default:
jaroslav@810
  1475
                        throw new ClassFormatError("invalid constant type: " + (int) tags[i]);
jaroslav@810
  1476
                }
jaroslav@810
  1477
            }
jaroslav@810
  1478
        }
jaroslav@810
  1479
jaroslav@810
  1480
        /**
jaroslav@810
  1481
         * Reads and strores field info.
jaroslav@810
  1482
         */
jaroslav@810
  1483
        protected void readFields(DataInputStream in) throws IOException {
jaroslav@810
  1484
            int fields_count = in.readUnsignedShort();
jaroslav@810
  1485
            fields = new FieldData[fields_count];
jaroslav@810
  1486
            for (int k = 0; k < fields_count; k++) {
jaroslav@810
  1487
                FieldData field = new FieldData(this);
jaroslav@810
  1488
                field.read(in);
jaroslav@810
  1489
                fields[k] = field;
jaroslav@810
  1490
            }
jaroslav@810
  1491
        }
jaroslav@810
  1492
jaroslav@810
  1493
        /**
jaroslav@810
  1494
         * Reads and strores Method info.
jaroslav@810
  1495
         */
jaroslav@810
  1496
        protected void readMethods(DataInputStream in) throws IOException {
jaroslav@810
  1497
            int methods_count = in.readUnsignedShort();
jaroslav@810
  1498
            methods = new MethodData[methods_count];
jaroslav@810
  1499
            for (int k = 0; k < methods_count; k++) {
jaroslav@810
  1500
                MethodData method = new MethodData(this);
jaroslav@810
  1501
                method.read(in);
jaroslav@810
  1502
                methods[k] = method;
jaroslav@810
  1503
            }
jaroslav@810
  1504
        }
jaroslav@810
  1505
jaroslav@810
  1506
        /**
jaroslav@810
  1507
         * get a string
jaroslav@810
  1508
         */
jaroslav@810
  1509
        public String getString(int n) {
jaroslav@810
  1510
            if (n == 0) {
jaroslav@810
  1511
                return null;
jaroslav@810
  1512
            } else {
jaroslav@810
  1513
                return (String) cpool[n];
jaroslav@810
  1514
            }
jaroslav@810
  1515
        }
jaroslav@810
  1516
jaroslav@810
  1517
        /**
jaroslav@810
  1518
         * get the type of constant given an index
jaroslav@810
  1519
         */
jaroslav@810
  1520
        public byte getTag(int n) {
jaroslav@810
  1521
            try {
jaroslav@810
  1522
                return tags[n];
jaroslav@810
  1523
            } catch (ArrayIndexOutOfBoundsException e) {
jaroslav@810
  1524
                return (byte) 100;
jaroslav@810
  1525
            }
jaroslav@810
  1526
        }
jaroslav@810
  1527
        static final String hexString = "0123456789ABCDEF";
jaroslav@810
  1528
        public static char hexTable[] = hexString.toCharArray();
jaroslav@810
  1529
jaroslav@810
  1530
        static String toHex(long val, int width) {
jaroslav@810
  1531
            StringBuffer s = new StringBuffer();
jaroslav@810
  1532
            for (int i = width - 1; i >= 0; i--) {
jaroslav@810
  1533
                s.append(hexTable[((int) (val >> (4 * i))) & 0xF]);
jaroslav@810
  1534
            }
jaroslav@810
  1535
            return "0x" + s.toString();
jaroslav@810
  1536
        }
jaroslav@810
  1537
jaroslav@810
  1538
        static String toHex(long val) {
jaroslav@810
  1539
            int width;
jaroslav@810
  1540
            for (width = 16; width > 0; width--) {
jaroslav@810
  1541
                if ((val >> (width - 1) * 4) != 0) {
jaroslav@810
  1542
                    break;
jaroslav@810
  1543
                }
jaroslav@810
  1544
            }
jaroslav@810
  1545
            return toHex(val, width);
jaroslav@810
  1546
        }
jaroslav@810
  1547
jaroslav@810
  1548
        static String toHex(int val) {
jaroslav@810
  1549
            int width;
jaroslav@810
  1550
            for (width = 8; width > 0; width--) {
jaroslav@810
  1551
                if ((val >> (width - 1) * 4) != 0) {
jaroslav@810
  1552
                    break;
jaroslav@810
  1553
                }
jaroslav@810
  1554
            }
jaroslav@810
  1555
            return toHex(val, width);
jaroslav@810
  1556
        }
jaroslav@810
  1557
jaroslav@810
  1558
        /**
jaroslav@810
  1559
         * Returns the name of this class.
jaroslav@810
  1560
         */
jaroslav@810
  1561
        public String getClassName() {
jaroslav@810
  1562
            String res = null;
jaroslav@810
  1563
            if (this_class == 0) {
jaroslav@810
  1564
                return res;
jaroslav@810
  1565
            }
jaroslav@810
  1566
            int tcpx;
jaroslav@810
  1567
            try {
jaroslav@810
  1568
                if (tags[this_class] != CONSTANT_CLASS) {
jaroslav@810
  1569
                    return res; //"<CP["+cpx+"] is not a Class> ";
jaroslav@810
  1570
                }
jaroslav@810
  1571
                tcpx = ((CPX) cpool[this_class]).cpx;
jaroslav@810
  1572
            } catch (ArrayIndexOutOfBoundsException e) {
jaroslav@810
  1573
                return res; // "#"+cpx+"// invalid constant pool index";
jaroslav@810
  1574
            } catch (Throwable e) {
jaroslav@810
  1575
                return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
jaroslav@810
  1576
            }
jaroslav@810
  1577
jaroslav@810
  1578
            try {
jaroslav@810
  1579
                return (String) (cpool[tcpx]);
jaroslav@810
  1580
            } catch (ArrayIndexOutOfBoundsException e) {
jaroslav@810
  1581
                return res; // "class #"+scpx+"// invalid constant pool index";
jaroslav@810
  1582
            } catch (ClassCastException e) {
jaroslav@810
  1583
                return res; // "class #"+scpx+"// invalid constant pool reference";
jaroslav@810
  1584
            } catch (Throwable e) {
jaroslav@810
  1585
                return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
jaroslav@810
  1586
            }
jaroslav@810
  1587
jaroslav@810
  1588
        }
jaroslav@810
  1589
jaroslav@810
  1590
        /**
jaroslav@810
  1591
         * Returns the name of class at perticular index.
jaroslav@810
  1592
         */
jaroslav@810
  1593
        public String getClassName(int cpx) {
jaroslav@810
  1594
            String res = "#" + cpx;
jaroslav@810
  1595
            if (cpx == 0) {
jaroslav@810
  1596
                return res;
jaroslav@810
  1597
            }
jaroslav@810
  1598
            int scpx;
jaroslav@810
  1599
            try {
jaroslav@810
  1600
                if (tags[cpx] != CONSTANT_CLASS) {
jaroslav@810
  1601
                    return res; //"<CP["+cpx+"] is not a Class> ";
jaroslav@810
  1602
                }
jaroslav@810
  1603
                scpx = ((CPX) cpool[cpx]).cpx;
jaroslav@810
  1604
            } catch (ArrayIndexOutOfBoundsException e) {
jaroslav@810
  1605
                return res; // "#"+cpx+"// invalid constant pool index";
jaroslav@810
  1606
            } catch (Throwable e) {
jaroslav@810
  1607
                return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
jaroslav@810
  1608
            }
jaroslav@810
  1609
            res = "#" + scpx;
jaroslav@810
  1610
            try {
jaroslav@810
  1611
                return (String) (cpool[scpx]);
jaroslav@810
  1612
            } catch (ArrayIndexOutOfBoundsException e) {
jaroslav@810
  1613
                return res; // "class #"+scpx+"// invalid constant pool index";
jaroslav@810
  1614
            } catch (ClassCastException e) {
jaroslav@810
  1615
                return res; // "class #"+scpx+"// invalid constant pool reference";
jaroslav@810
  1616
            } catch (Throwable e) {
jaroslav@810
  1617
                return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
jaroslav@810
  1618
            }
jaroslav@810
  1619
        }
jaroslav@810
  1620
jaroslav@810
  1621
        public int getAccessFlags() {
jaroslav@810
  1622
            return access;
jaroslav@810
  1623
        }
jaroslav@810
  1624
jaroslav@810
  1625
        /**
jaroslav@810
  1626
         * Returns true if it is a class
jaroslav@810
  1627
         */
jaroslav@810
  1628
        public boolean isClass() {
jaroslav@810
  1629
            if ((access & ACC_INTERFACE) == 0) {
jaroslav@810
  1630
                return true;
jaroslav@810
  1631
            }
jaroslav@810
  1632
            return false;
jaroslav@810
  1633
        }
jaroslav@810
  1634
jaroslav@810
  1635
        /**
jaroslav@810
  1636
         * Returns true if it is a interface.
jaroslav@810
  1637
         */
jaroslav@810
  1638
        public boolean isInterface() {
jaroslav@810
  1639
            if ((access & ACC_INTERFACE) != 0) {
jaroslav@810
  1640
                return true;
jaroslav@810
  1641
            }
jaroslav@810
  1642
            return false;
jaroslav@810
  1643
        }
jaroslav@810
  1644
jaroslav@810
  1645
        /**
jaroslav@810
  1646
         * Returns true if this member is public, false otherwise.
jaroslav@810
  1647
         */
jaroslav@810
  1648
        public boolean isPublic() {
jaroslav@810
  1649
            return (access & ACC_PUBLIC) != 0;
jaroslav@810
  1650
        }
jaroslav@810
  1651
jaroslav@810
  1652
        /**
jaroslav@810
  1653
         * Returns the access of this class or interface.
jaroslav@810
  1654
         */
jaroslav@810
  1655
        public String[] getAccess() {
jaroslav@810
  1656
            Vector v = new Vector();
jaroslav@810
  1657
            if ((access & ACC_PUBLIC) != 0) {
jaroslav@810
  1658
                v.addElement("public");
jaroslav@810
  1659
            }
jaroslav@810
  1660
            if ((access & ACC_FINAL) != 0) {
jaroslav@810
  1661
                v.addElement("final");
jaroslav@810
  1662
            }
jaroslav@810
  1663
            if ((access & ACC_ABSTRACT) != 0) {
jaroslav@810
  1664
                v.addElement("abstract");
jaroslav@810
  1665
            }
jaroslav@810
  1666
            String[] accflags = new String[v.size()];
jaroslav@810
  1667
            v.copyInto(accflags);
jaroslav@810
  1668
            return accflags;
jaroslav@810
  1669
        }
jaroslav@810
  1670
jaroslav@810
  1671
        /**
jaroslav@810
  1672
         * Returns list of innerclasses.
jaroslav@810
  1673
         */
jaroslav@810
  1674
        public InnerClassData[] getInnerClasses() {
jaroslav@810
  1675
            return innerClasses;
jaroslav@810
  1676
        }
jaroslav@810
  1677
jaroslav@810
  1678
        /**
jaroslav@810
  1679
         * Returns list of attributes.
jaroslav@810
  1680
         */
jaroslav@810
  1681
        final AttrData[] getAttributes() {
jaroslav@810
  1682
            return attrs;
jaroslav@810
  1683
        }
jaroslav@810
  1684
jaroslav@810
  1685
        public byte[] findAnnotationData(boolean classRetention) {
jaroslav@810
  1686
            String n = classRetention
jaroslav@810
  1687
                ? "RuntimeInvisibleAnnotations" : // NOI18N
jaroslav@810
  1688
                "RuntimeVisibleAnnotations"; // NOI18N
jaroslav@810
  1689
            return findAttr(n, attrs);
jaroslav@810
  1690
        }
jaroslav@810
  1691
jaroslav@810
  1692
        /**
jaroslav@810
  1693
         * Returns true if superbit is set.
jaroslav@810
  1694
         */
jaroslav@810
  1695
        public boolean isSuperSet() {
jaroslav@810
  1696
            if ((access & ACC_SUPER) != 0) {
jaroslav@810
  1697
                return true;
jaroslav@810
  1698
            }
jaroslav@810
  1699
            return false;
jaroslav@810
  1700
        }
jaroslav@810
  1701
jaroslav@810
  1702
        /**
jaroslav@810
  1703
         * Returns super class name.
jaroslav@810
  1704
         */
jaroslav@810
  1705
        public String getSuperClassName() {
jaroslav@810
  1706
            String res = null;
jaroslav@810
  1707
            if (super_class == 0) {
jaroslav@810
  1708
                return res;
jaroslav@810
  1709
            }
jaroslav@810
  1710
            int scpx;
jaroslav@810
  1711
            try {
jaroslav@810
  1712
                if (tags[super_class] != CONSTANT_CLASS) {
jaroslav@810
  1713
                    return res; //"<CP["+cpx+"] is not a Class> ";
jaroslav@810
  1714
                }
jaroslav@810
  1715
                scpx = ((CPX) cpool[super_class]).cpx;
jaroslav@810
  1716
            } catch (ArrayIndexOutOfBoundsException e) {
jaroslav@810
  1717
                return res; // "#"+cpx+"// invalid constant pool index";
jaroslav@810
  1718
            } catch (Throwable e) {
jaroslav@810
  1719
                return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
jaroslav@810
  1720
            }
jaroslav@810
  1721
jaroslav@810
  1722
            try {
jaroslav@810
  1723
                return (String) (cpool[scpx]);
jaroslav@810
  1724
            } catch (ArrayIndexOutOfBoundsException e) {
jaroslav@810
  1725
                return res; // "class #"+scpx+"// invalid constant pool index";
jaroslav@810
  1726
            } catch (ClassCastException e) {
jaroslav@810
  1727
                return res; // "class #"+scpx+"// invalid constant pool reference";
jaroslav@810
  1728
            } catch (Throwable e) {
jaroslav@810
  1729
                return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
jaroslav@810
  1730
            }
jaroslav@810
  1731
        }
jaroslav@810
  1732
jaroslav@810
  1733
        /**
jaroslav@810
  1734
         * Returns list of super interfaces.
jaroslav@810
  1735
         */
jaroslav@810
  1736
        public String[] getSuperInterfaces() {
jaroslav@810
  1737
            String interfacenames[] = new String[interfaces.length];
jaroslav@810
  1738
            int interfacecpx = -1;
jaroslav@810
  1739
            for (int i = 0; i < interfaces.length; i++) {
jaroslav@810
  1740
                interfacecpx = ((CPX) cpool[interfaces[i]]).cpx;
jaroslav@810
  1741
                interfacenames[i] = (String) (cpool[interfacecpx]);
jaroslav@810
  1742
            }
jaroslav@810
  1743
            return interfacenames;
jaroslav@810
  1744
        }
jaroslav@810
  1745
jaroslav@810
  1746
        /**
jaroslav@810
  1747
         * Returns string at prticular constant pool index.
jaroslav@810
  1748
         */
jaroslav@810
  1749
        public String getStringValue(int cpoolx) {
jaroslav@810
  1750
            try {
jaroslav@810
  1751
                return ((String) cpool[cpoolx]);
jaroslav@810
  1752
            } catch (ArrayIndexOutOfBoundsException e) {
jaroslav@810
  1753
                return "//invalid constant pool index:" + cpoolx;
jaroslav@810
  1754
            } catch (ClassCastException e) {
jaroslav@810
  1755
                return "//invalid constant pool ref:" + cpoolx;
jaroslav@810
  1756
            }
jaroslav@810
  1757
        }
jaroslav@810
  1758
jaroslav@810
  1759
        /**
jaroslav@810
  1760
         * Returns list of field info.
jaroslav@810
  1761
         */
jaroslav@810
  1762
        public FieldData[] getFields() {
jaroslav@810
  1763
            return fields;
jaroslav@810
  1764
        }
jaroslav@810
  1765
jaroslav@810
  1766
        /**
jaroslav@810
  1767
         * Returns list of method info.
jaroslav@810
  1768
         */
jaroslav@810
  1769
        public MethodData[] getMethods() {
jaroslav@810
  1770
            return methods;
jaroslav@810
  1771
        }
jaroslav@810
  1772
jaroslav@810
  1773
        /**
jaroslav@810
  1774
         * Returns constant pool entry at that index.
jaroslav@810
  1775
         */
jaroslav@810
  1776
        public CPX2 getCpoolEntry(int cpx) {
jaroslav@810
  1777
            return ((CPX2) (cpool[cpx]));
jaroslav@810
  1778
        }
jaroslav@810
  1779
jaroslav@810
  1780
        public Object getCpoolEntryobj(int cpx) {
jaroslav@810
  1781
            return (cpool[cpx]);
jaroslav@810
  1782
        }
jaroslav@810
  1783
jaroslav@810
  1784
        /**
jaroslav@810
  1785
         * Returns index of this class.
jaroslav@810
  1786
         */
jaroslav@810
  1787
        public int getthis_cpx() {
jaroslav@810
  1788
            return this_class;
jaroslav@810
  1789
        }
jaroslav@810
  1790
jaroslav@810
  1791
        /**
jaroslav@810
  1792
         * Returns string at that index.
jaroslav@810
  1793
         */
jaroslav@810
  1794
        public String StringValue(int cpx) {
jaroslav@810
  1795
            return stringValue(cpx, false);
jaroslav@810
  1796
        }
jaroslav@810
  1797
jaroslav@810
  1798
        public String stringValue(int cpx, boolean textual) {
jaroslav@810
  1799
            return stringValue(cpx, textual, null);
jaroslav@810
  1800
        }
jaroslav@810
  1801
jaroslav@810
  1802
        public String stringValue(int cpx, String[] classRefs) {
jaroslav@810
  1803
            return stringValue(cpx, true, classRefs);
jaroslav@810
  1804
        }
jaroslav@810
  1805
jaroslav@810
  1806
        private String stringValue(int cpx, boolean textual, String[] refs) {
jaroslav@810
  1807
            if (cpx == 0) {
jaroslav@810
  1808
                return "#0";
jaroslav@810
  1809
            }
jaroslav@810
  1810
            int tag;
jaroslav@810
  1811
            Object x;
jaroslav@810
  1812
            String suffix = "";
jaroslav@810
  1813
            try {
jaroslav@810
  1814
                tag = tags[cpx];
jaroslav@810
  1815
                x = cpool[cpx];
jaroslav@810
  1816
            } catch (IndexOutOfBoundsException e) {
jaroslav@810
  1817
                return "<Incorrect CP index:" + cpx + ">";
jaroslav@810
  1818
            }
jaroslav@810
  1819
jaroslav@810
  1820
            if (x == null) {
jaroslav@810
  1821
                return "<NULL>";
jaroslav@810
  1822
            }
jaroslav@810
  1823
            switch (tag) {
jaroslav@810
  1824
                case CONSTANT_UTF8: {
jaroslav@810
  1825
                    if (!textual) {
jaroslav@810
  1826
                        return (String) x;
jaroslav@810
  1827
                    }
jaroslav@810
  1828
                    StringBuilder sb = new StringBuilder();
jaroslav@810
  1829
                    String s = (String) x;
jaroslav@810
  1830
                    for (int k = 0; k < s.length(); k++) {
jaroslav@810
  1831
                        char c = s.charAt(k);
jaroslav@810
  1832
                        switch (c) {
jaroslav@810
  1833
                            case '\\':
jaroslav@810
  1834
                                sb.append('\\').append('\\');
jaroslav@810
  1835
                                break;
jaroslav@810
  1836
                            case '\t':
jaroslav@810
  1837
                                sb.append('\\').append('t');
jaroslav@810
  1838
                                break;
jaroslav@810
  1839
                            case '\n':
jaroslav@810
  1840
                                sb.append('\\').append('n');
jaroslav@810
  1841
                                break;
jaroslav@810
  1842
                            case '\r':
jaroslav@810
  1843
                                sb.append('\\').append('r');
jaroslav@810
  1844
                                break;
jaroslav@810
  1845
                            case '\"':
jaroslav@810
  1846
                                sb.append('\\').append('\"');
jaroslav@810
  1847
                                break;
jaroslav@1354
  1848
                            case '\u2028':
jaroslav@1354
  1849
                                sb.append("\\u2028");
jaroslav@1354
  1850
                                break;
jaroslav@1354
  1851
                            case '\u2029':
jaroslav@1354
  1852
                                sb.append("\\u2029");
jaroslav@1354
  1853
                                break;
jaroslav@810
  1854
                            default:
jaroslav@810
  1855
                                sb.append(c);
jaroslav@810
  1856
                        }
jaroslav@810
  1857
                    }
jaroslav@810
  1858
                    return sb.toString();
jaroslav@810
  1859
                }
jaroslav@810
  1860
                case CONSTANT_DOUBLE: {
jaroslav@810
  1861
                    Double d = (Double) x;
jaroslav@810
  1862
                    String sd = d.toString();
jaroslav@810
  1863
                    if (textual) {
jaroslav@810
  1864
                        return sd;
jaroslav@810
  1865
                    }
jaroslav@810
  1866
                    return sd + "d";
jaroslav@810
  1867
                }
jaroslav@810
  1868
                case CONSTANT_FLOAT: {
jaroslav@810
  1869
                    Float f = (Float) x;
jaroslav@810
  1870
                    String sf = (f).toString();
jaroslav@810
  1871
                    if (textual) {
jaroslav@810
  1872
                        return sf;
jaroslav@810
  1873
                    }
jaroslav@810
  1874
                    return sf + "f";
jaroslav@810
  1875
                }
jaroslav@810
  1876
                case CONSTANT_LONG: {
jaroslav@810
  1877
                    Long ln = (Long) x;
jaroslav@810
  1878
                    if (textual) {
jaroslav@810
  1879
                        return ln.toString();
jaroslav@810
  1880
                    }
jaroslav@810
  1881
                    return ln.toString() + 'l';
jaroslav@810
  1882
                }
jaroslav@810
  1883
                case CONSTANT_INTEGER: {
jaroslav@810
  1884
                    Integer in = (Integer) x;
jaroslav@810
  1885
                    return in.toString();
jaroslav@810
  1886
                }
jaroslav@810
  1887
                case CONSTANT_CLASS:
jaroslav@810
  1888
                    String jn = getClassName(cpx);
jaroslav@810
  1889
                    if (textual) {
jaroslav@810
  1890
                        if (refs != null) {
jaroslav@810
  1891
                            refs[0] = jn;
jaroslav@810
  1892
                        }
jaroslav@810
  1893
                        return jn;
jaroslav@810
  1894
                    }
jaroslav@810
  1895
                    return javaName(jn);
jaroslav@810
  1896
                case CONSTANT_STRING:
jaroslav@810
  1897
                    String sv = stringValue(((CPX) x).cpx, textual);
jaroslav@810
  1898
                    if (textual) {
jaroslav@810
  1899
                        return '"' + sv + '"';
jaroslav@810
  1900
                    } else {
jaroslav@810
  1901
                        return sv;
jaroslav@810
  1902
                    }
jaroslav@810
  1903
                case CONSTANT_FIELD:
jaroslav@810
  1904
                case CONSTANT_METHOD:
jaroslav@810
  1905
                case CONSTANT_INTERFACEMETHOD:
jaroslav@810
  1906
                    //return getShortClassName(((CPX2)x).cpx1)+"."+StringValue(((CPX2)x).cpx2);
jaroslav@810
  1907
                    return javaName(getClassName(((CPX2) x).cpx1)) + "." + StringValue(((CPX2) x).cpx2);
jaroslav@810
  1908
jaroslav@810
  1909
                case CONSTANT_NAMEANDTYPE:
jaroslav@810
  1910
                    return getName(((CPX2) x).cpx1) + ":" + StringValue(((CPX2) x).cpx2);
jaroslav@810
  1911
                default:
jaroslav@810
  1912
                    return "UnknownTag"; //TBD
jaroslav@810
  1913
            }
jaroslav@810
  1914
        }
jaroslav@810
  1915
jaroslav@810
  1916
        /**
jaroslav@810
  1917
         * Returns resolved java type name.
jaroslav@810
  1918
         */
jaroslav@810
  1919
        public String javaName(String name) {
jaroslav@810
  1920
            if (name == null) {
jaroslav@810
  1921
                return "null";
jaroslav@810
  1922
            }
jaroslav@810
  1923
            int len = name.length();
jaroslav@810
  1924
            if (len == 0) {
jaroslav@810
  1925
                return "\"\"";
jaroslav@810
  1926
            }
jaroslav@810
  1927
            int cc = '/';
jaroslav@810
  1928
            fullname:
jaroslav@810
  1929
            { // xxx/yyy/zzz
jaroslav@810
  1930
                int cp;
jaroslav@810
  1931
                for (int k = 0; k < len; k += Character.charCount(cp)) {
jaroslav@810
  1932
                    cp = name.codePointAt(k);
jaroslav@810
  1933
                    if (cc == '/') {
jaroslav@810
  1934
                        if (!isJavaIdentifierStart(cp)) {
jaroslav@810
  1935
                            break fullname;
jaroslav@810
  1936
                        }
jaroslav@810
  1937
                    } else if (cp != '/') {
jaroslav@810
  1938
                        if (!isJavaIdentifierPart(cp)) {
jaroslav@810
  1939
                            break fullname;
jaroslav@810
  1940
                        }
jaroslav@810
  1941
                    }
jaroslav@810
  1942
                    cc = cp;
jaroslav@810
  1943
                }
jaroslav@810
  1944
                return name;
jaroslav@810
  1945
            }
jaroslav@810
  1946
            return "\"" + name + "\"";
jaroslav@810
  1947
        }
jaroslav@810
  1948
jaroslav@810
  1949
        public String getName(int cpx) {
jaroslav@810
  1950
            String res;
jaroslav@810
  1951
            try {
jaroslav@810
  1952
                return javaName((String) cpool[cpx]); //.replace('/','.');
jaroslav@810
  1953
            } catch (ArrayIndexOutOfBoundsException e) {
jaroslav@810
  1954
                return "<invalid constant pool index:" + cpx + ">";
jaroslav@810
  1955
            } catch (ClassCastException e) {
jaroslav@810
  1956
                return "<invalid constant pool ref:" + cpx + ">";
jaroslav@810
  1957
            }
jaroslav@810
  1958
        }
jaroslav@810
  1959
jaroslav@810
  1960
        /**
jaroslav@810
  1961
         * Returns unqualified class name.
jaroslav@810
  1962
         */
jaroslav@810
  1963
        public String getShortClassName(int cpx) {
jaroslav@810
  1964
            String classname = javaName(getClassName(cpx));
jaroslav@810
  1965
            pkgPrefixLen = classname.lastIndexOf("/") + 1;
jaroslav@810
  1966
            if (pkgPrefixLen != 0) {
jaroslav@810
  1967
                pkgPrefix = classname.substring(0, pkgPrefixLen);
jaroslav@810
  1968
                if (classname.startsWith(pkgPrefix)) {
jaroslav@810
  1969
                    return classname.substring(pkgPrefixLen);
jaroslav@810
  1970
                }
jaroslav@810
  1971
            }
jaroslav@810
  1972
            return classname;
jaroslav@810
  1973
        }
jaroslav@810
  1974
jaroslav@810
  1975
        /**
jaroslav@810
  1976
         * Returns source file name.
jaroslav@810
  1977
         */
jaroslav@810
  1978
        public String getSourceName() {
jaroslav@810
  1979
            return getName(source_cpx);
jaroslav@810
  1980
        }
jaroslav@810
  1981
jaroslav@810
  1982
        /**
jaroslav@810
  1983
         * Returns package name.
jaroslav@810
  1984
         */
jaroslav@810
  1985
        public String getPkgName() {
jaroslav@810
  1986
            String classname = getClassName(this_class);
jaroslav@810
  1987
            pkgPrefixLen = classname.lastIndexOf("/") + 1;
jaroslav@810
  1988
            if (pkgPrefixLen != 0) {
jaroslav@810
  1989
                pkgPrefix = classname.substring(0, pkgPrefixLen);
jaroslav@810
  1990
                return ("package  " + pkgPrefix.substring(0, pkgPrefixLen - 1) + ";\n");
jaroslav@810
  1991
            } else {
jaroslav@810
  1992
                return null;
jaroslav@810
  1993
            }
jaroslav@810
  1994
        }
jaroslav@810
  1995
jaroslav@810
  1996
        /**
jaroslav@810
  1997
         * Returns total constant pool entry count.
jaroslav@810
  1998
         */
jaroslav@810
  1999
        public int getCpoolCount() {
jaroslav@810
  2000
            return cpool_count;
jaroslav@810
  2001
        }
jaroslav@810
  2002
jaroslav@810
  2003
        /**
jaroslav@810
  2004
         * Returns minor version of class file.
jaroslav@810
  2005
         */
jaroslav@810
  2006
        public int getMinor_version() {
jaroslav@810
  2007
            return minor_version;
jaroslav@810
  2008
        }
jaroslav@810
  2009
jaroslav@810
  2010
        /**
jaroslav@810
  2011
         * Returns major version of class file.
jaroslav@810
  2012
         */
jaroslav@810
  2013
        public int getMajor_version() {
jaroslav@810
  2014
            return major_version;
jaroslav@810
  2015
        }
jaroslav@810
  2016
jaroslav@810
  2017
        private boolean isJavaIdentifierStart(int cp) {
jaroslav@810
  2018
            return ('a' <= cp && cp <= 'z') || ('A' <= cp && cp <= 'Z');
jaroslav@810
  2019
        }
jaroslav@810
  2020
jaroslav@810
  2021
        private boolean isJavaIdentifierPart(int cp) {
jaroslav@810
  2022
            return isJavaIdentifierStart(cp) || ('0' <= cp && cp <= '9');
jaroslav@810
  2023
        }
jaroslav@810
  2024
jaroslav@810
  2025
        public String[] getNameAndType(int indx) {
jaroslav@810
  2026
            return getNameAndType(indx, 0, new String[2]);
jaroslav@810
  2027
        }
jaroslav@810
  2028
jaroslav@810
  2029
        private String[] getNameAndType(int indx, int at, String[] arr) {
jaroslav@810
  2030
            CPX2 c2 = getCpoolEntry(indx);
jaroslav@810
  2031
            arr[at] = StringValue(c2.cpx1);
jaroslav@810
  2032
            arr[at + 1] = StringValue(c2.cpx2);
jaroslav@810
  2033
            return arr;
jaroslav@810
  2034
        }
jaroslav@810
  2035
jaroslav@810
  2036
        public String[] getFieldInfoName(int indx) {
jaroslav@810
  2037
            CPX2 c2 = getCpoolEntry(indx);
jaroslav@810
  2038
            String[] arr = new String[3];
jaroslav@810
  2039
            arr[0] = getClassName(c2.cpx1);
jaroslav@810
  2040
            return getNameAndType(c2.cpx2, 1, arr);
jaroslav@810
  2041
        }
jaroslav@810
  2042
jaroslav@810
  2043
        static byte[] findAttr(String n, AttrData[] attrs) {
jaroslav@810
  2044
            for (AttrData ad : attrs) {
jaroslav@810
  2045
                if (n.equals(ad.getAttrName())) {
jaroslav@810
  2046
                    return ad.getData();
jaroslav@810
  2047
                }
jaroslav@810
  2048
            }
jaroslav@810
  2049
            return null;
jaroslav@810
  2050
        }
jaroslav@810
  2051
    }
jaroslav@810
  2052
jaroslav@810
  2053
    /**
jaroslav@810
  2054
     * Strores field data informastion.
jaroslav@810
  2055
     *
jaroslav@810
  2056
     * @author Sucheta Dambalkar (Adopted code from jdis)
jaroslav@810
  2057
     */
jaroslav@810
  2058
    static class FieldData {
jaroslav@810
  2059
jaroslav@810
  2060
        ClassData cls;
jaroslav@810
  2061
        int access;
jaroslav@810
  2062
        int name_index;
jaroslav@810
  2063
        int descriptor_index;
jaroslav@810
  2064
        int attributes_count;
jaroslav@810
  2065
        int value_cpx = 0;
jaroslav@810
  2066
        boolean isSynthetic = false;
jaroslav@810
  2067
        boolean isDeprecated = false;
jaroslav@810
  2068
        Vector attrs;
jaroslav@810
  2069
jaroslav@810
  2070
        public FieldData(ClassData cls) {
jaroslav@810
  2071
            this.cls = cls;
jaroslav@810
  2072
        }
jaroslav@810
  2073
jaroslav@810
  2074
        /**
jaroslav@810
  2075
         * Read and store field info.
jaroslav@810
  2076
         */
jaroslav@810
  2077
        public void read(DataInputStream in) throws IOException {
jaroslav@810
  2078
            access = in.readUnsignedShort();
jaroslav@810
  2079
            name_index = in.readUnsignedShort();
jaroslav@810
  2080
            descriptor_index = in.readUnsignedShort();
jaroslav@810
  2081
            // Read the attributes
jaroslav@810
  2082
            int attributes_count = in.readUnsignedShort();
jaroslav@810
  2083
            attrs = new Vector(attributes_count);
jaroslav@810
  2084
            for (int i = 0; i < attributes_count; i++) {
jaroslav@810
  2085
                int attr_name_index = in.readUnsignedShort();
jaroslav@810
  2086
                if (cls.getTag(attr_name_index) != CONSTANT_UTF8) {
jaroslav@810
  2087
                    continue;
jaroslav@810
  2088
                }
jaroslav@810
  2089
                String attr_name = cls.getString(attr_name_index);
jaroslav@810
  2090
                if (attr_name.equals("ConstantValue")) {
jaroslav@810
  2091
                    if (in.readInt() != 2) {
jaroslav@810
  2092
                        throw new ClassFormatError("invalid ConstantValue attr length");
jaroslav@810
  2093
                    }
jaroslav@810
  2094
                    value_cpx = in.readUnsignedShort();
jaroslav@810
  2095
                    AttrData attr = new AttrData(cls);
jaroslav@810
  2096
                    attr.read(attr_name_index);
jaroslav@810
  2097
                    attrs.addElement(attr);
jaroslav@810
  2098
                } else if (attr_name.equals("Synthetic")) {
jaroslav@810
  2099
                    if (in.readInt() != 0) {
jaroslav@810
  2100
                        throw new ClassFormatError("invalid Synthetic attr length");
jaroslav@810
  2101
                    }
jaroslav@810
  2102
                    isSynthetic = true;
jaroslav@810
  2103
                    AttrData attr = new AttrData(cls);
jaroslav@810
  2104
                    attr.read(attr_name_index);
jaroslav@810
  2105
                    attrs.addElement(attr);
jaroslav@810
  2106
                } else if (attr_name.equals("Deprecated")) {
jaroslav@810
  2107
                    if (in.readInt() != 0) {
jaroslav@810
  2108
                        throw new ClassFormatError("invalid Synthetic attr length");
jaroslav@810
  2109
                    }
jaroslav@810
  2110
                    isDeprecated = true;
jaroslav@810
  2111
                    AttrData attr = new AttrData(cls);
jaroslav@810
  2112
                    attr.read(attr_name_index);
jaroslav@810
  2113
                    attrs.addElement(attr);
jaroslav@810
  2114
                } else {
jaroslav@810
  2115
                    AttrData attr = new AttrData(cls);
jaroslav@810
  2116
                    attr.read(attr_name_index, in);
jaroslav@810
  2117
                    attrs.addElement(attr);
jaroslav@810
  2118
                }
jaroslav@810
  2119
            }
jaroslav@810
  2120
jaroslav@810
  2121
        }  // end read
jaroslav@810
  2122
jaroslav@810
  2123
        public boolean isStatic() {
jaroslav@810
  2124
            return (access & ACC_STATIC) != 0;
jaroslav@810
  2125
        }
jaroslav@810
  2126
jaroslav@810
  2127
        /**
jaroslav@810
  2128
         * Returns access of a field.
jaroslav@810
  2129
         */
jaroslav@810
  2130
        public String[] getAccess() {
jaroslav@810
  2131
            Vector v = new Vector();
jaroslav@810
  2132
            if ((access & ACC_PUBLIC) != 0) {
jaroslav@810
  2133
                v.addElement("public");
jaroslav@810
  2134
            }
jaroslav@810
  2135
            if ((access & ACC_PRIVATE) != 0) {
jaroslav@810
  2136
                v.addElement("private");
jaroslav@810
  2137
            }
jaroslav@810
  2138
            if ((access & ACC_PROTECTED) != 0) {
jaroslav@810
  2139
                v.addElement("protected");
jaroslav@810
  2140
            }
jaroslav@810
  2141
            if ((access & ACC_STATIC) != 0) {
jaroslav@810
  2142
                v.addElement("static");
jaroslav@810
  2143
            }
jaroslav@810
  2144
            if ((access & ACC_FINAL) != 0) {
jaroslav@810
  2145
                v.addElement("final");
jaroslav@810
  2146
            }
jaroslav@810
  2147
            if ((access & ACC_VOLATILE) != 0) {
jaroslav@810
  2148
                v.addElement("volatile");
jaroslav@810
  2149
            }
jaroslav@810
  2150
            if ((access & ACC_TRANSIENT) != 0) {
jaroslav@810
  2151
                v.addElement("transient");
jaroslav@810
  2152
            }
jaroslav@810
  2153
            String[] accflags = new String[v.size()];
jaroslav@810
  2154
            v.copyInto(accflags);
jaroslav@810
  2155
            return accflags;
jaroslav@810
  2156
        }
jaroslav@810
  2157
jaroslav@810
  2158
        /**
jaroslav@810
  2159
         * Returns name of a field.
jaroslav@810
  2160
         */
jaroslav@810
  2161
        public String getName() {
jaroslav@810
  2162
            return cls.getStringValue(name_index);
jaroslav@810
  2163
        }
jaroslav@810
  2164
jaroslav@810
  2165
        /**
jaroslav@810
  2166
         * Returns internal signature of a field
jaroslav@810
  2167
         */
jaroslav@810
  2168
        public String getInternalSig() {
jaroslav@810
  2169
            return cls.getStringValue(descriptor_index);
jaroslav@810
  2170
        }
jaroslav@810
  2171
jaroslav@810
  2172
        /**
jaroslav@810
  2173
         * Returns true if field is synthetic.
jaroslav@810
  2174
         */
jaroslav@810
  2175
        public boolean isSynthetic() {
jaroslav@810
  2176
            return isSynthetic;
jaroslav@810
  2177
        }
jaroslav@810
  2178
jaroslav@810
  2179
        /**
jaroslav@810
  2180
         * Returns true if field is deprecated.
jaroslav@810
  2181
         */
jaroslav@810
  2182
        public boolean isDeprecated() {
jaroslav@810
  2183
            return isDeprecated;
jaroslav@810
  2184
        }
jaroslav@810
  2185
jaroslav@810
  2186
        /**
jaroslav@810
  2187
         * Returns index of constant value in cpool.
jaroslav@810
  2188
         */
jaroslav@810
  2189
        public int getConstantValueIndex() {
jaroslav@810
  2190
            return (value_cpx);
jaroslav@810
  2191
        }
jaroslav@810
  2192
jaroslav@810
  2193
        /**
jaroslav@810
  2194
         * Returns list of attributes of field.
jaroslav@810
  2195
         */
jaroslav@810
  2196
        public Vector getAttributes() {
jaroslav@810
  2197
            return attrs;
jaroslav@810
  2198
        }
jaroslav@810
  2199
jaroslav@810
  2200
        public byte[] findAnnotationData(boolean classRetention) {
jaroslav@810
  2201
            String n = classRetention
jaroslav@810
  2202
                ? "RuntimeInvisibleAnnotations" : // NOI18N
jaroslav@810
  2203
                "RuntimeVisibleAnnotations"; // NOI18N
jaroslav@810
  2204
            AttrData[] arr = new AttrData[attrs.size()];
jaroslav@810
  2205
            attrs.copyInto(arr);
jaroslav@810
  2206
            return ClassData.findAttr(n, arr);
jaroslav@810
  2207
        }
jaroslav@810
  2208
    }
jaroslav@810
  2209
jaroslav@810
  2210
    /**
jaroslav@810
  2211
     * A JavaScript optimized replacement for Hashtable.
jaroslav@810
  2212
     *
jaroslav@810
  2213
     * @author Jaroslav Tulach <jtulach@netbeans.org>
jaroslav@810
  2214
     */
jaroslav@810
  2215
    private static final class Hashtable {
jaroslav@810
  2216
jaroslav@810
  2217
        private Object[] keys;
jaroslav@810
  2218
        private Object[] values;
jaroslav@810
  2219
jaroslav@810
  2220
        Hashtable(int i) {
jaroslav@810
  2221
            this();
jaroslav@810
  2222
        }
jaroslav@810
  2223
jaroslav@810
  2224
        Hashtable(int i, double d) {
jaroslav@810
  2225
            this();
jaroslav@810
  2226
        }
jaroslav@810
  2227
jaroslav@810
  2228
        Hashtable() {
jaroslav@810
  2229
        }
jaroslav@810
  2230
jaroslav@810
  2231
        synchronized void put(Object key, Object val) {
jaroslav@810
  2232
            int[] where = {-1, -1};
jaroslav@810
  2233
            Object found = get(key, where);
jaroslav@810
  2234
            if (where[0] != -1) {
jaroslav@810
  2235
                // key exists
jaroslav@810
  2236
                values[where[0]] = val;
jaroslav@810
  2237
            } else {
jaroslav@810
  2238
                if (where[1] != -1) {
jaroslav@810
  2239
                    // null found
jaroslav@810
  2240
                    keys[where[1]] = key;
jaroslav@810
  2241
                    values[where[1]] = val;
jaroslav@810
  2242
                } else {
jaroslav@810
  2243
                    if (keys == null) {
jaroslav@810
  2244
                        keys = new Object[11];
jaroslav@810
  2245
                        values = new Object[11];
jaroslav@810
  2246
                        keys[0] = key;
jaroslav@810
  2247
                        values[0] = val;
jaroslav@810
  2248
                    } else {
jaroslav@810
  2249
                        Object[] newKeys = new Object[keys.length * 2];
jaroslav@810
  2250
                        Object[] newValues = new Object[values.length * 2];
jaroslav@810
  2251
                        for (int i = 0; i < keys.length; i++) {
jaroslav@810
  2252
                            newKeys[i] = keys[i];
jaroslav@810
  2253
                            newValues[i] = values[i];
jaroslav@810
  2254
                        }
jaroslav@810
  2255
                        newKeys[keys.length] = key;
jaroslav@810
  2256
                        newValues[keys.length] = val;
jaroslav@810
  2257
                        keys = newKeys;
jaroslav@810
  2258
                        values = newValues;
jaroslav@810
  2259
                    }
jaroslav@810
  2260
                }
jaroslav@810
  2261
            }
jaroslav@810
  2262
        }
jaroslav@810
  2263
jaroslav@810
  2264
        Object get(Object key) {
jaroslav@810
  2265
            return get(key, null);
jaroslav@810
  2266
        }
jaroslav@810
  2267
jaroslav@810
  2268
        private synchronized Object get(Object key, int[] foundAndNull) {
jaroslav@810
  2269
            if (keys == null) {
jaroslav@810
  2270
                return null;
jaroslav@810
  2271
            }
jaroslav@810
  2272
            for (int i = 0; i < keys.length; i++) {
jaroslav@810
  2273
                if (keys[i] == null) {
jaroslav@810
  2274
                    if (foundAndNull != null) {
jaroslav@810
  2275
                        foundAndNull[1] = i;
jaroslav@810
  2276
                    }
jaroslav@810
  2277
                } else if (keys[i].equals(key)) {
jaroslav@810
  2278
                    if (foundAndNull != null) {
jaroslav@810
  2279
                        foundAndNull[0] = i;
jaroslav@810
  2280
                    }
jaroslav@810
  2281
                    return values[i];
jaroslav@810
  2282
                }
jaroslav@810
  2283
            }
jaroslav@810
  2284
            return null;
jaroslav@810
  2285
        }
jaroslav@810
  2286
    }
jaroslav@810
  2287
jaroslav@810
  2288
    /**
jaroslav@810
  2289
     * Strores InnerClass data informastion.
jaroslav@810
  2290
     *
jaroslav@810
  2291
     * @author Sucheta Dambalkar (Adopted code from jdis)
jaroslav@810
  2292
     */
jaroslav@810
  2293
    private static class InnerClassData {
jaroslav@810
  2294
jaroslav@810
  2295
        ClassData cls;
jaroslav@810
  2296
        int inner_class_info_index, outer_class_info_index, inner_name_index, access;
jaroslav@810
  2297
jaroslav@810
  2298
        public InnerClassData(ClassData cls) {
jaroslav@810
  2299
            this.cls = cls;
jaroslav@810
  2300
jaroslav@810
  2301
        }
jaroslav@810
  2302
jaroslav@810
  2303
        /**
jaroslav@810
  2304
         * Read Innerclass attribute data.
jaroslav@810
  2305
         */
jaroslav@810
  2306
        public void read(DataInputStream in) throws IOException {
jaroslav@810
  2307
            inner_class_info_index = in.readUnsignedShort();
jaroslav@810
  2308
            outer_class_info_index = in.readUnsignedShort();
jaroslav@810
  2309
            inner_name_index = in.readUnsignedShort();
jaroslav@810
  2310
            access = in.readUnsignedShort();
jaroslav@810
  2311
        }  // end read
jaroslav@810
  2312
jaroslav@810
  2313
        /**
jaroslav@810
  2314
         * Returns the access of this class or interface.
jaroslav@810
  2315
         */
jaroslav@810
  2316
        public String[] getAccess() {
jaroslav@810
  2317
            Vector v = new Vector();
jaroslav@810
  2318
            if ((access & ACC_PUBLIC) != 0) {
jaroslav@810
  2319
                v.addElement("public");
jaroslav@810
  2320
            }
jaroslav@810
  2321
            if ((access & ACC_FINAL) != 0) {
jaroslav@810
  2322
                v.addElement("final");
jaroslav@810
  2323
            }
jaroslav@810
  2324
            if ((access & ACC_ABSTRACT) != 0) {
jaroslav@810
  2325
                v.addElement("abstract");
jaroslav@810
  2326
            }
jaroslav@810
  2327
            String[] accflags = new String[v.size()];
jaroslav@810
  2328
            v.copyInto(accflags);
jaroslav@810
  2329
            return accflags;
jaroslav@810
  2330
        }
jaroslav@810
  2331
    } // end InnerClassData
jaroslav@810
  2332
jaroslav@810
  2333
    /**
jaroslav@810
  2334
     * Strores LineNumberTable data information.
jaroslav@810
  2335
     *
jaroslav@810
  2336
     * @author Sucheta Dambalkar (Adopted code from jdis)
jaroslav@810
  2337
     */
jaroslav@810
  2338
    private static class LineNumData {
jaroslav@810
  2339
jaroslav@810
  2340
        short start_pc, line_number;
jaroslav@810
  2341
jaroslav@810
  2342
        public LineNumData() {
jaroslav@810
  2343
        }
jaroslav@810
  2344
jaroslav@810
  2345
        /**
jaroslav@810
  2346
         * Read LineNumberTable attribute.
jaroslav@810
  2347
         */
jaroslav@810
  2348
        public LineNumData(DataInputStream in) throws IOException {
jaroslav@810
  2349
            start_pc = in.readShort();
jaroslav@810
  2350
            line_number = in.readShort();
jaroslav@810
  2351
jaroslav@810
  2352
        }
jaroslav@810
  2353
    }
jaroslav@810
  2354
jaroslav@810
  2355
    /**
jaroslav@810
  2356
     * Strores LocalVariableTable data information.
jaroslav@810
  2357
     *
jaroslav@810
  2358
     * @author Sucheta Dambalkar (Adopted code from jdis)
jaroslav@810
  2359
     */
jaroslav@810
  2360
    private static class LocVarData {
jaroslav@810
  2361
jaroslav@810
  2362
        short start_pc, length, name_cpx, sig_cpx, slot;
jaroslav@810
  2363
jaroslav@810
  2364
        public LocVarData() {
jaroslav@810
  2365
        }
jaroslav@810
  2366
jaroslav@810
  2367
        /**
jaroslav@810
  2368
         * Read LocalVariableTable attribute.
jaroslav@810
  2369
         */
jaroslav@810
  2370
        public LocVarData(DataInputStream in) throws IOException {
jaroslav@810
  2371
            start_pc = in.readShort();
jaroslav@810
  2372
            length = in.readShort();
jaroslav@810
  2373
            name_cpx = in.readShort();
jaroslav@810
  2374
            sig_cpx = in.readShort();
jaroslav@810
  2375
            slot = in.readShort();
jaroslav@810
  2376
jaroslav@810
  2377
        }
jaroslav@810
  2378
    }
jaroslav@810
  2379
    /**
jaroslav@810
  2380
     * Strores method data informastion.
jaroslav@810
  2381
     *
jaroslav@810
  2382
     * @author Sucheta Dambalkar (Adopted code from jdis)
jaroslav@810
  2383
     */
jaroslav@810
  2384
    static class MethodData {
jaroslav@810
  2385
jaroslav@810
  2386
        ClassData cls;
jaroslav@810
  2387
        int access;
jaroslav@810
  2388
        int name_index;
jaroslav@810
  2389
        int descriptor_index;
jaroslav@810
  2390
        int attributes_count;
jaroslav@810
  2391
        byte[] code;
jaroslav@810
  2392
        Vector exception_table = new Vector(0);
jaroslav@810
  2393
        Vector lin_num_tb = new Vector(0);
jaroslav@810
  2394
        Vector loc_var_tb = new Vector(0);
jaroslav@810
  2395
        StackMapTableData[] stackMapTable;
jaroslav@810
  2396
        StackMapData[] stackMap;
jaroslav@810
  2397
        int[] exc_index_table = null;
jaroslav@810
  2398
        Vector attrs = new Vector(0);
jaroslav@810
  2399
        Vector code_attrs = new Vector(0);
jaroslav@810
  2400
        int max_stack, max_locals;
jaroslav@810
  2401
        boolean isSynthetic = false;
jaroslav@810
  2402
        boolean isDeprecated = false;
jaroslav@810
  2403
jaroslav@810
  2404
        public MethodData(ClassData cls) {
jaroslav@810
  2405
            this.cls = cls;
jaroslav@810
  2406
        }
jaroslav@810
  2407
jaroslav@810
  2408
        /**
jaroslav@810
  2409
         * Read method info.
jaroslav@810
  2410
         */
jaroslav@810
  2411
        public void read(DataInputStream in) throws IOException {
jaroslav@810
  2412
            access = in.readUnsignedShort();
jaroslav@810
  2413
            name_index = in.readUnsignedShort();
jaroslav@810
  2414
            descriptor_index = in.readUnsignedShort();
jaroslav@810
  2415
            int attributes_count = in.readUnsignedShort();
jaroslav@810
  2416
            for (int i = 0; i < attributes_count; i++) {
jaroslav@810
  2417
                int attr_name_index = in.readUnsignedShort();
jaroslav@810
  2418
jaroslav@810
  2419
                readAttr:
jaroslav@810
  2420
                {
jaroslav@810
  2421
                    if (cls.getTag(attr_name_index) == CONSTANT_UTF8) {
jaroslav@810
  2422
                        String attr_name = cls.getString(attr_name_index);
jaroslav@810
  2423
                        if (attr_name.equals("Code")) {
jaroslav@810
  2424
                            readCode(in);
jaroslav@810
  2425
                            AttrData attr = new AttrData(cls);
jaroslav@810
  2426
                            attr.read(attr_name_index);
jaroslav@810
  2427
                            attrs.addElement(attr);
jaroslav@810
  2428
                            break readAttr;
jaroslav@810
  2429
                        } else if (attr_name.equals("Exceptions")) {
jaroslav@810
  2430
                            readExceptions(in);
jaroslav@810
  2431
                            AttrData attr = new AttrData(cls);
jaroslav@810
  2432
                            attr.read(attr_name_index);
jaroslav@810
  2433
                            attrs.addElement(attr);
jaroslav@810
  2434
                            break readAttr;
jaroslav@810
  2435
                        } else if (attr_name.equals("Synthetic")) {
jaroslav@810
  2436
                            if (in.readInt() != 0) {
jaroslav@810
  2437
                                throw new ClassFormatError("invalid Synthetic attr length");
jaroslav@810
  2438
                            }
jaroslav@810
  2439
                            isSynthetic = true;
jaroslav@810
  2440
                            AttrData attr = new AttrData(cls);
jaroslav@810
  2441
                            attr.read(attr_name_index);
jaroslav@810
  2442
                            attrs.addElement(attr);
jaroslav@810
  2443
                            break readAttr;
jaroslav@810
  2444
                        } else if (attr_name.equals("Deprecated")) {
jaroslav@810
  2445
                            if (in.readInt() != 0) {
jaroslav@810
  2446
                                throw new ClassFormatError("invalid Synthetic attr length");
jaroslav@810
  2447
                            }
jaroslav@810
  2448
                            isDeprecated = true;
jaroslav@810
  2449
                            AttrData attr = new AttrData(cls);
jaroslav@810
  2450
                            attr.read(attr_name_index);
jaroslav@810
  2451
                            attrs.addElement(attr);
jaroslav@810
  2452
                            break readAttr;
jaroslav@810
  2453
                        }
jaroslav@810
  2454
                    }
jaroslav@810
  2455
                    AttrData attr = new AttrData(cls);
jaroslav@810
  2456
                    attr.read(attr_name_index, in);
jaroslav@810
  2457
                    attrs.addElement(attr);
jaroslav@810
  2458
                }
jaroslav@810
  2459
            }
jaroslav@810
  2460
        }
jaroslav@810
  2461
jaroslav@810
  2462
        /**
jaroslav@810
  2463
         * Read code attribute info.
jaroslav@810
  2464
         */
jaroslav@810
  2465
        public void readCode(DataInputStream in) throws IOException {
jaroslav@810
  2466
jaroslav@810
  2467
            int attr_length = in.readInt();
jaroslav@810
  2468
            max_stack = in.readUnsignedShort();
jaroslav@810
  2469
            max_locals = in.readUnsignedShort();
jaroslav@810
  2470
            int codelen = in.readInt();
jaroslav@810
  2471
jaroslav@810
  2472
            code = new byte[codelen];
jaroslav@810
  2473
            int totalread = 0;
jaroslav@810
  2474
            while (totalread < codelen) {
jaroslav@810
  2475
                totalread += in.read(code, totalread, codelen - totalread);
jaroslav@810
  2476
            }
jaroslav@810
  2477
            //      in.read(code, 0, codelen);
jaroslav@810
  2478
            int clen = 0;
jaroslav@810
  2479
            readExceptionTable(in);
jaroslav@810
  2480
            int code_attributes_count = in.readUnsignedShort();
jaroslav@810
  2481
jaroslav@810
  2482
            for (int k = 0; k < code_attributes_count; k++) {
jaroslav@810
  2483
                int table_name_index = in.readUnsignedShort();
jaroslav@810
  2484
                int table_name_tag = cls.getTag(table_name_index);
jaroslav@810
  2485
                AttrData attr = new AttrData(cls);
jaroslav@810
  2486
                if (table_name_tag == CONSTANT_UTF8) {
jaroslav@810
  2487
                    String table_name_tstr = cls.getString(table_name_index);
jaroslav@810
  2488
                    if (table_name_tstr.equals("LineNumberTable")) {
jaroslav@810
  2489
                        readLineNumTable(in);
jaroslav@810
  2490
                        attr.read(table_name_index);
jaroslav@810
  2491
                    } else if (table_name_tstr.equals("LocalVariableTable")) {
jaroslav@810
  2492
                        readLocVarTable(in);
jaroslav@810
  2493
                        attr.read(table_name_index);
jaroslav@810
  2494
                    } else if (table_name_tstr.equals("StackMapTable")) {
jaroslav@810
  2495
                        readStackMapTable(in);
jaroslav@810
  2496
                        attr.read(table_name_index);
jaroslav@810
  2497
                    } else if (table_name_tstr.equals("StackMap")) {
jaroslav@810
  2498
                        readStackMap(in);
jaroslav@810
  2499
                        attr.read(table_name_index);
jaroslav@810
  2500
                    } else {
jaroslav@810
  2501
                        attr.read(table_name_index, in);
jaroslav@810
  2502
                    }
jaroslav@810
  2503
                    code_attrs.addElement(attr);
jaroslav@810
  2504
                    continue;
jaroslav@810
  2505
                }
jaroslav@810
  2506
jaroslav@810
  2507
                attr.read(table_name_index, in);
jaroslav@810
  2508
                code_attrs.addElement(attr);
jaroslav@810
  2509
            }
jaroslav@810
  2510
        }
jaroslav@810
  2511
jaroslav@810
  2512
        /**
jaroslav@810
  2513
         * Read exception table info.
jaroslav@810
  2514
         */
jaroslav@810
  2515
        void readExceptionTable(DataInputStream in) throws IOException {
jaroslav@810
  2516
            int exception_table_len = in.readUnsignedShort();
jaroslav@810
  2517
            exception_table = new Vector(exception_table_len);
jaroslav@810
  2518
            for (int l = 0; l < exception_table_len; l++) {
jaroslav@810
  2519
                exception_table.addElement(new TrapData(in, l));
jaroslav@810
  2520
            }
jaroslav@810
  2521
        }
jaroslav@810
  2522
jaroslav@810
  2523
        /**
jaroslav@810
  2524
         * Read LineNumberTable attribute info.
jaroslav@810
  2525
         */
jaroslav@810
  2526
        void readLineNumTable(DataInputStream in) throws IOException {
jaroslav@810
  2527
            int attr_len = in.readInt(); // attr_length
jaroslav@810
  2528
            int lin_num_tb_len = in.readUnsignedShort();
jaroslav@810
  2529
            lin_num_tb = new Vector(lin_num_tb_len);
jaroslav@810
  2530
            for (int l = 0; l < lin_num_tb_len; l++) {
jaroslav@810
  2531
                lin_num_tb.addElement(new LineNumData(in));
jaroslav@810
  2532
            }
jaroslav@810
  2533
        }
jaroslav@810
  2534
jaroslav@810
  2535
        /**
jaroslav@810
  2536
         * Read LocalVariableTable attribute info.
jaroslav@810
  2537
         */
jaroslav@810
  2538
        void readLocVarTable(DataInputStream in) throws IOException {
jaroslav@810
  2539
            int attr_len = in.readInt(); // attr_length
jaroslav@810
  2540
            int loc_var_tb_len = in.readUnsignedShort();
jaroslav@810
  2541
            loc_var_tb = new Vector(loc_var_tb_len);
jaroslav@810
  2542
            for (int l = 0; l < loc_var_tb_len; l++) {
jaroslav@810
  2543
                loc_var_tb.addElement(new LocVarData(in));
jaroslav@810
  2544
            }
jaroslav@810
  2545
        }
jaroslav@810
  2546
jaroslav@810
  2547
        /**
jaroslav@810
  2548
         * Read Exception attribute info.
jaroslav@810
  2549
         */
jaroslav@810
  2550
        public void readExceptions(DataInputStream in) throws IOException {
jaroslav@810
  2551
            int attr_len = in.readInt(); // attr_length in prog
jaroslav@810
  2552
            int num_exceptions = in.readUnsignedShort();
jaroslav@810
  2553
            exc_index_table = new int[num_exceptions];
jaroslav@810
  2554
            for (int l = 0; l < num_exceptions; l++) {
jaroslav@810
  2555
                int exc = in.readShort();
jaroslav@810
  2556
                exc_index_table[l] = exc;
jaroslav@810
  2557
            }
jaroslav@810
  2558
        }
jaroslav@810
  2559
jaroslav@810
  2560
        /**
jaroslav@810
  2561
         * Read StackMapTable attribute info.
jaroslav@810
  2562
         */
jaroslav@810
  2563
        void readStackMapTable(DataInputStream in) throws IOException {
jaroslav@810
  2564
            int attr_len = in.readInt();  //attr_length
jaroslav@810
  2565
            int stack_map_tb_len = in.readUnsignedShort();
jaroslav@810
  2566
            stackMapTable = new StackMapTableData[stack_map_tb_len];
jaroslav@810
  2567
            for (int i = 0; i < stack_map_tb_len; i++) {
jaroslav@810
  2568
                stackMapTable[i] = StackMapTableData.getInstance(in, this);
jaroslav@810
  2569
            }
jaroslav@810
  2570
        }
jaroslav@810
  2571
jaroslav@810
  2572
        /**
jaroslav@810
  2573
         * Read StackMap attribute info.
jaroslav@810
  2574
         */
jaroslav@810
  2575
        void readStackMap(DataInputStream in) throws IOException {
jaroslav@810
  2576
            int attr_len = in.readInt();  //attr_length
jaroslav@810
  2577
            int stack_map_len = in.readUnsignedShort();
jaroslav@810
  2578
            stackMap = new StackMapData[stack_map_len];
jaroslav@810
  2579
            for (int i = 0; i < stack_map_len; i++) {
jaroslav@810
  2580
                stackMap[i] = new StackMapData(in, this);
jaroslav@810
  2581
            }
jaroslav@810
  2582
        }
jaroslav@810
  2583
jaroslav@810
  2584
        /**
jaroslav@810
  2585
         * Return access of the method.
jaroslav@810
  2586
         */
jaroslav@810
  2587
        public int getAccess() {
jaroslav@810
  2588
            return access;
jaroslav@810
  2589
        }
jaroslav@810
  2590
jaroslav@810
  2591
        /**
jaroslav@810
  2592
         * Return name of the method.
jaroslav@810
  2593
         */
jaroslav@810
  2594
        public String getName() {
jaroslav@810
  2595
            return cls.getStringValue(name_index);
jaroslav@810
  2596
        }
jaroslav@810
  2597
jaroslav@810
  2598
        /**
jaroslav@810
  2599
         * Return internal siganature of the method.
jaroslav@810
  2600
         */
jaroslav@810
  2601
        public String getInternalSig() {
jaroslav@810
  2602
            return cls.getStringValue(descriptor_index);
jaroslav@810
  2603
        }
jaroslav@810
  2604
jaroslav@810
  2605
        /**
jaroslav@810
  2606
         * Return code attribute data of a method.
jaroslav@810
  2607
         */
jaroslav@810
  2608
        public byte[] getCode() {
jaroslav@810
  2609
            return code;
jaroslav@810
  2610
        }
jaroslav@810
  2611
jaroslav@810
  2612
        /**
jaroslav@810
  2613
         * Return LineNumberTable size.
jaroslav@810
  2614
         */
jaroslav@810
  2615
        public int getnumlines() {
jaroslav@810
  2616
            return lin_num_tb.size();
jaroslav@810
  2617
        }
jaroslav@810
  2618
jaroslav@810
  2619
        /**
jaroslav@810
  2620
         * Return LineNumberTable
jaroslav@810
  2621
         */
jaroslav@810
  2622
        public Vector getlin_num_tb() {
jaroslav@810
  2623
            return lin_num_tb;
jaroslav@810
  2624
        }
jaroslav@810
  2625
jaroslav@810
  2626
        /**
jaroslav@810
  2627
         * Return LocalVariableTable size.
jaroslav@810
  2628
         */
jaroslav@810
  2629
        public int getloc_var_tbsize() {
jaroslav@810
  2630
            return loc_var_tb.size();
jaroslav@810
  2631
        }
jaroslav@810
  2632
jaroslav@810
  2633
        /**
jaroslav@810
  2634
         * Return LocalVariableTable.
jaroslav@810
  2635
         */
jaroslav@810
  2636
        public Vector getloc_var_tb() {
jaroslav@810
  2637
            return loc_var_tb;
jaroslav@810
  2638
        }
jaroslav@810
  2639
jaroslav@810
  2640
        /**
jaroslav@810
  2641
         * Return StackMap.
jaroslav@810
  2642
         */
jaroslav@810
  2643
        public StackMapData[] getStackMap() {
jaroslav@810
  2644
            return stackMap;
jaroslav@810
  2645
        }
jaroslav@810
  2646
jaroslav@810
  2647
        /**
jaroslav@810
  2648
         * Return StackMapTable.
jaroslav@810
  2649
         */
jaroslav@810
  2650
        public StackMapTableData[] getStackMapTable() {
jaroslav@810
  2651
            return stackMapTable;
jaroslav@810
  2652
        }
jaroslav@810
  2653
jaroslav@810
  2654
        public StackMapIterator createStackMapIterator() {
jaroslav@810
  2655
            return new StackMapIterator(this);
jaroslav@810
  2656
        }
jaroslav@810
  2657
jaroslav@810
  2658
        /**
jaroslav@810
  2659
         * Return true if method is static
jaroslav@810
  2660
         */
jaroslav@810
  2661
        public boolean isStatic() {
jaroslav@810
  2662
            if ((access & ACC_STATIC) != 0) {
jaroslav@810
  2663
                return true;
jaroslav@810
  2664
            }
jaroslav@810
  2665
            return false;
jaroslav@810
  2666
        }
jaroslav@810
  2667
jaroslav@810
  2668
        /**
jaroslav@810
  2669
         * Return max depth of operand stack.
jaroslav@810
  2670
         */
jaroslav@810
  2671
        public int getMaxStack() {
jaroslav@810
  2672
            return max_stack;
jaroslav@810
  2673
        }
jaroslav@810
  2674
jaroslav@810
  2675
        /**
jaroslav@810
  2676
         * Return number of local variables.
jaroslav@810
  2677
         */
jaroslav@810
  2678
        public int getMaxLocals() {
jaroslav@810
  2679
            return max_locals;
jaroslav@810
  2680
        }
jaroslav@810
  2681
jaroslav@810
  2682
        /**
jaroslav@810
  2683
         * Return exception index table in Exception attribute.
jaroslav@810
  2684
         */
jaroslav@810
  2685
        public int[] get_exc_index_table() {
jaroslav@810
  2686
            return exc_index_table;
jaroslav@810
  2687
        }
jaroslav@810
  2688
jaroslav@810
  2689
        /**
jaroslav@810
  2690
         * Return exception table in code attributre.
jaroslav@810
  2691
         */
jaroslav@810
  2692
        public TrapDataIterator getTrapDataIterator() {
jaroslav@810
  2693
            return new TrapDataIterator(exception_table);
jaroslav@810
  2694
        }
jaroslav@810
  2695
jaroslav@810
  2696
        /**
jaroslav@810
  2697
         * Return method attributes.
jaroslav@810
  2698
         */
jaroslav@810
  2699
        public Vector getAttributes() {
jaroslav@810
  2700
            return attrs;
jaroslav@810
  2701
        }
jaroslav@810
  2702
jaroslav@810
  2703
        /**
jaroslav@810
  2704
         * Return code attributes.
jaroslav@810
  2705
         */
jaroslav@810
  2706
        public Vector getCodeAttributes() {
jaroslav@810
  2707
            return code_attrs;
jaroslav@810
  2708
        }
jaroslav@810
  2709
jaroslav@810
  2710
        /**
jaroslav@810
  2711
         * Return true if method id synthetic.
jaroslav@810
  2712
         */
jaroslav@810
  2713
        public boolean isSynthetic() {
jaroslav@810
  2714
            return isSynthetic;
jaroslav@810
  2715
        }
jaroslav@810
  2716
jaroslav@810
  2717
        /**
jaroslav@810
  2718
         * Return true if method is deprecated.
jaroslav@810
  2719
         */
jaroslav@810
  2720
        public boolean isDeprecated() {
jaroslav@810
  2721
            return isDeprecated;
jaroslav@810
  2722
        }
jaroslav@810
  2723
jaroslav@810
  2724
        public byte[] findAnnotationData(boolean classRetention) {
jaroslav@810
  2725
            String n = classRetention
jaroslav@810
  2726
                ? "RuntimeInvisibleAnnotations" : // NOI18N
jaroslav@810
  2727
                "RuntimeVisibleAnnotations"; // NOI18N
jaroslav@810
  2728
            AttrData[] arr = new AttrData[attrs.size()];
jaroslav@810
  2729
            attrs.copyInto(arr);
jaroslav@810
  2730
            return ClassData.findAttr(n, arr);
jaroslav@810
  2731
        }
jaroslav@810
  2732
jaroslav@810
  2733
        public boolean isConstructor() {
jaroslav@810
  2734
            return "<init>".equals(getName());
jaroslav@810
  2735
        }
jaroslav@810
  2736
    }
jaroslav@810
  2737
jaroslav@810
  2738
    /* represents one entry of StackMap attribute
jaroslav@810
  2739
     */
jaroslav@810
  2740
    private static class StackMapData {
jaroslav@810
  2741
jaroslav@810
  2742
        final int offset;
jaroslav@810
  2743
        final int[] locals;
jaroslav@810
  2744
        final int[] stack;
jaroslav@810
  2745
jaroslav@810
  2746
        StackMapData(int offset, int[] locals, int[] stack) {
jaroslav@810
  2747
            this.offset = offset;
jaroslav@810
  2748
            this.locals = locals;
jaroslav@810
  2749
            this.stack = stack;
jaroslav@810
  2750
        }
jaroslav@810
  2751
jaroslav@810
  2752
        StackMapData(DataInputStream in, MethodData method) throws IOException {
jaroslav@810
  2753
            offset = in.readUnsignedShort();
jaroslav@810
  2754
            int local_size = in.readUnsignedShort();
jaroslav@810
  2755
            locals = readTypeArray(in, local_size, method);
jaroslav@810
  2756
            int stack_size = in.readUnsignedShort();
jaroslav@810
  2757
            stack = readTypeArray(in, stack_size, method);
jaroslav@810
  2758
        }
jaroslav@810
  2759
jaroslav@810
  2760
        static final int[] readTypeArray(DataInputStream in, int length, MethodData method) throws IOException {
jaroslav@810
  2761
            int[] types = new int[length];
jaroslav@810
  2762
            for (int i = 0; i < length; i++) {
jaroslav@810
  2763
                types[i] = readType(in, method);
jaroslav@810
  2764
            }
jaroslav@810
  2765
            return types;
jaroslav@810
  2766
        }
jaroslav@810
  2767
jaroslav@810
  2768
        static final int readType(DataInputStream in, MethodData method) throws IOException {
jaroslav@810
  2769
            int type = in.readUnsignedByte();
jaroslav@810
  2770
            if (type == ITEM_Object || type == ITEM_NewObject) {
jaroslav@810
  2771
                type = type | (in.readUnsignedShort() << 8);
jaroslav@810
  2772
            }
jaroslav@810
  2773
            return type;
jaroslav@810
  2774
        }
jaroslav@810
  2775
    }
jaroslav@810
  2776
jaroslav@810
  2777
    static final class StackMapIterator {
jaroslav@810
  2778
jaroslav@810
  2779
        private final StackMapTableData[] stackMapTable;
jaroslav@810
  2780
        private final TypeArray argTypes;
jaroslav@810
  2781
        private final TypeArray localTypes;
jaroslav@810
  2782
        private final TypeArray stackTypes;
jaroslav@810
  2783
        private int nextFrameIndex;
jaroslav@810
  2784
        private int lastFrameByteCodeOffset;
jaroslav@810
  2785
        private int byteCodeOffset;
jaroslav@810
  2786
jaroslav@810
  2787
        StackMapIterator(final MethodData methodData) {
jaroslav@810
  2788
            this(methodData.getStackMapTable(),
jaroslav@810
  2789
                methodData.getInternalSig(),
jaroslav@810
  2790
                methodData.isStatic());
jaroslav@810
  2791
        }
jaroslav@810
  2792
jaroslav@810
  2793
        StackMapIterator(final StackMapTableData[] stackMapTable,
jaroslav@810
  2794
            final String methodSignature,
jaroslav@810
  2795
            final boolean isStaticMethod) {
jaroslav@810
  2796
            this.stackMapTable = (stackMapTable != null)
jaroslav@810
  2797
                ? stackMapTable
jaroslav@810
  2798
                : new StackMapTableData[0];
jaroslav@810
  2799
jaroslav@810
  2800
            argTypes = getArgTypes(methodSignature, isStaticMethod);
jaroslav@810
  2801
            localTypes = new TypeArray();
jaroslav@810
  2802
            stackTypes = new TypeArray();
jaroslav@810
  2803
jaroslav@810
  2804
            localTypes.addAll(argTypes);
jaroslav@810
  2805
jaroslav@810
  2806
            lastFrameByteCodeOffset = -1;
jaroslav@810
  2807
            advanceBy(0);
jaroslav@810
  2808
        }
jaroslav@810
  2809
jaroslav@810
  2810
        public String getFrameAsString() {
jaroslav@810
  2811
            return (nextFrameIndex == 0)
jaroslav@810
  2812
                ? StackMapTableData.toString("INITIAL", 0, null, null)
jaroslav@810
  2813
                : stackMapTable[nextFrameIndex - 1].toString();
jaroslav@810
  2814
        }
jaroslav@810
  2815
jaroslav@810
  2816
        public int getFrameIndex() {
jaroslav@810
  2817
            return nextFrameIndex;
jaroslav@810
  2818
        }
jaroslav@810
  2819
jaroslav@810
  2820
        public TypeArray getFrameStack() {
jaroslav@810
  2821
            return stackTypes;
jaroslav@810
  2822
        }
jaroslav@810
  2823
jaroslav@810
  2824
        public TypeArray getFrameLocals() {
jaroslav@810
  2825
            return localTypes;
jaroslav@810
  2826
        }
jaroslav@810
  2827
jaroslav@810
  2828
        public TypeArray getArguments() {
jaroslav@810
  2829
            return argTypes;
jaroslav@810
  2830
        }
jaroslav@810
  2831
jaroslav@810
  2832
        public void advanceBy(final int numByteCodes) {
jaroslav@810
  2833
            if (numByteCodes < 0) {
jaroslav@810
  2834
                throw new IllegalStateException("Forward only iterator");
jaroslav@810
  2835
            }
jaroslav@810
  2836
jaroslav@810
  2837
            byteCodeOffset += numByteCodes;
jaroslav@810
  2838
            while ((nextFrameIndex < stackMapTable.length)
jaroslav@810
  2839
                && ((byteCodeOffset - lastFrameByteCodeOffset)
jaroslav@810
  2840
                >= (stackMapTable[nextFrameIndex].offsetDelta
jaroslav@810
  2841
                + 1))) {
jaroslav@810
  2842
                final StackMapTableData nextFrame = stackMapTable[nextFrameIndex];
jaroslav@810
  2843
jaroslav@810
  2844
                lastFrameByteCodeOffset += nextFrame.offsetDelta + 1;
jaroslav@810
  2845
                nextFrame.applyTo(localTypes, stackTypes);
jaroslav@810
  2846
jaroslav@810
  2847
                ++nextFrameIndex;
jaroslav@810
  2848
            }
jaroslav@810
  2849
        }
jaroslav@810
  2850
jaroslav@810
  2851
        public void advanceTo(final int nextByteCodeOffset) {
jaroslav@810
  2852
            advanceBy(nextByteCodeOffset - byteCodeOffset);
jaroslav@810
  2853
        }
jaroslav@810
  2854
jaroslav@810
  2855
        private static TypeArray getArgTypes(final String methodSignature,
jaroslav@810
  2856
            final boolean isStaticMethod) {
jaroslav@810
  2857
            final TypeArray argTypes = new TypeArray();
jaroslav@810
  2858
jaroslav@810
  2859
            if (!isStaticMethod) {
jaroslav@810
  2860
                argTypes.add(ITEM_Object);
jaroslav@810
  2861
            }
jaroslav@810
  2862
jaroslav@810
  2863
            if (methodSignature.charAt(0) != '(') {
jaroslav@810
  2864
                throw new IllegalArgumentException("Invalid method signature");
jaroslav@810
  2865
            }
jaroslav@810
  2866
jaroslav@810
  2867
            final int length = methodSignature.length();
jaroslav@810
  2868
            boolean skipType = false;
jaroslav@810
  2869
            int argType;
jaroslav@810
  2870
            for (int i = 1; i < length; ++i) {
jaroslav@810
  2871
                switch (methodSignature.charAt(i)) {
jaroslav@810
  2872
                    case 'B':
jaroslav@810
  2873
                    case 'C':
jaroslav@810
  2874
                    case 'S':
jaroslav@810
  2875
                    case 'Z':
jaroslav@810
  2876
                    case 'I':
jaroslav@810
  2877
                        argType = ITEM_Integer;
jaroslav@810
  2878
                        break;
jaroslav@810
  2879
                    case 'J':
jaroslav@810
  2880
                        argType = ITEM_Long;
jaroslav@810
  2881
                        break;
jaroslav@810
  2882
                    case 'F':
jaroslav@810
  2883
                        argType = ITEM_Float;
jaroslav@810
  2884
                        break;
jaroslav@810
  2885
                    case 'D':
jaroslav@810
  2886
                        argType = ITEM_Double;
jaroslav@810
  2887
                        break;
jaroslav@810
  2888
                    case 'L': {
jaroslav@810
  2889
                        i = methodSignature.indexOf(';', i + 1);
jaroslav@810
  2890
                        if (i == -1) {
jaroslav@810
  2891
                            throw new IllegalArgumentException(
jaroslav@810
  2892
                                "Invalid method signature");
jaroslav@810
  2893
                        }
jaroslav@810
  2894
                        argType = ITEM_Object;
jaroslav@810
  2895
                        break;
jaroslav@810
  2896
                    }
jaroslav@810
  2897
                    case ')':
jaroslav@810
  2898
                        // not interested in the return value type
jaroslav@810
  2899
                        return argTypes;
jaroslav@810
  2900
                    case '[':
jaroslav@810
  2901
                        if (!skipType) {
jaroslav@810
  2902
                            argTypes.add(ITEM_Object);
jaroslav@810
  2903
                            skipType = true;
jaroslav@810
  2904
                        }
jaroslav@810
  2905
                        continue;
jaroslav@810
  2906
jaroslav@810
  2907
                    default:
jaroslav@810
  2908
                        throw new IllegalArgumentException(
jaroslav@810
  2909
                            "Invalid method signature");
jaroslav@810
  2910
                }
jaroslav@810
  2911
jaroslav@810
  2912
                if (!skipType) {
jaroslav@810
  2913
                    argTypes.add(argType);
jaroslav@810
  2914
                } else {
jaroslav@810
  2915
                    skipType = false;
jaroslav@810
  2916
                }
jaroslav@810
  2917
            }
jaroslav@810
  2918
jaroslav@810
  2919
            return argTypes;
jaroslav@810
  2920
        }
jaroslav@810
  2921
    }
jaroslav@810
  2922
    /* represents one entry of StackMapTable attribute
jaroslav@810
  2923
     */
jaroslav@810
  2924
jaroslav@810
  2925
    private static abstract class StackMapTableData {
jaroslav@810
  2926
jaroslav@810
  2927
        final int frameType;
jaroslav@810
  2928
        int offsetDelta;
jaroslav@810
  2929
jaroslav@810
  2930
        StackMapTableData(int frameType) {
jaroslav@810
  2931
            this.frameType = frameType;
jaroslav@810
  2932
        }
jaroslav@810
  2933
jaroslav@810
  2934
        abstract void applyTo(TypeArray localTypes, TypeArray stackTypes);
jaroslav@810
  2935
jaroslav@810
  2936
        protected static String toString(
jaroslav@810
  2937
            final String frameType,
jaroslav@810
  2938
            final int offset,
jaroslav@810
  2939
            final int[] localTypes,
jaroslav@810
  2940
            final int[] stackTypes) {
jaroslav@810
  2941
            final StringBuilder sb = new StringBuilder(frameType);
jaroslav@810
  2942
jaroslav@810
  2943
            sb.append("(off: +").append(offset);
jaroslav@810
  2944
            if (localTypes != null) {
jaroslav@810
  2945
                sb.append(", locals: ");
jaroslav@810
  2946
                appendTypes(sb, localTypes);
jaroslav@810
  2947
            }
jaroslav@810
  2948
            if (stackTypes != null) {
jaroslav@810
  2949
                sb.append(", stack: ");
jaroslav@810
  2950
                appendTypes(sb, stackTypes);
jaroslav@810
  2951
            }
jaroslav@810
  2952
            sb.append(')');
jaroslav@810
  2953
jaroslav@810
  2954
            return sb.toString();
jaroslav@810
  2955
        }
jaroslav@810
  2956
jaroslav@810
  2957
        private static void appendTypes(final StringBuilder sb, final int[] types) {
jaroslav@810
  2958
            sb.append('[');
jaroslav@810
  2959
            if (types.length > 0) {
jaroslav@810
  2960
                sb.append(TypeArray.typeString(types[0]));
jaroslav@810
  2961
                for (int i = 1; i < types.length; ++i) {
jaroslav@810
  2962
                    sb.append(", ");
jaroslav@810
  2963
                    sb.append(TypeArray.typeString(types[i]));
jaroslav@810
  2964
                }
jaroslav@810
  2965
            }
jaroslav@810
  2966
            sb.append(']');
jaroslav@810
  2967
        }
jaroslav@810
  2968
jaroslav@810
  2969
        private static class SameFrame extends StackMapTableData {
jaroslav@810
  2970
jaroslav@810
  2971
            SameFrame(int frameType, int offsetDelta) {
jaroslav@810
  2972
                super(frameType);
jaroslav@810
  2973
                this.offsetDelta = offsetDelta;
jaroslav@810
  2974
            }
jaroslav@810
  2975
jaroslav@810
  2976
            @Override
jaroslav@810
  2977
            void applyTo(TypeArray localTypes, TypeArray stackTypes) {
jaroslav@810
  2978
                stackTypes.clear();
jaroslav@810
  2979
            }
jaroslav@810
  2980
jaroslav@810
  2981
            @Override
jaroslav@810
  2982
            public String toString() {
jaroslav@810
  2983
                return toString("SAME" + ((frameType == SAME_FRAME_EXTENDED)
jaroslav@810
  2984
                    ? "_FRAME_EXTENDED" : ""),
jaroslav@810
  2985
                    offsetDelta,
jaroslav@810
  2986
                    null, null);
jaroslav@810
  2987
            }
jaroslav@810
  2988
        }
jaroslav@810
  2989
jaroslav@810
  2990
        private static class SameLocals1StackItem extends StackMapTableData {
jaroslav@810
  2991
jaroslav@810
  2992
            final int[] stack;
jaroslav@810
  2993
jaroslav@810
  2994
            SameLocals1StackItem(int frameType, int offsetDelta, int[] stack) {
jaroslav@810
  2995
                super(frameType);
jaroslav@810
  2996
                this.offsetDelta = offsetDelta;
jaroslav@810
  2997
                this.stack = stack;
jaroslav@810
  2998
            }
jaroslav@810
  2999
jaroslav@810
  3000
            @Override
jaroslav@810
  3001
            void applyTo(TypeArray localTypes, TypeArray stackTypes) {
jaroslav@810
  3002
                stackTypes.setAll(stack);
jaroslav@810
  3003
            }
jaroslav@810
  3004
jaroslav@810
  3005
            @Override
jaroslav@810
  3006
            public String toString() {
jaroslav@810
  3007
                return toString(
jaroslav@810
  3008
                    "SAME_LOCALS_1_STACK_ITEM"
jaroslav@810
  3009
                    + ((frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED)
jaroslav@810
  3010
                    ? "_EXTENDED" : ""),
jaroslav@810
  3011
                    offsetDelta,
jaroslav@810
  3012
                    null, stack);
jaroslav@810
  3013
            }
jaroslav@810
  3014
        }
jaroslav@810
  3015
jaroslav@810
  3016
        private static class ChopFrame extends StackMapTableData {
jaroslav@810
  3017
jaroslav@810
  3018
            ChopFrame(int frameType, int offsetDelta) {
jaroslav@810
  3019
                super(frameType);
jaroslav@810
  3020
                this.offsetDelta = offsetDelta;
jaroslav@810
  3021
            }
jaroslav@810
  3022
jaroslav@810
  3023
            @Override
jaroslav@810
  3024
            void applyTo(TypeArray localTypes, TypeArray stackTypes) {
jaroslav@810
  3025
                localTypes.setSize(localTypes.getSize()
jaroslav@810
  3026
                    - (SAME_FRAME_EXTENDED - frameType));
jaroslav@810
  3027
                stackTypes.clear();
jaroslav@810
  3028
            }
jaroslav@810
  3029
jaroslav@810
  3030
            @Override
jaroslav@810
  3031
            public String toString() {
jaroslav@810
  3032
                return toString("CHOP", offsetDelta, null, null);
jaroslav@810
  3033
            }
jaroslav@810
  3034
        }
jaroslav@810
  3035
jaroslav@810
  3036
        private static class AppendFrame extends StackMapTableData {
jaroslav@810
  3037
jaroslav@810
  3038
            final int[] locals;
jaroslav@810
  3039
jaroslav@810
  3040
            AppendFrame(int frameType, int offsetDelta, int[] locals) {
jaroslav@810
  3041
                super(frameType);
jaroslav@810
  3042
                this.offsetDelta = offsetDelta;
jaroslav@810
  3043
                this.locals = locals;
jaroslav@810
  3044
            }
jaroslav@810
  3045
jaroslav@810
  3046
            @Override
jaroslav@810
  3047
            void applyTo(TypeArray localTypes, TypeArray stackTypes) {
jaroslav@810
  3048
                localTypes.addAll(locals);
jaroslav@810
  3049
                stackTypes.clear();
jaroslav@810
  3050
            }
jaroslav@810
  3051
jaroslav@810
  3052
            @Override
jaroslav@810
  3053
            public String toString() {
jaroslav@810
  3054
                return toString("APPEND", offsetDelta, locals, null);
jaroslav@810
  3055
            }
jaroslav@810
  3056
        }
jaroslav@810
  3057
jaroslav@810
  3058
        private static class FullFrame extends StackMapTableData {
jaroslav@810
  3059
jaroslav@810
  3060
            final int[] locals;
jaroslav@810
  3061
            final int[] stack;
jaroslav@810
  3062
jaroslav@810
  3063
            FullFrame(int offsetDelta, int[] locals, int[] stack) {
jaroslav@810
  3064
                super(FULL_FRAME);
jaroslav@810
  3065
                this.offsetDelta = offsetDelta;
jaroslav@810
  3066
                this.locals = locals;
jaroslav@810
  3067
                this.stack = stack;
jaroslav@810
  3068
            }
jaroslav@810
  3069
jaroslav@810
  3070
            @Override
jaroslav@810
  3071
            void applyTo(TypeArray localTypes, TypeArray stackTypes) {
jaroslav@810
  3072
                localTypes.setAll(locals);
jaroslav@810
  3073
                stackTypes.setAll(stack);
jaroslav@810
  3074
            }
jaroslav@810
  3075
jaroslav@810
  3076
            @Override
jaroslav@810
  3077
            public String toString() {
jaroslav@810
  3078
                return toString("FULL", offsetDelta, locals, stack);
jaroslav@810
  3079
            }
jaroslav@810
  3080
        }
jaroslav@810
  3081
jaroslav@810
  3082
        static StackMapTableData getInstance(DataInputStream in, MethodData method)
jaroslav@810
  3083
            throws IOException {
jaroslav@810
  3084
            int frameType = in.readUnsignedByte();
jaroslav@810
  3085
jaroslav@810
  3086
            if (frameType < SAME_FRAME_BOUND) {
jaroslav@810
  3087
                // same_frame
jaroslav@810
  3088
                return new SameFrame(frameType, frameType);
jaroslav@810
  3089
            } else if (SAME_FRAME_BOUND <= frameType && frameType < SAME_LOCALS_1_STACK_ITEM_BOUND) {
jaroslav@810
  3090
                // same_locals_1_stack_item_frame
jaroslav@810
  3091
                // read additional single stack element
jaroslav@810
  3092
                return new SameLocals1StackItem(frameType,
jaroslav@810
  3093
                    (frameType - SAME_FRAME_BOUND),
jaroslav@810
  3094
                    StackMapData.readTypeArray(in, 1, method));
jaroslav@810
  3095
            } else if (frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
jaroslav@810
  3096
                // same_locals_1_stack_item_extended
jaroslav@810
  3097
                return new SameLocals1StackItem(frameType,
jaroslav@810
  3098
                    in.readUnsignedShort(),
jaroslav@810
  3099
                    StackMapData.readTypeArray(in, 1, method));
jaroslav@810
  3100
            } else if (SAME_LOCALS_1_STACK_ITEM_EXTENDED < frameType && frameType < SAME_FRAME_EXTENDED) {
jaroslav@810
  3101
                // chop_frame or same_frame_extended
jaroslav@810
  3102
                return new ChopFrame(frameType, in.readUnsignedShort());
jaroslav@810
  3103
            } else if (frameType == SAME_FRAME_EXTENDED) {
jaroslav@810
  3104
                // chop_frame or same_frame_extended
jaroslav@810
  3105
                return new SameFrame(frameType, in.readUnsignedShort());
jaroslav@810
  3106
            } else if (SAME_FRAME_EXTENDED < frameType && frameType < FULL_FRAME) {
jaroslav@810
  3107
                // append_frame
jaroslav@810
  3108
                return new AppendFrame(frameType, in.readUnsignedShort(),
jaroslav@810
  3109
                    StackMapData.readTypeArray(in, frameType - SAME_FRAME_EXTENDED, method));
jaroslav@810
  3110
            } else if (frameType == FULL_FRAME) {
jaroslav@810
  3111
                // full_frame
jaroslav@810
  3112
                int offsetDelta = in.readUnsignedShort();
jaroslav@810
  3113
                int locals_size = in.readUnsignedShort();
jaroslav@810
  3114
                int[] locals = StackMapData.readTypeArray(in, locals_size, method);
jaroslav@810
  3115
                int stack_size = in.readUnsignedShort();
jaroslav@810
  3116
                int[] stack = StackMapData.readTypeArray(in, stack_size, method);
jaroslav@810
  3117
                return new FullFrame(offsetDelta, locals, stack);
jaroslav@810
  3118
            } else {
jaroslav@810
  3119
                throw new ClassFormatError("unrecognized frame_type in StackMapTable");
jaroslav@810
  3120
            }
jaroslav@810
  3121
        }
jaroslav@810
  3122
    }
jaroslav@810
  3123
jaroslav@810
  3124
    /**
jaroslav@810
  3125
     * Stores exception table data in code attribute.
jaroslav@810
  3126
     *
jaroslav@810
  3127
     * @author Sucheta Dambalkar (Adopted code from jdis)
jaroslav@810
  3128
     */
jaroslav@810
  3129
    static final class TrapData {
jaroslav@810
  3130
jaroslav@810
  3131
        public final short start_pc;
jaroslav@810
  3132
        public final short end_pc;
jaroslav@810
  3133
        public final short handler_pc;
jaroslav@810
  3134
        public final short catch_cpx;
jaroslav@810
  3135
        final int num;
jaroslav@810
  3136
jaroslav@810
  3137
        /**
jaroslav@810
  3138
         * Read and store exception table data in code attribute.
jaroslav@810
  3139
         */
jaroslav@810
  3140
        TrapData(DataInputStream in, int num) throws IOException {
jaroslav@810
  3141
            this.num = num;
jaroslav@810
  3142
            start_pc = in.readShort();
jaroslav@810
  3143
            end_pc = in.readShort();
jaroslav@810
  3144
            handler_pc = in.readShort();
jaroslav@810
  3145
            catch_cpx = in.readShort();
jaroslav@810
  3146
        }
jaroslav@810
  3147
jaroslav@810
  3148
        /**
jaroslav@810
  3149
         * returns recommended identifier
jaroslav@810
  3150
         */
jaroslav@810
  3151
        public String ident() {
jaroslav@810
  3152
            return "t" + num;
jaroslav@810
  3153
        }
jaroslav@810
  3154
    }
jaroslav@810
  3155
    /**
jaroslav@810
  3156
     *
jaroslav@810
  3157
     * @author Jaroslav Tulach <jtulach@netbeans.org>
jaroslav@810
  3158
     */
jaroslav@810
  3159
    static final class TrapDataIterator {
jaroslav@810
  3160
jaroslav@810
  3161
        private final Hashtable exStart = new Hashtable();
jaroslav@810
  3162
        private final Hashtable exStop = new Hashtable();
jaroslav@810
  3163
        private TrapData[] current = new TrapData[10];
jaroslav@810
  3164
        private int currentCount;
jaroslav@810
  3165
jaroslav@810
  3166
        TrapDataIterator(Vector exceptionTable) {
jaroslav@810
  3167
            for (int i = 0; i < exceptionTable.size(); i++) {
jaroslav@810
  3168
                final TrapData td = (TrapData) exceptionTable.elementAt(i);
jaroslav@810
  3169
                put(exStart, td.start_pc, td);
jaroslav@810
  3170
                put(exStop, td.end_pc, td);
jaroslav@810
  3171
            }
jaroslav@810
  3172
        }
jaroslav@810
  3173
jaroslav@810
  3174
        private static void put(Hashtable h, short key, TrapData td) {
jaroslav@810
  3175
            Short s = Short.valueOf((short) key);
jaroslav@810
  3176
            Vector v = (Vector) h.get(s);
jaroslav@810
  3177
            if (v == null) {
jaroslav@810
  3178
                v = new Vector(1);
jaroslav@810
  3179
                h.put(s, v);
jaroslav@810
  3180
            }
jaroslav@810
  3181
            v.add(td);
jaroslav@810
  3182
        }
jaroslav@810
  3183
jaroslav@810
  3184
        private boolean processAll(Hashtable h, Short key, boolean add) {
jaroslav@810
  3185
            boolean change = false;
jaroslav@810
  3186
            Vector v = (Vector) h.get(key);
jaroslav@810
  3187
            if (v != null) {
jaroslav@810
  3188
                int s = v.size();
jaroslav@810
  3189
                for (int i = 0; i < s; i++) {
jaroslav@810
  3190
                    TrapData td = (TrapData) v.elementAt(i);
jaroslav@810
  3191
                    if (add) {
jaroslav@810
  3192
                        add(td);
jaroslav@810
  3193
                        change = true;
jaroslav@810
  3194
                    } else {
jaroslav@810
  3195
                        remove(td);
jaroslav@810
  3196
                        change = true;
jaroslav@810
  3197
                    }
jaroslav@810
  3198
                }
jaroslav@810
  3199
            }
jaroslav@810
  3200
            return change;
jaroslav@810
  3201
        }
jaroslav@810
  3202
jaroslav@810
  3203
        public boolean advanceTo(int i) {
jaroslav@810
  3204
            Short s = Short.valueOf((short) i);
jaroslav@810
  3205
            boolean ch1 = processAll(exStart, s, true);
jaroslav@810
  3206
            boolean ch2 = processAll(exStop, s, false);
jaroslav@810
  3207
            return ch1 || ch2;
jaroslav@810
  3208
        }
jaroslav@810
  3209
jaroslav@810
  3210
        public boolean useTry() {
jaroslav@810
  3211
            return currentCount > 0;
jaroslav@810
  3212
        }
jaroslav@810
  3213
jaroslav@810
  3214
        public TrapData[] current() {
jaroslav@810
  3215
            TrapData[] copy = new TrapData[currentCount];
jaroslav@810
  3216
            for (int i = 0; i < currentCount; i++) {
jaroslav@810
  3217
                copy[i] = current[i];
jaroslav@810
  3218
            }
jaroslav@810
  3219
            return copy;
jaroslav@810
  3220
        }
jaroslav@810
  3221
jaroslav@810
  3222
        private void add(TrapData e) {
jaroslav@810
  3223
            if (currentCount == current.length) {
jaroslav@810
  3224
                TrapData[] data = new TrapData[currentCount * 2];
jaroslav@810
  3225
                for (int i = 0; i < currentCount; i++) {
jaroslav@810
  3226
                    data[i] = current[i];
jaroslav@810
  3227
                }
jaroslav@810
  3228
                current = data;
jaroslav@810
  3229
            }
jaroslav@810
  3230
            current[currentCount++] = e;
jaroslav@810
  3231
        }
jaroslav@810
  3232
jaroslav@810
  3233
        private void remove(TrapData e) {
jaroslav@810
  3234
            if (currentCount == 0) {
jaroslav@810
  3235
                return;
jaroslav@810
  3236
            }
jaroslav@810
  3237
            int from = 0;
jaroslav@810
  3238
            while (from < currentCount) {
jaroslav@810
  3239
                if (e == current[from++]) {
jaroslav@810
  3240
                    break;
jaroslav@810
  3241
                }
jaroslav@810
  3242
            }
jaroslav@810
  3243
            while (from < currentCount) {
jaroslav@810
  3244
                current[from - 1] = current[from];
jaroslav@810
  3245
                current[from] = null;
jaroslav@810
  3246
                from++;
jaroslav@810
  3247
            }
jaroslav@810
  3248
            currentCount--;
jaroslav@810
  3249
        }
jaroslav@810
  3250
    }
jaroslav@810
  3251
    static final class TypeArray {
jaroslav@810
  3252
jaroslav@810
  3253
        private static final int CAPACITY_INCREMENT = 16;
jaroslav@810
  3254
        private int[] types;
jaroslav@810
  3255
        private int size;
jaroslav@810
  3256
jaroslav@810
  3257
        public TypeArray() {
jaroslav@810
  3258
        }
jaroslav@810
  3259
jaroslav@810
  3260
        public TypeArray(final TypeArray initialTypes) {
jaroslav@810
  3261
            setAll(initialTypes);
jaroslav@810
  3262
        }
jaroslav@810
  3263
jaroslav@810
  3264
        public void add(final int newType) {
jaroslav@810
  3265
            ensureCapacity(size + 1);
jaroslav@810
  3266
            types[size++] = newType;
jaroslav@810
  3267
        }
jaroslav@810
  3268
jaroslav@810
  3269
        public void addAll(final TypeArray newTypes) {
jaroslav@810
  3270
            addAll(newTypes.types, 0, newTypes.size);
jaroslav@810
  3271
        }
jaroslav@810
  3272
jaroslav@810
  3273
        public void addAll(final int[] newTypes) {
jaroslav@810
  3274
            addAll(newTypes, 0, newTypes.length);
jaroslav@810
  3275
        }
jaroslav@810
  3276
jaroslav@810
  3277
        public void addAll(final int[] newTypes,
jaroslav@810
  3278
            final int offset,
jaroslav@810
  3279
            final int count) {
jaroslav@810
  3280
            if (count > 0) {
jaroslav@810
  3281
                ensureCapacity(size + count);
jaroslav@810
  3282
                arraycopy(newTypes, offset, types, size, count);
jaroslav@810
  3283
                size += count;
jaroslav@810
  3284
            }
jaroslav@810
  3285
        }
jaroslav@810
  3286
jaroslav@810
  3287
        public void set(final int index, final int newType) {
jaroslav@810
  3288
            types[index] = newType;
jaroslav@810
  3289
        }
jaroslav@810
  3290
jaroslav@810
  3291
        public void setAll(final TypeArray newTypes) {
jaroslav@810
  3292
            setAll(newTypes.types, 0, newTypes.size);
jaroslav@810
  3293
        }
jaroslav@810
  3294
jaroslav@810
  3295
        public void setAll(final int[] newTypes) {
jaroslav@810
  3296
            setAll(newTypes, 0, newTypes.length);
jaroslav@810
  3297
        }
jaroslav@810
  3298
jaroslav@810
  3299
        public void setAll(final int[] newTypes,
jaroslav@810
  3300
            final int offset,
jaroslav@810
  3301
            final int count) {
jaroslav@810
  3302
            if (count > 0) {
jaroslav@810
  3303
                ensureCapacity(count);
jaroslav@810
  3304
                arraycopy(newTypes, offset, types, 0, count);
jaroslav@810
  3305
                size = count;
jaroslav@810
  3306
            } else {
jaroslav@810
  3307
                clear();
jaroslav@810
  3308
            }
jaroslav@810
  3309
        }
jaroslav@810
  3310
jaroslav@810
  3311
        public void setSize(final int newSize) {
jaroslav@810
  3312
            if (size != newSize) {
jaroslav@810
  3313
                ensureCapacity(newSize);
jaroslav@810
  3314
jaroslav@810
  3315
                for (int i = size; i < newSize; ++i) {
jaroslav@810
  3316
                    types[i] = 0;
jaroslav@810
  3317
                }
jaroslav@810
  3318
                size = newSize;
jaroslav@810
  3319
            }
jaroslav@810
  3320
        }
jaroslav@810
  3321
jaroslav@810
  3322
        public void clear() {
jaroslav@810
  3323
            size = 0;
jaroslav@810
  3324
        }
jaroslav@810
  3325
jaroslav@810
  3326
        public int getSize() {
jaroslav@810
  3327
            return size;
jaroslav@810
  3328
        }
jaroslav@810
  3329
jaroslav@810
  3330
        public int get(final int index) {
jaroslav@810
  3331
            return types[index];
jaroslav@810
  3332
        }
jaroslav@810
  3333
jaroslav@810
  3334
        public static String typeString(final int type) {
jaroslav@810
  3335
            switch (type & 0xff) {
jaroslav@810
  3336
                case ITEM_Bogus:
jaroslav@810
  3337
                    return "_top_";
jaroslav@810
  3338
                case ITEM_Integer:
jaroslav@810
  3339
                    return "_int_";
jaroslav@810
  3340
                case ITEM_Float:
jaroslav@810
  3341
                    return "_float_";
jaroslav@810
  3342
                case ITEM_Double:
jaroslav@810
  3343
                    return "_double_";
jaroslav@810
  3344
                case ITEM_Long:
jaroslav@810
  3345
                    return "_long_";
jaroslav@810
  3346
                case ITEM_Null:
jaroslav@810
  3347
                    return "_null_";
jaroslav@810
  3348
                case ITEM_InitObject: // UninitializedThis
jaroslav@810
  3349
                    return "_init_";
jaroslav@810
  3350
                case ITEM_Object:
jaroslav@810
  3351
                    return "_object_";
jaroslav@810
  3352
                case ITEM_NewObject: // Uninitialized
jaroslav@810
  3353
                    return "_new_";
jaroslav@810
  3354
                default:
jaroslav@810
  3355
                    throw new IllegalArgumentException("Unknown type");
jaroslav@810
  3356
            }
jaroslav@810
  3357
        }
jaroslav@810
  3358
jaroslav@810
  3359
        @Override
jaroslav@810
  3360
        public String toString() {
jaroslav@810
  3361
            final StringBuilder sb = new StringBuilder("[");
jaroslav@810
  3362
            if (size > 0) {
jaroslav@810
  3363
                sb.append(typeString(types[0]));
jaroslav@810
  3364
                for (int i = 1; i < size; ++i) {
jaroslav@810
  3365
                    sb.append(", ");
jaroslav@810
  3366
                    sb.append(typeString(types[i]));
jaroslav@810
  3367
                }
jaroslav@810
  3368
            }
jaroslav@810
  3369
jaroslav@810
  3370
            return sb.append(']').toString();
jaroslav@810
  3371
        }
jaroslav@810
  3372
jaroslav@810
  3373
        private void ensureCapacity(final int minCapacity) {
jaroslav@810
  3374
            if ((minCapacity == 0)
jaroslav@810
  3375
                || (types != null) && (minCapacity <= types.length)) {
jaroslav@810
  3376
                return;
jaroslav@810
  3377
            }
jaroslav@810
  3378
jaroslav@810
  3379
            final int newCapacity =
jaroslav@810
  3380
                ((minCapacity + CAPACITY_INCREMENT - 1) / CAPACITY_INCREMENT)
jaroslav@810
  3381
                * CAPACITY_INCREMENT;
jaroslav@810
  3382
            final int[] newTypes = new int[newCapacity];
jaroslav@810
  3383
jaroslav@810
  3384
            if (size > 0) {
jaroslav@810
  3385
                arraycopy(types, 0, newTypes, 0, size);
jaroslav@810
  3386
            }
jaroslav@810
  3387
jaroslav@810
  3388
            types = newTypes;
jaroslav@810
  3389
        }
jaroslav@810
  3390
jaroslav@810
  3391
        // no System.arraycopy
jaroslav@810
  3392
        private void arraycopy(final int[] src, final int srcPos,
jaroslav@810
  3393
            final int[] dest, final int destPos,
jaroslav@810
  3394
            final int length) {
jaroslav@810
  3395
            for (int i = 0; i < length; ++i) {
jaroslav@810
  3396
                dest[destPos + i] = src[srcPos + i];
jaroslav@810
  3397
            }
jaroslav@810
  3398
        }
jaroslav@810
  3399
    }
jaroslav@810
  3400
    /**
jaroslav@810
  3401
     * A JavaScript ready replacement for java.util.Vector
jaroslav@810
  3402
     *
jaroslav@810
  3403
     * @author Jaroslav Tulach <jtulach@netbeans.org>
jaroslav@810
  3404
     */
jaroslav@810
  3405
    @JavaScriptPrototype(prototype = "new Array")
jaroslav@810
  3406
    private static final class Vector {
jaroslav@810
  3407
jaroslav@810
  3408
        private Object[] arr;
jaroslav@810
  3409
jaroslav@810
  3410
        Vector() {
jaroslav@810
  3411
        }
jaroslav@810
  3412
jaroslav@810
  3413
        Vector(int i) {
jaroslav@810
  3414
        }
jaroslav@810
  3415
jaroslav@810
  3416
        void add(Object objectType) {
jaroslav@810
  3417
            addElement(objectType);
jaroslav@810
  3418
        }
jaroslav@810
  3419
jaroslav@810
  3420
        @JavaScriptBody(args = {"obj"}, body =
jaroslav@810
  3421
            "this.push(obj);")
jaroslav@810
  3422
        void addElement(Object obj) {
jaroslav@810
  3423
            final int s = size();
jaroslav@810
  3424
            setSize(s + 1);
jaroslav@810
  3425
            setElementAt(obj, s);
jaroslav@810
  3426
        }
jaroslav@810
  3427
jaroslav@810
  3428
        @JavaScriptBody(args = {}, body =
jaroslav@810
  3429
            "return this.length;")
jaroslav@810
  3430
        int size() {
jaroslav@810
  3431
            return arr == null ? 0 : arr.length;
jaroslav@810
  3432
        }
jaroslav@810
  3433
jaroslav@810
  3434
        @JavaScriptBody(args = {"newArr"}, body =
jaroslav@810
  3435
            "for (var i = 0; i < this.length; i++) {\n"
jaroslav@810
  3436
            + "  newArr[i] = this[i];\n"
jaroslav@810
  3437
            + "}\n")
jaroslav@810
  3438
        void copyInto(Object[] newArr) {
jaroslav@810
  3439
            if (arr == null) {
jaroslav@810
  3440
                return;
jaroslav@810
  3441
            }
jaroslav@810
  3442
            int min = Math.min(newArr.length, arr.length);
jaroslav@810
  3443
            for (int i = 0; i < min; i++) {
jaroslav@810
  3444
                newArr[i] = arr[i];
jaroslav@810
  3445
            }
jaroslav@810
  3446
        }
jaroslav@810
  3447
jaroslav@810
  3448
        @JavaScriptBody(args = {"index"}, body =
jaroslav@810
  3449
            "return this[index];")
jaroslav@810
  3450
        Object elementAt(int index) {
jaroslav@810
  3451
            return arr[index];
jaroslav@810
  3452
        }
jaroslav@810
  3453
jaroslav@810
  3454
        private void setSize(int len) {
jaroslav@810
  3455
            Object[] newArr = new Object[len];
jaroslav@810
  3456
            copyInto(newArr);
jaroslav@810
  3457
            arr = newArr;
jaroslav@810
  3458
        }
jaroslav@810
  3459
jaroslav@810
  3460
        @JavaScriptBody(args = {"val", "index"}, body =
jaroslav@810
  3461
            "this[index] = val;")
jaroslav@810
  3462
        void setElementAt(Object val, int index) {
jaroslav@810
  3463
            arr[index] = val;
jaroslav@810
  3464
        }
jaroslav@810
  3465
    }
jaroslav@810
  3466
    
jaroslav@810
  3467
}