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