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