1 /*
   2  * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.java.util.jar.pack;
  27 
  28 import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
  29 import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
  30 import com.sun.java.util.jar.pack.ConstantPool.Entry;
  31 import com.sun.java.util.jar.pack.ConstantPool.Index;
  32 import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
  33 import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
  34 import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
  35 import java.io.*;
  36 import java.util.*;
  37 import com.sun.java.util.jar.pack.Package.Class;
  38 import com.sun.java.util.jar.pack.Package.File;
  39 import com.sun.java.util.jar.pack.Package.InnerClass;
  40 
  41 /**
  42  * Reader for a package file.
  43  *
  44  * @see PackageWriter
  45  * @author John Rose
  46  */
  47 class PackageReader extends BandStructure {
  48     Package pkg;
  49     byte[] bytes;
  50     LimitedBuffer in;
  51 
  52     PackageReader(Package pkg, InputStream in) throws IOException {
  53         this.pkg = pkg;
  54         this.in = new LimitedBuffer(in);
  55     }
  56 
  57     /** A buffered input stream which is careful not to
  58      *  read its underlying stream ahead of a given mark,
  59      *  called the 'readLimit'.  This property declares
  60      *  the maximum number of characters that future reads
  61      *  can consume from the underlying stream.
  62      */
  63     static
  64     class LimitedBuffer extends BufferedInputStream {
  65         long served;     // total number of charburgers served
  66         int  servedPos;  // ...as of this value of super.pos
  67         long limit;      // current declared limit
  68         long buffered;
  69         public boolean atLimit() {
  70             boolean z = (getBytesServed() == limit);
  71             assert(!z || limit == buffered);
  72             return z;
  73         }
  74         public long getBytesServed() {
  75             return served + (pos - servedPos);
  76         }
  77         public void setReadLimit(long newLimit) {
  78             if (newLimit == -1)
  79                 limit = -1;
  80             else
  81                 limit = getBytesServed() + newLimit;
  82         }
  83         public long getReadLimit() {
  84             if (limit == -1)
  85                 return limit;
  86             else
  87                 return limit - getBytesServed();
  88         }
  89         public int read() throws IOException {
  90             if (pos < count) {
  91                 // fast path
  92                 return buf[pos++] & 0xFF;
  93             }
  94             served += (pos - servedPos);
  95             int ch = super.read();
  96             servedPos = pos;
  97             if (ch >= 0)  served += 1;
  98             assert(served <= limit || limit == -1);
  99             return ch;
 100         }
 101         public int read(byte b[], int off, int len) throws IOException {
 102             served += (pos - servedPos);
 103             int nr = super.read(b, off, len);
 104             servedPos = pos;
 105             if (nr >= 0)  served += nr;
 106             assert(served <= limit || limit == -1);
 107             return nr;
 108         }
 109         public long skip(long n) throws IOException {
 110             throw new RuntimeException("no skipping");
 111         }
 112         LimitedBuffer(InputStream originalIn) {
 113             super(null, 1<<14);
 114             servedPos = pos;
 115             super.in = new FilterInputStream(originalIn) {
 116                 public int read() throws IOException {
 117                     if (buffered == limit)
 118                         return -1;
 119                     ++buffered;
 120                     return super.read();
 121                 }
 122                 public int read(byte b[], int off, int len) throws IOException {
 123                     if (buffered == limit)
 124                         return -1;
 125                     if (limit != -1) {
 126                         long remaining = limit - buffered;
 127                         if (len > remaining)
 128                             len = (int)remaining;
 129                     }
 130                     int nr = super.read(b, off, len);
 131                     if (nr >= 0)  buffered += nr;
 132                     return nr;
 133                 }
 134             };
 135         }
 136     }
 137 
 138     void read() throws IOException {
 139         boolean ok = false;
 140         try {
 141             //  pack200_archive:
 142             //        file_header
 143             //        *band_headers :BYTE1
 144             //        cp_bands
 145             //        attr_definition_bands
 146             //        ic_bands
 147             //        class_bands
 148             //        bc_bands
 149             //        file_bands
 150             readFileHeader();
 151             readBandHeaders();
 152             readConstantPool();  // cp_bands
 153             readAttrDefs();
 154             readInnerClasses();
 155             Class[] classes = readClasses();
 156             readByteCodes();
 157             readFiles();     // file_bands
 158             assert(archiveSize1 == 0 || in.atLimit());
 159             assert(archiveSize1 == 0 ||
 160                    in.getBytesServed() == archiveSize0+archiveSize1);
 161             all_bands.doneDisbursing();
 162 
 163             // As a post-pass, build constant pools and inner classes.
 164             for (int i = 0; i < classes.length; i++) {
 165                 reconstructClass(classes[i]);
 166             }
 167 
 168             ok = true;
 169         } catch (Exception ee) {
 170             Utils.log.warning("Error on input: "+ee, ee);
 171             if (verbose > 0)
 172                 Utils.log.info("Stream offsets:"+
 173                                  " served="+in.getBytesServed()+
 174                                  " buffered="+in.buffered+
 175                                  " limit="+in.limit);
 176             //if (verbose > 0)  ee.printStackTrace();
 177             if (ee instanceof IOException)  throw (IOException)ee;
 178             if (ee instanceof RuntimeException)  throw (RuntimeException)ee;
 179             throw new Error("error unpacking", ee);
 180         }
 181     }
 182 
 183     // Temporary count values, until band decoding gets rolling.
 184     int[] tagCount = new int[CONSTANT_Limit];
 185     int numFiles;
 186     int numAttrDefs;
 187     int numInnerClasses;
 188     int numClasses;
 189 
 190     void readFileHeader() throws IOException {
 191         //  file_header:
 192         //        archive_magic archive_header
 193         readArchiveMagic();
 194         readArchiveHeader();
 195     }
 196 
 197     // Local routine used to parse fixed-format scalars
 198     // in the file_header:
 199     private int getMagicInt32() throws IOException {
 200         int res = 0;
 201         for (int i = 0; i < 4; i++) {
 202             res <<= 8;
 203             res |= (archive_magic.getByte() & 0xFF);
 204         }
 205         return res;
 206     }
 207 
 208     final static int MAGIC_BYTES = 4;
 209 
 210     void readArchiveMagic() throws IOException {
 211 
 212         // Read a minimum of bytes in the first gulp.
 213         in.setReadLimit(MAGIC_BYTES + AH_LENGTH_MIN);
 214 
 215         //  archive_magic:
 216         //        #archive_magic_word :BYTE1[4]
 217         archive_magic.expectLength(MAGIC_BYTES);
 218         archive_magic.readFrom(in);
 219 
 220         // read and check magic numbers:
 221         pkg.magic = getMagicInt32();
 222         archive_magic.doneDisbursing();
 223     }
 224 
 225     void readArchiveHeader() throws IOException {
 226         //  archive_header:
 227         //        #archive_minver :UNSIGNED5[1]
 228         //        #archive_majver :UNSIGNED5[1]
 229         //        #archive_options :UNSIGNED5[1]
 230         //        (archive_file_counts) ** (#have_file_headers)
 231         //        (archive_special_counts) ** (#have_special_formats)
 232         //        cp_counts
 233         //        class_counts
 234         //
 235         //  archive_file_counts:
 236         //        #archive_size_hi :UNSIGNED5[1]
 237         //        #archive_size_lo :UNSIGNED5[1]
 238         //        #archive_next_count :UNSIGNED5[1]
 239         //        #archive_modtime :UNSIGNED5[1]
 240         //        #file_count :UNSIGNED5[1]
 241         //
 242         //  class_counts:
 243         //        #ic_count :UNSIGNED5[1]
 244         //        #default_class_minver :UNSIGNED5[1]
 245         //        #default_class_majver :UNSIGNED5[1]
 246         //        #class_count :UNSIGNED5[1]
 247         //
 248         //  archive_special_counts:
 249         //        #band_headers_size :UNSIGNED5[1]
 250         //        #attr_definition_count :UNSIGNED5[1]
 251         //
 252         assert(AH_LENGTH == 8+(ConstantPool.TAGS_IN_ORDER.length)+6);
 253         archive_header_0.expectLength(AH_LENGTH_0);
 254         archive_header_0.readFrom(in);
 255 
 256         pkg.package_minver = archive_header_0.getInt();
 257         pkg.package_majver = archive_header_0.getInt();
 258         pkg.checkVersion();
 259         this.initPackageMajver(pkg.package_majver);
 260 
 261         archiveOptions = archive_header_0.getInt();
 262         archive_header_0.doneDisbursing();
 263 
 264         // detect archive optional fields in archive header
 265         boolean haveSpecial = testBit(archiveOptions, AO_HAVE_SPECIAL_FORMATS);
 266         boolean haveFiles   = testBit(archiveOptions, AO_HAVE_FILE_HEADERS);
 267         boolean haveNumbers = testBit(archiveOptions, AO_HAVE_CP_NUMBERS);
 268         initAttrIndexLimit();
 269 
 270         // now we are ready to use the data:
 271         archive_header_S.expectLength(haveFiles? AH_LENGTH_S: 0);
 272         archive_header_S.readFrom(in);
 273         if (haveFiles) {
 274             long sizeHi = archive_header_S.getInt();
 275             long sizeLo = archive_header_S.getInt();
 276             archiveSize1 = (sizeHi << 32) + ((sizeLo << 32) >>> 32);
 277             // Set the limit, now, up to the file_bits.
 278             in.setReadLimit(archiveSize1);  // for debug only
 279         } else {
 280             archiveSize1 = 0;
 281             in.setReadLimit(-1);  // remove limitation
 282         }
 283         archive_header_S.doneDisbursing();
 284         archiveSize0 = in.getBytesServed();
 285 
 286         int remainingHeaders = AH_LENGTH - AH_LENGTH_0 - AH_LENGTH_S;
 287         if (!haveFiles)    remainingHeaders -= AH_FILE_HEADER_LEN-AH_LENGTH_S;
 288         if (!haveSpecial)  remainingHeaders -= AH_SPECIAL_FORMAT_LEN;
 289         if (!haveNumbers)  remainingHeaders -= AH_CP_NUMBER_LEN;
 290         assert(remainingHeaders >= AH_LENGTH_MIN - AH_LENGTH_0);
 291         archive_header_1.expectLength(remainingHeaders);
 292         archive_header_1.readFrom(in);
 293 
 294         if (haveFiles) {
 295             archiveNextCount = archive_header_1.getInt();
 296             pkg.default_modtime = archive_header_1.getInt();
 297             numFiles = archive_header_1.getInt();
 298         } else {
 299             archiveNextCount = 0;
 300             numFiles = 0;
 301         }
 302 
 303         if (haveSpecial) {
 304             band_headers.expectLength(archive_header_1.getInt());
 305             numAttrDefs = archive_header_1.getInt();
 306         } else {
 307             band_headers.expectLength(0);
 308             numAttrDefs = 0;
 309         }
 310 
 311         readConstantPoolCounts(haveNumbers);
 312 
 313         numInnerClasses = archive_header_1.getInt();
 314 
 315         pkg.default_class_minver = (short) archive_header_1.getInt();
 316         pkg.default_class_majver = (short) archive_header_1.getInt();
 317         numClasses = archive_header_1.getInt();
 318 
 319         archive_header_1.doneDisbursing();
 320 
 321         // set some derived archive bits
 322         if (testBit(archiveOptions, AO_DEFLATE_HINT)) {
 323             pkg.default_options |= FO_DEFLATE_HINT;
 324         }
 325     }
 326 
 327     void readBandHeaders() throws IOException {
 328         band_headers.readFrom(in);
 329         bandHeaderBytePos = 1;  // Leave room to pushback the initial XB byte.
 330         bandHeaderBytes = new byte[bandHeaderBytePos + band_headers.length()];
 331         for (int i = bandHeaderBytePos; i < bandHeaderBytes.length; i++) {
 332             bandHeaderBytes[i] = (byte) band_headers.getByte();
 333         }
 334         band_headers.doneDisbursing();
 335     }
 336 
 337     void readConstantPoolCounts(boolean haveNumbers) throws IOException {
 338         // size the constant pools:
 339         for (int k = 0; k < ConstantPool.TAGS_IN_ORDER.length; k++) {
 340             //  cp_counts:
 341             //        #cp_Utf8_count :UNSIGNED5[1]
 342             //        (cp_number_counts) ** (#have_cp_numbers)
 343             //        #cp_String_count :UNSIGNED5[1]
 344             //        #cp_Class_count :UNSIGNED5[1]
 345             //        #cp_Signature_count :UNSIGNED5[1]
 346             //        #cp_Descr_count :UNSIGNED5[1]
 347             //        #cp_Field_count :UNSIGNED5[1]
 348             //        #cp_Method_count :UNSIGNED5[1]
 349             //        #cp_Imethod_count :UNSIGNED5[1]
 350             //
 351             //  cp_number_counts:
 352             //        #cp_Int_count :UNSIGNED5[1]
 353             //        #cp_Float_count :UNSIGNED5[1]
 354             //        #cp_Long_count :UNSIGNED5[1]
 355             //        #cp_Double_count :UNSIGNED5[1]
 356             //
 357             byte tag = ConstantPool.TAGS_IN_ORDER[k];
 358             if (!haveNumbers) {
 359                 // These four counts are optional.
 360                 switch (tag) {
 361                 case CONSTANT_Integer:
 362                 case CONSTANT_Float:
 363                 case CONSTANT_Long:
 364                 case CONSTANT_Double:
 365                     continue;
 366                 }
 367             }
 368             tagCount[tag] = archive_header_1.getInt();
 369         }
 370     }
 371 
 372     protected Index getCPIndex(byte tag) {
 373         return pkg.cp.getIndexByTag(tag);
 374     }
 375     Index initCPIndex(byte tag, Entry[] cpMap) {
 376         if (verbose > 3) {
 377             for (int i = 0; i < cpMap.length; i++) {
 378                 Utils.log.fine("cp.add "+cpMap[i]);
 379             }
 380         }
 381         Index index = ConstantPool.makeIndex(ConstantPool.tagName(tag), cpMap);
 382         if (verbose > 1)  Utils.log.fine("Read "+index);
 383         pkg.cp.initIndexByTag(tag, index);
 384         return index;
 385     }
 386 
 387     void readConstantPool() throws IOException {
 388         //  cp_bands:
 389         //        cp_Utf8
 390         //        *cp_Int :UDELTA5
 391         //        *cp_Float :UDELTA5
 392         //        cp_Long
 393         //        cp_Double
 394         //        *cp_String :UDELTA5  (cp_Utf8)
 395         //        *cp_Class :UDELTA5  (cp_Utf8)
 396         //        cp_Signature
 397         //        cp_Descr
 398         //        cp_Field
 399         //        cp_Method
 400         //        cp_Imethod
 401 
 402         if (verbose > 0)  Utils.log.info("Reading CP");
 403 
 404         for (int k = 0; k < ConstantPool.TAGS_IN_ORDER.length; k++) {
 405             byte tag = ConstantPool.TAGS_IN_ORDER[k];
 406             int  len = tagCount[tag];
 407 
 408             Entry[] cpMap = new Entry[len];
 409             if (verbose > 0)
 410                 Utils.log.info("Reading "+cpMap.length+" "+ConstantPool.tagName(tag)+" entries...");
 411 
 412             switch (tag) {
 413             case CONSTANT_Utf8:
 414                 readUtf8Bands(cpMap);
 415                 break;
 416             case CONSTANT_Integer:
 417                 cp_Int.expectLength(cpMap.length);
 418                 cp_Int.readFrom(in);
 419                 for (int i = 0; i < cpMap.length; i++) {
 420                     int x = cp_Int.getInt();  // coding handles signs OK
 421                     cpMap[i] = ConstantPool.getLiteralEntry(new Integer(x));
 422                 }
 423                 cp_Int.doneDisbursing();
 424                 break;
 425             case CONSTANT_Float:
 426                 cp_Float.expectLength(cpMap.length);
 427                 cp_Float.readFrom(in);
 428                 for (int i = 0; i < cpMap.length; i++) {
 429                     int x = cp_Float.getInt();
 430                     float fx = Float.intBitsToFloat(x);
 431                     cpMap[i] = ConstantPool.getLiteralEntry(new Float(fx));
 432                 }
 433                 cp_Float.doneDisbursing();
 434                 break;
 435             case CONSTANT_Long:
 436                 //  cp_Long:
 437                 //        *cp_Long_hi :UDELTA5
 438                 //        *cp_Long_lo :DELTA5
 439                 cp_Long_hi.expectLength(cpMap.length);
 440                 cp_Long_hi.readFrom(in);
 441                 cp_Long_lo.expectLength(cpMap.length);
 442                 cp_Long_lo.readFrom(in);
 443                 for (int i = 0; i < cpMap.length; i++) {
 444                     long hi = cp_Long_hi.getInt();
 445                     long lo = cp_Long_lo.getInt();
 446                     long x = (hi << 32) + ((lo << 32) >>> 32);
 447                     cpMap[i] = ConstantPool.getLiteralEntry(new Long(x));
 448                 }
 449                 cp_Long_hi.doneDisbursing();
 450                 cp_Long_lo.doneDisbursing();
 451                 break;
 452             case CONSTANT_Double:
 453                 //  cp_Double:
 454                 //        *cp_Double_hi :UDELTA5
 455                 //        *cp_Double_lo :DELTA5
 456                 cp_Double_hi.expectLength(cpMap.length);
 457                 cp_Double_hi.readFrom(in);
 458                 cp_Double_lo.expectLength(cpMap.length);
 459                 cp_Double_lo.readFrom(in);
 460                 for (int i = 0; i < cpMap.length; i++) {
 461                     long hi = cp_Double_hi.getInt();
 462                     long lo = cp_Double_lo.getInt();
 463                     long x = (hi << 32) + ((lo << 32) >>> 32);
 464                     double dx = Double.longBitsToDouble(x);
 465                     cpMap[i] = ConstantPool.getLiteralEntry(new Double(dx));
 466                 }
 467                 cp_Double_hi.doneDisbursing();
 468                 cp_Double_lo.doneDisbursing();
 469                 break;
 470             case CONSTANT_String:
 471                 cp_String.expectLength(cpMap.length);
 472                 cp_String.readFrom(in);
 473                 cp_String.setIndex(getCPIndex(CONSTANT_Utf8));
 474                 for (int i = 0; i < cpMap.length; i++) {
 475                     cpMap[i] = ConstantPool.getLiteralEntry(cp_String.getRef().stringValue());
 476                 }
 477                 cp_String.doneDisbursing();
 478                 break;
 479             case CONSTANT_Class:
 480                 cp_Class.expectLength(cpMap.length);
 481                 cp_Class.readFrom(in);
 482                 cp_Class.setIndex(getCPIndex(CONSTANT_Utf8));
 483                 for (int i = 0; i < cpMap.length; i++) {
 484                     cpMap[i] = ConstantPool.getClassEntry(cp_Class.getRef().stringValue());
 485                 }
 486                 cp_Class.doneDisbursing();
 487                 break;
 488             case CONSTANT_Signature:
 489                 readSignatureBands(cpMap);
 490                 break;
 491             case CONSTANT_NameandType:
 492                 //  cp_Descr:
 493                 //        *cp_Descr_type :DELTA5  (cp_Signature)
 494                 //        *cp_Descr_name :UDELTA5  (cp_Utf8)
 495                 cp_Descr_name.expectLength(cpMap.length);
 496                 cp_Descr_name.readFrom(in);
 497                 cp_Descr_name.setIndex(getCPIndex(CONSTANT_Utf8));
 498                 cp_Descr_type.expectLength(cpMap.length);
 499                 cp_Descr_type.readFrom(in);
 500                 cp_Descr_type.setIndex(getCPIndex(CONSTANT_Signature));
 501                 for (int i = 0; i < cpMap.length; i++) {
 502                     Entry ref  = cp_Descr_name.getRef();
 503                     Entry ref2 = cp_Descr_type.getRef();
 504                     cpMap[i] = ConstantPool.getDescriptorEntry((Utf8Entry)ref,
 505                                                         (SignatureEntry)ref2);
 506                 }
 507                 cp_Descr_name.doneDisbursing();
 508                 cp_Descr_type.doneDisbursing();
 509                 break;
 510             case CONSTANT_Fieldref:
 511                 readMemberRefs(tag, cpMap, cp_Field_class, cp_Field_desc);
 512                 break;
 513             case CONSTANT_Methodref:
 514                 readMemberRefs(tag, cpMap, cp_Method_class, cp_Method_desc);
 515                 break;
 516             case CONSTANT_InterfaceMethodref:
 517                 readMemberRefs(tag, cpMap, cp_Imethod_class, cp_Imethod_desc);
 518                 break;
 519             default:
 520                 assert(false);
 521             }
 522 
 523             Index index = initCPIndex(tag, cpMap);
 524 
 525             if (optDumpBands) {
 526                 PrintStream ps = new PrintStream(getDumpStream(index, ".idx"));
 527                 printArrayTo(ps, index.cpMap, 0, index.cpMap.length);
 528                 ps.close();
 529             }
 530         }
 531 
 532         cp_bands.doneDisbursing();
 533 
 534         setBandIndexes();
 535     }
 536 
 537     void readUtf8Bands(Entry[] cpMap) throws IOException {
 538         //  cp_Utf8:
 539         //        *cp_Utf8_prefix :DELTA5
 540         //        *cp_Utf8_suffix :UNSIGNED5
 541         //        *cp_Utf8_chars :CHAR3
 542         //        *cp_Utf8_big_suffix :DELTA5
 543         //        (*cp_Utf8_big_chars :DELTA5)
 544         //          ** length(cp_Utf8_big_suffix)
 545         int len = cpMap.length;
 546         if (len == 0)
 547             return;  // nothing to read
 548 
 549         // Bands have implicit leading zeroes, for the empty string:
 550         final int SUFFIX_SKIP_1 = 1;
 551         final int PREFIX_SKIP_2 = 2;
 552 
 553         // First band:  Read lengths of shared prefixes.
 554         cp_Utf8_prefix.expectLength(Math.max(0, len - PREFIX_SKIP_2));
 555         cp_Utf8_prefix.readFrom(in);
 556 
 557         // Second band:  Read lengths of unshared suffixes:
 558         cp_Utf8_suffix.expectLength(Math.max(0, len - SUFFIX_SKIP_1));
 559         cp_Utf8_suffix.readFrom(in);
 560 
 561         char[][] suffixChars = new char[len][];
 562         int bigSuffixCount = 0;
 563 
 564         // Third band:  Read the char values in the unshared suffixes:
 565         cp_Utf8_chars.expectLength(cp_Utf8_suffix.getIntTotal());
 566         cp_Utf8_chars.readFrom(in);
 567         for (int i = 0; i < len; i++) {
 568             int suffix = (i < SUFFIX_SKIP_1)? 0: cp_Utf8_suffix.getInt();
 569             if (suffix == 0 && i >= SUFFIX_SKIP_1) {
 570                 // chars are packed in cp_Utf8_big_chars
 571                 bigSuffixCount += 1;
 572                 continue;
 573             }
 574             suffixChars[i] = new char[suffix];
 575             for (int j = 0; j < suffix; j++) {
 576                 int ch = cp_Utf8_chars.getInt();
 577                 assert(ch == (char)ch);
 578                 suffixChars[i][j] = (char)ch;
 579             }
 580         }
 581         cp_Utf8_chars.doneDisbursing();
 582 
 583         // Fourth band:  Go back and size the specially packed strings.
 584         int maxChars = 0;
 585         cp_Utf8_big_suffix.expectLength(bigSuffixCount);
 586         cp_Utf8_big_suffix.readFrom(in);
 587         cp_Utf8_suffix.resetForSecondPass();
 588         for (int i = 0; i < len; i++) {
 589             int suffix = (i < SUFFIX_SKIP_1)? 0: cp_Utf8_suffix.getInt();
 590             int prefix = (i < PREFIX_SKIP_2)? 0: cp_Utf8_prefix.getInt();
 591             if (suffix == 0 && i >= SUFFIX_SKIP_1) {
 592                 assert(suffixChars[i] == null);
 593                 suffix = cp_Utf8_big_suffix.getInt();
 594             } else {
 595                 assert(suffixChars[i] != null);
 596             }
 597             if (maxChars < prefix + suffix)
 598                 maxChars = prefix + suffix;
 599         }
 600         char[] buf = new char[maxChars];
 601 
 602         // Fifth band(s):  Get the specially packed characters.
 603         cp_Utf8_suffix.resetForSecondPass();
 604         cp_Utf8_big_suffix.resetForSecondPass();
 605         for (int i = 0; i < len; i++) {
 606             if (i < SUFFIX_SKIP_1)  continue;
 607             int suffix = cp_Utf8_suffix.getInt();
 608             if (suffix != 0)  continue;  // already input
 609             suffix = cp_Utf8_big_suffix.getInt();
 610             suffixChars[i] = new char[suffix];
 611             if (suffix == 0) {
 612                 // Do not bother to add an empty "(Utf8_big_0)" band.
 613                 continue;
 614             }
 615             IntBand packed = cp_Utf8_big_chars.newIntBand("(Utf8_big_"+i+")");
 616             packed.expectLength(suffix);
 617             packed.readFrom(in);
 618             for (int j = 0; j < suffix; j++) {
 619                 int ch = packed.getInt();
 620                 assert(ch == (char)ch);
 621                 suffixChars[i][j] = (char)ch;
 622             }
 623             packed.doneDisbursing();
 624         }
 625         cp_Utf8_big_chars.doneDisbursing();
 626 
 627         // Finally, sew together all the prefixes and suffixes.
 628         cp_Utf8_prefix.resetForSecondPass();
 629         cp_Utf8_suffix.resetForSecondPass();
 630         cp_Utf8_big_suffix.resetForSecondPass();
 631         for (int i = 0; i < len; i++) {
 632             int prefix = (i < PREFIX_SKIP_2)? 0: cp_Utf8_prefix.getInt();
 633             int suffix = (i < SUFFIX_SKIP_1)? 0: cp_Utf8_suffix.getInt();
 634             if (suffix == 0 && i >= SUFFIX_SKIP_1)
 635                 suffix = cp_Utf8_big_suffix.getInt();
 636 
 637             // by induction, the buffer is already filled with the prefix
 638             System.arraycopy(suffixChars[i], 0, buf, prefix, suffix);
 639 
 640             cpMap[i] = ConstantPool.getUtf8Entry(new String(buf, 0, prefix+suffix));
 641         }
 642 
 643         cp_Utf8_prefix.doneDisbursing();
 644         cp_Utf8_suffix.doneDisbursing();
 645         cp_Utf8_big_suffix.doneDisbursing();
 646     }
 647 
 648     HashMap utf8Signatures;  // Utf8Entry->SignatureEntry
 649 
 650     void readSignatureBands(Entry[] cpMap) throws IOException {
 651         //  cp_Signature:
 652         //        *cp_Signature_form :DELTA5  (cp_Utf8)
 653         //        *cp_Signature_classes :UDELTA5  (cp_Class)
 654         cp_Signature_form.expectLength(cpMap.length);
 655         cp_Signature_form.readFrom(in);
 656         cp_Signature_form.setIndex(getCPIndex(CONSTANT_Utf8));
 657         int[] numSigClasses = new int[cpMap.length];
 658         for (int i = 0; i < cpMap.length; i++) {
 659             Utf8Entry formRef = (Utf8Entry) cp_Signature_form.getRef();
 660             numSigClasses[i] = ConstantPool.countClassParts(formRef);
 661         }
 662         cp_Signature_form.resetForSecondPass();
 663         cp_Signature_classes.expectLength(getIntTotal(numSigClasses));
 664         cp_Signature_classes.readFrom(in);
 665         cp_Signature_classes.setIndex(getCPIndex(CONSTANT_Class));
 666         utf8Signatures = new HashMap();
 667         for (int i = 0; i < cpMap.length; i++) {
 668             Utf8Entry formRef = (Utf8Entry) cp_Signature_form.getRef();
 669             ClassEntry[] classRefs = new ClassEntry[numSigClasses[i]];
 670             for (int j = 0; j < classRefs.length; j++) {
 671                 classRefs[j] = (ClassEntry) cp_Signature_classes.getRef();
 672             }
 673             SignatureEntry se = ConstantPool.getSignatureEntry(formRef, classRefs);
 674             cpMap[i] = se;
 675             utf8Signatures.put(se.asUtf8Entry(), se);
 676         }
 677         cp_Signature_form.doneDisbursing();
 678         cp_Signature_classes.doneDisbursing();
 679     }
 680 
 681     void readMemberRefs(byte tag, Entry[] cpMap, CPRefBand cp_class, CPRefBand cp_desc) throws IOException {
 682         //  cp_Field:
 683         //        *cp_Field_class :DELTA5  (cp_Class)
 684         //        *cp_Field_desc :UDELTA5  (cp_Descr)
 685         //  cp_Method:
 686         //        *cp_Method_class :DELTA5  (cp_Class)
 687         //        *cp_Method_desc :UDELTA5  (cp_Descr)
 688         //  cp_Imethod:
 689         //        *cp_Imethod_class :DELTA5  (cp_Class)
 690         //        *cp_Imethod_desc :UDELTA5  (cp_Descr)
 691         cp_class.expectLength(cpMap.length);
 692         cp_class.readFrom(in);
 693         cp_class.setIndex(getCPIndex(CONSTANT_Class));
 694         cp_desc.expectLength(cpMap.length);
 695         cp_desc.readFrom(in);
 696         cp_desc.setIndex(getCPIndex(CONSTANT_NameandType));
 697         for (int i = 0; i < cpMap.length; i++) {
 698             ClassEntry      mclass = (ClassEntry     ) cp_class.getRef();
 699             DescriptorEntry mdescr = (DescriptorEntry) cp_desc.getRef();
 700             cpMap[i] = ConstantPool.getMemberEntry(tag, mclass, mdescr);
 701         }
 702         cp_class.doneDisbursing();
 703         cp_desc.doneDisbursing();
 704     }
 705 
 706     void readFiles() throws IOException {
 707         //  file_bands:
 708         //        *file_name :UNSIGNED5  (cp_Utf8)
 709         //        *file_size_hi :UNSIGNED5
 710         //        *file_size_lo :UNSIGNED5
 711         //        *file_modtime :DELTA5
 712         //        *file_options :UNSIGNED5
 713         //        *file_bits :BYTE1
 714         if (verbose > 0)
 715             Utils.log.info("  ...building "+numFiles+" files...");
 716         file_name.expectLength(numFiles);
 717         file_size_lo.expectLength(numFiles);
 718         int options = archiveOptions;
 719         boolean haveSizeHi  = testBit(options, AO_HAVE_FILE_SIZE_HI);
 720         boolean haveModtime = testBit(options, AO_HAVE_FILE_MODTIME);
 721         boolean haveOptions = testBit(options, AO_HAVE_FILE_OPTIONS);
 722         if (haveSizeHi)
 723             file_size_hi.expectLength(numFiles);
 724         if (haveModtime)
 725             file_modtime.expectLength(numFiles);
 726         if (haveOptions)
 727             file_options.expectLength(numFiles);
 728 
 729         file_name.readFrom(in);
 730         file_size_hi.readFrom(in);
 731         file_size_lo.readFrom(in);
 732         file_modtime.readFrom(in);
 733         file_options.readFrom(in);
 734         file_bits.setInputStreamFrom(in);
 735 
 736         Iterator nextClass = pkg.getClasses().iterator();
 737 
 738         // Compute file lengths before reading any file bits.
 739         long totalFileLength = 0;
 740         long[] fileLengths = new long[numFiles];
 741         for (int i = 0; i < numFiles; i++) {
 742             long size = ((long)file_size_lo.getInt() << 32) >>> 32;
 743             if (haveSizeHi)
 744                 size += (long)file_size_hi.getInt() << 32;
 745             fileLengths[i] = size;
 746             totalFileLength += size;
 747         }
 748         assert(in.getReadLimit() == -1 || in.getReadLimit() == totalFileLength);
 749 
 750         byte[] buf = new byte[1<<16];
 751         for (int i = 0; i < numFiles; i++) {
 752             // %%% Use a big temp file for file bits?
 753             Utf8Entry name = (Utf8Entry) file_name.getRef();
 754             long size = fileLengths[i];
 755             File file = pkg.new File(name);
 756             file.modtime = pkg.default_modtime;
 757             file.options = pkg.default_options;
 758             if (haveModtime)
 759                 file.modtime += file_modtime.getInt();
 760             if (haveOptions)
 761                 file.options |= file_options.getInt();
 762             if (verbose > 1)
 763                 Utils.log.fine("Reading "+size+" bytes of "+name.stringValue());
 764             long toRead = size;
 765             while (toRead > 0) {
 766                 int nr = buf.length;
 767                 if (nr > toRead)  nr = (int) toRead;
 768                 nr = file_bits.getInputStream().read(buf, 0, nr);
 769                 if (nr < 0)  throw new EOFException();
 770                 file.addBytes(buf, 0, nr);
 771                 toRead -= nr;
 772             }
 773             pkg.addFile(file);
 774             if (file.isClassStub()) {
 775                 assert(file.getFileLength() == 0);
 776                 Class cls = (Class) nextClass.next();
 777                 cls.initFile(file);
 778             }
 779         }
 780 
 781         // Do the rest of the classes.
 782         while (nextClass.hasNext()) {
 783             Class cls = (Class) nextClass.next();
 784             cls.initFile(null);  // implicitly initialize to a trivial one
 785             cls.file.modtime = pkg.default_modtime;
 786         }
 787 
 788         file_name.doneDisbursing();
 789         file_size_hi.doneDisbursing();
 790         file_size_lo.doneDisbursing();
 791         file_modtime.doneDisbursing();
 792         file_options.doneDisbursing();
 793         file_bits.doneDisbursing();
 794         file_bands.doneDisbursing();
 795 
 796         if (archiveSize1 != 0 && !in.atLimit()) {
 797             throw new RuntimeException("Predicted archive_size "+
 798                                        archiveSize1+" != "+
 799                                        (in.getBytesServed()-archiveSize0));
 800         }
 801     }
 802 
 803     void readAttrDefs() throws IOException {
 804         //  attr_definition_bands:
 805         //        *attr_definition_headers :BYTE1
 806         //        *attr_definition_name :UNSIGNED5  (cp_Utf8)
 807         //        *attr_definition_layout :UNSIGNED5  (cp_Utf8)
 808         attr_definition_headers.expectLength(numAttrDefs);
 809         attr_definition_name.expectLength(numAttrDefs);
 810         attr_definition_layout.expectLength(numAttrDefs);
 811         attr_definition_headers.readFrom(in);
 812         attr_definition_name.readFrom(in);
 813         attr_definition_layout.readFrom(in);
 814         PrintStream dump = !optDumpBands ? null
 815             : new PrintStream(getDumpStream(attr_definition_headers, ".def"));
 816         for (int i = 0; i < numAttrDefs; i++) {
 817             int       header = attr_definition_headers.getByte();
 818             Utf8Entry name   = (Utf8Entry) attr_definition_name.getRef();
 819             Utf8Entry layout = (Utf8Entry) attr_definition_layout.getRef();
 820             int       ctype  = (header &  ADH_CONTEXT_MASK);
 821             int       index  = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
 822             Attribute.Layout def = new Attribute.Layout(ctype,
 823                                                         name.stringValue(),
 824                                                         layout.stringValue());
 825             // Check layout string for Java 6 extensions.
 826             String pvLayout = def.layoutForPackageMajver(getPackageMajver());
 827             if (!pvLayout.equals(def.layout())) {
 828                 throw new IOException("Bad attribute layout in version 150 archive: "+def.layout());
 829             }
 830             this.setAttributeLayoutIndex(def, index);
 831             if (dump != null)  dump.println(index+" "+def);
 832         }
 833         if (dump != null)  dump.close();
 834         attr_definition_headers.doneDisbursing();
 835         attr_definition_name.doneDisbursing();
 836         attr_definition_layout.doneDisbursing();
 837         // Attribute layouts define bands, one per layout element.
 838         // Create them now, all at once.
 839         makeNewAttributeBands();
 840         attr_definition_bands.doneDisbursing();
 841     }
 842 
 843     void readInnerClasses() throws IOException {
 844         //  ic_bands:
 845         //        *ic_this_class :UDELTA5  (cp_Class)
 846         //        *ic_flags :UNSIGNED5
 847         //        *ic_outer_class :DELTA5  (null or cp_Class)
 848         //        *ic_name :DELTA5  (null or cp_Utf8)
 849         ic_this_class.expectLength(numInnerClasses);
 850         ic_this_class.readFrom(in);
 851         ic_flags.expectLength(numInnerClasses);
 852         ic_flags.readFrom(in);
 853         int longICCount = 0;
 854         for (int i = 0; i < numInnerClasses; i++) {
 855             int flags = ic_flags.getInt();
 856             boolean longForm = (flags & ACC_IC_LONG_FORM) != 0;
 857             if (longForm) {
 858                 longICCount += 1;
 859             }
 860         }
 861         ic_outer_class.expectLength(longICCount);
 862         ic_outer_class.readFrom(in);
 863         ic_name.expectLength(longICCount);
 864         ic_name.readFrom(in);
 865         ic_flags.resetForSecondPass();
 866         ArrayList icList = new ArrayList(numInnerClasses);
 867         for (int i = 0; i < numInnerClasses; i++) {
 868             int flags = ic_flags.getInt();
 869             boolean longForm = (flags & ACC_IC_LONG_FORM) != 0;
 870             flags &= ~ACC_IC_LONG_FORM;
 871             ClassEntry thisClass = (ClassEntry) ic_this_class.getRef();
 872             ClassEntry outerClass;
 873             Utf8Entry  thisName;
 874             if (longForm) {
 875                 outerClass = (ClassEntry) ic_outer_class.getRef();
 876                 thisName   = (Utf8Entry)  ic_name.getRef();
 877             } else {
 878                 String n = thisClass.stringValue();
 879                 String[] parse = pkg.parseInnerClassName(n);
 880                 assert(parse != null);
 881                 String pkgOuter = parse[0];
 882                 //String number = parse[1];
 883                 String name     = parse[2];
 884                 if (pkgOuter == null)
 885                     outerClass = null;
 886                 else
 887                     outerClass = ConstantPool.getClassEntry(pkgOuter);
 888                 if (name == null)
 889                     thisName   = null;
 890                 else
 891                     thisName   = ConstantPool.getUtf8Entry(name);
 892             }
 893             InnerClass ic =
 894                 new InnerClass(thisClass, outerClass, thisName, flags);
 895             assert(longForm || ic.predictable);
 896             icList.add(ic);
 897         }
 898         ic_flags.doneDisbursing();
 899         ic_this_class.doneDisbursing();
 900         ic_outer_class.doneDisbursing();
 901         ic_name.doneDisbursing();
 902         pkg.setAllInnerClasses(icList);
 903         ic_bands.doneDisbursing();
 904     }
 905 
 906     void readLocalInnerClasses(Class cls) throws IOException {
 907         int nc = class_InnerClasses_N.getInt();
 908         ArrayList localICs = new ArrayList(nc);
 909         for (int i = 0; i < nc; i++) {
 910             ClassEntry thisClass = (ClassEntry) class_InnerClasses_RC.getRef();
 911             int        flags     =              class_InnerClasses_F.getInt();
 912             if (flags == 0) {
 913                 // A zero flag means copy a global IC here.
 914                 InnerClass ic = pkg.getGlobalInnerClass(thisClass);
 915                 assert(ic != null);  // must be a valid global IC reference
 916                 localICs.add(ic);
 917             } else {
 918                 if (flags == ACC_IC_LONG_FORM)
 919                     flags = 0;  // clear the marker bit
 920                 ClassEntry outer = (ClassEntry) class_InnerClasses_outer_RCN.getRef();
 921                 Utf8Entry name   = (Utf8Entry)  class_InnerClasses_name_RUN.getRef();
 922                 localICs.add(new InnerClass(thisClass, outer, name, flags));
 923             }
 924         }
 925         cls.setInnerClasses(localICs);
 926         // cls.expandLocalICs may add more tuples to ics also,
 927         // or may even delete tuples.
 928         // We cannot do that now, because we do not know the
 929         // full contents of the local constant pool yet.
 930     }
 931 
 932     static final int NO_FLAGS_YET = 0;  // placeholder for later flag read-in
 933 
 934     Class[] readClasses() throws IOException {
 935         //  class_bands:
 936         //        *class_this :DELTA5  (cp_Class)
 937         //        *class_super :DELTA5  (cp_Class)
 938         //        *class_interface_count :DELTA5
 939         //        *class_interface :DELTA5  (cp_Class)
 940         //        ...(member bands)...
 941         //        class_attr_bands
 942         //        code_bands
 943         Class[] classes = new Class[numClasses];
 944         if (verbose > 0)
 945             Utils.log.info("  ...building "+classes.length+" classes...");
 946 
 947         class_this.expectLength(numClasses);
 948         class_super.expectLength(numClasses);
 949         class_interface_count.expectLength(numClasses);
 950 
 951         class_this.readFrom(in);
 952         class_super.readFrom(in);
 953         class_interface_count.readFrom(in);
 954         class_interface.expectLength(class_interface_count.getIntTotal());
 955         class_interface.readFrom(in);
 956         for (int i = 0; i < classes.length; i++) {
 957             ClassEntry   thisClass  = (ClassEntry) class_this.getRef();
 958             ClassEntry   superClass = (ClassEntry) class_super.getRef();
 959             ClassEntry[] interfaces = new ClassEntry[class_interface_count.getInt()];
 960             for (int j = 0; j < interfaces.length; j++) {
 961                 interfaces[j] = (ClassEntry) class_interface.getRef();
 962             }
 963             // Packer encoded rare case of null superClass as thisClass:
 964             if (superClass == thisClass)  superClass = null;
 965             Class cls = pkg.new Class(NO_FLAGS_YET,
 966                                       thisClass, superClass, interfaces);
 967             classes[i] = cls;
 968         }
 969         class_this.doneDisbursing();
 970         class_super.doneDisbursing();
 971         class_interface_count.doneDisbursing();
 972         class_interface.doneDisbursing();
 973         readMembers(classes);
 974         countAndReadAttrs(ATTR_CONTEXT_CLASS, Arrays.asList(classes));
 975         pkg.trimToSize();
 976         readCodeHeaders();
 977         //code_bands.doneDisbursing(); // still need to read code attrs
 978         //class_bands.doneDisbursing(); // still need to read code attrs
 979         return classes;
 980     }
 981 
 982     private int getOutputIndex(Entry e) {
 983         // Output CPs do not contain signatures.
 984         assert(e.tag != CONSTANT_Signature);
 985         int k = pkg.cp.untypedIndexOf(e);
 986         // In the output ordering, input signatures can serve
 987         // in place of Utf8s.
 988         if (k >= 0)
 989             return k;
 990         if (e.tag == CONSTANT_Utf8) {
 991             Entry se = (Entry) utf8Signatures.get(e);
 992             return pkg.cp.untypedIndexOf(se);
 993         }
 994         return -1;
 995     }
 996 
 997     Comparator entryOutputOrder = new Comparator() {
 998         public int compare(Object o0, Object o1) {
 999             Entry e0 = (Entry) o0;
1000             Entry e1 = (Entry) o1;
1001             int k0 = getOutputIndex(e0);
1002             int k1 = getOutputIndex(e1);
1003             if (k0 >= 0 && k1 >= 0)
1004                 // If both have keys, use the keys.
1005                 return k0 - k1;
1006             if (k0 == k1)
1007                 // If neither have keys, use their native tags & spellings.
1008                 return e0.compareTo(e1);
1009             // Otherwise, the guy with the key comes first.
1010             return (k0 >= 0)? 0-1: 1-0;
1011         }
1012     };
1013 
1014     void reconstructClass(Class cls) {
1015         if (verbose > 1)  Utils.log.fine("reconstruct "+cls);
1016 
1017         // check for local .ClassFile.version
1018         Attribute retroVersion = cls.getAttribute(attrClassFileVersion);
1019         if (retroVersion != null) {
1020             cls.removeAttribute(retroVersion);
1021             short[] minmajver = parseClassFileVersionAttr(retroVersion);
1022             cls.minver = minmajver[0];
1023             cls.majver = minmajver[1];
1024         } else {
1025             cls.minver = pkg.default_class_minver;
1026             cls.majver = pkg.default_class_majver;
1027         }
1028 
1029         // Replace null SourceFile by "obvious" string.
1030         cls.expandSourceFile();
1031 
1032         // record the local cp:
1033         cls.setCPMap(reconstructLocalCPMap(cls));
1034     }
1035 
1036     Entry[] reconstructLocalCPMap(Class cls) {
1037         HashSet ldcRefs = (HashSet) ldcRefMap.get(cls);
1038         HashSet cpRefs = new HashSet();
1039         HashSet sigSet = new HashSet();
1040 
1041         // look for constant pool entries:
1042         cls.visitRefs(VRM_CLASSIC, cpRefs);
1043 
1044         // flesh out the local constant pool
1045         ConstantPool.completeReferencesIn(cpRefs, true);
1046 
1047         // Now that we know all our local class references,
1048         // compute the InnerClasses attribute.
1049         int changed = cls.expandLocalICs();
1050 
1051         if (changed != 0) {
1052             if (changed > 0) {
1053                 // Just visit the expanded InnerClasses attr.
1054                 cls.visitInnerClassRefs(VRM_CLASSIC, cpRefs);
1055             } else {
1056                 // Have to recompute from scratch, because of deletions.
1057                 cpRefs.clear();
1058                 cls.visitRefs(VRM_CLASSIC, cpRefs);
1059             }
1060 
1061             // flesh out the local constant pool, again
1062             ConstantPool.completeReferencesIn(cpRefs, true);
1063         }
1064 
1065         // construct a local constant pool
1066         int numDoubles = 0;
1067         for (Iterator i = cpRefs.iterator(); i.hasNext(); ) {
1068             Entry e = (Entry) i.next();
1069             if (e.isDoubleWord())  numDoubles++;
1070             assert(e.tag != CONSTANT_Signature) : (e);
1071         }
1072         Entry[] cpMap = new Entry[1+numDoubles+cpRefs.size()];
1073         int fillp = 1;
1074 
1075         // Add all ldc operands first.
1076         if (ldcRefs != null) {
1077             assert(cpRefs.containsAll(ldcRefs));
1078             for (Iterator i = ldcRefs.iterator(); i.hasNext(); ) {
1079                 Entry e = (Entry) i.next();
1080                 cpMap[fillp++] = e;
1081             }
1082             assert(fillp == 1+ldcRefs.size());
1083             cpRefs.removeAll(ldcRefs);
1084             ldcRefs = null;  // done with it
1085         }
1086 
1087         // Next add all the two-byte references.
1088         HashSet wideRefs = cpRefs;
1089         cpRefs = null;  // do not use!
1090         int narrowLimit = fillp;
1091         for (Iterator i = wideRefs.iterator(); i.hasNext(); ) {
1092             Entry e = (Entry) i.next();
1093             cpMap[fillp++] = e;
1094         }
1095         assert(fillp == narrowLimit+wideRefs.size());
1096         Arrays.sort(cpMap, 1, narrowLimit, entryOutputOrder);
1097         Arrays.sort(cpMap, narrowLimit, fillp, entryOutputOrder);
1098 
1099         if (verbose > 3) {
1100             Utils.log.fine("CP of "+this+" {");
1101             for (int i = 0; i < fillp; i++) {
1102                 Entry e = cpMap[i];
1103                 Utils.log.fine("  "+((e==null)?-1:getOutputIndex(e))
1104                                    +" : "+e);
1105             }
1106             Utils.log.fine("}");
1107         }
1108 
1109         // Now repack backwards, introducing null elements.
1110         int revp = cpMap.length;
1111         for (int i = fillp; --i >= 1; ) {
1112             Entry e = cpMap[i];
1113             if (e.isDoubleWord())
1114                 cpMap[--revp] = null;
1115             cpMap[--revp] = e;
1116         }
1117         assert(revp == 1);  // do not process the initial null
1118 
1119         return cpMap;
1120     }
1121 
1122     void readMembers(Class[] classes) throws IOException {
1123         //  class_bands:
1124         //        ...
1125         //        *class_field_count :DELTA5
1126         //        *class_method_count :DELTA5
1127         //
1128         //        *field_descr :DELTA5  (cp_Descr)
1129         //        field_attr_bands
1130         //
1131         //        *method_descr :MDELTA5  (cp_Descr)
1132         //        method_attr_bands
1133         //        ...
1134         assert(classes.length == numClasses);
1135         class_field_count.expectLength(numClasses);
1136         class_method_count.expectLength(numClasses);
1137         class_field_count.readFrom(in);
1138         class_method_count.readFrom(in);
1139 
1140         // Make a pre-pass over field and method counts to size the descrs:
1141         int totalNF = class_field_count.getIntTotal();
1142         int totalNM = class_method_count.getIntTotal();
1143         field_descr.expectLength(totalNF);
1144         method_descr.expectLength(totalNM);
1145         if (verbose > 1)  Utils.log.fine("expecting #fields="+totalNF+" and #methods="+totalNM+" in #classes="+numClasses);
1146 
1147         ArrayList fields = new ArrayList(totalNF);
1148         field_descr.readFrom(in);
1149         for (int i = 0; i < classes.length; i++) {
1150             Class c = classes[i];
1151             int nf = class_field_count.getInt();
1152             for (int j = 0; j < nf; j++) {
1153                 Class.Field f = c.new Field(NO_FLAGS_YET, (DescriptorEntry)
1154                                             field_descr.getRef());
1155                 fields.add(f);
1156             }
1157         }
1158         class_field_count.doneDisbursing();
1159         field_descr.doneDisbursing();
1160         countAndReadAttrs(ATTR_CONTEXT_FIELD, fields);
1161         fields = null;  // release to GC
1162 
1163         ArrayList methods = new ArrayList(totalNM);
1164         method_descr.readFrom(in);
1165         for (int i = 0; i < classes.length; i++) {
1166             Class c = classes[i];
1167             int nm = class_method_count.getInt();
1168             for (int j = 0; j < nm; j++) {
1169                 Class.Method m = c.new Method(NO_FLAGS_YET, (DescriptorEntry)
1170                                               method_descr.getRef());
1171                 methods.add(m);
1172             }
1173         }
1174         class_method_count.doneDisbursing();
1175         method_descr.doneDisbursing();
1176         countAndReadAttrs(ATTR_CONTEXT_METHOD, methods);
1177 
1178         // Up to this point, Code attributes look like empty attributes.
1179         // Now we start to special-case them.  The empty canonical Code
1180         // attributes stay in the method attribute lists, however.
1181         allCodes = buildCodeAttrs(methods);
1182     }
1183 
1184     Code[] allCodes;
1185     List codesWithFlags;
1186     HashMap ldcRefMap = new HashMap();  // HashMap<Class, HashSet<Entry>>
1187 
1188     Code[] buildCodeAttrs(List methods) {
1189         ArrayList codes = new ArrayList(methods.size());
1190         for (Iterator i = methods.iterator(); i.hasNext(); ) {
1191             Class.Method m = (Class.Method) i.next();
1192             if (m.getAttribute(attrCodeEmpty) != null) {
1193                 m.code = new Code(m);
1194                 codes.add(m.code);
1195             }
1196         }
1197         Code[] a = new Code[codes.size()];
1198         codes.toArray(a);
1199         return a;
1200     }
1201 
1202     void readCodeHeaders() throws IOException {
1203         //  code_bands:
1204         //        *code_headers :BYTE1
1205         //
1206         //        *code_max_stack :UNSIGNED5
1207         //        *code_max_na_locals :UNSIGNED5
1208         //        *code_handler_count :UNSIGNED5
1209         //        ...
1210         //        code_attr_bands
1211         boolean attrsOK = testBit(archiveOptions, AO_HAVE_ALL_CODE_FLAGS);
1212         code_headers.expectLength(allCodes.length);
1213         code_headers.readFrom(in);
1214         ArrayList longCodes = new ArrayList(allCodes.length / 10);
1215         for (int i = 0; i < allCodes.length; i++) {
1216             Code c = allCodes[i];
1217             int sc = code_headers.getByte();
1218             assert(sc == (sc & 0xFF));
1219             if (verbose > 2)
1220                 Utils.log.fine("codeHeader "+c+" = "+sc);
1221             if (sc == LONG_CODE_HEADER) {
1222                 // We will read ms/ml/nh/flags from bands shortly.
1223                 longCodes.add(c);
1224                 continue;
1225             }
1226             // Short code header is the usual case:
1227             c.setMaxStack(     shortCodeHeader_max_stack(sc) );
1228             c.setMaxNALocals(  shortCodeHeader_max_na_locals(sc) );
1229             c.setHandlerCount( shortCodeHeader_handler_count(sc) );
1230             assert(shortCodeHeader(c) == sc);
1231         }
1232         code_headers.doneDisbursing();
1233         code_max_stack.expectLength(longCodes.size());
1234         code_max_na_locals.expectLength(longCodes.size());
1235         code_handler_count.expectLength(longCodes.size());
1236 
1237         // Do the long headers now.
1238         code_max_stack.readFrom(in);
1239         code_max_na_locals.readFrom(in);
1240         code_handler_count.readFrom(in);
1241         for (Iterator i = longCodes.iterator(); i.hasNext(); ) {
1242             Code c = (Code) i.next();
1243             c.setMaxStack(     code_max_stack.getInt() );
1244             c.setMaxNALocals(  code_max_na_locals.getInt() );
1245             c.setHandlerCount( code_handler_count.getInt() );
1246         }
1247         code_max_stack.doneDisbursing();
1248         code_max_na_locals.doneDisbursing();
1249         code_handler_count.doneDisbursing();
1250 
1251         readCodeHandlers();
1252 
1253         if (attrsOK) {
1254             // Code attributes are common (debug info not stripped).
1255             codesWithFlags = Arrays.asList(allCodes);
1256         } else {
1257             // Code attributes are very sparse (debug info is stripped).
1258             codesWithFlags = longCodes;
1259         }
1260         countAttrs(ATTR_CONTEXT_CODE, codesWithFlags);
1261         // do readAttrs later, after BCs are scanned
1262     }
1263 
1264     void readCodeHandlers() throws IOException {
1265         //  code_bands:
1266         //        ...
1267         //        *code_handler_start_P :BCI5
1268         //        *code_handler_end_PO :BRANCH5
1269         //        *code_handler_catch_PO :BRANCH5
1270         //        *code_handler_class_RCN :UNSIGNED5  (null or cp_Class)
1271         //        ...
1272         int nh = 0;
1273         for (int i = 0; i < allCodes.length; i++) {
1274             Code c = allCodes[i];
1275             nh += c.getHandlerCount();
1276         }
1277 
1278         ValueBand[] code_handler_bands = {
1279             code_handler_start_P,
1280             code_handler_end_PO,
1281             code_handler_catch_PO,
1282             code_handler_class_RCN
1283         };
1284 
1285         for (int i = 0; i < code_handler_bands.length; i++) {
1286             code_handler_bands[i].expectLength(nh);
1287             code_handler_bands[i].readFrom(in);
1288         }
1289 
1290         for (int i = 0; i < allCodes.length; i++) {
1291             Code c = allCodes[i];
1292             for (int j = 0, jmax = c.getHandlerCount(); j < jmax; j++) {
1293                 c.handler_class[j] = code_handler_class_RCN.getRef();
1294                 // For now, just record the raw BCI codes.
1295                 // We must wait until we have instruction boundaries.
1296                 c.handler_start[j] = code_handler_start_P.getInt();
1297                 c.handler_end[j]   = code_handler_end_PO.getInt();
1298                 c.handler_catch[j] = code_handler_catch_PO.getInt();
1299             }
1300         }
1301         for (int i = 0; i < code_handler_bands.length; i++) {
1302             code_handler_bands[i].doneDisbursing();
1303         }
1304     }
1305 
1306     void fixupCodeHandlers() {
1307         // Actually decode (renumber) the BCIs now.
1308         for (int i = 0; i < allCodes.length; i++) {
1309             Code c = allCodes[i];
1310             for (int j = 0, jmax = c.getHandlerCount(); j < jmax; j++) {
1311                 int sum = c.handler_start[j];
1312                 c.handler_start[j] = c.decodeBCI(sum);
1313                 sum += c.handler_end[j];
1314                 c.handler_end[j]   = c.decodeBCI(sum);
1315                 sum += c.handler_catch[j];
1316                 c.handler_catch[j] = c.decodeBCI(sum);
1317             }
1318         }
1319     }
1320 
1321     // Generic routines for reading attributes of
1322     // classes, fields, methods, and codes.
1323     // The holders is a global list, already collected,
1324     // of attribute "customers".
1325     void countAndReadAttrs(int ctype, Collection holders) throws IOException {
1326         //  class_attr_bands:
1327         //        *class_flags :UNSIGNED5
1328         //        *class_attr_count :UNSIGNED5
1329         //        *class_attr_indexes :UNSIGNED5
1330         //        *class_attr_calls :UNSIGNED5
1331         //        *class_Signature_RS :UNSIGNED5 (cp_Signature)
1332         //        class_metadata_bands
1333         //        *class_SourceFile_RU :UNSIGNED5 (cp_Utf8)
1334         //        *class_EnclosingMethod_RM :UNSIGNED5 (cp_Method)
1335         //        ic_local_bands
1336         //        *class_ClassFile_version_minor_H :UNSIGNED5
1337         //        *class_ClassFile_version_major_H :UNSIGNED5
1338         //
1339         //  field_attr_bands:
1340         //        *field_flags :UNSIGNED5
1341         //        *field_attr_count :UNSIGNED5
1342         //        *field_attr_indexes :UNSIGNED5
1343         //        *field_attr_calls :UNSIGNED5
1344         //        *field_Signature_RS :UNSIGNED5 (cp_Signature)
1345         //        field_metadata_bands
1346         //        *field_ConstantValue_KQ :UNSIGNED5 (cp_Int, etc.; see note)
1347         //
1348         //  method_attr_bands:
1349         //        *method_flags :UNSIGNED5
1350         //        *method_attr_count :UNSIGNED5
1351         //        *method_attr_indexes :UNSIGNED5
1352         //        *method_attr_calls :UNSIGNED5
1353         //        *method_Signature_RS :UNSIGNED5 (cp_Signature)
1354         //        method_metadata_bands
1355         //        *method_Exceptions_N :UNSIGNED5
1356         //        *method_Exceptions_RC :UNSIGNED5  (cp_Class)
1357         //
1358         //  code_attr_bands:
1359         //        *code_flags :UNSIGNED5
1360         //        *code_attr_count :UNSIGNED5
1361         //        *code_attr_indexes :UNSIGNED5
1362         //        *code_attr_calls :UNSIGNED5
1363         //        *code_LineNumberTable_N :UNSIGNED5
1364         //        *code_LineNumberTable_bci_P :BCI5
1365         //        *code_LineNumberTable_line :UNSIGNED5
1366         //        *code_LocalVariableTable_N :UNSIGNED5
1367         //        *code_LocalVariableTable_bci_P :BCI5
1368         //        *code_LocalVariableTable_span_O :BRANCH5
1369         //        *code_LocalVariableTable_name_RU :UNSIGNED5 (cp_Utf8)
1370         //        *code_LocalVariableTable_type_RS :UNSIGNED5 (cp_Signature)
1371         //        *code_LocalVariableTable_slot :UNSIGNED5
1372 
1373         countAttrs(ctype, holders);
1374         readAttrs(ctype, holders);
1375     }
1376 
1377     // Read flags and count the attributes that are to be placed
1378     // on the given holders.
1379     void countAttrs(int ctype, Collection holders) throws IOException {
1380         // Here, xxx stands for one of class, field, method, code.
1381         MultiBand xxx_attr_bands = attrBands[ctype];
1382         long flagMask = attrFlagMask[ctype];
1383         if (verbose > 1) {
1384             Utils.log.fine("scanning flags and attrs for "+Attribute.contextName(ctype)+"["+holders.size()+"]");
1385         }
1386 
1387         // Fetch the attribute layout definitions which govern the bands
1388         // we are about to read.
1389         Attribute.Layout[] defs = new Attribute.Layout[attrDefs[ctype].size()];
1390         attrDefs[ctype].toArray(defs);
1391         IntBand xxx_flags_hi = getAttrBand(xxx_attr_bands, AB_FLAGS_HI);
1392         IntBand xxx_flags_lo = getAttrBand(xxx_attr_bands, AB_FLAGS_LO);
1393         IntBand xxx_attr_count = getAttrBand(xxx_attr_bands, AB_ATTR_COUNT);
1394         IntBand xxx_attr_indexes = getAttrBand(xxx_attr_bands, AB_ATTR_INDEXES);
1395         IntBand xxx_attr_calls = getAttrBand(xxx_attr_bands, AB_ATTR_CALLS);
1396 
1397         // Count up the number of holders which have overflow attrs.
1398         int overflowMask = attrOverflowMask[ctype];
1399         int overflowHolderCount = 0;
1400         boolean haveLongFlags = haveFlagsHi(ctype);
1401         xxx_flags_hi.expectLength(haveLongFlags? holders.size(): 0);
1402         xxx_flags_hi.readFrom(in);
1403         xxx_flags_lo.expectLength(holders.size());
1404         xxx_flags_lo.readFrom(in);
1405         assert((flagMask & overflowMask) == overflowMask);
1406         for (Iterator i = holders.iterator(); i.hasNext(); ) {
1407             Attribute.Holder h = (Attribute.Holder) i.next();
1408             int flags = xxx_flags_lo.getInt();
1409             h.flags = flags;
1410             if ((flags & overflowMask) != 0)
1411                 overflowHolderCount += 1;
1412         }
1413 
1414         // For each holder with overflow attrs, read a count.
1415         xxx_attr_count.expectLength(overflowHolderCount);
1416         xxx_attr_count.readFrom(in);
1417         xxx_attr_indexes.expectLength(xxx_attr_count.getIntTotal());
1418         xxx_attr_indexes.readFrom(in);
1419 
1420         // Now it's time to check flag bits that indicate attributes.
1421         // We accumulate (a) a list of attribute types for each holder
1422         // (class/field/method/code), and also we accumulate (b) a total
1423         // count for each attribute type.
1424         int[] totalCounts = new int[defs.length];
1425         for (Iterator i = holders.iterator(); i.hasNext(); ) {
1426             Attribute.Holder h = (Attribute.Holder) i.next();
1427             assert(h.attributes == null);
1428             // System.out.println("flags="+h.flags+" using fm="+flagMask);
1429             long attrBits = ((h.flags & flagMask) << 32) >>> 32;
1430             // Clean up the flags now.
1431             h.flags -= (int)attrBits;   // strip attr bits
1432             assert(h.flags == (char)h.flags);  // 16 bits only now
1433             assert((ctype != ATTR_CONTEXT_CODE) || h.flags == 0);
1434             if (haveLongFlags)
1435                 attrBits += (long)xxx_flags_hi.getInt() << 32;
1436             if (attrBits == 0)  continue;  // no attrs on this guy
1437 
1438             int noa = 0;  // number of overflow attrs
1439             long overflowBit = (attrBits & overflowMask);
1440             assert(overflowBit >= 0);
1441             attrBits -= overflowBit;
1442             if (overflowBit != 0) {
1443                 noa = xxx_attr_count.getInt();
1444             }
1445 
1446             int nfa = 0;  // number of flag attrs
1447             long bits = attrBits;
1448             for (int ai = 0; bits != 0; ai++) {
1449                 if ((bits & (1L<<ai)) == 0)  continue;
1450                 bits -= (1L<<ai);
1451                 nfa += 1;
1452             }
1453             ArrayList ha = new ArrayList(nfa + noa);
1454             h.attributes = ha;
1455             bits = attrBits;  // iterate again
1456             for (int ai = 0; bits != 0; ai++) {
1457                 if ((bits & (1L<<ai)) == 0)  continue;
1458                 bits -= (1L<<ai);
1459                 totalCounts[ai] += 1;
1460                 // This definition index is live in this holder.
1461                 if (defs[ai] == null)  badAttrIndex(ai, ctype);
1462                 Attribute canonical = defs[ai].canonicalInstance();
1463                 ha.add(canonical);
1464                 nfa -= 1;
1465             }
1466             assert(nfa == 0);
1467             for (; noa > 0; noa--) {
1468                 int ai = xxx_attr_indexes.getInt();
1469                 totalCounts[ai] += 1;
1470                 // This definition index is live in this holder.
1471                 if (defs[ai] == null)  badAttrIndex(ai, ctype);
1472                 Attribute canonical = defs[ai].canonicalInstance();
1473                 ha.add(canonical);
1474             }
1475         }
1476 
1477         xxx_flags_hi.doneDisbursing();
1478         xxx_flags_lo.doneDisbursing();
1479         xxx_attr_count.doneDisbursing();
1480         xxx_attr_indexes.doneDisbursing();
1481 
1482         // Now each holder has a list of canonical attribute instances.
1483         // For layouts with no elements, we are done.  However, for
1484         // layouts with bands, we must replace each canonical (empty)
1485         // instance with a value-bearing one, initialized from the
1486         // appropriate bands.
1487 
1488         // Make a small pass to detect and read backward call counts.
1489         int callCounts = 0;
1490         for (boolean predef = true; ; predef = false) {
1491             for (int ai = 0; ai < defs.length; ai++) {
1492                 Attribute.Layout def = defs[ai];
1493                 if (def == null)  continue;  // unused index
1494                 if (predef != isPredefinedAttr(ctype, ai))
1495                     continue;  // wrong pass
1496                 int totalCount = totalCounts[ai];
1497                 if (totalCount == 0)
1498                     continue;  // irrelevant
1499                 Attribute.Layout.Element[] cbles = def.getCallables();
1500                 for (int j = 0; j < cbles.length; j++) {
1501                     assert(cbles[j].kind == Attribute.EK_CBLE);
1502                     if (cbles[j].flagTest(Attribute.EF_BACK))
1503                         callCounts += 1;
1504                 }
1505             }
1506             if (!predef)  break;
1507         }
1508         xxx_attr_calls.expectLength(callCounts);
1509         xxx_attr_calls.readFrom(in);
1510 
1511         // Finally, size all the attribute bands.
1512         for (boolean predef = true; ; predef = false) {
1513             for (int ai = 0; ai < defs.length; ai++) {
1514                 Attribute.Layout def = defs[ai];
1515                 if (def == null)  continue;  // unused index
1516                 if (predef != isPredefinedAttr(ctype, ai))
1517                     continue;  // wrong pass
1518                 int totalCount = totalCounts[ai];
1519                 Band[] ab = (Band[]) attrBandTable.get(def);
1520                 if (def == attrInnerClassesEmpty) {
1521                     // Special case.
1522                     // Size the bands as if using the following layout:
1523                     //    [RCH TI[ (0)[] ()[RCNH RUNH] ]].
1524                     class_InnerClasses_N.expectLength(totalCount);
1525                     class_InnerClasses_N.readFrom(in);
1526                     int tupleCount = class_InnerClasses_N.getIntTotal();
1527                     class_InnerClasses_RC.expectLength(tupleCount);
1528                     class_InnerClasses_RC.readFrom(in);
1529                     class_InnerClasses_F.expectLength(tupleCount);
1530                     class_InnerClasses_F.readFrom(in);
1531                     // Drop remaining columns wherever flags are zero:
1532                     tupleCount -= class_InnerClasses_F.getIntCount(0);
1533                     class_InnerClasses_outer_RCN.expectLength(tupleCount);
1534                     class_InnerClasses_outer_RCN.readFrom(in);
1535                     class_InnerClasses_name_RUN.expectLength(tupleCount);
1536                     class_InnerClasses_name_RUN.readFrom(in);
1537                 } else if (totalCount == 0) {
1538                     // Expect no elements at all.  Skip quickly.
1539                     for (int j = 0; j < ab.length; j++) {
1540                         ab[j].doneWithUnusedBand();
1541                     }
1542                 } else {
1543                     // Read these bands in sequence.
1544                     boolean hasCallables = def.hasCallables();
1545                     if (!hasCallables) {
1546                         readAttrBands(def.elems, totalCount, new int[0], ab);
1547                     } else {
1548                         Attribute.Layout.Element[] cbles = def.getCallables();
1549                         // At first, record initial calls.
1550                         // Later, forward calls may also accumulate here:
1551                         int[] forwardCounts = new int[cbles.length];
1552                         forwardCounts[0] = totalCount;
1553                         for (int j = 0; j < cbles.length; j++) {
1554                             assert(cbles[j].kind == Attribute.EK_CBLE);
1555                             int entryCount = forwardCounts[j];
1556                             forwardCounts[j] = -1;  // No more, please!
1557                             if (cbles[j].flagTest(Attribute.EF_BACK))
1558                                 entryCount += xxx_attr_calls.getInt();
1559                             readAttrBands(cbles[j].body, entryCount, forwardCounts, ab);
1560                         }
1561                     }
1562                 }
1563             }
1564             if (!predef)  break;
1565         }
1566         xxx_attr_calls.doneDisbursing();
1567     }
1568 
1569     void badAttrIndex(int ai, int ctype) throws IOException {
1570         throw new IOException("Unknown attribute index "+ai+" for "+
1571                                    ATTR_CONTEXT_NAME[ctype]+" attribute");
1572     }
1573 
1574     void readAttrs(int ctype, Collection holders) throws IOException {
1575         // Decode band values into attributes.
1576         HashSet sawDefs = new HashSet();
1577         ByteArrayOutputStream buf = new ByteArrayOutputStream();
1578         for (Iterator i = holders.iterator(); i.hasNext(); ) {
1579             final Attribute.Holder h = (Attribute.Holder) i.next();
1580             if (h.attributes == null)  continue;
1581             for (ListIterator j = h.attributes.listIterator(); j.hasNext(); ) {
1582                 Attribute a = (Attribute) j.next();
1583                 Attribute.Layout def = a.layout();
1584                 if (def.bandCount == 0) {
1585                     if (def == attrInnerClassesEmpty) {
1586                         // Special logic to read this attr.
1587                         readLocalInnerClasses((Class) h);
1588                         continue;
1589                     }
1590                     // Canonical empty attr works fine (e.g., Synthetic).
1591                     continue;
1592                 }
1593                 sawDefs.add(def);
1594                 boolean isCV = (ctype == ATTR_CONTEXT_FIELD && def == attrConstantValue);
1595                 if (isCV)  setConstantValueIndex((Class.Field)h);
1596                 if (verbose > 2)
1597                     Utils.log.fine("read "+a+" in "+h);
1598                 final Band[] ab = (Band[]) attrBandTable.get(def);
1599                 // Read one attribute of type def from ab into a byte array.
1600                 buf.reset();
1601                 Object fixups = a.unparse(new Attribute.ValueStream() {
1602                     public int getInt(int bandIndex) {
1603                         return ((IntBand) ab[bandIndex]).getInt();
1604                     }
1605                     public Entry getRef(int bandIndex) {
1606                         return ((CPRefBand) ab[bandIndex]).getRef();
1607                     }
1608                     public int decodeBCI(int bciCode) {
1609                         Code code = (Code) h;
1610                         return code.decodeBCI(bciCode);
1611                     }
1612                 }, buf);
1613                 // Replace the canonical attr with the one just read.
1614                 j.set(a.addContent(buf.toByteArray(), fixups));
1615                 if (isCV)  setConstantValueIndex(null);  // clean up
1616             }
1617         }
1618 
1619         // Mark the bands we just used as done disbursing.
1620         for (Iterator i = sawDefs.iterator(); i.hasNext(); ) {
1621             Attribute.Layout def = (Attribute.Layout) i.next();
1622             if (def == null)  continue;  // unused index
1623             Band[] ab = (Band[]) attrBandTable.get(def);
1624             for (int j = 0; j < ab.length; j++) {
1625                 ab[j].doneDisbursing();
1626             }
1627         }
1628 
1629         if (ctype == ATTR_CONTEXT_CLASS) {
1630             class_InnerClasses_N.doneDisbursing();
1631             class_InnerClasses_RC.doneDisbursing();
1632             class_InnerClasses_F.doneDisbursing();
1633             class_InnerClasses_outer_RCN.doneDisbursing();
1634             class_InnerClasses_name_RUN.doneDisbursing();
1635         }
1636 
1637         MultiBand xxx_attr_bands = attrBands[ctype];
1638         for (int i = 0; i < xxx_attr_bands.size(); i++) {
1639             Band b = xxx_attr_bands.get(i);
1640             if (b instanceof MultiBand)
1641                 b.doneDisbursing();
1642         }
1643         xxx_attr_bands.doneDisbursing();
1644     }
1645 
1646     private
1647     void readAttrBands(Attribute.Layout.Element[] elems,
1648                        int count, int[] forwardCounts,
1649                        Band[] ab)
1650             throws IOException {
1651         for (int i = 0; i < elems.length; i++) {
1652             Attribute.Layout.Element e = elems[i];
1653             Band eBand = null;
1654             if (e.hasBand()) {
1655                 eBand = ab[e.bandIndex];
1656                 eBand.expectLength(count);
1657                 eBand.readFrom(in);
1658             }
1659             switch (e.kind) {
1660             case Attribute.EK_REPL:
1661                 // Recursive call.
1662                 int repCount = ((IntBand)eBand).getIntTotal();
1663                 // Note:  getIntTotal makes an extra pass over this band.
1664                 readAttrBands(e.body, repCount, forwardCounts, ab);
1665                 break;
1666             case Attribute.EK_UN:
1667                 int remainingCount = count;
1668                 for (int j = 0; j < e.body.length; j++) {
1669                     int caseCount;
1670                     if (j == e.body.length-1) {
1671                         caseCount = remainingCount;
1672                     } else {
1673                         caseCount = 0;
1674                         for (int j0 = j;
1675                              (j == j0)
1676                              || (j < e.body.length
1677                                  && e.body[j].flagTest(Attribute.EF_BACK));
1678                              j++) {
1679                             caseCount += ((IntBand)eBand).getIntCount(e.body[j].value);
1680                         }
1681                         --j;  // back up to last occurrence of this body
1682                     }
1683                     remainingCount -= caseCount;
1684                     readAttrBands(e.body[j].body, caseCount, forwardCounts, ab);
1685                 }
1686                 assert(remainingCount == 0);
1687                 break;
1688             case Attribute.EK_CALL:
1689                 assert(e.body.length == 1);
1690                 assert(e.body[0].kind == Attribute.EK_CBLE);
1691                 if (!e.flagTest(Attribute.EF_BACK)) {
1692                     // Backward calls are pre-counted, but forwards are not.
1693                     // Push the present count forward.
1694                     assert(forwardCounts[e.value] >= 0);
1695                     forwardCounts[e.value] += count;
1696                 }
1697                 break;
1698             case Attribute.EK_CBLE:
1699                 assert(false);
1700                 break;
1701             }
1702         }
1703     }
1704 
1705     void readByteCodes() throws IOException {
1706         //  bc_bands:
1707         //        *bc_codes :BYTE1
1708         //        *bc_case_count :UNSIGNED5
1709         //        *bc_case_value :DELTA5
1710         //        *bc_byte :BYTE1
1711         //        *bc_short :DELTA5
1712         //        *bc_local :UNSIGNED5
1713         //        *bc_label :BRANCH5
1714         //        *bc_intref :DELTA5  (cp_Int)
1715         //        *bc_floatref :DELTA5  (cp_Float)
1716         //        *bc_longref :DELTA5  (cp_Long)
1717         //        *bc_doubleref :DELTA5  (cp_Double)
1718         //        *bc_stringref :DELTA5  (cp_String)
1719         //        *bc_classref :UNSIGNED5  (current class or cp_Class)
1720         //        *bc_fieldref :DELTA5  (cp_Field)
1721         //        *bc_methodref :UNSIGNED5  (cp_Method)
1722         //        *bc_imethodref :DELTA5  (cp_Imethod)
1723         //        *bc_thisfield :UNSIGNED5 (cp_Field, only for current class)
1724         //        *bc_superfield :UNSIGNED5 (cp_Field, only for current super)
1725         //        *bc_thismethod :UNSIGNED5 (cp_Method, only for current class)
1726         //        *bc_supermethod :UNSIGNED5 (cp_Method, only for current super)
1727         //        *bc_initref :UNSIGNED5 (cp_Field, only for most recent new)
1728         //        *bc_escref :UNSIGNED5 (cp_All)
1729         //        *bc_escrefsize :UNSIGNED5
1730         //        *bc_escsize :UNSIGNED5
1731         //        *bc_escbyte :BYTE1
1732         bc_codes.elementCountForDebug = allCodes.length;
1733         bc_codes.setInputStreamFrom(in);
1734         readByteCodeOps();  // reads from bc_codes and bc_case_count
1735         bc_codes.doneDisbursing();
1736 
1737         // All the operand bands have now been sized.  Read them all in turn.
1738         Band[] operand_bands = {
1739             bc_case_value,
1740             bc_byte, bc_short,
1741             bc_local, bc_label,
1742             bc_intref, bc_floatref,
1743             bc_longref, bc_doubleref, bc_stringref,
1744             bc_classref, bc_fieldref,
1745             bc_methodref, bc_imethodref,
1746             bc_thisfield, bc_superfield,
1747             bc_thismethod, bc_supermethod,
1748             bc_initref,
1749             bc_escref, bc_escrefsize, bc_escsize
1750         };
1751         for (int i = 0; i < operand_bands.length; i++) {
1752             operand_bands[i].readFrom(in);
1753         }
1754         bc_escbyte.expectLength(bc_escsize.getIntTotal());
1755         bc_escbyte.readFrom(in);
1756 
1757         expandByteCodeOps();
1758 
1759         // Done fetching values from operand bands:
1760         bc_case_count.doneDisbursing();
1761         for (int i = 0; i < operand_bands.length; i++) {
1762             operand_bands[i].doneDisbursing();
1763         }
1764         bc_escbyte.doneDisbursing();
1765         bc_bands.doneDisbursing();
1766 
1767         // We must delay the parsing of Code attributes until we
1768         // have a complete model of bytecodes, for BCI encodings.
1769         readAttrs(ATTR_CONTEXT_CODE, codesWithFlags);
1770         // Ditto for exception handlers in codes.
1771         fixupCodeHandlers();
1772         // Now we can finish with class_bands; cf. readClasses().
1773         code_bands.doneDisbursing();
1774         class_bands.doneDisbursing();
1775     }
1776 
1777     private void readByteCodeOps() throws IOException {
1778         // scratch buffer for collecting code::
1779         byte[] buf = new byte[1<<12];
1780         // record of all switch opcodes (these are variable-length)
1781         ArrayList allSwitchOps = new ArrayList();
1782         for (int k = 0; k < allCodes.length; k++) {
1783             Code c = allCodes[k];
1784         scanOneMethod:
1785             for (int i = 0; ; i++) {
1786                 int bc = bc_codes.getByte();
1787                 if (i + 10 > buf.length)  buf = realloc(buf);
1788                 buf[i] = (byte)bc;
1789                 boolean isWide = false;
1790                 if (bc == _wide) {
1791                     bc = bc_codes.getByte();
1792                     buf[++i] = (byte)bc;
1793                     isWide = true;
1794                 }
1795                 assert(bc == (0xFF & bc));
1796                 // Adjust expectations of various band sizes.
1797                 switch (bc) {
1798                 case _tableswitch:
1799                 case _lookupswitch:
1800                     bc_case_count.expectMoreLength(1);
1801                     allSwitchOps.add(new Integer(bc));
1802                     break;
1803                 case _iinc:
1804                     bc_local.expectMoreLength(1);
1805                     if (isWide)
1806                         bc_short.expectMoreLength(1);
1807                     else
1808                         bc_byte.expectMoreLength(1);
1809                     break;
1810                 case _sipush:
1811                     bc_short.expectMoreLength(1);
1812                     break;
1813                 case _bipush:
1814                     bc_byte.expectMoreLength(1);
1815                     break;
1816                 case _newarray:
1817                     bc_byte.expectMoreLength(1);
1818                     break;
1819                 case _multianewarray:
1820                     assert(getCPRefOpBand(bc) == bc_classref);
1821                     bc_classref.expectMoreLength(1);
1822                     bc_byte.expectMoreLength(1);
1823                     break;
1824                 case _ref_escape:
1825                     bc_escrefsize.expectMoreLength(1);
1826                     bc_escref.expectMoreLength(1);
1827                     break;
1828                 case _byte_escape:
1829                     bc_escsize.expectMoreLength(1);
1830                     // bc_escbyte will have to be counted too
1831                     break;
1832                 default:
1833                     if (Instruction.isInvokeInitOp(bc)) {
1834                         bc_initref.expectMoreLength(1);
1835                         break;
1836                     }
1837                     if (Instruction.isSelfLinkerOp(bc)) {
1838                         CPRefBand bc_which = selfOpRefBand(bc);
1839                         bc_which.expectMoreLength(1);
1840                         break;
1841                     }
1842                     if (Instruction.isBranchOp(bc)) {
1843                         bc_label.expectMoreLength(1);
1844                         break;
1845                     }
1846                     if (Instruction.isCPRefOp(bc)) {
1847                         CPRefBand bc_which = getCPRefOpBand(bc);
1848                         bc_which.expectMoreLength(1);
1849                         assert(bc != _multianewarray);  // handled elsewhere
1850                         break;
1851                     }
1852                     if (Instruction.isLocalSlotOp(bc)) {
1853                         bc_local.expectMoreLength(1);
1854                         break;
1855                     }
1856                     break;
1857                 case _end_marker:
1858                     {
1859                         // Transfer from buf to a more permanent place:
1860                         c.bytes = realloc(buf, i);
1861                         break scanOneMethod;
1862                     }
1863                 }
1864             }
1865         }
1866 
1867         // To size instruction bands correctly, we need info on switches:
1868         bc_case_count.readFrom(in);
1869         for (Iterator i = allSwitchOps.iterator(); i.hasNext(); ) {
1870             int bc = ((Integer)i.next()).intValue();
1871             int caseCount = bc_case_count.getInt();
1872             bc_label.expectMoreLength(1+caseCount); // default label + cases
1873             bc_case_value.expectMoreLength(bc == _tableswitch ? 1 : caseCount);
1874         }
1875         bc_case_count.resetForSecondPass();
1876     }
1877 
1878     private void expandByteCodeOps() throws IOException {
1879         // scratch buffer for collecting code:
1880         byte[] buf = new byte[1<<12];
1881         // scratch buffer for collecting instruction boundaries:
1882         int[] insnMap = new int[1<<12];
1883         // list of label carriers, for label decoding post-pass:
1884         int[] labels = new int[1<<10];
1885         // scratch buffer for registering CP refs:
1886         Fixups fixupBuf = new Fixups();
1887 
1888         for (int k = 0; k < allCodes.length; k++) {
1889             Code code = allCodes[k];
1890             byte[] codeOps = code.bytes;
1891             code.bytes = null;  // just for now, while we accumulate bits
1892 
1893             Class curClass = code.thisClass();
1894 
1895             HashSet ldcRefSet = (HashSet) ldcRefMap.get(curClass);
1896             if (ldcRefSet == null)
1897                 ldcRefMap.put(curClass, ldcRefSet = new HashSet());
1898 
1899             ClassEntry thisClass  = curClass.thisClass;
1900             ClassEntry superClass = curClass.superClass;
1901             ClassEntry newClass   = null;  // class of last _new opcode
1902 
1903             int pc = 0;  // fill pointer in buf; actual bytecode PC
1904             int numInsns = 0;
1905             int numLabels = 0;
1906             boolean hasEscs = false;
1907             fixupBuf.clear();
1908             for (int i = 0; i < codeOps.length; i++) {
1909                 int bc = Instruction.getByte(codeOps, i);
1910                 int curPC = pc;
1911                 insnMap[numInsns++] = curPC;
1912                 if (pc + 10 > buf.length)  buf = realloc(buf);
1913                 if (numInsns+10 > insnMap.length)  insnMap = realloc(insnMap);
1914                 if (numLabels+10 > labels.length)  labels = realloc(labels);
1915                 boolean isWide = false;
1916                 if (bc == _wide) {
1917                     buf[pc++] = (byte) bc;
1918                     bc = Instruction.getByte(codeOps, ++i);
1919                     isWide = true;
1920                 }
1921                 switch (bc) {
1922                 case _tableswitch: // apc:  (df, lo, hi, (hi-lo+1)*(label))
1923                 case _lookupswitch: // apc:  (df, nc, nc*(case, label))
1924                     {
1925                         int caseCount = bc_case_count.getInt();
1926                         while ((pc + 30 + caseCount*8) > buf.length)
1927                             buf = realloc(buf);
1928                         buf[pc++] = (byte) bc;
1929                         //initialize apc, df, lo, hi bytes to reasonable bits:
1930                         Arrays.fill(buf, pc, pc+30, (byte)0);
1931                         Instruction.Switch isw = (Instruction.Switch)
1932                             Instruction.at(buf, curPC);
1933                         //isw.setDefaultLabel(getLabel(bc_label, code, curPC));
1934                         isw.setCaseCount(caseCount);
1935                         if (bc == _tableswitch) {
1936                             isw.setCaseValue(0, bc_case_value.getInt());
1937                         } else {
1938                             for (int j = 0; j < caseCount; j++) {
1939                                 isw.setCaseValue(j, bc_case_value.getInt());
1940                             }
1941                         }
1942                         // Make our getLabel calls later.
1943                         labels[numLabels++] = curPC;
1944                         pc = isw.getNextPC();
1945                         continue;
1946                     }
1947                 case _iinc:
1948                     {
1949                         buf[pc++] = (byte) bc;
1950                         int local = bc_local.getInt();
1951                         int delta;
1952                         if (isWide) {
1953                             delta = bc_short.getInt();
1954                             Instruction.setShort(buf, pc, local); pc += 2;
1955                             Instruction.setShort(buf, pc, delta); pc += 2;
1956                         } else {
1957                             delta = (byte) bc_byte.getByte();
1958                             buf[pc++] = (byte)local;
1959                             buf[pc++] = (byte)delta;
1960                         }
1961                         continue;
1962                     }
1963                 case _sipush:
1964                     {
1965                         int val = bc_short.getInt();
1966                         buf[pc++] = (byte) bc;
1967                         Instruction.setShort(buf, pc, val); pc += 2;
1968                         continue;
1969                     }
1970                 case _bipush:
1971                 case _newarray:
1972                     {
1973                         int val = bc_byte.getByte();
1974                         buf[pc++] = (byte) bc;
1975                         buf[pc++] = (byte) val;
1976                         continue;
1977                     }
1978                 case _ref_escape:
1979                     {
1980                         // Note that insnMap has one entry for this.
1981                         hasEscs = true;
1982                         int size = bc_escrefsize.getInt();
1983                         Entry ref = bc_escref.getRef();
1984                         if (size == 1)  ldcRefSet.add(ref);
1985                         int fmt;
1986                         switch (size) {
1987                         case 1: fmt = Fixups.U1_FORMAT; break;
1988                         case 2: fmt = Fixups.U2_FORMAT; break;
1989                         default: assert(false); fmt = 0;
1990                         }
1991                         fixupBuf.add(pc, fmt, ref);
1992                         buf[pc+0] = buf[pc+1] = 0;
1993                         pc += size;
1994                     }
1995                     continue;
1996                 case _byte_escape:
1997                     {
1998                         // Note that insnMap has one entry for all these bytes.
1999                         hasEscs = true;
2000                         int size = bc_escsize.getInt();
2001                         while ((pc + size) > buf.length)
2002                             buf = realloc(buf);
2003                         while (size-- > 0) {
2004                             buf[pc++] = (byte) bc_escbyte.getByte();
2005                         }
2006                     }
2007                     continue;
2008                 default:
2009                     if (Instruction.isInvokeInitOp(bc)) {
2010                         int idx = (bc - _invokeinit_op);
2011                         int origBC = _invokespecial;
2012                         ClassEntry classRef;
2013                         switch (idx) {
2014                         case _invokeinit_self_option:
2015                             classRef = thisClass; break;
2016                         case _invokeinit_super_option:
2017                             classRef = superClass; break;
2018                         default:
2019                             assert(idx == _invokeinit_new_option);
2020                             classRef = newClass; break;
2021                         }
2022                         buf[pc++] = (byte) origBC;
2023                         int coding = bc_initref.getInt();
2024                         // Find the nth overloading of <init> in classRef.
2025                         MemberEntry ref = pkg.cp.getOverloadingForIndex(CONSTANT_Methodref, classRef, "<init>", coding);
2026                         fixupBuf.add(pc, Fixups.U2_FORMAT, ref);
2027                         buf[pc+0] = buf[pc+1] = 0;
2028                         pc += 2;
2029                         assert(Instruction.opLength(origBC) == (pc - curPC));
2030                         continue;
2031                     }
2032                     if (Instruction.isSelfLinkerOp(bc)) {
2033                         int idx = (bc - _self_linker_op);
2034                         boolean isSuper = (idx >= _self_linker_super_flag);
2035                         if (isSuper)  idx -= _self_linker_super_flag;
2036                         boolean isAload = (idx >= _self_linker_aload_flag);
2037                         if (isAload)  idx -= _self_linker_aload_flag;
2038                         int origBC = _first_linker_op + idx;
2039                         boolean isField = Instruction.isFieldOp(origBC);
2040                         CPRefBand bc_which;
2041                         ClassEntry which_cls  = isSuper ? superClass : thisClass;
2042                         Index which_ix;
2043                         if (isField) {
2044                             bc_which = isSuper ? bc_superfield  : bc_thisfield;
2045                             which_ix = pkg.cp.getMemberIndex(CONSTANT_Fieldref, which_cls);
2046                         } else {
2047                             bc_which = isSuper ? bc_supermethod : bc_thismethod;
2048                             which_ix = pkg.cp.getMemberIndex(CONSTANT_Methodref, which_cls);
2049                         }
2050                         assert(bc_which == selfOpRefBand(bc));
2051                         MemberEntry ref = (MemberEntry) bc_which.getRef(which_ix);
2052                         if (isAload) {
2053                             buf[pc++] = (byte) _aload_0;
2054                             curPC = pc;
2055                             // Note: insnMap keeps the _aload_0 separate.
2056                             insnMap[numInsns++] = curPC;
2057                         }
2058                         buf[pc++] = (byte) origBC;
2059                         fixupBuf.add(pc, Fixups.U2_FORMAT, ref);
2060                         buf[pc+0] = buf[pc+1] = 0;
2061                         pc += 2;
2062                         assert(Instruction.opLength(origBC) == (pc - curPC));
2063                         continue;
2064                     }
2065                     if (Instruction.isBranchOp(bc)) {
2066                         buf[pc++] = (byte) bc;
2067                         assert(!isWide);  // no wide prefix for branches
2068                         int nextPC = curPC + Instruction.opLength(bc);
2069                         // Make our getLabel calls later.
2070                         labels[numLabels++] = curPC;
2071                         //Instruction.at(buf, curPC).setBranchLabel(getLabel(bc_label, code, curPC));
2072                         while (pc < nextPC)  buf[pc++] = 0;
2073                         continue;
2074                     }
2075                     if (Instruction.isCPRefOp(bc)) {
2076                         CPRefBand bc_which = getCPRefOpBand(bc);
2077                         Entry ref = bc_which.getRef();
2078                         if (ref == null) {
2079                             if (bc_which == bc_classref) {
2080                                 // Shorthand for class self-references.
2081                                 ref = thisClass;
2082                             } else {
2083                                 assert(false);
2084                             }
2085                         }
2086                         int origBC = bc;
2087                         int size = 2;
2088                         switch (bc) {
2089                         case _ildc:
2090                         case _cldc:
2091                         case _fldc:
2092                         case _aldc:
2093                             origBC = _ldc;
2094                             size = 1;
2095                             ldcRefSet.add(ref);
2096                             break;
2097                         case _ildc_w:
2098                         case _cldc_w:
2099                         case _fldc_w:
2100                         case _aldc_w:
2101                             origBC = _ldc_w;
2102                             break;
2103                         case _lldc2_w:
2104                         case _dldc2_w:
2105                             origBC = _ldc2_w;
2106                             break;
2107                         case _new:
2108                             newClass = (ClassEntry) ref;
2109                             break;
2110                         }
2111                         buf[pc++] = (byte) origBC;
2112                         int fmt;
2113                         switch (size) {
2114                         case 1: fmt = Fixups.U1_FORMAT; break;
2115                         case 2: fmt = Fixups.U2_FORMAT; break;
2116                         default: assert(false); fmt = 0;
2117                         }
2118                         fixupBuf.add(pc, fmt, ref);
2119                         buf[pc+0] = buf[pc+1] = 0;
2120                         pc += size;
2121                         if (origBC == _multianewarray) {
2122                             // Copy the trailing byte also.
2123                             int val = bc_byte.getByte();
2124                             buf[pc++] = (byte) val;
2125                         } else if (origBC == _invokeinterface) {
2126                             int argSize = ((MemberEntry)ref).descRef.typeRef.computeSize(true);
2127                             buf[pc++] = (byte)( 1 + argSize );
2128                             buf[pc++] = 0;
2129                         }
2130                         assert(Instruction.opLength(origBC) == (pc - curPC));
2131                         continue;
2132                     }
2133                     if (Instruction.isLocalSlotOp(bc)) {
2134                         buf[pc++] = (byte) bc;
2135                         int local = bc_local.getInt();
2136                         if (isWide) {
2137                             Instruction.setShort(buf, pc, local);
2138                             pc += 2;
2139                             if (bc == _iinc) {
2140                                 int iVal = bc_short.getInt();
2141                                 Instruction.setShort(buf, pc, iVal);
2142                                 pc += 2;
2143                             }
2144                         } else {
2145                             Instruction.setByte(buf, pc, local);
2146                             pc += 1;
2147                             if (bc == _iinc) {
2148                                 int iVal = bc_byte.getByte();
2149                                 Instruction.setByte(buf, pc, iVal);
2150                                 pc += 1;
2151                             }
2152                         }
2153                         assert(Instruction.opLength(bc) == (pc - curPC));
2154                         continue;
2155                     }
2156                     // Random bytecode.  Just copy it.
2157                     if (bc >= _bytecode_limit)
2158                         Utils.log.warning("unrecognized bytescode "+bc
2159                                             +" "+Instruction.byteName(bc));
2160                     assert(bc < _bytecode_limit);
2161                     buf[pc++] = (byte) bc;
2162                     assert(Instruction.opLength(bc) == (pc - curPC));
2163                     continue;
2164                 }
2165             }
2166             // now make a permanent copy of the bytecodes
2167             code.setBytes(realloc(buf, pc));
2168             code.setInstructionMap(insnMap, numInsns);
2169             // fix up labels, now that code has its insnMap
2170             Instruction ibr = null;  // temporary branch instruction
2171             for (int i = 0; i < numLabels; i++) {
2172                 int curPC = labels[i];
2173                 // (Note:  Passing ibr in allows reuse, a speed hack.)
2174                 ibr = Instruction.at(code.bytes, curPC, ibr);
2175                 if (ibr instanceof Instruction.Switch) {
2176                     Instruction.Switch isw = (Instruction.Switch) ibr;
2177                     isw.setDefaultLabel(getLabel(bc_label, code, curPC));
2178                     int caseCount = isw.getCaseCount();
2179                     for (int j = 0; j < caseCount; j++) {
2180                         isw.setCaseLabel(j, getLabel(bc_label, code, curPC));
2181                     }
2182                 } else {
2183                     ibr.setBranchLabel(getLabel(bc_label, code, curPC));
2184                 }
2185             }
2186             if (fixupBuf.size() > 0) {
2187                 if (verbose > 2)
2188                     Utils.log.fine("Fixups in code: "+fixupBuf);
2189                 code.addFixups(fixupBuf);
2190             }
2191         }
2192     }
2193 }