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