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