/*
 * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

// -*- C++ -*-
// Program for unpacking specially compressed Java packages.
// John R. Rose

#include <sys/types.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>

#include <limits.h>
#include <time.h>




#include "defines.h"
#include "bytes.h"
#include "utils.h"
#include "coding.h"
#include "bands.h"

#include "constants.h"

#include "zip.h"

#include "unpack.h"


// tags, in canonical order:
static const byte TAGS_IN_ORDER[] = {
  CONSTANT_Utf8,
  CONSTANT_Integer,
  CONSTANT_Float,
  CONSTANT_Long,
  CONSTANT_Double,
  CONSTANT_String,
  CONSTANT_Class,
  CONSTANT_Signature,
  CONSTANT_NameandType,
  CONSTANT_Fieldref,
  CONSTANT_Methodref,
  CONSTANT_InterfaceMethodref
};
#define N_TAGS_IN_ORDER (sizeof TAGS_IN_ORDER)

#ifndef PRODUCT
static const char* TAG_NAME[] = {
  "*None",
  "Utf8",
  "*Unicode",
  "Integer",
  "Float",
  "Long",
  "Double",
  "Class",
  "String",
  "Fieldref",
  "Methodref",
  "InterfaceMethodref",
  "NameandType",
  "*Signature",
  0
};

static const char* ATTR_CONTEXT_NAME[] = {  // match ATTR_CONTEXT_NAME, etc.
  "class", "field", "method", "code"
};

#else

#define ATTR_CONTEXT_NAME ((const char**)null)

#endif


// REQUESTED must be -2 for u2 and REQUESTED_LDC must be -1 for u1
enum { NOT_REQUESTED = 0, REQUESTED = -2, REQUESTED_LDC = -1 };

#define NO_INORD ((uint)-1)

struct entry {
  byte tag;

  #if 0
  byte bits;
  enum {
    //EB_EXTRA = 1,
    EB_SUPER = 2
  };
  #endif
  unsigned short nrefs;  // pack w/ tag

  int  outputIndex;
  uint inord;   // &cp.entries[cp.tag_base[this->tag]+this->inord] == this

  entry* *refs;

  // put last to pack best
  union {
    bytes b;
    int i;
    jlong l;
  } value;

  void requestOutputIndex(cpool& cp, int req = REQUESTED);
  int getOutputIndex() {
    assert(outputIndex > NOT_REQUESTED);
    return outputIndex;
  }

  entry* ref(int refnum) {
    assert((uint)refnum < nrefs);
    return refs[refnum];
  }

  const char* utf8String() {
    assert(tagMatches(CONSTANT_Utf8));
    assert(value.b.len == strlen((const char*)value.b.ptr));
    return (const char*)value.b.ptr;
  }

  entry* className() {
    assert(tagMatches(CONSTANT_Class));
    return ref(0);
  }

  entry* memberClass() {
    assert(tagMatches(CONSTANT_Member));
    return ref(0);
  }

  entry* memberDescr() {
    assert(tagMatches(CONSTANT_Member));
    return ref(1);
  }

  entry* descrName() {
    assert(tagMatches(CONSTANT_NameandType));
    return ref(0);
  }

  entry* descrType() {
    assert(tagMatches(CONSTANT_NameandType));
    return ref(1);
  }

  int typeSize();

  bytes& asUtf8();
  int    asInteger() { assert(tag == CONSTANT_Integer); return value.i; }

  bool isUtf8(bytes& b) { return tagMatches(CONSTANT_Utf8) && value.b.equals(b); }

  bool isDoubleWord() { return tag == CONSTANT_Double || tag == CONSTANT_Long; }

  bool tagMatches(byte tag2) {
    return (tag2 == tag)
      || (tag2 == CONSTANT_Utf8 && tag == CONSTANT_Signature)
      #ifndef PRODUCT
      || (tag2 == CONSTANT_Literal
          && tag >= CONSTANT_Integer && tag <= CONSTANT_String && tag != CONSTANT_Class)
      || (tag2 == CONSTANT_Member
          && tag >= CONSTANT_Fieldref && tag <= CONSTANT_InterfaceMethodref)
      #endif
      ;
  }

#ifdef PRODUCT
  char* string() { return 0; }
#else
  char* string();  // see far below
#endif
};

entry* cpindex::get(uint i) {
  if (i >= len)
    return null;
  else if (base1 != null)
    // primary index
    return &base1[i];
  else
    // secondary index
    return base2[i];
}

inline bytes& entry::asUtf8() {
  assert(tagMatches(CONSTANT_Utf8));
  return value.b;
}

int entry::typeSize() {
  assert(tagMatches(CONSTANT_Utf8));
  const char* sigp = (char*) value.b.ptr;
  switch (*sigp) {
  case '(': sigp++; break;  // skip opening '('
  case 'D':
  case 'J': return 2; // double field
  default:  return 1; // field
  }
  int siglen = 0;
  for (;;) {
    int ch = *sigp++;
    switch (ch) {
    case 'D': case 'J':
      siglen += 1;
      break;
    case '[':
      // Skip rest of array info.
      while (ch == '[') { ch = *sigp++; }
      if (ch != 'L')  break;
      // else fall through
    case 'L':
      sigp = strchr(sigp, ';');
      if (sigp == null) {
          unpack_abort("bad data");
          return 0;
      }
      sigp += 1;
      break;
    case ')':  // closing ')'
      return siglen;
    }
    siglen += 1;
  }
}

inline cpindex* cpool::getFieldIndex(entry* classRef) {
  assert(classRef->tagMatches(CONSTANT_Class));
  assert((uint)classRef->inord < tag_count[CONSTANT_Class]);
  return &member_indexes[classRef->inord*2+0];
}
inline cpindex* cpool::getMethodIndex(entry* classRef) {
  assert(classRef->tagMatches(CONSTANT_Class));
  assert((uint)classRef->inord < tag_count[CONSTANT_Class]);
  return &member_indexes[classRef->inord*2+1];
}

struct inner_class {
  entry* inner;
  entry* outer;
  entry* name;
  int    flags;
  inner_class* next_sibling;
  bool   requested;
};

// Here is where everything gets deallocated:
void unpacker::free() {
  int i;
  assert(jniobj == null); // caller resp.
  assert(infileptr == null);  // caller resp.
  if (jarout != null)  jarout->reset();
  if (gzin != null)    { gzin->free(); gzin = null; }
  if (free_input)  input.free();
  // free everybody ever allocated with U_NEW or (recently) with T_NEW
  assert(smallbuf.base()  == null || mallocs.contains(smallbuf.base()));
  assert(tsmallbuf.base() == null || tmallocs.contains(tsmallbuf.base()));
  mallocs.freeAll();
  tmallocs.freeAll();
  smallbuf.init();
  tsmallbuf.init();
  bcimap.free();
  class_fixup_type.free();
  class_fixup_offset.free();
  class_fixup_ref.free();
  code_fixup_type.free();
  code_fixup_offset.free();
  code_fixup_source.free();
  requested_ics.free();
  cur_classfile_head.free();
  cur_classfile_tail.free();
  for (i = 0; i < ATTR_CONTEXT_LIMIT; i++)
    attr_defs[i].free();

  // free CP state
  cp.outputEntries.free();
  for (i = 0; i < CONSTANT_Limit; i++)
    cp.tag_extras[i].free();
}

// input handling
// Attempts to advance rplimit so that (rplimit-rp) is at least 'more'.
// Will eagerly read ahead by larger chunks, if possible.
// Returns false if (rplimit-rp) is not at least 'more',
// unless rplimit hits input.limit().
bool unpacker::ensure_input(jlong more) {
  julong want = more - input_remaining();
  if ((jlong)want <= 0)          return true;  // it's already in the buffer
  if (rplimit == input.limit())  return true;  // not expecting any more

  if (read_input_fn == null) {
    // assume it is already all there
    bytes_read += input.limit() - rplimit;
    rplimit = input.limit();
    return true;
  }
  CHECK_0;

  julong remaining = (input.limit() - rplimit);  // how much left to read?
  byte* rpgoal = (want >= remaining)? input.limit(): rplimit + (size_t)want;
  enum { CHUNK_SIZE = (1<<14) };
  julong fetch = want;
  if (fetch < CHUNK_SIZE)
    fetch = CHUNK_SIZE;
  if (fetch > remaining*3/4)
    fetch = remaining;
  // Try to fetch at least "more" bytes.
  while ((jlong)fetch > 0) {
    jlong nr = (*read_input_fn)(this, rplimit, fetch, remaining);
    if (nr <= 0) {
      return (rplimit >= rpgoal);
    }
    remaining -= nr;
    rplimit += nr;
    fetch -= nr;
    bytes_read += nr;
    assert(remaining == (input.limit() - rplimit));
  }
  return true;
}

// output handling

fillbytes* unpacker::close_output(fillbytes* which) {
  assert(wp != null);
  if (which == null) {
    if (wpbase == cur_classfile_head.base()) {
      which = &cur_classfile_head;
    } else {
      which = &cur_classfile_tail;
    }
  }
  assert(wpbase  == which->base());
  assert(wplimit == which->end());
  which->setLimit(wp);
  wp      = null;
  wplimit = null;
  //wpbase = null;
  return which;
}

//maybe_inline
void unpacker::ensure_put_space(size_t size) {
  if (wp + size <= wplimit)  return;
  // Determine which segment needs expanding.
  fillbytes* which = close_output();
  byte* wp0 = which->grow(size);
  wpbase  = which->base();
  wplimit = which->end();
  wp = wp0;
}

maybe_inline
byte* unpacker::put_space(size_t size) {
  byte* wp0 = wp;
  byte* wp1 = wp0 + size;
  if (wp1 > wplimit) {
    ensure_put_space(size);
    wp0 = wp;
    wp1 = wp0 + size;
  }
  wp = wp1;
  return wp0;
}

maybe_inline
void unpacker::putu2_at(byte* wp, int n) {
  if (n != (unsigned short)n) {
    unpack_abort(ERROR_OVERFLOW);
    return;
  }
  wp[0] = (n) >> 8;
  wp[1] = (n) >> 0;
}

maybe_inline
void unpacker::putu4_at(byte* wp, int n) {
  wp[0] = (n) >> 24;
  wp[1] = (n) >> 16;
  wp[2] = (n) >> 8;
  wp[3] = (n) >> 0;
}

maybe_inline
void unpacker::putu8_at(byte* wp, jlong n) {
  putu4_at(wp+0, (int)((julong)n >> 32));
  putu4_at(wp+4, (int)((julong)n >> 0));
}

maybe_inline
void unpacker::putu2(int n) {
  putu2_at(put_space(2), n);
}

maybe_inline
void unpacker::putu4(int n) {
  putu4_at(put_space(4), n);
}

maybe_inline
void unpacker::putu8(jlong n) {
  putu8_at(put_space(8), n);
}

maybe_inline
int unpacker::putref_index(entry* e, int size) {
  if (e == null)
    return 0;
  else if (e->outputIndex > NOT_REQUESTED)
    return e->outputIndex;
  else if (e->tag == CONSTANT_Signature)
    return putref_index(e->ref(0), size);
  else {
    e->requestOutputIndex(cp, -size);
    // Later on we'll fix the bits.
    class_fixup_type.addByte(size);
    class_fixup_offset.add(wpoffset());
    class_fixup_ref.add(e);
    return !assert(1) ? 0 : 0x20+size;  // 0x22 is easy to eyeball
  }
}

maybe_inline
void unpacker::putref(entry* e) {
  int oidx = putref_index(e, 2);
  putu2_at(put_space(2), oidx);
}

maybe_inline
void unpacker::putu1ref(entry* e) {
  int oidx = putref_index(e, 1);
  putu1_at(put_space(1), oidx);
}


static int total_cp_size[] = {0, 0};
static int largest_cp_ref[] = {0, 0};
static int hash_probes[] = {0, 0};

// Allocation of small and large blocks.

enum { CHUNK = (1 << 14), SMALL = (1 << 9) };

// Call malloc.  Try to combine small blocks and free much later.
void* unpacker::alloc_heap(size_t size, bool smallOK, bool temp) {
  CHECK_0;
  if (!smallOK || size > SMALL) {
    void* res = must_malloc(size);
    (temp ? &tmallocs : &mallocs)->add(res);
    return res;
  }
  fillbytes& xsmallbuf = *(temp ? &tsmallbuf : &smallbuf);
  if (!xsmallbuf.canAppend(size+1)) {
    xsmallbuf.init(CHUNK);
    (temp ? &tmallocs : &mallocs)->add(xsmallbuf.base());
  }
  int growBy = size;
  growBy += -growBy & 7;  // round up mod 8
  return xsmallbuf.grow(growBy);
}

maybe_inline
void unpacker::saveTo(bytes& b, byte* ptr, size_t len) {
  b.ptr = U_NEW(byte, len+1);
  if (aborting()) {
    b.len = 0;
    return;
  }
  b.len = len;
  b.copyFrom(ptr, len);
}

// Read up through band_headers.
// Do the archive_size dance to set the size of the input mega-buffer.
void unpacker::read_file_header() {
  // Read file header to determine file type and total size.
  enum {
    MAGIC_BYTES = 4,
    AH_LENGTH_0 = 3,  //minver, majver, options are outside of archive_size
    AH_LENGTH   = 26, //maximum archive header length (w/ all fields)
    // Length contributions from optional header fields:
    AH_FILE_HEADER_LEN = 5, // sizehi/lo/next/modtime/files
    AH_CP_NUMBER_LEN = 4,  // int/float/long/double
    AH_SPECIAL_FORMAT_LEN = 2, // layouts/band-headers
    AH_LENGTH_MIN = AH_LENGTH
        -(AH_FILE_HEADER_LEN+AH_SPECIAL_FORMAT_LEN+AH_CP_NUMBER_LEN),
    FIRST_READ  = MAGIC_BYTES + AH_LENGTH_MIN
  };
  bool foreign_buf = (read_input_fn == null);
  byte initbuf[FIRST_READ + C_SLOP + 200];  // 200 is for JAR I/O
  if (foreign_buf) {
    // inbytes is all there is
    input.set(inbytes);
    rp      = input.base();
    rplimit = input.limit();
  } else {
    // inbytes, if not empty, contains some read-ahead we must use first
    // ensure_input will take care of copying it into initbuf,
    // then querying read_input_fn for any additional data needed.
    // However, the caller must assume that we use up all of inbytes.
    // There is no way to tell the caller that we used only part of them.
    // Therefore, the caller must use only a bare minimum of read-ahead.
    if (inbytes.len > FIRST_READ) {
      abort("too much pushback");
      return;
    }
    input.set(initbuf, sizeof(initbuf));
    input.b.clear();
    input.b.copyFrom(inbytes);
    rplimit = rp = input.base();
    rplimit += inbytes.len;
    bytes_read += inbytes.len;
  }
  // Read only 19 bytes, which is certain to contain #archive_size fields,
  // but is certain not to overflow past the archive_header.
  input.b.len = FIRST_READ;
  if (!ensure_input(FIRST_READ))
    abort("EOF reading archive magic number");

  if (rp[0] == 'P' && rp[1] == 'K') {
#ifdef UNPACK_JNI
    // Java driver must handle this case before we get this far.
    abort("encountered a JAR header in unpacker");
#else
    // In the Unix-style program, we simply simulate a copy command.
    // Copy until EOF; assume the JAR file is the last segment.
    fprintf(errstrm, "Copy-mode.\n");
    for (;;) {
      jarout->write_data(rp, input_remaining());
      if (foreign_buf)
        break;  // one-time use of a passed in buffer
      if (input.size() < CHUNK) {
        // Get some breathing room.
        input.set(U_NEW(byte, (size_t) CHUNK + C_SLOP), (size_t) CHUNK);
        CHECK;
      }
      rp = rplimit = input.base();
      if (!ensure_input(1))
        break;
    }
    jarout->closeJarFile(false);
#endif
    return;
  }

  // Read the magic number.
  magic = 0;
  for (int i1 = 0; i1 < sizeof(magic); i1++) {
    magic <<= 8;
    magic += (*rp++ & 0xFF);
  }

  // Read the first 3 values from the header.
  value_stream hdr;
  int          hdrVals = 0;
  int          hdrValsSkipped = 0;  // debug only
  hdr.init(rp, rplimit, UNSIGNED5_spec);
  minver = hdr.getInt();
  majver = hdr.getInt();
  hdrVals += 2;

  if (magic != JAVA_PACKAGE_MAGIC ||
      (majver != JAVA5_PACKAGE_MAJOR_VERSION  &&
       majver != JAVA6_PACKAGE_MAJOR_VERSION) ||
      (minver != JAVA5_PACKAGE_MINOR_VERSION  &&
       minver != JAVA6_PACKAGE_MINOR_VERSION)) {
    char message[200];
    sprintf(message, "@" ERROR_FORMAT ": magic/ver = "
            "%08X/%d.%d should be %08X/%d.%d OR %08X/%d.%d\n",
            magic, majver, minver,
            JAVA_PACKAGE_MAGIC, JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION,
            JAVA_PACKAGE_MAGIC, JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION);
    abort(message);
  }
  CHECK;

  archive_options = hdr.getInt();
  hdrVals += 1;
  assert(hdrVals == AH_LENGTH_0);  // first three fields only

#define ORBIT(bit) |(bit)
  int OPTION_LIMIT = (0 ARCHIVE_BIT_DO(ORBIT));
#undef ORBIT
  if ((archive_options & ~OPTION_LIMIT) != 0) {
    fprintf(errstrm, "Warning: Illegal archive options 0x%x\n",
            archive_options);
    // Do not abort.  If the format really changes, version numbers will bump.
    //abort("illegal archive options");
  }

  if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) {
    uint hi = hdr.getInt();
    uint lo = hdr.getInt();
    archive_size = band::makeLong(hi, lo);
    hdrVals += 2;
  } else {
    hdrValsSkipped += 2;
  }

  if (archive_size != (size_t)archive_size) {
    // Silly size specified.
    abort("archive too large");
    return;
  }

  // Now we can size the whole archive.
  // Read everything else into a mega-buffer.
  rp = hdr.rp;
  int header_size_0 = (rp - input.base()); // used-up header (4byte + 3int)
  int header_size_1 = (rplimit - rp);      // buffered unused initial fragment
  int header_size   = header_size_0+header_size_1;
  unsized_bytes_read = header_size_0;
  CHECK;
  if (foreign_buf) {
    if (archive_size > header_size_1) {
      abort("EOF reading fixed input buffer");
      return;
    }
  } else if (archive_size > 0) {
    input.set(U_NEW(byte, (size_t) header_size_0 + archive_size + C_SLOP),
              (size_t) header_size_0 + archive_size);
    assert(input.limit()[0] == 0);
    // Move all the bytes we read initially into the real buffer.
    input.b.copyFrom(initbuf, header_size);
    rp      = input.b.ptr + header_size_0;
    rplimit = input.b.ptr + header_size;
  } else {
    // It's more complicated and painful.
    // A zero archive_size means that we must read until EOF.
    assert(archive_size == 0);
    input.init(CHUNK*2);
    CHECK;
    input.b.len = input.allocated;
    rp = rplimit = input.base();
    // Set up input buffer as if we already read the header:
    input.b.copyFrom(initbuf, header_size);
    rplimit += header_size;
    while (ensure_input(input.limit() - rp)) {
      size_t dataSoFar = input_remaining();
      size_t nextSize = dataSoFar + CHUNK;
      input.ensureSize(nextSize);
      CHECK;
      input.b.len = input.allocated;
      rp = rplimit = input.base();
      rplimit += dataSoFar;
    }
    size_t dataSize = (rplimit - input.base());
    input.b.len = dataSize;
    input.grow(C_SLOP);
    CHECK;
    free_input = true;  // free it later
    input.b.len = dataSize;
    assert(input.limit()[0] == 0);
    rp = rplimit = input.base();
    rplimit += dataSize;
    rp += header_size_0;  // already scanned these bytes...
  }
  live_input = true;    // mark as "do not reuse"
  if (aborting()) {
    abort("cannot allocate large input buffer for package file");
    return;
  }

  // read the rest of the header fields
  ensure_input((AH_LENGTH-AH_LENGTH_0) * B_MAX);
  CHECK;
  hdr.rp      = rp;
  hdr.rplimit = rplimit;

  if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) {
    archive_next_count = hdr.getInt();
    archive_modtime = hdr.getInt();
    file_count = hdr.getInt();
    hdrVals += 3;
  } else {
    hdrValsSkipped += 3;
  }

  if ((archive_options & AO_HAVE_SPECIAL_FORMATS) != 0) {
    band_headers_size = hdr.getInt();
    attr_definition_count = hdr.getInt();
    hdrVals += 2;
  } else {
    hdrValsSkipped += 2;
  }

  int cp_counts[N_TAGS_IN_ORDER];
  for (int k = 0; k < N_TAGS_IN_ORDER; k++) {
    if (!(archive_options & AO_HAVE_CP_NUMBERS)) {
      switch (TAGS_IN_ORDER[k]) {
      case CONSTANT_Integer:
      case CONSTANT_Float:
      case CONSTANT_Long:
      case CONSTANT_Double:
        cp_counts[k] = 0;
        hdrValsSkipped += 1;
        continue;
      }
    }
    cp_counts[k] = hdr.getInt();
    hdrVals += 1;
  }

  ic_count = hdr.getInt();
  default_class_minver = hdr.getInt();
  default_class_majver = hdr.getInt();
  class_count = hdr.getInt();
  hdrVals += 4;

  // done with archive_header
  hdrVals += hdrValsSkipped;
  assert(hdrVals == AH_LENGTH);
#ifndef PRODUCT
  int assertSkipped = AH_LENGTH - AH_LENGTH_MIN;
  if ((archive_options & AO_HAVE_FILE_HEADERS) != 0)
    assertSkipped -= AH_FILE_HEADER_LEN;
  if ((archive_options & AO_HAVE_SPECIAL_FORMATS) != 0)
    assertSkipped -= AH_SPECIAL_FORMAT_LEN;
  if ((archive_options & AO_HAVE_CP_NUMBERS) != 0)
    assertSkipped -= AH_CP_NUMBER_LEN;
  assert(hdrValsSkipped == assertSkipped);
#endif //PRODUCT

  rp = hdr.rp;
  if (rp > rplimit)
    abort("EOF reading archive header");

  // Now size the CP.
  assert(N_TAGS_IN_ORDER == cpool::NUM_COUNTS);
  cp.init(this, cp_counts);
  CHECK;

  default_file_modtime = archive_modtime;
  if (default_file_modtime == 0 && !(archive_options & AO_HAVE_FILE_MODTIME))
    default_file_modtime = DEFAULT_ARCHIVE_MODTIME;  // taken from driver
  if ((archive_options & AO_DEFLATE_HINT) != 0)
    default_file_options |= FO_DEFLATE_HINT;

  // meta-bytes, if any, immediately follow archive header
  //band_headers.readData(band_headers_size);
  ensure_input(band_headers_size);
  if (input_remaining() < band_headers_size) {
    abort("EOF reading band headers");
    return;
  }
  bytes band_headers;
  // The "1+" allows an initial byte to be pushed on the front.
  band_headers.set(1+U_NEW(byte, 1+band_headers_size+C_SLOP),
                   band_headers_size);
  CHECK;
  // Start scanning band headers here:
  band_headers.copyFrom(rp, band_headers.len);
  rp += band_headers.len;
  assert(rp <= rplimit);
  meta_rp = band_headers.ptr;
  // Put evil meta-codes at the end of the band headers,
  // so we are sure to throw an error if we run off the end.
  bytes::of(band_headers.limit(), C_SLOP).clear(_meta_error);
}


void unpacker::finish() {
  if (verbose >= 1) {
    fprintf(errstrm,
            "A total of %lld bytes were read in %d segment(s).\n",
            bytes_read_before_reset+bytes_read,
            segments_read_before_reset+1);
    fprintf(errstrm,
            "A total of %lld file content bytes were written.\n",
            bytes_written_before_reset+bytes_written);
    fprintf(errstrm,
            "A total of %d files (of which %d are classes) were written to output.\n",
            files_written_before_reset+files_written,
            classes_written_before_reset+classes_written);
  }
  if (jarout != null)
    jarout->closeJarFile(true);
  if (errstrm != null) {
    if (errstrm == stdout || errstrm == stderr) {
      fflush(errstrm);
    } else {
      fclose(errstrm);
    }
    errstrm = null;
    errstrm_name = null;
  }
}


// Cf. PackageReader.readConstantPoolCounts
void cpool::init(unpacker* u_, int counts[NUM_COUNTS]) {
  this->u = u_;

  // Fill-pointer for CP.
  int next_entry = 0;

  // Size the constant pool:
  for (int k = 0; k < N_TAGS_IN_ORDER; k++) {
    byte tag = TAGS_IN_ORDER[k];
    int  len = counts[k];
    tag_count[tag] = len;
    tag_base[tag] = next_entry;
    next_entry += len;
    // Detect and defend against constant pool size overflow.
    // (Pack200 forbids the sum of CP counts to exceed 2^29-1.)
    enum {
      CP_SIZE_LIMIT = (1<<29),
      IMPLICIT_ENTRY_COUNT = 1  // empty Utf8 string
    };
    if (len >= (1<<29) || len < 0
        || next_entry >= CP_SIZE_LIMIT+IMPLICIT_ENTRY_COUNT) {
      abort("archive too large:  constant pool limit exceeded");
      return;
    }
  }

  // Close off the end of the CP:
  nentries = next_entry;

  // place a limit on future CP growth:
  int generous = 0;
  generous += u->ic_count*3; // implicit name, outer, outer.utf8
  generous += 40;  // WKUs, misc
  generous += u->class_count;  // implicit SourceFile strings
  maxentries = nentries + generous;

  // Note that this CP does not include "empty" entries
  // for longs and doubles.  Those are introduced when
  // the entries are renumbered for classfile output.

  entries = U_NEW(entry, maxentries);
  CHECK;

  first_extra_entry = &entries[nentries];

  // Initialize the standard indexes.
  tag_count[CONSTANT_All] = nentries;
  tag_base[ CONSTANT_All] = 0;
  for (int tag = 0; tag < CONSTANT_Limit; tag++) {
    entry* cpMap = &entries[tag_base[tag]];
    tag_index[tag].init(tag_count[tag], cpMap, tag);
  }

  // Initialize hashTab to a generous power-of-two size.
  uint pow2 = 1;
  uint target = maxentries + maxentries/2;  // 60% full
  while (pow2 < target)  pow2 <<= 1;
  hashTab = U_NEW(entry*, hashTabLength = pow2);
}

static byte* store_Utf8_char(byte* cp, unsigned short ch) {
  if (ch >= 0x001 && ch <= 0x007F) {
    *cp++ = (byte) ch;
  } else if (ch <= 0x07FF) {
    *cp++ = (byte) (0xC0 | ((ch >>  6) & 0x1F));
    *cp++ = (byte) (0x80 | ((ch >>  0) & 0x3F));
  } else {
    *cp++ = (byte) (0xE0 | ((ch >> 12) & 0x0F));
    *cp++ = (byte) (0x80 | ((ch >>  6) & 0x3F));
    *cp++ = (byte) (0x80 | ((ch >>  0) & 0x3F));
  }
  return cp;
}

static byte* skip_Utf8_chars(byte* cp, int len) {
  for (;; cp++) {
    int ch = *cp & 0xFF;
    if ((ch & 0xC0) != 0x80) {
      if (len-- == 0)
        return cp;
      if (ch < 0x80 && len == 0)
        return cp+1;
    }
  }
}

static int compare_Utf8_chars(bytes& b1, bytes& b2) {
  int l1 = b1.len;
  int l2 = b2.len;
  int l0 = (l1 < l2) ? l1 : l2;
  byte* p1 = b1.ptr;
  byte* p2 = b2.ptr;
  int c0 = 0;
  for (int i = 0; i < l0; i++) {
    int c1 = p1[i] & 0xFF;
    int c2 = p2[i] & 0xFF;
    if (c1 != c2) {
      // Before returning the obvious answer,
      // check to see if c1 or c2 is part of a 0x0000,
      // which encodes as {0xC0,0x80}.  The 0x0000 is the
      // lowest-sorting Java char value, and yet it encodes
      // as if it were the first char after 0x7F, which causes
      // strings containing nulls to sort too high.  All other
      // comparisons are consistent between Utf8 and Java chars.
      if (c1 == 0xC0 && (p1[i+1] & 0xFF) == 0x80)  c1 = 0;
      if (c2 == 0xC0 && (p2[i+1] & 0xFF) == 0x80)  c2 = 0;
      if (c0 == 0xC0) {
        assert(((c1|c2) & 0xC0) == 0x80);  // c1 & c2 are extension chars
        if (c1 == 0x80)  c1 = 0;  // will sort below c2
        if (c2 == 0x80)  c2 = 0;  // will sort below c1
      }
      return c1 - c2;
    }
    c0 = c1;  // save away previous char
  }
  // common prefix is identical; return length difference if any
  return l1 - l2;
}

// Cf. PackageReader.readUtf8Bands
local_inline
void unpacker::read_Utf8_values(entry* cpMap, int len) {
  // Implicit first Utf8 string is the empty string.
  enum {
    // certain bands begin with implicit zeroes
    PREFIX_SKIP_2 = 2,
    SUFFIX_SKIP_1 = 1
  };

  int i;

  // First band:  Read lengths of shared prefixes.
  if (len > PREFIX_SKIP_2)
    cp_Utf8_prefix.readData(len - PREFIX_SKIP_2);

  // Second band:  Read lengths of unshared suffixes:
  if (len > SUFFIX_SKIP_1)
    cp_Utf8_suffix.readData(len - SUFFIX_SKIP_1);

  bytes* allsuffixes = T_NEW(bytes, len);
  CHECK;

  int nbigsuf = 0;
  fillbytes charbuf;    // buffer to allocate small strings
  charbuf.init();

  // Third band:  Read the char values in the unshared suffixes:
  cp_Utf8_chars.readData(cp_Utf8_suffix.getIntTotal());
  for (i = 0; i < len; i++) {
    int suffix = (i < SUFFIX_SKIP_1)? 0: cp_Utf8_suffix.getInt();
    if (suffix < 0) {
      abort("bad utf8 suffix");
      return;
    }
    if (suffix == 0 && i >= SUFFIX_SKIP_1) {
      // chars are packed in cp_Utf8_big_chars
      nbigsuf += 1;
      continue;
    }
    bytes& chars  = allsuffixes[i];
    uint size3    = suffix * 3;     // max Utf8 length
    bool isMalloc = (suffix > SMALL);
    if (isMalloc) {
      chars.malloc(size3);
    } else {
      if (!charbuf.canAppend(size3+1)) {
        assert(charbuf.allocated == 0 || tmallocs.contains(charbuf.base()));
        charbuf.init(CHUNK);  // Reset to new buffer.
        tmallocs.add(charbuf.base());
      }
      chars.set(charbuf.grow(size3+1), size3);
    }
    CHECK;
    byte* chp = chars.ptr;
    for (int j = 0; j < suffix; j++) {
      unsigned short ch = cp_Utf8_chars.getInt();
      chp = store_Utf8_char(chp, ch);
    }
    // shrink to fit:
    if (isMalloc) {
      chars.realloc(chp - chars.ptr);
      CHECK;
      tmallocs.add(chars.ptr); // free it later
    } else {
      int shrink = chars.limit() - chp;
      chars.len -= shrink;
      charbuf.b.len -= shrink;  // ungrow to reclaim buffer space
      // Note that we did not reclaim the final '\0'.
      assert(chars.limit() == charbuf.limit()-1);
      assert(strlen((char*)chars.ptr) == chars.len);
    }
  }
  //cp_Utf8_chars.done();
  if (assert(1))  charbuf.b.set(null, 0); // tidy

  // Fourth band:  Go back and size the specially packed strings.
  int maxlen = 0;
  cp_Utf8_big_suffix.readData(nbigsuf);
  cp_Utf8_suffix.rewind();
  for (i = 0; i < len; i++) {
    int suffix = (i < SUFFIX_SKIP_1)? 0: cp_Utf8_suffix.getInt();
    int prefix = (i < PREFIX_SKIP_2)? 0: cp_Utf8_prefix.getInt();
    if (prefix < 0 || prefix+suffix < 0) {
       abort("bad utf8 prefix");
       return;
    }
    bytes& chars = allsuffixes[i];
    if (suffix == 0 && i >= SUFFIX_SKIP_1) {
      suffix = cp_Utf8_big_suffix.getInt();
      assert(chars.ptr == null);
      chars.len = suffix;  // just a momentary hack
    } else {
      assert(chars.ptr != null);
    }
    if (maxlen < prefix + suffix) {
      maxlen = prefix + suffix;
    }
  }
  //cp_Utf8_suffix.done();      // will use allsuffixes[i].len (ptr!=null)
  //cp_Utf8_big_suffix.done();  // will use allsuffixes[i].len

  // Fifth band(s):  Get the specially packed characters.
  cp_Utf8_big_suffix.rewind();
  for (i = 0; i < len; i++) {
    bytes& chars = allsuffixes[i];
    if (chars.ptr != null)  continue;  // already input
    int suffix = chars.len;  // pick up the hack
    uint size3 = suffix * 3;
    if (suffix == 0)  continue;  // done with empty string
    chars.malloc(size3);
    byte* chp = chars.ptr;
    band saved_band = cp_Utf8_big_chars;
    cp_Utf8_big_chars.readData(suffix);
    for (int j = 0; j < suffix; j++) {
      unsigned short ch = cp_Utf8_big_chars.getInt();
      chp = store_Utf8_char(chp, ch);
    }
    chars.realloc(chp - chars.ptr);
    CHECK;
    tmallocs.add(chars.ptr);  // free it later
    //cp_Utf8_big_chars.done();
    cp_Utf8_big_chars = saved_band;  // reset the band for the next string
  }
  cp_Utf8_big_chars.readData(0);  // zero chars
  //cp_Utf8_big_chars.done();

  // Finally, sew together all the prefixes and suffixes.
  bytes bigbuf;
  bigbuf.malloc(maxlen * 3 + 1);  // max Utf8 length, plus slop for null
  CHECK;
  int prevlen = 0;  // previous string length (in chars)
  tmallocs.add(bigbuf.ptr);  // free after this block
  cp_Utf8_prefix.rewind();
  for (i = 0; i < len; i++) {
    bytes& chars = allsuffixes[i];
    int prefix = (i < PREFIX_SKIP_2)? 0: cp_Utf8_prefix.getInt();
    int suffix = chars.len;
    byte* fillp;
    // by induction, the buffer is already filled with the prefix
    // make sure the prefix value is not corrupted, though:
    if (prefix > prevlen) {
       abort("utf8 prefix overflow");
       return;
    }
    fillp = skip_Utf8_chars(bigbuf.ptr, prefix);
    // copy the suffix into the same buffer:
    fillp = chars.writeTo(fillp);
    assert(bigbuf.inBounds(fillp));
    *fillp = 0;  // bigbuf must contain a well-formed Utf8 string
    int length = fillp - bigbuf.ptr;
    bytes& value = cpMap[i].value.b;
    value.set(U_NEW(byte, length+1), length);
    value.copyFrom(bigbuf.ptr, length);
    CHECK;
    // Index all Utf8 strings
    entry* &htref = cp.hashTabRef(CONSTANT_Utf8, value);
    if (htref == null) {
      // Note that if two identical strings are transmitted,
      // the first is taken to be the canonical one.
      htref = &cpMap[i];
    }
    prevlen = prefix + suffix;
  }
  //cp_Utf8_prefix.done();

  // Free intermediate buffers.
  free_temps();
}

local_inline
void unpacker::read_single_words(band& cp_band, entry* cpMap, int len) {
  cp_band.readData(len);
  for (int i = 0; i < len; i++) {
    cpMap[i].value.i = cp_band.getInt();  // coding handles signs OK
  }
}

maybe_inline
void unpacker::read_double_words(band& cp_bands, entry* cpMap, int len) {
  band& cp_band_hi = cp_bands;
  band& cp_band_lo = cp_bands.nextBand();
  cp_band_hi.readData(len);
  cp_band_lo.readData(len);
  for (int i = 0; i < len; i++) {
    cpMap[i].value.l = cp_band_hi.getLong(cp_band_lo, true);
  }
  //cp_band_hi.done();
  //cp_band_lo.done();
}

maybe_inline
void unpacker::read_single_refs(band& cp_band, byte refTag, entry* cpMap, int len) {
  assert(refTag == CONSTANT_Utf8);
  cp_band.setIndexByTag(refTag);
  cp_band.readData(len);
  CHECK;
  int indexTag = (cp_band.bn == e_cp_Class) ? CONSTANT_Class : 0;
  for (int i = 0; i < len; i++) {
    entry& e = cpMap[i];
    e.refs = U_NEW(entry*, e.nrefs = 1);
    entry* utf = cp_band.getRef();
    CHECK;
    e.refs[0] = utf;
    e.value.b = utf->value.b;  // copy value of Utf8 string to self
    if (indexTag != 0) {
      // Maintain cross-reference:
      entry* &htref = cp.hashTabRef(indexTag, e.value.b);
      if (htref == null) {
        // Note that if two identical classes are transmitted,
        // the first is taken to be the canonical one.
        htref = &e;
      }
    }
  }
  //cp_band.done();
}

maybe_inline
void unpacker::read_double_refs(band& cp_band, byte ref1Tag, byte ref2Tag,
                                entry* cpMap, int len) {
  band& cp_band1 = cp_band;
  band& cp_band2 = cp_band.nextBand();
  cp_band1.setIndexByTag(ref1Tag);
  cp_band2.setIndexByTag(ref2Tag);
  cp_band1.readData(len);
  cp_band2.readData(len);
  CHECK;
  for (int i = 0; i < len; i++) {
    entry& e = cpMap[i];
    e.refs = U_NEW(entry*, e.nrefs = 2);
    e.refs[0] = cp_band1.getRef();
    e.refs[1] = cp_band2.getRef();
    CHECK;
  }
  //cp_band1.done();
  //cp_band2.done();
}

// Cf. PackageReader.readSignatureBands
maybe_inline
void unpacker::read_signature_values(entry* cpMap, int len) {
  cp_Signature_form.setIndexByTag(CONSTANT_Utf8);
  cp_Signature_form.readData(len);
  CHECK;
  int ncTotal = 0;
  int i;
  for (i = 0; i < len; i++) {
    entry& e = cpMap[i];
    entry& form = *cp_Signature_form.getRef();
    CHECK;
    int nc = 0;

    for ( const char* ncp = form.utf8String() ; *ncp; ncp++) {
      if (*ncp == 'L')  nc++;
    }

    ncTotal += nc;
    e.refs = U_NEW(entry*, cpMap[i].nrefs = 1 + nc);
    CHECK;
    e.refs[0] = &form;
  }
  //cp_Signature_form.done();
  cp_Signature_classes.setIndexByTag(CONSTANT_Class);
  cp_Signature_classes.readData(ncTotal);
  for (i = 0; i < len; i++) {
    entry& e = cpMap[i];
    for (int j = 1; j < e.nrefs; j++) {
      e.refs[j] = cp_Signature_classes.getRef();
      CHECK;
    }
  }
  //cp_Signature_classes.done();
}

// Cf. PackageReader.readConstantPool
void unpacker::read_cp() {
  byte* rp0 = rp;

  int i;

  for (int k = 0; k < N_TAGS_IN_ORDER; k++) {
    byte tag = TAGS_IN_ORDER[k];
    int  len = cp.tag_count[tag];
    int base = cp.tag_base[tag];

    printcr(1,"Reading %d %s entries...", len, NOT_PRODUCT(TAG_NAME[tag])+0);
    entry* cpMap = &cp.entries[base];
    for (i = 0; i < len; i++) {
      cpMap[i].tag = tag;
      cpMap[i].inord = i;
    }

    switch (tag) {
    case CONSTANT_Utf8:
      read_Utf8_values(cpMap, len);
      break;
    case CONSTANT_Integer:
      read_single_words(cp_Int, cpMap, len);
      break;
    case CONSTANT_Float:
      read_single_words(cp_Float, cpMap, len);
      break;
    case CONSTANT_Long:
      read_double_words(cp_Long_hi /*& cp_Long_lo*/, cpMap, len);
      break;
    case CONSTANT_Double:
      read_double_words(cp_Double_hi /*& cp_Double_lo*/, cpMap, len);
      break;
    case CONSTANT_String:
      read_single_refs(cp_String, CONSTANT_Utf8, cpMap, len);
      break;
    case CONSTANT_Class:
      read_single_refs(cp_Class, CONSTANT_Utf8, cpMap, len);
      break;
    case CONSTANT_Signature:
      read_signature_values(cpMap, len);
      break;
    case CONSTANT_NameandType:
      read_double_refs(cp_Descr_name /*& cp_Descr_type*/,
                       CONSTANT_Utf8, CONSTANT_Signature,
                       cpMap, len);
      break;
    case CONSTANT_Fieldref:
      read_double_refs(cp_Field_class /*& cp_Field_desc*/,
                       CONSTANT_Class, CONSTANT_NameandType,
                       cpMap, len);
      break;
    case CONSTANT_Methodref:
      read_double_refs(cp_Method_class /*& cp_Method_desc*/,
                       CONSTANT_Class, CONSTANT_NameandType,
                       cpMap, len);
      break;
    case CONSTANT_InterfaceMethodref:
      read_double_refs(cp_Imethod_class /*& cp_Imethod_desc*/,
                       CONSTANT_Class, CONSTANT_NameandType,
                       cpMap, len);
      break;
    default:
      assert(false);
      break;
    }

    // Initialize the tag's CP index right away, since it might be needed
    // in the next pass to initialize the CP for another tag.
#ifndef PRODUCT
    cpindex* ix = &cp.tag_index[tag];
    assert(ix->ixTag == tag);
    assert(ix->len   == len);
    assert(ix->base1 == cpMap);
#endif
    CHECK;
  }

  cp.expandSignatures();
  CHECK;
  cp.initMemberIndexes();
  CHECK;

  printcr(1,"parsed %d constant pool entries in %d bytes", cp.nentries, (rp - rp0));

  #define SNAME(n,s) #s "\0"
  const char* symNames = (
    ALL_ATTR_DO(SNAME)
    "<init>"
  );
  #undef SNAME

  for (int sn = 0; sn < cpool::s_LIMIT; sn++) {
    assert(symNames[0] >= '0' && symNames[0] <= 'Z');  // sanity
    bytes name; name.set(symNames);
    if (name.len > 0 && name.ptr[0] != '0') {
      cp.sym[sn] = cp.ensureUtf8(name);
      printcr(4, "well-known sym %d=%s", sn, cp.sym[sn]->string());
    }
    symNames += name.len + 1;  // skip trailing null to next name
  }

  band::initIndexes(this);
}

static band* no_bands[] = { null };  // shared empty body

inline
band& unpacker::attr_definitions::fixed_band(int e_class_xxx) {
  return u->all_bands[xxx_flags_hi_bn + (e_class_xxx-e_class_flags_hi)];
}
inline band& unpacker::attr_definitions::xxx_flags_hi()
  { return fixed_band(e_class_flags_hi); }
inline band& unpacker::attr_definitions::xxx_flags_lo()
  { return fixed_band(e_class_flags_lo); }
inline band& unpacker::attr_definitions::xxx_attr_count()
  { return fixed_band(e_class_attr_count); }
inline band& unpacker::attr_definitions::xxx_attr_indexes()
  { return fixed_band(e_class_attr_indexes); }
inline band& unpacker::attr_definitions::xxx_attr_calls()
  { return fixed_band(e_class_attr_calls); }


inline
unpacker::layout_definition*
unpacker::attr_definitions::defineLayout(int idx,
                                         entry* nameEntry,
                                         const char* layout) {
  const char* name = nameEntry->value.b.strval();
  layout_definition* lo = defineLayout(idx, name, layout);
  CHECK_0;
  lo->nameEntry = nameEntry;
  return lo;
}

unpacker::layout_definition*
unpacker::attr_definitions::defineLayout(int idx,
                                         const char* name,
                                         const char* layout) {
  assert(flag_limit != 0);  // must be set up already
  if (idx >= 0) {
    // Fixed attr.
    if (idx >= flag_limit)
      abort("attribute index too large");
    if (isRedefined(idx))
      abort("redefined attribute index");
    redef |= ((julong)1<<idx);
  } else {
    idx = flag_limit + overflow_count.length();
    overflow_count.add(0);  // make a new counter
  }
  layout_definition* lo = U_NEW(layout_definition, 1);
  CHECK_0;
  lo->idx = idx;
  lo->name = name;
  lo->layout = layout;
  for (int adds = (idx+1) - layouts.length(); adds > 0; adds--) {
    layouts.add(null);
  }
  CHECK_0;
  layouts.get(idx) = lo;
  return lo;
}

band**
unpacker::attr_definitions::buildBands(unpacker::layout_definition* lo) {
  int i;
  if (lo->elems != null)
    return lo->bands();
  if (lo->layout[0] == '\0') {
    lo->elems = no_bands;
  } else {
    // Create bands for this attribute by parsing the layout.
    bool hasCallables = lo->hasCallables();
    bands_made = 0x10000;  // base number for bands made
    const char* lp = lo->layout;
    lp = parseLayout(lp, lo->elems, -1);
    CHECK_0;
    if (lp[0] != '\0' || band_stack.length() > 0) {
      abort("garbage at end of layout");
    }
    band_stack.popTo(0);
    CHECK_0;

    // Fix up callables to point at their callees.
    band** bands = lo->elems;
    assert(bands == lo->bands());
    int num_callables = 0;
    if (hasCallables) {
      while (bands[num_callables] != null) {
        if (bands[num_callables]->le_kind != EK_CBLE) {
          abort("garbage mixed with callables");
          break;
        }
        num_callables += 1;
      }
    }
    for (i = 0; i < calls_to_link.length(); i++) {
      band& call = *(band*) calls_to_link.get(i);
      assert(call.le_kind == EK_CALL);
      // Determine the callee.
      int call_num = call.le_len;
      if (call_num < 0 || call_num >= num_callables) {
        abort("bad call in layout");
        break;
      }
      band& cble = *bands[call_num];
      // Link the call to it.
      call.le_body[0] = &cble;
      // Distinguish backward calls and callables:
      assert(cble.le_kind == EK_CBLE);
      assert(cble.le_len == call_num);
      cble.le_back |= call.le_back;
    }
    calls_to_link.popTo(0);
  }
  return lo->elems;
}

/* attribute layout language parser

  attribute_layout:
        ( layout_element )* | ( callable )+
  layout_element:
        ( integral | replication | union | call | reference )

  callable:
        '[' body ']'
  body:
        ( layout_element )+

  integral:
        ( unsigned_int | signed_int | bc_index | bc_offset | flag )
  unsigned_int:
        uint_type
  signed_int:
        'S' uint_type
  any_int:
        ( unsigned_int | signed_int )
  bc_index:
        ( 'P' uint_type | 'PO' uint_type )
  bc_offset:
        'O' any_int
  flag:
        'F' uint_type
  uint_type:
        ( 'B' | 'H' | 'I' | 'V' )

  replication:
        'N' uint_type '[' body ']'

  union:
        'T' any_int (union_case)* '(' ')' '[' (body)? ']'
  union_case:
        '(' union_case_tag (',' union_case_tag)* ')' '[' (body)? ']'
  union_case_tag:
        ( numeral | numeral '-' numeral )
  call:
        '(' numeral ')'

  reference:
        reference_type ( 'N' )? uint_type
  reference_type:
        ( constant_ref | schema_ref | utf8_ref | untyped_ref )
  constant_ref:
        ( 'KI' | 'KJ' | 'KF' | 'KD' | 'KS' | 'KQ' )
  schema_ref:
        ( 'RC' | 'RS' | 'RD' | 'RF' | 'RM' | 'RI' )
  utf8_ref:
        'RU'
  untyped_ref:
        'RQ'

  numeral:
        '(' ('-')? (digit)+ ')'
  digit:
        ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )

*/

const char*
unpacker::attr_definitions::parseIntLayout(const char* lp, band* &res,
                                           byte le_kind, bool can_be_signed) {
  const char* lp0 = lp;
  band* b = U_NEW(band, 1);
  CHECK_(lp);
  char le = *lp++;
  int spec = UNSIGNED5_spec;
  if (le == 'S' && can_be_signed) {
    // Note:  This is the last use of sign.  There is no 'EF_SIGN'.
    spec = SIGNED5_spec;
    le = *lp++;
  } else if (le == 'B') {
    spec = BYTE1_spec;  // unsigned byte
  }
  b->init(u, bands_made++, spec);
  b->le_kind = le_kind;
  int le_len = 0;
  switch (le) {
  case 'B': le_len = 1; break;
  case 'H': le_len = 2; break;
  case 'I': le_len = 4; break;
  case 'V': le_len = 0; break;
  default:  abort("bad layout element");
  }
  b->le_len = le_len;
  band_stack.add(b);
  res = b;
  return lp;
}

const char*
unpacker::attr_definitions::parseNumeral(const char* lp, int &res) {
  const char* lp0 = lp;
  bool sgn = false;
  if (*lp == '0') { res = 0; return lp+1; }  // special case '0'
  if (*lp == '-') { sgn = true; lp++; }
  const char* dp = lp;
  int con = 0;
  while (*dp >= '0' && *dp <= '9') {
    int con0 = con;
    con *= 10;
    con += (*dp++) - '0';
    if (con <= con0) { con = -1; break; }  //  numeral overflow
  }
  if (lp == dp) {
    abort("missing numeral in layout");
    return "";
  }
  lp = dp;
  if (con < 0 && !(sgn && con == -con)) {
    // (Portability note:  Misses the error if int is not 32 bits.)
    abort("numeral overflow");
    return "" ;
  }
  if (sgn)  con = -con;
  res = con;
  return lp;
}

band**
unpacker::attr_definitions::popBody(int bs_base) {
  // Return everything that was pushed, as a null-terminated pointer array.
  int bs_limit = band_stack.length();
  if (bs_base == bs_limit) {
    return no_bands;
  } else {
    int nb = bs_limit - bs_base;
    band** res = U_NEW(band*, nb+1);
    CHECK_(no_bands);
    for (int i = 0; i < nb; i++) {
      band* b = (band*) band_stack.get(bs_base + i);
      res[i] = b;
    }
    band_stack.popTo(bs_base);
    return res;
  }
}

const char*
unpacker::attr_definitions::parseLayout(const char* lp, band** &res,
                                        int curCble) {
  const char* lp0 = lp;
  int bs_base = band_stack.length();
  bool top_level = (bs_base == 0);
  band* b;
  enum { can_be_signed = true };  // optional arg to parseIntLayout

  for (bool done = false; !done; ) {
    switch (*lp++) {
    case 'B': case 'H': case 'I': case 'V': // unsigned_int
    case 'S': // signed_int
      --lp;  // reparse
    case 'F':
      lp = parseIntLayout(lp, b, EK_INT);
      break;
    case 'P':
      {
        int le_bci = EK_BCI;
        if (*lp == 'O') {
          ++lp;
          le_bci = EK_BCID;
        }
        assert(*lp != 'S');  // no PSH, etc.
        lp = parseIntLayout(lp, b, EK_INT);
        b->le_bci = le_bci;
        if (le_bci == EK_BCI)
          b->defc = coding::findBySpec(BCI5_spec);
        else
          b->defc = coding::findBySpec(BRANCH5_spec);
      }
      break;
    case 'O':
      lp = parseIntLayout(lp, b, EK_INT, can_be_signed);
      b->le_bci = EK_BCO;
      b->defc = coding::findBySpec(BRANCH5_spec);
      break;
    case 'N': // replication: 'N' uint '[' elem ... ']'
      lp = parseIntLayout(lp, b, EK_REPL);
      assert(*lp == '[');
      ++lp;
      lp = parseLayout(lp, b->le_body, curCble);
      CHECK_(lp);
      break;
    case 'T': // union: 'T' any_int union_case* '(' ')' '[' body ']'
      lp = parseIntLayout(lp, b, EK_UN, can_be_signed);
      {
        int union_base = band_stack.length();
        for (;;) {   // for each case
          band& k_case = *U_NEW(band, 1);
          CHECK_(lp);
          band_stack.add(&k_case);
          k_case.le_kind = EK_CASE;
          k_case.bn = bands_made++;
          if (*lp++ != '(') {
            abort("bad union case");
            return "";
          }
          if (*lp++ != ')') {
            --lp;  // reparse
            // Read some case values.  (Use band_stack for temp. storage.)
            int case_base = band_stack.length();
            for (;;) {
              int caseval = 0;
              lp = parseNumeral(lp, caseval);
              band_stack.add((void*)caseval);
              if (*lp == '-') {
                // new in version 160, allow (1-5) for (1,2,3,4,5)
                if (u->majver < JAVA6_PACKAGE_MAJOR_VERSION) {
                  abort("bad range in union case label (old archive format)");
                  return "";
                }
                int caselimit = caseval;
                lp++;
                lp = parseNumeral(lp, caselimit);
                if (caseval >= caselimit
                    || (uint)(caselimit - caseval) > 0x10000) {
                  // Note:  0x10000 is arbitrary implementation restriction.
                  // We can remove it later if it's important to.
                  abort("bad range in union case label");
                  return "";
                }
                for (;;) {
                  ++caseval;
                  band_stack.add((void*)caseval);
                  if (caseval == caselimit)  break;
                }
              }
              if (*lp != ',')  break;
              lp++;
            }
            if (*lp++ != ')') {
              abort("bad case label");
              return "";
            }
            // save away the case labels
            int ntags = band_stack.length() - case_base;
            int* tags = U_NEW(int, 1+ntags);
            CHECK_(lp);
            k_case.le_casetags = tags;
            *tags++ = ntags;
            for (int i = 0; i < ntags; i++) {
              *tags++ = ptrlowbits(band_stack.get(case_base+i));
            }
            band_stack.popTo(case_base);
            CHECK_(lp);
          }
          // Got le_casetags.  Now grab the body.
          assert(*lp == '[');
          ++lp;
          lp = parseLayout(lp, k_case.le_body, curCble);
          CHECK_(lp);
          if (k_case.le_casetags == null)  break;  // done
        }
        b->le_body = popBody(union_base);
      }
      break;
    case '(': // call: '(' -?NN* ')'
      {
        band& call = *U_NEW(band, 1);
        CHECK_(lp);
        band_stack.add(&call);
        call.le_kind = EK_CALL;
        call.bn = bands_made++;
        call.le_body = U_NEW(band*, 2); // fill in later
        int call_num = 0;
        lp = parseNumeral(lp, call_num);
        call.le_back = (call_num <= 0);
        call_num += curCble;  // numeral is self-relative offset
        call.le_len = call_num;  //use le_len as scratch
        calls_to_link.add(&call);
        CHECK_(lp);
        if (*lp++ != ')') {
          abort("bad call label");
          return "";
        }
      }
      break;
    case 'K': // reference_type: constant_ref
    case 'R': // reference_type: schema_ref
      {
        int ixTag = CONSTANT_None;
        if (lp[-1] == 'K') {
          switch (*lp++) {
          case 'I': ixTag = CONSTANT_Integer; break;
          case 'J': ixTag = CONSTANT_Long; break;
          case 'F': ixTag = CONSTANT_Float; break;
          case 'D': ixTag = CONSTANT_Double; break;
          case 'S': ixTag = CONSTANT_String; break;
          case 'Q': ixTag = CONSTANT_Literal; break;
          }
        } else {
          switch (*lp++) {
          case 'C': ixTag = CONSTANT_Class; break;
          case 'S': ixTag = CONSTANT_Signature; break;
          case 'D': ixTag = CONSTANT_NameandType; break;
          case 'F': ixTag = CONSTANT_Fieldref; break;
          case 'M': ixTag = CONSTANT_Methodref; break;
          case 'I': ixTag = CONSTANT_InterfaceMethodref; break;
          case 'U': ixTag = CONSTANT_Utf8; break; //utf8_ref
          case 'Q': ixTag = CONSTANT_All; break; //untyped_ref
          }
        }
        if (ixTag == CONSTANT_None) {
          abort("bad reference layout");
          break;
        }
        bool nullOK = false;
        if (*lp == 'N') {
          nullOK = true;
          lp++;
        }
        lp = parseIntLayout(lp, b, EK_REF);
        b->defc = coding::findBySpec(UNSIGNED5_spec);
        b->initRef(ixTag, nullOK);
      }
      break;
    case '[':
      {
        // [callable1][callable2]...
        if (!top_level) {
          abort("bad nested callable");
          break;
        }
        curCble += 1;
        NOT_PRODUCT(int call_num = band_stack.length() - bs_base);
        band& cble = *U_NEW(band, 1);
        CHECK_(lp);
        band_stack.add(&cble);
        cble.le_kind = EK_CBLE;
        NOT_PRODUCT(cble.le_len = call_num);
        cble.bn = bands_made++;
        lp = parseLayout(lp, cble.le_body, curCble);
      }
      break;
    case ']':
      // Hit a closing brace.  This ends whatever body we were in.
      done = true;
      break;
    case '\0':
      // Hit a null.  Also ends the (top-level) body.
      --lp;  // back up, so caller can see the null also
      done = true;
      break;
    default:
      abort("bad layout");
      break;
    }
    CHECK_(lp);
  }

  // Return the accumulated bands:
  res = popBody(bs_base);
  return lp;
}

void unpacker::read_attr_defs() {
  int i;

  // Tell each AD which attrc it is and where its fixed flags are:
  attr_defs[ATTR_CONTEXT_CLASS].attrc            = ATTR_CONTEXT_CLASS;
  attr_defs[ATTR_CONTEXT_CLASS].xxx_flags_hi_bn  = e_class_flags_hi;
  attr_defs[ATTR_CONTEXT_FIELD].attrc            = ATTR_CONTEXT_FIELD;
  attr_defs[ATTR_CONTEXT_FIELD].xxx_flags_hi_bn  = e_field_flags_hi;
  attr_defs[ATTR_CONTEXT_METHOD].attrc           = ATTR_CONTEXT_METHOD;
  attr_defs[ATTR_CONTEXT_METHOD].xxx_flags_hi_bn = e_method_flags_hi;
  attr_defs[ATTR_CONTEXT_CODE].attrc             = ATTR_CONTEXT_CODE;
  attr_defs[ATTR_CONTEXT_CODE].xxx_flags_hi_bn   = e_code_flags_hi;

  // Decide whether bands for the optional high flag words are present.
  attr_defs[ATTR_CONTEXT_CLASS]
    .setHaveLongFlags((archive_options & AO_HAVE_CLASS_FLAGS_HI) != 0);
  attr_defs[ATTR_CONTEXT_FIELD]
    .setHaveLongFlags((archive_options & AO_HAVE_FIELD_FLAGS_HI) != 0);
  attr_defs[ATTR_CONTEXT_METHOD]
    .setHaveLongFlags((archive_options & AO_HAVE_METHOD_FLAGS_HI) != 0);
  attr_defs[ATTR_CONTEXT_CODE]
    .setHaveLongFlags((archive_options & AO_HAVE_CODE_FLAGS_HI) != 0);

  // Set up built-in attrs.
  // (The simple ones are hard-coded.  The metadata layouts are not.)
  const char* md_layout = (
    // parameter annotations:
#define MDL0 \
    "[NB[(1)]]"
    MDL0
    // annotations:
#define MDL1 \
    "[NH[(1)]]" \
    "[RSHNH[RUH(1)]]"
    MDL1
    // member_value:
    "[TB"
      "(66,67,73,83,90)[KIH]"
      "(68)[KDH]"
      "(70)[KFH]"
      "(74)[KJH]"
      "(99)[RSH]"
      "(101)[RSHRUH]"
      "(115)[RUH]"
      "(91)[NH[(0)]]"
      "(64)["
        // nested annotation:
        "RSH"
        "NH[RUH(0)]"
        "]"
      "()[]"
    "]"
    );

  const char* md_layout_P = md_layout;
  const char* md_layout_A = md_layout+strlen(MDL0);
  const char* md_layout_V = md_layout+strlen(MDL0 MDL1);
  assert(0 == strncmp(&md_layout_A[-3], ")]][", 4));
  assert(0 == strncmp(&md_layout_V[-3], ")]][", 4));

  for (i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
    attr_definitions& ad = attr_defs[i];
    ad.defineLayout(X_ATTR_RuntimeVisibleAnnotations,
                    "RuntimeVisibleAnnotations", md_layout_A);
    ad.defineLayout(X_ATTR_RuntimeInvisibleAnnotations,
                    "RuntimeInvisibleAnnotations", md_layout_A);
    if (i != ATTR_CONTEXT_METHOD)  continue;
    ad.defineLayout(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
                    "RuntimeVisibleParameterAnnotations", md_layout_P);
    ad.defineLayout(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
                    "RuntimeInvisibleParameterAnnotations", md_layout_P);
    ad.defineLayout(METHOD_ATTR_AnnotationDefault,
                    "AnnotationDefault", md_layout_V);
  }

  attr_definition_headers.readData(attr_definition_count);
  attr_definition_name.readData(attr_definition_count);
  attr_definition_layout.readData(attr_definition_count);

  CHECK;

  // Initialize correct predef bits, to distinguish predefs from new defs.
#define ORBIT(n,s) |((julong)1<<n)
  attr_defs[ATTR_CONTEXT_CLASS].predef
    = (0 X_ATTR_DO(ORBIT) CLASS_ATTR_DO(ORBIT));
  attr_defs[ATTR_CONTEXT_FIELD].predef
    = (0 X_ATTR_DO(ORBIT) FIELD_ATTR_DO(ORBIT));
  attr_defs[ATTR_CONTEXT_METHOD].predef
    = (0 X_ATTR_DO(ORBIT) METHOD_ATTR_DO(ORBIT));
  attr_defs[ATTR_CONTEXT_CODE].predef
    = (0 O_ATTR_DO(ORBIT) CODE_ATTR_DO(ORBIT));
#undef ORBIT
  // Clear out the redef bits, folding them back into predef.
  for (i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
    attr_defs[i].predef |= attr_defs[i].redef;
    attr_defs[i].redef = 0;
  }

  // Now read the transmitted locally defined attrs.
  // This will set redef bits again.
  for (i = 0; i < attr_definition_count; i++) {
    int    header  = attr_definition_headers.getByte();
    int    attrc   = ADH_BYTE_CONTEXT(header);
    int    idx     = ADH_BYTE_INDEX(header);
    entry* name    = attr_definition_name.getRef();
    entry* layout  = attr_definition_layout.getRef();
    CHECK;
    attr_defs[attrc].defineLayout(idx, name, layout->value.b.strval());
  }
}

#define NO_ENTRY_YET ((entry*)-1)

static bool isDigitString(bytes& x, int beg, int end) {
  if (beg == end)  return false;  // null string
  byte* xptr = x.ptr;
  for (int i = beg; i < end; i++) {
    char ch = xptr[i];
    if (!(ch >= '0' && ch <= '9'))  return false;
  }
  return true;
}

enum {  // constants for parsing class names
  SLASH_MIN = '.',
  SLASH_MAX = '/',
  DOLLAR_MIN = 0,
  DOLLAR_MAX = '-'
};

static int lastIndexOf(int chmin, int chmax, bytes& x, int pos) {
  byte* ptr = x.ptr;
  for (byte* cp = ptr + pos; --cp >= ptr; ) {
    assert(x.inBounds(cp));
    if (*cp >= chmin && *cp <= chmax)
      return cp - ptr;
  }
  return -1;
}

maybe_inline
inner_class* cpool::getIC(entry* inner) {
  if (inner == null)  return null;
  assert(inner->tag == CONSTANT_Class);
  if (inner->inord == NO_INORD)  return null;
  inner_class* ic = ic_index[inner->inord];
  assert(ic == null || ic->inner == inner);
  return ic;
}

maybe_inline
inner_class* cpool::getFirstChildIC(entry* outer) {
  if (outer == null)  return null;
  assert(outer->tag == CONSTANT_Class);
  if (outer->inord == NO_INORD)  return null;
  inner_class* ic = ic_child_index[outer->inord];
  assert(ic == null || ic->outer == outer);
  return ic;
}

maybe_inline
inner_class* cpool::getNextChildIC(inner_class* child) {
  inner_class* ic = child->next_sibling;
  assert(ic == null || ic->outer == child->outer);
  return ic;
}

void unpacker::read_ics() {
  int i;
  int index_size = cp.tag_count[CONSTANT_Class];
  inner_class** ic_index       = U_NEW(inner_class*, index_size);
  inner_class** ic_child_index = U_NEW(inner_class*, index_size);
  cp.ic_index = ic_index;
  cp.ic_child_index = ic_child_index;
  ics = U_NEW(inner_class, ic_count);
  ic_this_class.readData(ic_count);
  ic_flags.readData(ic_count);
  CHECK;
  // Scan flags to get count of long-form bands.
  int long_forms = 0;
  for (i = 0; i < ic_count; i++) {
    int flags = ic_flags.getInt();  // may be long form!
    if ((flags & ACC_IC_LONG_FORM) != 0) {
      long_forms += 1;
      ics[i].name = NO_ENTRY_YET;
    }
    flags &= ~ACC_IC_LONG_FORM;
    entry* inner = ic_this_class.getRef();
    CHECK;
    uint inord = inner->inord;
    assert(inord < cp.tag_count[CONSTANT_Class]);
    if (ic_index[inord] != null) {
      abort("identical inner class");
      break;
    }
    ic_index[inord] = &ics[i];
    ics[i].inner = inner;
    ics[i].flags = flags;
    assert(cp.getIC(inner) == &ics[i]);
  }
  CHECK;
  //ic_this_class.done();
  //ic_flags.done();
  ic_outer_class.readData(long_forms);
  ic_name.readData(long_forms);
  for (i = 0; i < ic_count; i++) {
    if (ics[i].name == NO_ENTRY_YET) {
      // Long form.
      ics[i].outer = ic_outer_class.getRefN();
      ics[i].name  = ic_name.getRefN();
    } else {
      // Fill in outer and name based on inner.
      bytes& n = ics[i].inner->value.b;
      bytes pkgOuter;
      bytes number;
      bytes name;
      // Parse n into pkgOuter and name (and number).
      printcr(5, "parse short IC name %s", n.ptr);
      int dollar1, dollar2;  // pointers to $ in the pattern
      // parse n = (<pkg>/)*<outer>($<number>)?($<name>)?
      int nlen = n.len;
      int pkglen = lastIndexOf(SLASH_MIN,  SLASH_MAX,  n, nlen) + 1;
      dollar2    = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, nlen);
      if (dollar2 < 0) {
         abort();
         return;
      }
      assert(dollar2 >= pkglen);
      if (isDigitString(n, dollar2+1, nlen)) {
        // n = (<pkg>/)*<outer>$<number>
        number = n.slice(dollar2+1, nlen);
        name.set(null,0);
        dollar1 = dollar2;
      } else if (pkglen < (dollar1
                           = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, dollar2-1))
                 && isDigitString(n, dollar1+1, dollar2)) {
        // n = (<pkg>/)*<outer>$<number>$<name>
        number = n.slice(dollar1+1, dollar2);
        name = n.slice(dollar2+1, nlen);
      } else {
        // n = (<pkg>/)*<outer>$<name>
        dollar1 = dollar2;
        number.set(null,0);
        name = n.slice(dollar2+1, nlen);
      }
      if (number.ptr == null)
        pkgOuter = n.slice(0, dollar1);
      else
        pkgOuter.set(null,0);
      printcr(5,"=> %s$ 0%s $%s",
              pkgOuter.string(), number.string(), name.string());

      if (pkgOuter.ptr != null)
        ics[i].outer = cp.ensureClass(pkgOuter);

      if (name.ptr != null)
        ics[i].name = cp.ensureUtf8(name);
    }

    // update child/sibling list
    if (ics[i].outer != null) {
      uint outord = ics[i].outer->inord;
      if (outord != NO_INORD) {
        assert(outord < cp.tag_count[CONSTANT_Class]);
        ics[i].next_sibling = ic_child_index[outord];
        ic_child_index[outord] = &ics[i];
      }
    }
  }
  //ic_outer_class.done();
  //ic_name.done();
}

void unpacker::read_classes() {
  int i;
  printcr(1,"  ...scanning %d classes...", class_count);
  class_this.readData(class_count);
  class_super.readData(class_count);
  class_interface_count.readData(class_count);
  class_interface.readData(class_interface_count.getIntTotal());

  CHECK;

  #if 0
  // Make a little mark on super-classes.
  for (i = 0; i < class_count; i++) {
    entry* e = class_super.getRefN();
    if (e != null)  e->bits |= entry::EB_SUPER;
  }
  class_super.rewind();
  #endif

  // Members.
  class_field_count.readData(class_count);
  class_method_count.readData(class_count);

  CHECK;

  int field_count = class_field_count.getIntTotal();
  int method_count = class_method_count.getIntTotal();

  field_descr.readData(field_count);
  read_attrs(ATTR_CONTEXT_FIELD, field_count);

  method_descr.readData(method_count);
  read_attrs(ATTR_CONTEXT_METHOD, method_count);

  CHECK;

  read_attrs(ATTR_CONTEXT_CLASS, class_count);

  read_code_headers();

  printcr(1,"scanned %d classes, %d fields, %d methods, %d code headers",
          class_count, field_count, method_count, code_count);
}

maybe_inline
int unpacker::attr_definitions::predefCount(uint idx) {
  return isPredefined(idx) ? flag_count[idx] : 0;
}

void unpacker::read_attrs(int attrc, int obj_count) {
  attr_definitions& ad = attr_defs[attrc];
  assert(ad.attrc == attrc);

  int i, idx, count;

  CHECK;

  bool haveLongFlags = ad.haveLongFlags();

  band& xxx_flags_hi = ad.xxx_flags_hi();
  assert(endsWith(xxx_flags_hi.name, "_flags_hi"));
  if (haveLongFlags)
    xxx_flags_hi.readData(obj_count);

  band& xxx_flags_lo = ad.xxx_flags_lo();
  assert(endsWith(xxx_flags_lo.name, "_flags_lo"));
  xxx_flags_lo.readData(obj_count);

  // pre-scan flags, counting occurrences of each index bit
  julong indexMask = ad.flagIndexMask();  // which flag bits are index bits?
  for (i = 0; i < obj_count; i++) {
    julong indexBits = xxx_flags_hi.getLong(xxx_flags_lo, haveLongFlags);
    if ((indexBits & ~indexMask) > (ushort)-1) {
      abort("undefined attribute flag bit");
      return;
    }
    indexBits &= indexMask;  // ignore classfile flag bits
    for (idx = 0; indexBits != 0; idx++, indexBits >>= 1) {
      ad.flag_count[idx] += (indexBits & 1);
    }
  }
  // we'll scan these again later for output:
  xxx_flags_lo.rewind();
  xxx_flags_hi.rewind();

  band& xxx_attr_count = ad.xxx_attr_count();
  assert(endsWith(xxx_attr_count.name, "_attr_count"));
  // There is one count element for each 1<<16 bit set in flags:
  xxx_attr_count.readData(ad.predefCount(X_ATTR_OVERFLOW));

  band& xxx_attr_indexes = ad.xxx_attr_indexes();
  assert(endsWith(xxx_attr_indexes.name, "_attr_indexes"));
  int overflowIndexCount = xxx_attr_count.getIntTotal();
  xxx_attr_indexes.readData(overflowIndexCount);
  // pre-scan attr indexes, counting occurrences of each value
  for (i = 0; i < overflowIndexCount; i++) {
    idx = xxx_attr_indexes.getInt();
    if (!ad.isIndex(idx)) {
      abort("attribute index out of bounds");
      return;
    }
    ad.getCount(idx) += 1;
  }
  xxx_attr_indexes.rewind();  // we'll scan it again later for output

  // We will need a backward call count for each used backward callable.
  int backwardCounts = 0;
  for (idx = 0; idx < ad.layouts.length(); idx++) {
    layout_definition* lo = ad.getLayout(idx);
    if (lo != null && ad.getCount(idx) != 0) {
      // Build the bands lazily, only when they are used.
      band** bands = ad.buildBands(lo);
      CHECK;
      if (lo->hasCallables()) {
        for (i = 0; bands[i] != null; i++) {
          if (bands[i]->le_back) {
            assert(bands[i]->le_kind == EK_CBLE);
            backwardCounts += 1;
          }
        }
      }
    }
  }
  ad.xxx_attr_calls().readData(backwardCounts);

  // Read built-in bands.
  // Mostly, these are hand-coded equivalents to readBandData().
  switch (attrc) {
  case ATTR_CONTEXT_CLASS:

    count = ad.predefCount(CLASS_ATTR_SourceFile);
    class_SourceFile_RUN.readData(count);

    count = ad.predefCount(CLASS_ATTR_EnclosingMethod);
    class_EnclosingMethod_RC.readData(count);
    class_EnclosingMethod_RDN.readData(count);

    count = ad.predefCount(X_ATTR_Signature);
    class_Signature_RS.readData(count);

    ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
    ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);

    count = ad.predefCount(CLASS_ATTR_InnerClasses);
    class_InnerClasses_N.readData(count);
    count = class_InnerClasses_N.getIntTotal();
    class_InnerClasses_RC.readData(count);
    class_InnerClasses_F.readData(count);
    // Drop remaining columns wherever flags are zero:
    count -= class_InnerClasses_F.getIntCount(0);
    class_InnerClasses_outer_RCN.readData(count);
    class_InnerClasses_name_RUN.readData(count);

    count = ad.predefCount(CLASS_ATTR_ClassFile_version);
    class_ClassFile_version_minor_H.readData(count);
    class_ClassFile_version_major_H.readData(count);
    break;

  case ATTR_CONTEXT_FIELD:

    count = ad.predefCount(FIELD_ATTR_ConstantValue);
    field_ConstantValue_KQ.readData(count);

    count = ad.predefCount(X_ATTR_Signature);
    field_Signature_RS.readData(count);

    ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
    ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
    break;

  case ATTR_CONTEXT_METHOD:

    code_count = ad.predefCount(METHOD_ATTR_Code);
    // Code attrs are handled very specially below...

    count = ad.predefCount(METHOD_ATTR_Exceptions);
    method_Exceptions_N.readData(count);
    count = method_Exceptions_N.getIntTotal();
    method_Exceptions_RC.readData(count);

    count = ad.predefCount(X_ATTR_Signature);
    method_Signature_RS.readData(count);

    ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
    ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
    ad.readBandData(METHOD_ATTR_RuntimeVisibleParameterAnnotations);
    ad.readBandData(METHOD_ATTR_RuntimeInvisibleParameterAnnotations);
    ad.readBandData(METHOD_ATTR_AnnotationDefault);
    break;

  case ATTR_CONTEXT_CODE:
    // (keep this code aligned with its brother in unpacker::write_attrs)
    count = ad.predefCount(CODE_ATTR_StackMapTable);
    // disable this feature in old archives!
    if (count != 0 && majver < JAVA6_PACKAGE_MAJOR_VERSION) {
      abort("undefined StackMapTable attribute (old archive format)");
      return;
    }
    code_StackMapTable_N.readData(count);
    count = code_StackMapTable_N.getIntTotal();
    code_StackMapTable_frame_T.readData(count);
    // the rest of it depends in a complicated way on frame tags
    {
      int fat_frame_count = 0;
      int offset_count = 0;
      int type_count = 0;
      for (int k = 0; k < count; k++) {
        int tag = code_StackMapTable_frame_T.getByte();
        if (tag <= 127) {
          // (64-127)  [(2)]
          if (tag >= 64)  type_count++;
        } else if (tag <= 251) {
          // (247)     [(1)(2)]
          // (248-251) [(1)]
          if (tag >= 247)  offset_count++;
          if (tag == 247)  type_count++;
        } else if (tag <= 254) {
          // (252)     [(1)(2)]
          // (253)     [(1)(2)(2)]
          // (254)     [(1)(2)(2)(2)]
          offset_count++;
          type_count += (tag - 251);
        } else {
          // (255)     [(1)NH[(2)]NH[(2)]]
          fat_frame_count++;
        }
      }

      // done pre-scanning frame tags:
      code_StackMapTable_frame_T.rewind();

      // deal completely with fat frames:
      offset_count += fat_frame_count;
      code_StackMapTable_local_N.readData(fat_frame_count);
      type_count += code_StackMapTable_local_N.getIntTotal();
      code_StackMapTable_stack_N.readData(fat_frame_count);
      type_count += code_StackMapTable_stack_N.getIntTotal();
      // read the rest:
      code_StackMapTable_offset.readData(offset_count);
      code_StackMapTable_T.readData(type_count);
      // (7) [RCH]
      count = code_StackMapTable_T.getIntCount(7);
      code_StackMapTable_RC.readData(count);
      // (8) [PH]
      count = code_StackMapTable_T.getIntCount(8);
      code_StackMapTable_P.readData(count);
    }

    count = ad.predefCount(CODE_ATTR_LineNumberTable);
    code_LineNumberTable_N.readData(count);
    count = code_LineNumberTable_N.getIntTotal();
    code_LineNumberTable_bci_P.readData(count);
    code_LineNumberTable_line.readData(count);

    count = ad.predefCount(CODE_ATTR_LocalVariableTable);
    code_LocalVariableTable_N.readData(count);
    count = code_LocalVariableTable_N.getIntTotal();
    code_LocalVariableTable_bci_P.readData(count);
    code_LocalVariableTable_span_O.readData(count);
    code_LocalVariableTable_name_RU.readData(count);
    code_LocalVariableTable_type_RS.readData(count);
    code_LocalVariableTable_slot.readData(count);

    count = ad.predefCount(CODE_ATTR_LocalVariableTypeTable);
    code_LocalVariableTypeTable_N.readData(count);
    count = code_LocalVariableTypeTable_N.getIntTotal();
    code_LocalVariableTypeTable_bci_P.readData(count);
    code_LocalVariableTypeTable_span_O.readData(count);
    code_LocalVariableTypeTable_name_RU.readData(count);
    code_LocalVariableTypeTable_type_RS.readData(count);
    code_LocalVariableTypeTable_slot.readData(count);
    break;
  }

  // Read compressor-defined bands.
  for (idx = 0; idx < ad.layouts.length(); idx++) {
    if (ad.getLayout(idx) == null)
      continue;  // none at this fixed index <32
    if (idx < ad.flag_limit && ad.isPredefined(idx))
      continue;  // already handled
    if (ad.getCount(idx) == 0)
      continue;  // no attributes of this type (then why transmit layouts?)
    ad.readBandData(idx);
  }
}

void unpacker::attr_definitions::readBandData(int idx) {
  int j;
  uint count = getCount(idx);
  if (count == 0)  return;
  layout_definition* lo = getLayout(idx);
  if (lo != null) {
    printcr(1, "counted %d [redefined = %d predefined = %d] attributes of type %s.%s",
            count, isRedefined(idx), isPredefined(idx),
            ATTR_CONTEXT_NAME[attrc], lo->name);
  }
  bool hasCallables = lo->hasCallables();
  band** bands = lo->bands();
  if (!hasCallables) {
    // Read through the rest of the bands in a regular way.
    readBandData(bands, count);
  } else {
    // Deal with the callables.
    // First set up the forward entry count for each callable.
    // This is stored on band::length of the callable.
    bands[0]->expectMoreLength(count);
    for (j = 0; bands[j] != null; j++) {
      band& j_cble = *bands[j];
      assert(j_cble.le_kind == EK_CBLE);
      if (j_cble.le_back) {
        // Add in the predicted effects of backward calls, too.
        int back_calls = xxx_attr_calls().getInt();
        j_cble.expectMoreLength(back_calls);
        // In a moment, more forward calls may increment j_cble.length.
      }
    }
    // Now consult whichever callables have non-zero entry counts.
    readBandData(bands, -1);
  }
}

// Recursive helper to the previous function:
void unpacker::attr_definitions::readBandData(band** body, uint count) {
  int i, j, k;
  for (j = 0; body[j] != null; j++) {
    band& b = *body[j];
    if (b.defc != null) {
      // It has data, so read it.
      b.readData(count);
    }
    switch (b.le_kind) {
    case EK_REPL:
      {
        int reps = b.getIntTotal();
        readBandData(b.le_body, reps);
      }
      break;
    case EK_UN:
      {
        int remaining = count;
        for (k = 0; b.le_body[k] != null; k++) {
          band& k_case = *b.le_body[k];
          int   k_count = 0;
          if (k_case.le_casetags == null) {
            k_count = remaining;  // last (empty) case
          } else {
            int* tags = k_case.le_casetags;
            int ntags = *tags++;  // 1st element is length (why not?)
            while (ntags-- > 0) {
              int tag = *tags++;
              k_count += b.getIntCount(tag);
            }
          }
          readBandData(k_case.le_body, k_count);
          remaining -= k_count;
        }
        assert(remaining == 0);
      }
      break;
    case EK_CALL:
      // Push the count forward, if it is not a backward call.
      if (!b.le_back) {
        band& cble = *b.le_body[0];
        assert(cble.le_kind == EK_CBLE);
        cble.expectMoreLength(count);
      }
      break;
    case EK_CBLE:
      assert(count == -1);  // incoming count is meaningless
      k = b.length;
      assert(k >= 0);
      // This is intended and required for non production mode.
      assert((b.length = -1)); // make it unable to accept more calls now.
      readBandData(b.le_body, k);
      break;
    }
  }
}

static inline
band** findMatchingCase(int matchTag, band** cases) {
  for (int k = 0; cases[k] != null; k++) {
    band& k_case = *cases[k];
    if (k_case.le_casetags != null) {
      // If it has tags, it must match a tag.
      int* tags = k_case.le_casetags;
      int ntags = *tags++;  // 1st element is length
      for (; ntags > 0; ntags--) {
        int tag = *tags++;
        if (tag == matchTag)
          break;
      }
      if (ntags == 0)
        continue;   // does not match
    }
    return k_case.le_body;
  }
  return null;
}

// write attribute band data:
void unpacker::putlayout(band** body) {
  int i;
  int prevBII = -1;
  int prevBCI = -1;
  for (i = 0; body[i] != null; i++) {
    band& b = *body[i];
    byte le_kind = b.le_kind;

    // Handle scalar part, if any.
    int    x = 0;
    entry* e = null;
    if (b.defc != null) {
      // It has data, so unparse an element.
      if (b.ixTag != CONSTANT_None) {
        assert(le_kind == EK_REF);
        if (b.ixTag == CONSTANT_Literal)
          e = b.getRefUsing(cp.getKQIndex());
        else
          e = b.getRefN();
        switch (b.le_len) {
        case 0: break;
        case 1: putu1ref(e); break;
        case 2: putref(e); break;
        case 4: putu2(0); putref(e); break;
        default: assert(false);
        }
      } else {
        assert(le_kind == EK_INT || le_kind == EK_REPL || le_kind == EK_UN);
        x = b.getInt();

        assert(!b.le_bci || prevBCI == to_bci(prevBII));
        switch (b.le_bci) {
        case EK_BCI:   // PH:  transmit R(bci), store bci
          x = to_bci(prevBII = x);
          prevBCI = x;
          break;
        case EK_BCID:  // POH: transmit D(R(bci)), store bci
          x = to_bci(prevBII += x);
          prevBCI = x;
          break;
        case EK_BCO:   // OH:  transmit D(R(bci)), store D(bci)
          x = to_bci(prevBII += x) - prevBCI;
          prevBCI += x;
          break;
        }
        assert(!b.le_bci || prevBCI == to_bci(prevBII));

        switch (b.le_len) {
        case 0: break;
        case 1: putu1(x); break;
        case 2: putu2(x); break;
        case 4: putu4(x); break;
        default: assert(false);
        }
      }
    }

    // Handle subparts, if any.
    switch (le_kind) {
    case EK_REPL:
      // x is the repeat count
      while (x-- > 0) {
        putlayout(b.le_body);
      }
      break;
    case EK_UN:
      // x is the tag
      putlayout(findMatchingCase(x, b.le_body));
      break;
    case EK_CALL:
      {
        band& cble = *b.le_body[0];
        assert(cble.le_kind == EK_CBLE);
        assert(cble.le_len == b.le_len);
        putlayout(cble.le_body);
      }
      break;

    #ifndef PRODUCT
    case EK_CBLE:
    case EK_CASE:
      assert(false);  // should not reach here
    #endif
    }
  }
}

void unpacker::read_files() {
  file_name.readData(file_count);
  if ((archive_options & AO_HAVE_FILE_SIZE_HI) != 0)
    file_size_hi.readData(file_count);
  file_size_lo.readData(file_count);
  if ((archive_options & AO_HAVE_FILE_MODTIME) != 0)
    file_modtime.readData(file_count);
  int allFiles = file_count + class_count;
  if ((archive_options & AO_HAVE_FILE_OPTIONS) != 0) {
    file_options.readData(file_count);
    // FO_IS_CLASS_STUB might be set, causing overlap between classes and files
    for (int i = 0; i < file_count; i++) {
      if ((file_options.getInt() & FO_IS_CLASS_STUB) != 0) {
        allFiles -= 1;  // this one counts as both class and file
      }
    }
    file_options.rewind();
  }
  assert((default_file_options & FO_IS_CLASS_STUB) == 0);
  files_remaining = allFiles;
}

maybe_inline
void unpacker::get_code_header(int& max_stack,
                               int& max_na_locals,
                               int& handler_count,
                               int& cflags) {
  int sc = code_headers.getByte();
  if (sc == 0) {
    max_stack = max_na_locals = handler_count = cflags = -1;
    return;
  }
  // Short code header is the usual case:
  int nh;
  int mod;
  if (sc < 1 + 12*12) {
    sc -= 1;
    nh = 0;
    mod = 12;
  } else if (sc < 1 + 12*12 + 8*8) {
    sc -= 1 + 12*12;
    nh = 1;
    mod = 8;
  } else {
    assert(sc < 1 + 12*12 + 8*8 + 7*7);
    sc -= 1 + 12*12 + 8*8;
    nh = 2;
    mod = 7;
  }
  max_stack     = sc % mod;
  max_na_locals = sc / mod;  // caller must add static, siglen
  handler_count = nh;
  if ((archive_options & AO_HAVE_ALL_CODE_FLAGS) != 0)
    cflags      = -1;
  else
    cflags      = 0;  // this one has no attributes
}

// Cf. PackageReader.readCodeHeaders
void unpacker::read_code_headers() {
  code_headers.readData(code_count);
  CHECK;
  int totalHandlerCount = 0;
  int totalFlagsCount   = 0;
  for (int i = 0; i < code_count; i++) {
    int max_stack, max_locals, handler_count, cflags;
    get_code_header(max_stack, max_locals, handler_count, cflags);
    if (max_stack < 0)      code_max_stack.expectMoreLength(1);
    if (max_locals < 0)     code_max_na_locals.expectMoreLength(1);
    if (handler_count < 0)  code_handler_count.expectMoreLength(1);
    else                    totalHandlerCount += handler_count;
    if (cflags < 0)         totalFlagsCount += 1;
  }
  code_headers.rewind();  // replay later during writing

  code_max_stack.readData();
  code_max_na_locals.readData();
  code_handler_count.readData();
  totalHandlerCount += code_handler_count.getIntTotal();

  // Read handler specifications.
  // Cf. PackageReader.readCodeHandlers.
  code_handler_start_P.readData(totalHandlerCount);
  code_handler_end_PO.readData(totalHandlerCount);
  code_handler_catch_PO.readData(totalHandlerCount);
  code_handler_class_RCN.readData(totalHandlerCount);

  read_attrs(ATTR_CONTEXT_CODE, totalFlagsCount);
}

static inline bool is_in_range(uint n, uint min, uint max) {
  return n - min <= max - min;  // unsigned arithmetic!
}
static inline bool is_field_op(int bc) {
  return is_in_range(bc, bc_getstatic, bc_putfield);
}
static inline bool is_invoke_init_op(int bc) {
  return is_in_range(bc, _invokeinit_op, _invokeinit_limit-1);
}
static inline bool is_self_linker_op(int bc) {
  return is_in_range(bc, _self_linker_op, _self_linker_limit-1);
}
static bool is_branch_op(int bc) {
  return is_in_range(bc, bc_ifeq,   bc_jsr)
      || is_in_range(bc, bc_ifnull, bc_jsr_w);
}
static bool is_local_slot_op(int bc) {
  return is_in_range(bc, bc_iload,  bc_aload)
      || is_in_range(bc, bc_istore, bc_astore)
      || bc == bc_iinc || bc == bc_ret;
}
band* unpacker::ref_band_for_op(int bc) {
  switch (bc) {
  case bc_ildc:
  case bc_ildc_w:
    return &bc_intref;
  case bc_fldc:
  case bc_fldc_w:
    return &bc_floatref;
  case bc_lldc2_w:
    return &bc_longref;
  case bc_dldc2_w:
    return &bc_doubleref;
  case bc_aldc:
  case bc_aldc_w:
    return &bc_stringref;
  case bc_cldc:
  case bc_cldc_w:
    return &bc_classref;

  case bc_getstatic:
  case bc_putstatic:
  case bc_getfield:
  case bc_putfield:
    return &bc_fieldref;

  case bc_invokevirtual:
  case bc_invokespecial:
  case bc_invokestatic:
    return &bc_methodref;
  case bc_invokeinterface:
    return &bc_imethodref;

  case bc_new:
  case bc_anewarray:
  case bc_checkcast:
  case bc_instanceof:
  case bc_multianewarray:
    return &bc_classref;
  }
  return null;
}

maybe_inline
band* unpacker::ref_band_for_self_op(int bc, bool& isAloadVar, int& origBCVar) {
  if (!is_self_linker_op(bc))  return null;
  int idx = (bc - _self_linker_op);
  bool isSuper = (idx >= _self_linker_super_flag);
  if (isSuper)  idx -= _self_linker_super_flag;
  bool isAload = (idx >= _self_linker_aload_flag);
  if (isAload)  idx -= _self_linker_aload_flag;
  int origBC = _first_linker_op + idx;
  bool isField = is_field_op(origBC);
  isAloadVar = isAload;
  origBCVar  = _first_linker_op + idx;
  if (!isSuper)
    return isField? &bc_thisfield: &bc_thismethod;
  else
    return isField? &bc_superfield: &bc_supermethod;
}

// Cf. PackageReader.readByteCodes
inline  // called exactly once => inline
void unpacker::read_bcs() {
  printcr(3, "reading compressed bytecodes and operands for %d codes...",
          code_count);

  // read from bc_codes and bc_case_count
  fillbytes all_switch_ops;
  all_switch_ops.init();
  CHECK;

  // Read directly from rp/rplimit.
  //Do this later:  bc_codes.readData(...)
  byte* rp0 = rp;

  band* bc_which;
  byte* opptr = rp;
  byte* oplimit = rplimit;

  bool  isAload;  // passed by ref and then ignored
  int   junkBC;   // passed by ref and then ignored
  for (int k = 0; k < code_count; k++) {
    // Scan one method:
    for (;;) {
      if (opptr+2 > oplimit) {
        rp = opptr;
        ensure_input(2);
        oplimit = rplimit;
        rp = rp0;  // back up
      }
      if (opptr == oplimit) { abort(); break; }
      int bc = *opptr++ & 0xFF;
      bool isWide = false;
      if (bc == bc_wide) {
        if (opptr == oplimit) { abort(); break; }
        bc = *opptr++ & 0xFF;
        isWide = true;
      }
      // Adjust expectations of various band sizes.
      switch (bc) {
      case bc_tableswitch:
      case bc_lookupswitch:
        all_switch_ops.addByte(bc);
        break;
      case bc_iinc:
        bc_local.expectMoreLength(1);
        bc_which = isWide ? &bc_short : &bc_byte;
        bc_which->expectMoreLength(1);
        break;
      case bc_sipush:
        bc_short.expectMoreLength(1);
        break;
      case bc_bipush:
        bc_byte.expectMoreLength(1);
        break;
      case bc_newarray:
        bc_byte.expectMoreLength(1);
        break;
      case bc_multianewarray:
        assert(ref_band_for_op(bc) == &bc_classref);
        bc_classref.expectMoreLength(1);
        bc_byte.expectMoreLength(1);
        break;
      case bc_ref_escape:
        bc_escrefsize.expectMoreLength(1);
        bc_escref.expectMoreLength(1);
        break;
      case bc_byte_escape:
        bc_escsize.expectMoreLength(1);
        // bc_escbyte will have to be counted too
        break;
      default:
        if (is_invoke_init_op(bc)) {
          bc_initref.expectMoreLength(1);
          break;
        }
        bc_which = ref_band_for_self_op(bc, isAload, junkBC);
        if (bc_which != null) {
          bc_which->expectMoreLength(1);
          break;
        }
        if (is_branch_op(bc)) {
          bc_label.expectMoreLength(1);
          break;
        }
        bc_which = ref_band_for_op(bc);
        if (bc_which != null) {
          bc_which->expectMoreLength(1);
          assert(bc != bc_multianewarray);  // handled elsewhere
          break;
        }
        if (is_local_slot_op(bc)) {
          bc_local.expectMoreLength(1);
          break;
        }
        break;
      case bc_end_marker:
        // Increment k and test against code_count.
        goto doneScanningMethod;
      }
    }
  doneScanningMethod:{}
    if (aborting())  break;
  }

  // Go through the formality, so we can use it in a regular fashion later:
  assert(rp == rp0);
  bc_codes.readData(opptr - rp);

  int i = 0;

  // To size instruction bands correctly, we need info on switches:
  bc_case_count.readData(all_switch_ops.size());
  for (i = 0; i < all_switch_ops.size(); i++) {
    int caseCount = bc_case_count.getInt();
    int bc        = all_switch_ops.getByte(i);
    bc_label.expectMoreLength(1+caseCount); // default label + cases
    bc_case_value.expectMoreLength(bc == bc_tableswitch ? 1 : caseCount);
    printcr(2, "switch bc=%d caseCount=%d", bc, caseCount);
  }
  bc_case_count.rewind();  // uses again for output

  all_switch_ops.free();

  for (i = e_bc_case_value; i <= e_bc_escsize; i++) {
    all_bands[i].readData();
  }

  // The bc_escbyte band is counted by the immediately previous band.
  bc_escbyte.readData(bc_escsize.getIntTotal());

  printcr(3, "scanned %d opcode and %d operand bytes for %d codes...",
          (int)(bc_codes.size()),
          (int)(bc_escsize.maxRP() - bc_case_value.minRP()),
          code_count);
}

void unpacker::read_bands() {
  byte* rp0 = rp;
  int i;

  read_file_header();
  CHECK;

  if (cp.nentries == 0) {
    // read_file_header failed to read a CP, because it copied a JAR.
    return;
  }

  // Do this after the file header has been read:
  check_options();

  read_cp();
  CHECK;
  read_attr_defs();
  CHECK;
  read_ics();
  CHECK;
  read_classes();
  CHECK;
  read_bcs();
  CHECK;
  read_files();
}

/// CP routines

entry*& cpool::hashTabRef(byte tag, bytes& b) {
  printcr(5, "hashTabRef tag=%d %s[%d]", tag, b.string(), b.len);
  uint hash = tag + b.len;
  for (int i = 0; i < b.len; i++) {
    hash = hash * 31 + (0xFF & b.ptr[i]);
  }
  entry**  ht = hashTab;
  int    hlen = hashTabLength;
  assert((hlen & (hlen-1)) == 0);  // must be power of 2
  uint hash1 = hash & (hlen-1);    // == hash % hlen
  uint hash2 = 0;                  // lazily computed (requires mod op.)
  int probes = 0;
  while (ht[hash1] != null) {
    entry& e = *ht[hash1];
    if (e.value.b.equals(b) && e.tag == tag)
      break;
    if (hash2 == 0)
      // Note:  hash2 must be relatively prime to hlen, hence the "|1".
      hash2 = (((hash % 499) & (hlen-1)) | 1);
    hash1 += hash2;
    if (hash1 >= hlen)  hash1 -= hlen;
    assert(hash1 < hlen);
    assert(++probes < hlen);
  }
  #ifndef PRODUCT
  hash_probes[0] += 1;
  hash_probes[1] += probes;
  #endif
  printcr(5, " => @%d %p", hash1, ht[hash1]);
  return ht[hash1];
}

maybe_inline
static void insert_extra(entry* e, ptrlist& extras) {
  // This ordering helps implement the Pack200 requirement
  // of a predictable CP order in the class files produced.
  e->inord = NO_INORD;  // mark as an "extra"
  extras.add(e);
  // Note:  We will sort the list (by string-name) later.
}

entry* cpool::ensureUtf8(bytes& b) {
  entry*& ix = hashTabRef(CONSTANT_Utf8, b);
  if (ix != null)  return ix;
  // Make one.
  if (nentries == maxentries) {
    abort("cp utf8 overflow");
    return &entries[tag_base[CONSTANT_Utf8]];  // return something
  }
  entry& e = entries[nentries++];
  e.tag = CONSTANT_Utf8;
  u->saveTo(e.value.b, b);
  assert(&e >= first_extra_entry);
  insert_extra(&e, tag_extras[CONSTANT_Utf8]);
  printcr(4,"ensureUtf8 miss %s", e.string());
  return ix = &e;
}

entry* cpool::ensureClass(bytes& b) {
  entry*& ix = hashTabRef(CONSTANT_Class, b);
  if (ix != null)  return ix;
  // Make one.
  if (nentries == maxentries) {
    abort("cp class overflow");
    return &entries[tag_base[CONSTANT_Class]];  // return something
  }
  entry& e = entries[nentries++];
  e.tag = CONSTANT_Class;
  e.nrefs = 1;
  e.refs = U_NEW(entry*, 1);
  ix = &e;  // hold my spot in the index
  entry* utf = ensureUtf8(b);
  e.refs[0] = utf;
  e.value.b = utf->value.b;
  assert(&e >= first_extra_entry);
  insert_extra(&e, tag_extras[CONSTANT_Class]);
  printcr(4,"ensureClass miss %s", e.string());
  return &e;
}

void cpool::expandSignatures() {
  int i;
  int nsigs = 0;
  int nreused = 0;
  int first_sig = tag_base[CONSTANT_Signature];
  int sig_limit = tag_count[CONSTANT_Signature] + first_sig;
  fillbytes buf;
  buf.init(1<<10);
  CHECK;
  for (i = first_sig; i < sig_limit; i++) {
    entry& e = entries[i];
    assert(e.tag == CONSTANT_Signature);
    int refnum = 0;
    bytes form = e.refs[refnum++]->asUtf8();
    buf.empty();
    for (int j = 0; j < form.len; j++) {
      int c = form.ptr[j];
      buf.addByte(c);
      if (c == 'L') {
        entry* cls = e.refs[refnum++];
        buf.append(cls->className()->asUtf8());
      }
    }
    assert(refnum == e.nrefs);
    bytes& sig = buf.b;
    printcr(5,"signature %d %s -> %s", i, form.ptr, sig.ptr);

    // try to find a pre-existing Utf8:
    entry* &e2 = hashTabRef(CONSTANT_Utf8, sig);
    if (e2 != null) {
      assert(e2->isUtf8(sig));
      e.value.b = e2->value.b;
      e.refs[0] = e2;
      e.nrefs = 1;
      printcr(5,"signature replaced %d => %s", i, e.string());
      nreused++;
    } else {
      // there is no other replacement; reuse this CP entry as a Utf8
      u->saveTo(e.value.b, sig);
      e.tag = CONSTANT_Utf8;
      e.nrefs = 0;
      e2 = &e;
      printcr(5,"signature changed %d => %s", e.inord, e.string());
    }
    nsigs++;
  }
  printcr(1,"expanded %d signatures (reused %d utfs)", nsigs, nreused);
  buf.free();

  // go expunge all references to remaining signatures:
  for (i = 0; i < nentries; i++) {
    entry& e = entries[i];
    for (int j = 0; j < e.nrefs; j++) {
      entry*& e2 = e.refs[j];
      if (e2 != null && e2->tag == CONSTANT_Signature)
        e2 = e2->refs[0];
    }
  }
}

void cpool::initMemberIndexes() {
  // This function does NOT refer to any class schema.
  // It is totally internal to the cpool.
  int i, j, len;

  // Get the pre-existing indexes:
  int   nclasses = tag_count[CONSTANT_Class];
  entry* classes = tag_base[CONSTANT_Class] + entries;
  int   nfields  = tag_count[CONSTANT_Fieldref];
  entry* fields  = tag_base[CONSTANT_Fieldref] + entries;
  int   nmethods = tag_count[CONSTANT_Methodref];
  entry* methods = tag_base[CONSTANT_Methodref] + entries;

  int*     field_counts  = T_NEW(int, nclasses);
  int*     method_counts = T_NEW(int, nclasses);
  cpindex* all_indexes   = U_NEW(cpindex, nclasses*2);
  entry**  field_ix      = U_NEW(entry*, nfields+nclasses);
  entry**  method_ix     = U_NEW(entry*, nmethods+nclasses);

  for (j = 0; j < nfields; j++) {
    entry& f = fields[j];
    i = f.memberClass()->inord;
    assert((uint)i < nclasses);
    field_counts[i]++;
  }
  for (j = 0; j < nmethods; j++) {
    entry& m = methods[j];
    i = m.memberClass()->inord;
    assert((uint)i < nclasses);
    method_counts[i]++;
  }

  int fbase = 0, mbase = 0;
  for (i = 0; i < nclasses; i++) {
    int fc = field_counts[i];
    int mc = method_counts[i];
    all_indexes[i*2+0].init(fc, field_ix+fbase,
                            CONSTANT_Fieldref  + SUBINDEX_BIT);
    all_indexes[i*2+1].init(mc, method_ix+mbase,
                            CONSTANT_Methodref + SUBINDEX_BIT);
    // reuse field_counts and member_counts as fill pointers:
    field_counts[i] = fbase;
    method_counts[i] = mbase;
    printcr(3, "class %d fields @%d[%d] methods @%d[%d]",
            i, fbase, fc, mbase, mc);
    fbase += fc+1;
    mbase += mc+1;
    // (the +1 leaves a space between every subarray)
  }
  assert(fbase == nfields+nclasses);
  assert(mbase == nmethods+nclasses);

  for (j = 0; j < nfields; j++) {
    entry& f = fields[j];
    i = f.memberClass()->inord;
    field_ix[field_counts[i]++] = &f;
  }
  for (j = 0; j < nmethods; j++) {
    entry& m = methods[j];
    i = m.memberClass()->inord;
    method_ix[method_counts[i]++] = &m;
  }

  member_indexes = all_indexes;

#ifndef PRODUCT
  // Test the result immediately on every class and field.
  int fvisited = 0, mvisited = 0;
  int prevord;
  for (i = 0; i < nclasses; i++) {
    entry*   cls = &classes[i];
    cpindex* fix = getFieldIndex(cls);
    cpindex* mix = getMethodIndex(cls);
    printcr(2, "field and method index for %s [%d] [%d]",
            cls->string(), mix->len, fix->len);
    prevord = -1;
    for (j = 0, len = fix->len; j < len; j++) {
      entry* f = fix->get(j);
      assert(f != null);
      printcr(3, "- field %s", f->string());
      assert(f->memberClass() == cls);
      assert(prevord < (int)f->inord);
      prevord = f->inord;
      fvisited++;
    }
    assert(fix->base2[j] == null);
    prevord = -1;
    for (j = 0, len = mix->len; j < len; j++) {
      entry* m = mix->get(j);
      assert(m != null);
      printcr(3, "- method %s", m->string());
      assert(m->memberClass() == cls);
      assert(prevord < (int)m->inord);
      prevord = m->inord;
      mvisited++;
    }
    assert(mix->base2[j] == null);
  }
  assert(fvisited == nfields);
  assert(mvisited == nmethods);
#endif

  // Free intermediate buffers.
  u->free_temps();
}

void entry::requestOutputIndex(cpool& cp, int req) {
  assert(outputIndex <= NOT_REQUESTED);  // must not have assigned indexes yet
  if (tag == CONSTANT_Signature) {
    ref(0)->requestOutputIndex(cp, req);
    return;
  }
  assert(req == REQUESTED || req == REQUESTED_LDC);
  if (outputIndex != NOT_REQUESTED) {
    if (req == REQUESTED_LDC)
      outputIndex = req;  // this kind has precedence
    return;
  }
  outputIndex = req;
  //assert(!cp.outputEntries.contains(this));
  assert(tag != CONSTANT_Signature);
  cp.outputEntries.add(this);
  for (int j = 0; j < nrefs; j++) {
    ref(j)->requestOutputIndex(cp);
  }
}

void cpool::resetOutputIndexes() {
  int i;
  int    noes =           outputEntries.length();
  entry** oes = (entry**) outputEntries.base();
  for (i = 0; i < noes; i++) {
    entry& e = *oes[i];
    e.outputIndex = NOT_REQUESTED;
  }
  outputIndexLimit = 0;
  outputEntries.empty();
#ifndef PRODUCT
  // they must all be clear now
  for (i = 0; i < nentries; i++)
    assert(entries[i].outputIndex == NOT_REQUESTED);
#endif
}

static const byte TAG_ORDER[CONSTANT_Limit] = {
  0, 1, 0, 2, 3, 4, 5, 7, 6, 10, 11, 12, 9, 8
};

extern "C"
int outputEntry_cmp(const void* e1p, const void* e2p) {
  // Sort entries according to the Pack200 rules for deterministic
  // constant pool ordering.
  //
  // The four sort keys as follows, in order of decreasing importance:
  //   1. ldc first, then non-ldc guys
  //   2. normal cp_All entries by input order (i.e., address order)
  //   3. after that, extra entries by lexical order (as in tag_extras[*])
  entry& e1 = *(entry*) *(void**) e1p;
  entry& e2 = *(entry*) *(void**) e2p;
  int   oi1 = e1.outputIndex;
  int   oi2 = e2.outputIndex;
  assert(oi1 == REQUESTED || oi1 == REQUESTED_LDC);
  assert(oi2 == REQUESTED || oi2 == REQUESTED_LDC);
  if (oi1 != oi2) {
    if (oi1 == REQUESTED_LDC)  return 0-1;
    if (oi2 == REQUESTED_LDC)  return 1-0;
    // Else fall through; neither is an ldc request.
  }
  if (e1.inord != NO_INORD || e2.inord != NO_INORD) {
    // One or both is normal.  Use input order.
    if (&e1 > &e2)  return 1-0;
    if (&e1 < &e2)  return 0-1;
    return 0;  // equal pointers
  }
  // Both are extras.  Sort by tag and then by value.
  if (e1.tag != e2.tag) {
    return TAG_ORDER[e1.tag] - TAG_ORDER[e2.tag];
  }
  // If the tags are the same, use string comparison.
  return compare_Utf8_chars(e1.value.b, e2.value.b);
}

void cpool::computeOutputIndexes() {
  int i;

#ifndef PRODUCT
  // outputEntries must be a complete list of those requested:
  static uint checkStart = 0;
  int checkStep = 1;
  if (nentries > 100)  checkStep = nentries / 100;
  for (i = (checkStart++ % checkStep); i < nentries; i += checkStep) {
    entry& e = entries[i];
    if (e.outputIndex != NOT_REQUESTED) {
      assert(outputEntries.contains(&e));
    } else {
      assert(!outputEntries.contains(&e));
    }
  }

  // check hand-initialization of TAG_ORDER
  for (i = 0; i < N_TAGS_IN_ORDER; i++) {
    byte tag = TAGS_IN_ORDER[i];
    assert(TAG_ORDER[tag] == i+1);
  }
#endif

  int    noes =           outputEntries.length();
  entry** oes = (entry**) outputEntries.base();

  // Sort the output constant pool into the order required by Pack200.
  PTRLIST_QSORT(outputEntries, outputEntry_cmp);

  // Allocate a new index for each entry that needs one.
  // We do this in two passes, one for LDC entries and one for the rest.
  int nextIndex = 1;  // always skip index #0 in output cpool
  for (i = 0; i < noes; i++) {
    entry& e = *oes[i];
    assert(e.outputIndex == REQUESTED || e.outputIndex == REQUESTED_LDC);
    e.outputIndex = nextIndex++;
    if (e.isDoubleWord())  nextIndex++;  // do not use the next index
  }
  outputIndexLimit = nextIndex;
  printcr(3,"renumbering CP to %d entries", outputIndexLimit);
}

#ifndef PRODUCT
// debugging goo

unpacker* debug_u;

static bytes& getbuf(int len) {  // for debugging only!
  static int bn = 0;
  static bytes bufs[8] = { 0 };
  bytes& buf = bufs[bn++ & 7];
  while (buf.len < len+10)
    buf.realloc(buf.len ? buf.len * 2 : 1000);
  buf.ptr[0] = 0;  // for the sake of strcat
  return buf;
}

char* entry::string() {
  bytes buf;
  switch (tag) {
  case CONSTANT_None:
    return (char*)"<empty>";
  case CONSTANT_Signature:
    if (value.b.ptr == null)
      return ref(0)->string();
    // else fall through:
  case CONSTANT_Utf8:
    buf = value.b;
    break;
  case CONSTANT_Integer:
  case CONSTANT_Float:
    buf = getbuf(12);
    sprintf((char*)buf.ptr, "0x%08x", value.i);
    break;
  case CONSTANT_Long:
  case CONSTANT_Double:
    buf = getbuf(24);
    sprintf((char*)buf.ptr, "0x%016llx", value.l);
    break;
  default:
    if (nrefs == 0) {
      buf = getbuf(20);
      sprintf((char*)buf.ptr, "<tag=%d>", tag);
    } else if (nrefs == 1) {
      return refs[0]->string();
    } else {
      char* s1 = refs[0]->string();
      char* s2 = refs[1]->string();
      buf = getbuf(strlen(s1) + 1 + strlen(s2) + 4 + 1);
      buf.strcat(s1).strcat(" ").strcat(s2);
      if (nrefs > 2)  buf.strcat(" ...");
    }
  }
  return (char*)buf.ptr;
}

void print_cp_entry(int i) {
  entry& e = debug_u->cp.entries[i];
  char buf[30];
  sprintf(buf, ((uint)e.tag < CONSTANT_Limit)? TAG_NAME[e.tag]: "%d", e.tag);
  printf(" %d\t%s %s\n", i, buf, e.string());
}

void print_cp_entries(int beg, int end) {
  for (int i = beg; i < end; i++)
    print_cp_entry(i);
}

void print_cp() {
  print_cp_entries(0, debug_u->cp.nentries);
}

#endif

// Unpacker Start

const char str_tf[] = "true\0false";
#undef STR_TRUE
#undef STR_FALSE
#define STR_TRUE   (&str_tf[0])
#define STR_FALSE  (&str_tf[5])

const char* unpacker::get_option(const char* prop) {
  if (prop == null )  return null;
  if (strcmp(prop, UNPACK_DEFLATE_HINT) == 0) {
    return deflate_hint_or_zero == 0? null : STR_TF(deflate_hint_or_zero > 0);
#ifdef HAVE_STRIP
  } else if (strcmp(prop, UNPACK_STRIP_COMPILE) == 0) {
    return STR_TF(strip_compile);
  } else if (strcmp(prop, UNPACK_STRIP_DEBUG) == 0) {
    return STR_TF(strip_debug);
  } else if (strcmp(prop, UNPACK_STRIP_JCOV) == 0) {
    return STR_TF(strip_jcov);
#endif /*HAVE_STRIP*/
  } else if (strcmp(prop, UNPACK_REMOVE_PACKFILE) == 0) {
    return STR_TF(remove_packfile);
  } else if (strcmp(prop, DEBUG_VERBOSE) == 0) {
    return saveIntStr(verbose);
  } else if (strcmp(prop, UNPACK_MODIFICATION_TIME) == 0) {
    return (modification_time_or_zero == 0)? null:
      saveIntStr(modification_time_or_zero);
  } else if (strcmp(prop, UNPACK_LOG_FILE) == 0) {
    return log_file;
  } else {
    return NULL; // unknown option ignore
  }
}

bool unpacker::set_option(const char* prop, const char* value) {
  if (prop == NULL)  return false;
  if (strcmp(prop, UNPACK_DEFLATE_HINT) == 0) {
    deflate_hint_or_zero = ( (value == null || strcmp(value, "keep") == 0)
                                ? 0: BOOL_TF(value) ? +1: -1);
#ifdef HAVE_STRIP
  } else if (strcmp(prop, UNPACK_STRIP_COMPILE) == 0) {
    strip_compile = STR_TF(value);
  } else if (strcmp(prop, UNPACK_STRIP_DEBUG) == 0) {
    strip_debug = STR_TF(value);
  } else if (strcmp(prop, UNPACK_STRIP_JCOV) == 0) {
    strip_jcov = STR_TF(value);
#endif /*HAVE_STRIP*/
  } else if (strcmp(prop, UNPACK_REMOVE_PACKFILE) == 0) {
    remove_packfile = STR_TF(value);
  } else if (strcmp(prop, DEBUG_VERBOSE) == 0) {
    verbose = (value == null)? 0: atoi(value);
  } else if (strcmp(prop, DEBUG_VERBOSE ".bands") == 0) {
#ifndef PRODUCT
    verbose_bands = (value == null)? 0: atoi(value);
#endif
  } else if (strcmp(prop, UNPACK_MODIFICATION_TIME) == 0) {
    if (value == null || (strcmp(value, "keep") == 0)) {
      modification_time_or_zero = 0;
    } else if (strcmp(value, "now") == 0) {
      time_t now;
      time(&now);
      modification_time_or_zero = (int) now;
    } else {
      modification_time_or_zero = atoi(value);
      if (modification_time_or_zero == 0)
        modification_time_or_zero = 1;  // make non-zero
    }
  } else if (strcmp(prop, UNPACK_LOG_FILE) == 0) {
    log_file = (value == null)? value: saveStr(value);
  } else {
    return false; // unknown option ignore
  }
  return true;
}

// Deallocate all internal storage and reset to a clean state.
// Do not disturb any input or output connections, including
// infileptr, infileno, inbytes, read_input_fn, jarout, or errstrm.
// Do not reset any unpack options.
void unpacker::reset() {
  bytes_read_before_reset      += bytes_read;
  bytes_written_before_reset   += bytes_written;
  files_written_before_reset   += files_written;
  classes_written_before_reset += classes_written;
  segments_read_before_reset   += 1;
  if (verbose >= 2) {
    fprintf(errstrm,
            "After segment %d, %lld bytes read and %lld bytes written.\n",
            segments_read_before_reset-1,
            bytes_read_before_reset, bytes_written_before_reset);
    fprintf(errstrm,
            "After segment %d, %d files (of which %d are classes) written to output.\n",
            segments_read_before_reset-1,
            files_written_before_reset, classes_written_before_reset);
    if (archive_next_count != 0) {
      fprintf(errstrm,
              "After segment %d, %d segment%s remaining (estimated).\n",
              segments_read_before_reset-1,
              archive_next_count, archive_next_count==1?"":"s");
    }
  }

  unpacker save_u = (*this);  // save bytewise image
  infileptr = null;  // make asserts happy
  jniobj = null;  // make asserts happy
  jarout = null;  // do not close the output jar
  gzin = null;  // do not close the input gzip stream
  bytes esn;
  if (errstrm_name != null) {
    esn.saveFrom(errstrm_name);
  } else {
    esn.set(null, 0);
  }
  this->free();
  mtrace('s', 0, 0);  // note the boundary between segments
  this->init(read_input_fn);

  // restore selected interface state:
#define SAVE(x) this->x = save_u.x
  SAVE(jniobj);
  SAVE(jnienv);
  SAVE(infileptr);  // buffered
  SAVE(infileno);   // unbuffered
  SAVE(inbytes);    // direct
  SAVE(jarout);
  SAVE(gzin);
  //SAVE(read_input_fn);
  SAVE(errstrm);
  SAVE(verbose);  // verbose level, 0 means no output
  SAVE(strip_compile);
  SAVE(strip_debug);
  SAVE(strip_jcov);
  SAVE(remove_packfile);
  SAVE(deflate_hint_or_zero);  // ==0 means not set, otherwise -1 or 1
  SAVE(modification_time_or_zero);
  SAVE(bytes_read_before_reset);
  SAVE(bytes_written_before_reset);
  SAVE(files_written_before_reset);
  SAVE(classes_written_before_reset);
  SAVE(segments_read_before_reset);
#undef SAVE
  if (esn.len > 0) {
    errstrm_name = saveStr(esn.strval());
    esn.free();
  }
  log_file = errstrm_name;
  // Note:  If we use strip_names, watch out:  They get nuked here.
}

void unpacker::init(read_input_fn_t input_fn) {
  int i;
  NOT_PRODUCT(debug_u = this);
  BYTES_OF(*this).clear();
  if (assert(1))  free();  // just to make sure freeing is idempotent
  this->u = this;    // self-reference for U_NEW macro
  errstrm = stdout;  // default error-output
  log_file = LOGFILE_STDOUT;
  read_input_fn = input_fn;
  all_bands = band::makeBands(this);
  // Make a default jar buffer; caller may safely overwrite it.
  jarout = U_NEW(jar, 1);
  jarout->init(this);
  for (i = 0; i < ATTR_CONTEXT_LIMIT; i++)
    attr_defs[i].u = u;  // set up outer ptr
}

const char* unpacker::get_abort_message() {
   return abort_message;
}

void unpacker::dump_options() {
  static const char* opts[] = {
    UNPACK_LOG_FILE,
    UNPACK_DEFLATE_HINT,
#ifdef HAVE_STRIP
    UNPACK_STRIP_COMPILE,
    UNPACK_STRIP_DEBUG,
    UNPACK_STRIP_JCOV,
#endif /*HAVE_STRIP*/
    UNPACK_REMOVE_PACKFILE,
    DEBUG_VERBOSE,
    UNPACK_MODIFICATION_TIME,
    null
  };
  for (int i = 0; opts[i] != null; i++) {
    const char* str = get_option(opts[i]);
    if (str == null) {
      if (verbose == 0)  continue;
      str = "(not set)";
    }
    fprintf(errstrm, "%s=%s\n", opts[i], str);
  }
}


// Usage: unpack a byte buffer
// packptr is a reference to byte buffer containing a
// packed file and len is the length of the buffer.
// If null, the callback is used to fill an internal buffer.
void unpacker::start(void* packptr, size_t len) {
  NOT_PRODUCT(debug_u = this);
  if (packptr != null && len != 0) {
    inbytes.set((byte*) packptr, len);
  }
  read_bands();
}

void unpacker::check_options() {
  const char* strue  = "true";
  const char* sfalse = "false";
  if (deflate_hint_or_zero != 0) {
    bool force_deflate_hint = (deflate_hint_or_zero > 0);
    if (force_deflate_hint)
      default_file_options |= FO_DEFLATE_HINT;
    else
      default_file_options &= ~FO_DEFLATE_HINT;
    // Turn off per-file deflate hint by force.
    suppress_file_options |= FO_DEFLATE_HINT;
  }
  if (modification_time_or_zero != 0) {
    default_file_modtime = modification_time_or_zero;
    // Turn off per-file modtime by force.
    archive_options &= ~AO_HAVE_FILE_MODTIME;
  }
  // %%% strip_compile, etc...
}

// classfile writing

void unpacker::reset_cur_classfile() {
  // set defaults
  cur_class_minver = default_class_minver;
  cur_class_majver = default_class_majver;

  // reset constant pool state
  cp.resetOutputIndexes();

  // reset fixups
  class_fixup_type.empty();
  class_fixup_offset.empty();
  class_fixup_ref.empty();
  requested_ics.empty();
}

cpindex* cpool::getKQIndex() {
  char ch = '?';
  if (u->cur_descr != null) {
    entry* type = u->cur_descr->descrType();
    ch = type->value.b.ptr[0];
  }
  byte tag = CONSTANT_Integer;
  switch (ch) {
  case 'L': tag = CONSTANT_String;   break;
  case 'I': tag = CONSTANT_Integer;  break;
  case 'J': tag = CONSTANT_Long;     break;
  case 'F': tag = CONSTANT_Float;    break;
  case 'D': tag = CONSTANT_Double;   break;
  case 'B': case 'S': case 'C':
  case 'Z': tag = CONSTANT_Integer;  break;
  default:  abort("bad KQ reference"); break;
  }
  return getIndex(tag);
}

uint unpacker::to_bci(uint bii) {
  uint  len =         bcimap.length();
  uint* map = (uint*) bcimap.base();
  assert(len > 0);  // must be initialized before using to_bci
  if (bii < len)
    return map[bii];
  // Else it's a fractional or out-of-range BCI.
  uint key = bii-len;
  for (int i = len; ; i--) {
    if (map[i-1]-(i-1) <= key)
      break;
    else
      --bii;
  }
  return bii;
}

void unpacker::put_stackmap_type() {
  int tag = code_StackMapTable_T.getByte();
  putu1(tag);
  switch (tag) {
  case 7: // (7) [RCH]
    putref(code_StackMapTable_RC.getRef());
    break;
  case 8: // (8) [PH]
    putu2(to_bci(code_StackMapTable_P.getInt()));
    break;
  }
}

// Functions for writing code.

maybe_inline
void unpacker::put_label(int curIP, int size) {
  code_fixup_type.addByte(size);
  code_fixup_offset.add(put_empty(size));
  code_fixup_source.add(curIP);
}

inline  // called exactly once => inline
void unpacker::write_bc_ops() {
  bcimap.empty();
  code_fixup_type.empty();
  code_fixup_offset.empty();
  code_fixup_source.empty();

  band* bc_which;

  byte*  opptr = bc_codes.curRP();
  // No need for oplimit, since the codes are pre-counted.

  size_t codeBase = wpoffset();

  bool   isAload;  // copy-out result
  int    origBC;

  entry* thisClass  = cur_class;
  entry* superClass = cur_super;
  entry* newClass   = null;  // class of last _new opcode

  // overwrite any prior index on these bands; it changes w/ current class:
  bc_thisfield.setIndex(    cp.getFieldIndex( thisClass));
  bc_thismethod.setIndex(   cp.getMethodIndex(thisClass));
  if (superClass != null) {
    bc_superfield.setIndex( cp.getFieldIndex( superClass));
    bc_supermethod.setIndex(cp.getMethodIndex(superClass));
  } else {
    NOT_PRODUCT(bc_superfield.setIndex(null));
    NOT_PRODUCT(bc_supermethod.setIndex(null));
  }

  for (int curIP = 0; ; curIP++) {
    int curPC = wpoffset() - codeBase;
    bcimap.add(curPC);
    ensure_put_space(10);  // covers most instrs w/o further bounds check
    int bc = *opptr++ & 0xFF;

    putu1_fast(bc);
    // Note:  See '--wp' below for pseudo-bytecodes like bc_end_marker.

    bool isWide = false;
    if (bc == bc_wide) {
      bc = *opptr++ & 0xFF;
      putu1_fast(bc);
      isWide = true;
    }
    switch (bc) {
    case bc_end_marker:
      --wp;  // not really part of the code
      assert(opptr <= bc_codes.maxRP());
      bc_codes.curRP() = opptr;  // advance over this in bc_codes
      goto doneScanningMethod;
    case bc_tableswitch: // apc:  (df, lo, hi, (hi-lo+1)*(label))
    case bc_lookupswitch: // apc:  (df, nc, nc*(case, label))
      {
        int caseCount = bc_case_count.getInt();
        while (((wpoffset() - codeBase) % 4) != 0)  putu1_fast(0);
        ensure_put_space(30 + caseCount*8);
        put_label(curIP, 4);  //int df = bc_label.getInt();
        if (bc == bc_tableswitch) {
          int lo = bc_case_value.getInt();
          int hi = lo + caseCount-1;
          putu4(lo);
          putu4(hi);
          for (int j = 0; j < caseCount; j++) {
            put_label(curIP, 4); //int lVal = bc_label.getInt();
            //int cVal = lo + j;
          }
        } else {
          putu4(caseCount);
          for (int j = 0; j < caseCount; j++) {
            int cVal = bc_case_value.getInt();
            putu4(cVal);
            put_label(curIP, 4); //int lVal = bc_label.getInt();
          }
        }
        assert(to_bci(curIP) == curPC);
        continue;
      }
    case bc_iinc:
      {
        int local = bc_local.getInt();
        int delta = (isWide ? bc_short : bc_byte).getInt();
        if (isWide) {
          putu2(local);
          putu2(delta);
        } else {
          putu1_fast(local);
          putu1_fast(delta);
        }
        continue;
      }
    case bc_sipush:
      {
        int val = bc_short.getInt();
        putu2(val);
        continue;
      }
    case bc_bipush:
    case bc_newarray:
      {
        int val = bc_byte.getByte();
        putu1_fast(val);
        continue;
      }
    case bc_ref_escape:
      {
        // Note that insnMap has one entry for this.
        --wp;  // not really part of the code
        int size = bc_escrefsize.getInt();
        entry* ref = bc_escref.getRefN();
        CHECK;
        switch (size) {
        case 1: putu1ref(ref); break;
        case 2: putref(ref);   break;
        default: assert(false);
        }
        continue;
      }
    case bc_byte_escape:
      {
        // Note that insnMap has one entry for all these bytes.
        --wp;  // not really part of the code
        int size = bc_escsize.getInt();
        ensure_put_space(size);
        for (int j = 0; j < size; j++)
          putu1_fast(bc_escbyte.getByte());
        continue;
      }
    default:
      if (is_invoke_init_op(bc)) {
        origBC = bc_invokespecial;
        entry* classRef;
        switch (bc - _invokeinit_op) {
        case _invokeinit_self_option:   classRef = thisClass;  break;
        case _invokeinit_super_option:  classRef = superClass; break;
        default: assert(bc == _invokeinit_op+_invokeinit_new_option);
        case _invokeinit_new_option:    classRef = newClass;   break;
        }
        wp[-1] = origBC;  // overwrite with origBC
        int coding = bc_initref.getInt();
        // Find the nth overloading of <init> in classRef.
        entry*   ref = null;
        cpindex* ix = (classRef == null)? null: cp.getMethodIndex(classRef);
        for (int j = 0, which_init = 0; ; j++) {
          ref = (ix == null)? null: ix->get(j);
          if (ref == null)  break;  // oops, bad input
          assert(ref->tag == CONSTANT_Methodref);
          if (ref->memberDescr()->descrName() == cp.sym[cpool::s_lt_init_gt]) {
            if (which_init++ == coding)  break;
          }
        }
        putref(ref);
        continue;
      }
      bc_which = ref_band_for_self_op(bc, isAload, origBC);
      if (bc_which != null) {
        if (!isAload) {
          wp[-1] = origBC;  // overwrite with origBC
        } else {
          wp[-1] = bc_aload_0;  // overwrite with _aload_0
          // Note: insnMap keeps the _aload_0 separate.
          bcimap.add(++curPC);
          ++curIP;
          putu1_fast(origBC);
        }
        entry* ref = bc_which->getRef();
        CHECK;
        putref(ref);
        continue;
      }
      if (is_branch_op(bc)) {
        //int lVal = bc_label.getInt();
        if (bc < bc_goto_w) {
          put_label(curIP, 2);  //putu2(lVal & 0xFFFF);
        } else {
          assert(bc <= bc_jsr_w);
          put_label(curIP, 4);  //putu4(lVal);
        }
        assert(to_bci(curIP) == curPC);
        continue;
      }
      bc_which = ref_band_for_op(bc);
      if (bc_which != null) {
        entry* ref = bc_which->getRefCommon(bc_which->ix, bc_which->nullOK);
        CHECK;
        if (ref == null && bc_which == &bc_classref) {
          // Shorthand for class self-references.
          ref = thisClass;
        }
        origBC = bc;
        switch (bc) {
        case bc_ildc:
        case bc_cldc:
        case bc_fldc:
        case bc_aldc:
          origBC = bc_ldc;
          break;
        case bc_ildc_w:
        case bc_cldc_w:
        case bc_fldc_w:
        case bc_aldc_w:
          origBC = bc_ldc_w;
          break;
        case bc_lldc2_w:
        case bc_dldc2_w:
          origBC = bc_ldc2_w;
          break;
        case bc_new:
          newClass = ref;
          break;
        }
        wp[-1] = origBC;  // overwrite with origBC
        if (origBC == bc_ldc) {
          putu1ref(ref);
        } else {
          putref(ref);
        }
        if (origBC == bc_multianewarray) {
          // Copy the trailing byte also.
          int val = bc_byte.getByte();
          putu1_fast(val);
        } else if (origBC == bc_invokeinterface) {
          int argSize = ref->memberDescr()->descrType()->typeSize();
          putu1_fast(1 + argSize);
          putu1_fast(0);
        }
        continue;
      }
      if (is_local_slot_op(bc)) {
        int local = bc_local.getInt();
        if (isWide) {
          putu2(local);
          if (bc == bc_iinc) {
            int iVal = bc_short.getInt();
            putu2(iVal);
          }
        } else {
          putu1_fast(local);
          if (bc == bc_iinc) {
            int iVal = bc_byte.getByte();
            putu1_fast(iVal);
          }
        }
        continue;
      }
      // Random bytecode.  Just copy it.
      assert(bc < bc_bytecode_limit);
    }
  }
 doneScanningMethod:{}
  //bcimap.add(curPC);  // PC limit is already also in map, from bc_end_marker

  // Armed with a bcimap, we can now fix up all the labels.
  for (int i = 0; i < code_fixup_type.size(); i++) {
    int   type   = code_fixup_type.getByte(i);
    byte* bp     = wp_at(code_fixup_offset.get(i));
    int   curIP  = code_fixup_source.get(i);
    int   destIP = curIP + bc_label.getInt();
    int   span   = to_bci(destIP) - to_bci(curIP);
    switch (type) {
    case 2: putu2_at(bp, (ushort)span); break;
    case 4: putu4_at(bp,         span); break;
    default: assert(false);
    }
  }
}

inline  // called exactly once => inline
void unpacker::write_code() {
  int i, j;

  int max_stack, max_locals, handler_count, cflags;
  get_code_header(max_stack, max_locals, handler_count, cflags);

  if (max_stack < 0)      max_stack = code_max_stack.getInt();
  if (max_locals < 0)     max_locals = code_max_na_locals.getInt();
  if (handler_count < 0)  handler_count = code_handler_count.getInt();

  int siglen = cur_descr->descrType()->typeSize();
  CHECK;
  if ((cur_descr_flags & ACC_STATIC) == 0)  siglen++;
  max_locals += siglen;

  putu2(max_stack);
  putu2(max_locals);
  size_t bcbase = put_empty(4);

  // Write the bytecodes themselves.
  write_bc_ops();
  CHECK;

  byte* bcbasewp = wp_at(bcbase);
  putu4_at(bcbasewp, wp - (bcbasewp+4));  // size of code attr

  putu2(handler_count);
  for (j = 0; j < handler_count; j++) {
    int bii = code_handler_start_P.getInt();
    putu2(to_bci(bii));
    bii    += code_handler_end_PO.getInt();
    putu2(to_bci(bii));
    bii    += code_handler_catch_PO.getInt();
    putu2(to_bci(bii));
    putref(code_handler_class_RCN.getRefN());
    CHECK;
  }

  julong indexBits = cflags;
  if (cflags < 0) {
    bool haveLongFlags = attr_defs[ATTR_CONTEXT_CODE].haveLongFlags();
    indexBits = code_flags_hi.getLong(code_flags_lo, haveLongFlags);
  }
  write_attrs(ATTR_CONTEXT_CODE, indexBits);
}

int unpacker::write_attrs(int attrc, julong indexBits) {
  CHECK_0;
  if (indexBits == 0) {
    // Quick short-circuit.
    putu2(0);
    return 0;
  }

  attr_definitions& ad = attr_defs[attrc];

  int i, j, j2, idx, count;

  int oiCount = 0;
  if (ad.isPredefined(X_ATTR_OVERFLOW)
      && (indexBits & ((julong)1<<X_ATTR_OVERFLOW)) != 0) {
    indexBits -= ((julong)1<<X_ATTR_OVERFLOW);
    oiCount = ad.xxx_attr_count().getInt();
  }

  int bitIndexes[X_ATTR_LIMIT_FLAGS_HI];
  int biCount = 0;

  // Fill bitIndexes with index bits, in order.
  for (idx = 0; indexBits != 0; idx++, indexBits >>= 1) {
    if ((indexBits & 1) != 0)
      bitIndexes[biCount++] = idx;
  }
  assert(biCount <= lengthof(bitIndexes));

  // Write a provisional attribute count, perhaps to be corrected later.
  int naOffset = wpoffset();
  int na0 = biCount + oiCount;
  putu2(na0);

  int na = 0;
  for (i = 0; i < na0; i++) {
    if (i < biCount)
      idx = bitIndexes[i];
    else
      idx = ad.xxx_attr_indexes().getInt();
    assert(ad.isIndex(idx));
    entry* aname = null;
    entry* ref;  // scratch
    size_t abase = put_empty(2+4);
    CHECK_0;
    if (idx < ad.flag_limit && ad.isPredefined(idx)) {
      // Switch on the attrc and idx simultaneously.
      switch (ADH_BYTE(attrc, idx)) {

      case ADH_BYTE(ATTR_CONTEXT_CLASS,  X_ATTR_OVERFLOW):
      case ADH_BYTE(ATTR_CONTEXT_FIELD,  X_ATTR_OVERFLOW):
      case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_OVERFLOW):
      case ADH_BYTE(ATTR_CONTEXT_CODE,   X_ATTR_OVERFLOW):
        // no attribute at all, so back up on this one
        wp = wp_at(abase);
        continue;

      case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_ClassFile_version):
        cur_class_minver = class_ClassFile_version_minor_H.getInt();
        cur_class_majver = class_ClassFile_version_major_H.getInt();
        // back up; not a real attribute
        wp = wp_at(abase);
        continue;

      case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_InnerClasses):
        // note the existence of this attr, but save for later
        if (cur_class_has_local_ics)
          abort("too many InnerClasses attrs");
        cur_class_has_local_ics = true;
        wp = wp_at(abase);
        continue;

      case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_SourceFile):
        aname = cp.sym[cpool::s_SourceFile];
        ref = class_SourceFile_RUN.getRefN();
        CHECK_0;
        if (ref == null) {
          bytes& n = cur_class->ref(0)->value.b;
          // parse n = (<pkg>/)*<outer>?($<id>)*
          int pkglen = lastIndexOf(SLASH_MIN,  SLASH_MAX,  n, n.len)+1;
          bytes prefix = n.slice(pkglen, n.len);
          for (;;) {
            // Work backwards, finding all '$', '#', etc.
            int dollar = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, prefix, prefix.len);
            if (dollar < 0)  break;
            prefix = prefix.slice(0, dollar);
          }
          const char* suffix = ".java";
          int len = prefix.len + strlen(suffix);
          bytes name; name.set(T_NEW(byte, len + 1), len);
          name.strcat(prefix).strcat(suffix);
          ref = cp.ensureUtf8(name);
        }
        putref(ref);
        break;

      case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_EnclosingMethod):
        aname = cp.sym[cpool::s_EnclosingMethod];
        putref(class_EnclosingMethod_RC.getRefN());
        putref(class_EnclosingMethod_RDN.getRefN());
        break;

      case ADH_BYTE(ATTR_CONTEXT_FIELD, FIELD_ATTR_ConstantValue):
        aname = cp.sym[cpool::s_ConstantValue];
        putref(field_ConstantValue_KQ.getRefUsing(cp.getKQIndex()));
        break;

      case ADH_BYTE(ATTR_CONTEXT_METHOD, METHOD_ATTR_Code):
        aname = cp.sym[cpool::s_Code];
        write_code();
        break;

      case ADH_BYTE(ATTR_CONTEXT_METHOD, METHOD_ATTR_Exceptions):
        aname = cp.sym[cpool::s_Exceptions];
        putu2(count = method_Exceptions_N.getInt());
        for (j = 0; j < count; j++) {
          putref(method_Exceptions_RC.getRefN());
        }
        break;

      case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_StackMapTable):
        aname = cp.sym[cpool::s_StackMapTable];
        // (keep this code aligned with its brother in unpacker::read_attrs)
        putu2(count = code_StackMapTable_N.getInt());
        for (j = 0; j < count; j++) {
          int tag = code_StackMapTable_frame_T.getByte();
          putu1(tag);
          if (tag <= 127) {
            // (64-127)  [(2)]
            if (tag >= 64)  put_stackmap_type();
          } else if (tag <= 251) {
            // (247)     [(1)(2)]
            // (248-251) [(1)]
            if (tag >= 247)  putu2(code_StackMapTable_offset.getInt());
            if (tag == 247)  put_stackmap_type();
          } else if (tag <= 254) {
            // (252)     [(1)(2)]
            // (253)     [(1)(2)(2)]
            // (254)     [(1)(2)(2)(2)]
            putu2(code_StackMapTable_offset.getInt());
            for (int j2 = (tag - 251); j2 > 0; j2--) {
              put_stackmap_type();
            }
          } else {
            // (255)     [(1)NH[(2)]NH[(2)]]
            putu2(code_StackMapTable_offset.getInt());
            putu2(j2 = code_StackMapTable_local_N.getInt());
            while (j2-- > 0)  put_stackmap_type();
            putu2(j2 = code_StackMapTable_stack_N.getInt());
            while (j2-- > 0)  put_stackmap_type();
          }
        }
        break;

      case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LineNumberTable):
        aname = cp.sym[cpool::s_LineNumberTable];
        putu2(count = code_LineNumberTable_N.getInt());
        for (j = 0; j < count; j++) {
          putu2(to_bci(code_LineNumberTable_bci_P.getInt()));
          putu2(code_LineNumberTable_line.getInt());
        }
        break;

      case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LocalVariableTable):
        aname = cp.sym[cpool::s_LocalVariableTable];
        putu2(count = code_LocalVariableTable_N.getInt());
        for (j = 0; j < count; j++) {
          int bii = code_LocalVariableTable_bci_P.getInt();
          int bci = to_bci(bii);
          putu2(bci);
          bii    += code_LocalVariableTable_span_O.getInt();
          putu2(to_bci(bii) - bci);
          putref(code_LocalVariableTable_name_RU.getRefN());
          putref(code_LocalVariableTable_type_RS.getRefN());
          putu2(code_LocalVariableTable_slot.getInt());
        }
        break;

      case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LocalVariableTypeTable):
        aname = cp.sym[cpool::s_LocalVariableTypeTable];
        putu2(count = code_LocalVariableTypeTable_N.getInt());
        for (j = 0; j < count; j++) {
          int bii = code_LocalVariableTypeTable_bci_P.getInt();
          int bci = to_bci(bii);
          putu2(bci);
          bii    += code_LocalVariableTypeTable_span_O.getInt();
          putu2(to_bci(bii) - bci);
          putref(code_LocalVariableTypeTable_name_RU.getRefN());
          putref(code_LocalVariableTypeTable_type_RS.getRefN());
          putu2(code_LocalVariableTypeTable_slot.getInt());
        }
        break;

      case ADH_BYTE(ATTR_CONTEXT_CLASS, X_ATTR_Signature):
        aname = cp.sym[cpool::s_Signature];
        putref(class_Signature_RS.getRefN());
        break;

      case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_Signature):
        aname = cp.sym[cpool::s_Signature];
        putref(field_Signature_RS.getRefN());
        break;

      case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_Signature):
        aname = cp.sym[cpool::s_Signature];
        putref(method_Signature_RS.getRefN());
        break;

      case ADH_BYTE(ATTR_CONTEXT_CLASS,  X_ATTR_Deprecated):
      case ADH_BYTE(ATTR_CONTEXT_FIELD,  X_ATTR_Deprecated):
      case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_Deprecated):
        aname = cp.sym[cpool::s_Deprecated];
        // no data
        break;
      }
    }

    if (aname == null) {
      // Unparse a compressor-defined attribute.
      layout_definition* lo = ad.getLayout(idx);
      if (lo == null) {
        abort("bad layout index");
        break;
      }
      assert(lo->idx == idx);
      aname = lo->nameEntry;
      if (aname == null) {
        bytes nameb; nameb.set(lo->name);
        aname = cp.ensureUtf8(nameb);
        // Cache the name entry for next time.
        lo->nameEntry = aname;
      }
      // Execute all the layout elements.
      band** bands = lo->bands();
      if (lo->hasCallables()) {
        band& cble = *bands[0];
        assert(cble.le_kind == EK_CBLE);
        bands = cble.le_body;
      }
      putlayout(bands);
    }

    if (aname == null)
      abort("bad attribute index");
    CHECK_0;

    byte* wp1 = wp;
    wp = wp_at(abase);

    // DTRT if this attr is on the strip-list.
    // (Note that we emptied the data out of the band first.)
    if (ad.strip_names.contains(aname)) {
      continue;
    }

    // patch the name and length
    putref(aname);
    putu4(wp1 - (wp+4));  // put the attr size
    wp = wp1;
    na++;  // count the attrs actually written
  }

  if (na != na0)
    // Refresh changed count.
    putu2_at(wp_at(naOffset), na);
  return na;
}

void unpacker::write_members(int num, int attrc) {
  CHECK;
  attr_definitions& ad = attr_defs[attrc];
  band& member_flags_hi = ad.xxx_flags_hi();
  band& member_flags_lo = ad.xxx_flags_lo();
  band& member_descr = (&member_flags_hi)[e_field_descr-e_field_flags_hi];
  assert(endsWith(member_descr.name, "_descr"));
  assert(endsWith(member_flags_lo.name, "_flags_lo"));
  assert(endsWith(member_flags_lo.name, "_flags_lo"));
  bool haveLongFlags = ad.haveLongFlags();

  putu2(num);
  julong indexMask = attr_defs[attrc].flagIndexMask();
  for (int i = 0; i < num; i++) {
    julong mflags = member_flags_hi.getLong(member_flags_lo, haveLongFlags);
    entry* mdescr = member_descr.getRef();
    cur_descr = mdescr;
    putu2(cur_descr_flags = (ushort)(mflags & ~indexMask));
    CHECK;
    putref(mdescr->descrName());
    putref(mdescr->descrType());
    write_attrs(attrc, (mflags & indexMask));
    CHECK;
  }
  cur_descr = null;
}

extern "C"
int raw_address_cmp(const void* p1p, const void* p2p) {
  void* p1 = *(void**) p1p;
  void* p2 = *(void**) p2p;
  return (p1 > p2)? 1: (p1 < p2)? -1: 0;
}

void unpacker::write_classfile_tail() {
  cur_classfile_tail.empty();
  set_output(&cur_classfile_tail);

  int i, num;

  attr_definitions& ad = attr_defs[ATTR_CONTEXT_CLASS];

  bool haveLongFlags = ad.haveLongFlags();
  julong kflags = class_flags_hi.getLong(class_flags_lo, haveLongFlags);
  julong indexMask = ad.flagIndexMask();

  cur_class = class_this.getRef();
  cur_super = class_super.getRef();

  CHECK;

  if (cur_super == cur_class)  cur_super = null;
  // special representation for java/lang/Object

  putu2((ushort)(kflags & ~indexMask));
  putref(cur_class);
  putref(cur_super);

  putu2(num = class_interface_count.getInt());
  for (i = 0; i < num; i++) {
    putref(class_interface.getRef());
  }

  write_members(class_field_count.getInt(),  ATTR_CONTEXT_FIELD);
  write_members(class_method_count.getInt(), ATTR_CONTEXT_METHOD);
  CHECK;

  cur_class_has_local_ics = false;  // may be set true by write_attrs


  int naOffset = wpoffset();
  int na = write_attrs(ATTR_CONTEXT_CLASS, (kflags & indexMask));


  // at the very last, choose which inner classes (if any) pertain to k:
#ifdef ASSERT
  for (i = 0; i < ic_count; i++) {
    assert(!ics[i].requested);
  }
#endif
  // First, consult the global table and the local constant pool,
  // and decide on the globally implied inner classes.
  // (Note that we read the cpool's outputIndex fields, but we
  // do not yet write them, since the local IC attribute might
  // reverse a global decision to declare an IC.)
  assert(requested_ics.length() == 0);  // must start out empty
  // Always include all members of the current class.
  for (inner_class* child = cp.getFirstChildIC(cur_class);
       child != null;
       child = cp.getNextChildIC(child)) {
    child->requested = true;
    requested_ics.add(child);
  }
  // And, for each inner class mentioned in the constant pool,
  // include it and all its outers.
  int    noes =           cp.outputEntries.length();
  entry** oes = (entry**) cp.outputEntries.base();
  for (i = 0; i < noes; i++) {
    entry& e = *oes[i];
    if (e.tag != CONSTANT_Class)  continue;  // wrong sort
    for (inner_class* ic = cp.getIC(&e);
         ic != null;
         ic = cp.getIC(ic->outer)) {
      if (ic->requested)  break;  // already processed
      ic->requested = true;
      requested_ics.add(ic);
    }
  }
  int local_ics = requested_ics.length();
  // Second, consult a local attribute (if any) and adjust the global set.
  inner_class* extra_ics = null;
  int      num_extra_ics = 0;
  if (cur_class_has_local_ics) {
    // adjust the set of ICs by symmetric set difference w/ the locals
    num_extra_ics = class_InnerClasses_N.getInt();
    if (num_extra_ics == 0) {
      // Explicit zero count has an irregular meaning:  It deletes the attr.
      local_ics = 0;  // (short-circuit all tests of requested bits)
    } else {
      extra_ics = T_NEW(inner_class, num_extra_ics);
      // Note:  extra_ics will be freed up by next call to get_next_file().
    }
  }
  for (i = 0; i < num_extra_ics; i++) {
    inner_class& extra_ic = extra_ics[i];
    extra_ic.inner = class_InnerClasses_RC.getRef();
    CHECK;
    // Find the corresponding equivalent global IC:
    inner_class* global_ic = cp.getIC(extra_ic.inner);
    int flags = class_InnerClasses_F.getInt();
    if (flags == 0) {
      // The extra IC is simply a copy of a global IC.
      if (global_ic == null) {
        abort("bad reference to inner class");
        break;
      }
      extra_ic = (*global_ic);  // fill in rest of fields
    } else {
      flags &= ~ACC_IC_LONG_FORM;  // clear high bit if set to get clean zero
      extra_ic.flags = flags;
      extra_ic.outer = class_InnerClasses_outer_RCN.getRefN();
      extra_ic.name  = class_InnerClasses_name_RUN.getRefN();
      // Detect if this is an exact copy of the global tuple.
      if (global_ic != null) {
        if (global_ic->flags != extra_ic.flags ||
            global_ic->outer != extra_ic.outer ||
            global_ic->name  != extra_ic.name) {
          global_ic = null;  // not really the same, so break the link
        }
      }
    }
    if (global_ic != null && global_ic->requested) {
      // This local repetition reverses the globally implied request.
      global_ic->requested = false;
      extra_ic.requested = false;
      local_ics -= 1;
    } else {
      // The global either does not exist, or is not yet requested.
      extra_ic.requested = true;
      local_ics += 1;
    }
  }
  // Finally, if there are any that survived, put them into an attribute.
  // (Note that a zero-count attribute is always deleted.)
  // The putref calls below will tell the constant pool to add any
  // necessary local CP references to support the InnerClasses attribute.
  // This step must be the last round of additions to the local CP.
  if (local_ics > 0) {
    // append the new attribute:
    putref(cp.sym[cpool::s_InnerClasses]);
    putu4(2 + 2*4*local_ics);
    putu2(local_ics);
    PTRLIST_QSORT(requested_ics, raw_address_cmp);
    int num_global_ics = requested_ics.length();
    for (i = -num_global_ics; i < num_extra_ics; i++) {
      inner_class* ic;
      if (i < 0)
        ic = (inner_class*) requested_ics.get(num_global_ics+i);
      else
        ic = &extra_ics[i];
      if (ic->requested) {
        putref(ic->inner);
        putref(ic->outer);
        putref(ic->name);
        putu2(ic->flags);
        NOT_PRODUCT(local_ics--);
      }
    }
    assert(local_ics == 0);           // must balance
    putu2_at(wp_at(naOffset), ++na);  // increment class attr count
  }

  // Tidy up global 'requested' bits:
  for (i = requested_ics.length(); --i >= 0; ) {
    inner_class* ic = (inner_class*) requested_ics.get(i);
    ic->requested = false;
  }
  requested_ics.empty();

  CHECK;
  close_output();

  // rewrite CP references in the tail
  cp.computeOutputIndexes();
  int nextref = 0;
  for (i = 0; i < (int)class_fixup_type.size(); i++) {
    int    type = class_fixup_type.getByte(i);
    byte*  fixp = wp_at(class_fixup_offset.get(i));
    entry* e    = (entry*)class_fixup_ref.get(nextref++);
    int    idx  = e->getOutputIndex();
    switch (type) {
    case 1:  putu1_at(fixp, idx);  break;
    case 2:  putu2_at(fixp, idx);  break;
    default: assert(false);  // should not reach here
    }
  }
  CHECK;
}

void unpacker::write_classfile_head() {
  cur_classfile_head.empty();
  set_output(&cur_classfile_head);

  putu4(JAVA_MAGIC);
  putu2(cur_class_minver);
  putu2(cur_class_majver);
  putu2(cp.outputIndexLimit);

  int checkIndex = 1;
  int    noes =           cp.outputEntries.length();
  entry** oes = (entry**) cp.outputEntries.base();
  for (int i = 0; i < noes; i++) {
    entry& e = *oes[i];
    assert(e.getOutputIndex() == checkIndex++);
    byte tag = e.tag;
    assert(tag != CONSTANT_Signature);
    putu1(tag);
    switch (tag) {
    case CONSTANT_Utf8:
      putu2(e.value.b.len);
      put_bytes(e.value.b);
      break;
    case CONSTANT_Integer:
    case CONSTANT_Float:
      putu4(e.value.i);
      break;
    case CONSTANT_Long:
    case CONSTANT_Double:
      putu8(e.value.l);
      assert(checkIndex++);
      break;
    case CONSTANT_Class:
    case CONSTANT_String:
      // just write the ref
      putu2(e.refs[0]->getOutputIndex());
      break;
    case CONSTANT_Fieldref:
    case CONSTANT_Methodref:
    case CONSTANT_InterfaceMethodref:
    case CONSTANT_NameandType:
      putu2(e.refs[0]->getOutputIndex());
      putu2(e.refs[1]->getOutputIndex());
      break;
    default:
      abort(ERROR_INTERNAL);
    }
  }

#ifndef PRODUCT
  total_cp_size[0] += cp.outputIndexLimit;
  total_cp_size[1] += cur_classfile_head.size();
#endif
  close_output();
}

unpacker::file* unpacker::get_next_file() {
  CHECK_0;
  free_temps();
  if (files_remaining == 0) {
    // Leave a clue that we're exhausted.
    cur_file.name = null;
    cur_file.size = null;
    if (archive_size != 0) {
      julong predicted_size = unsized_bytes_read + archive_size;
      if (predicted_size != bytes_read)
        abort("archive header had incorrect size");
    }
    return null;
  }
  files_remaining -= 1;
  assert(files_written < file_count || classes_written < class_count);
  cur_file.name = "";
  cur_file.size = 0;
  cur_file.modtime = default_file_modtime;
  cur_file.options = default_file_options;
  cur_file.data[0].set(null, 0);
  cur_file.data[1].set(null, 0);
  if (files_written < file_count) {
    entry* e = file_name.getRef();
    CHECK_0;
    cur_file.name = e->utf8String();
    bool haveLongSize = ((archive_options & AO_HAVE_FILE_SIZE_HI) != 0);
    cur_file.size = file_size_hi.getLong(file_size_lo, haveLongSize);
    if ((archive_options & AO_HAVE_FILE_MODTIME) != 0)
      cur_file.modtime += file_modtime.getInt();  //relative to archive modtime
    if ((archive_options & AO_HAVE_FILE_OPTIONS) != 0)
      cur_file.options |= file_options.getInt() & ~suppress_file_options;
  } else if (classes_written < class_count) {
    // there is a class for a missing file record
    cur_file.options |= FO_IS_CLASS_STUB;
  }
  if ((cur_file.options & FO_IS_CLASS_STUB) != 0) {
    assert(classes_written < class_count);
    classes_written += 1;
    if (cur_file.size != 0) {
      abort("class file size transmitted");
      return null;
    }
    reset_cur_classfile();

    // write the meat of the classfile:
    write_classfile_tail();
    cur_file.data[1] = cur_classfile_tail.b;
    CHECK_0;

    // write the CP of the classfile, second:
    write_classfile_head();
    cur_file.data[0] = cur_classfile_head.b;
    CHECK_0;

    cur_file.size += cur_file.data[0].len;
    cur_file.size += cur_file.data[1].len;
    if (cur_file.name[0] == '\0') {
      bytes& prefix = cur_class->ref(0)->value.b;
      const char* suffix = ".class";
      int len = prefix.len + strlen(suffix);
      bytes name; name.set(T_NEW(byte, len + 1), len);
      cur_file.name = name.strcat(prefix).strcat(suffix).strval();
    }
  } else {
    // If there is buffered file data, produce a pointer to it.
    if (cur_file.size != (size_t) cur_file.size) {
      // Silly size specified.
      abort("resource file too large");
      return null;
    }
    size_t rpleft = input_remaining();
    if (rpleft > 0) {
      if (rpleft > cur_file.size)
        rpleft = (size_t) cur_file.size;
      cur_file.data[0].set(rp, rpleft);
      rp += rpleft;
    }
    if (rpleft < cur_file.size) {
      // Caller must read the rest.
      size_t fleft = cur_file.size - rpleft;
      bytes_read += fleft;  // Credit it to the overall archive size.
    }
  }
  CHECK_0;
  bytes_written += cur_file.size;
  files_written += 1;
  return &cur_file;
}

// Write a file to jarout.
void unpacker::write_file_to_jar(unpacker::file* f) {
  size_t htsize = f->data[0].len + f->data[1].len;
  julong fsize = f->size;
#ifndef PRODUCT
  if (nowrite NOT_PRODUCT(|| skipfiles-- > 0)) {
    printcr(2,"would write %d bytes to %s", (int) fsize, f->name);
    return;
  }
#endif
  if (htsize == fsize) {
    jarout->addJarEntry(f->name, f->deflate_hint(), f->modtime,
                        f->data[0], f->data[1]);
  } else {
    assert(input_remaining() == 0);
    bytes part1, part2;
    part1.len = f->data[0].len;
    part1.set(T_NEW(byte, part1.len), part1.len);
    part1.copyFrom(f->data[0]);
    assert(f->data[1].len == 0);
    part2.set(null, 0);
    size_t fleft = (size_t) fsize - part1.len;
    assert(bytes_read > fleft);  // part2 already credited by get_next_file
    bytes_read -= fleft;
    if (fleft > 0) {
      // Must read some more.
      if (live_input) {
        // Stop using the input buffer.  Make a new one:
        if (free_input)  input.free();
        input.init(fleft > (1<<12) ? fleft : (1<<12));
        free_input = true;
        live_input = false;
      } else {
        // Make it large enough.
        assert(free_input);  // must be reallocable
        input.ensureSize(fleft);
      }
      rplimit = rp = input.base();
      input.setLimit(rp + fleft);
      if (!ensure_input(fleft))
        abort("EOF reading resource file");
      part2.ptr = input_scan();
      part2.len = input_remaining();
      rplimit = rp = input.base();
    }
    jarout->addJarEntry(f->name, f->deflate_hint(), f->modtime,
                        part1, part2);
  }
  if (verbose >= 3) {
    fprintf(errstrm, "Wrote %lld bytes to: %s\n", fsize, f->name);
  }
}

// Redirect the stdio to the specified file in the unpack.log.file option
void unpacker::redirect_stdio() {
  if (log_file == null) {
    log_file = LOGFILE_STDOUT;
  }
  if (log_file == errstrm_name)
    // Nothing more to be done.
    return;
  errstrm_name = log_file;
  if (strcmp(log_file, LOGFILE_STDERR) == 0) {
    errstrm = stderr;
    return;
  } else if (strcmp(log_file, LOGFILE_STDOUT) == 0) {
    errstrm = stdout;
    return;
  } else if (log_file[0] != '\0' && (errstrm = fopen(log_file,"a+")) != NULL) {
    return;
  } else {
    char log_file_name[PATH_MAX+100];
    char tmpdir[PATH_MAX];
#ifdef WIN32
    int n = GetTempPath(PATH_MAX,tmpdir); //API returns with trailing '\'
    if (n < 1 || n > PATH_MAX) {
      sprintf(tmpdir,"C:\\");
    }
    sprintf(log_file_name, "%sunpack.log", tmpdir);
#else
    sprintf(tmpdir,"/tmp");
    sprintf(log_file_name, "/tmp/unpack.log");
#endif
    if ((errstrm = fopen(log_file_name, "a+")) != NULL) {
      log_file = errstrm_name = saveStr(log_file_name);
      return ;
    }

    char *tname = tempnam(tmpdir,"#upkg");
    sprintf(log_file_name, "%s", tname);
    if ((errstrm = fopen(log_file_name, "a+")) != NULL) {
      log_file = errstrm_name = saveStr(log_file_name);
      return ;
    }
#ifndef WIN32
    sprintf(log_file_name, "/dev/null");
    // On windows most likely it will fail.
    if ( (errstrm = fopen(log_file_name, "a+")) != NULL) {
      log_file = errstrm_name = saveStr(log_file_name);
      return ;
    }
#endif
    // Last resort
    // (Do not use stdout, since it might be jarout->jarfp.)
    errstrm = stderr;
    log_file = errstrm_name = LOGFILE_STDERR;
  }
}

#ifndef PRODUCT
int unpacker::printcr_if_verbose(int level, const char* fmt ...) {
  if (verbose < level+10)  return 0;
  va_list vl;
  va_start(vl, fmt);
  char fmtbuf[300];
  strcpy(fmtbuf+100, fmt);
  strcat(fmtbuf+100, "\n");
  char* fmt2 = fmtbuf+100;
  while (level-- > 0)  *--fmt2 = ' ';
  vfprintf(errstrm, fmt2, vl);
  return 1;  // for ?: usage
}
#endif

void unpacker::abort(const char* message) {
  if (message == null)  message = "error unpacking archive";
#ifdef UNPACK_JNI
  if (message[0] == '@') {  // secret convention for sprintf
     bytes saved;
     saved.saveFrom(message+1);
     mallocs.add(message = saved.strval());
   }
  abort_message = message;
  return;
#else
  if (message[0] == '@')  ++message;
  fprintf(errstrm, "%s\n", message);
#ifndef PRODUCT
  fflush(errstrm);
  ::abort();
#else
  exit(-1);
#endif
#endif // JNI
}
