| 1 11 package org.eclipse.jdt.internal.compiler; 12 13 import java.io.BufferedOutputStream ; 14 import java.io.File ; 15 import java.io.FileOutputStream ; 16 import java.io.IOException ; 17 import java.util.ArrayList ; 18 import java.util.Arrays ; 19 import java.util.Collections ; 20 import java.util.Comparator ; 21 import java.util.HashSet ; 22 import java.util.Set ; 23 import java.util.StringTokenizer ; 24 25 import org.eclipse.jdt.core.compiler.CategorizedProblem; 26 import org.eclipse.jdt.core.compiler.CharOperation; 27 import org.eclipse.jdt.core.compiler.IProblem; 28 import org.eclipse.jdt.internal.compiler.ast.ASTNode; 29 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; 30 import org.eclipse.jdt.internal.compiler.ast.Annotation; 31 import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration; 32 import org.eclipse.jdt.internal.compiler.ast.Argument; 33 import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer; 34 import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess; 35 import org.eclipse.jdt.internal.compiler.ast.Expression; 36 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; 37 import org.eclipse.jdt.internal.compiler.ast.MemberValuePair; 38 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; 39 import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation; 40 import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; 41 import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation; 42 import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; 43 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; 44 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 45 import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants; 46 import org.eclipse.jdt.internal.compiler.codegen.CodeStream; 47 import org.eclipse.jdt.internal.compiler.codegen.ConstantPool; 48 import org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel; 49 import org.eclipse.jdt.internal.compiler.codegen.VerificationTypeInfo; 50 import org.eclipse.jdt.internal.compiler.codegen.StackMapFrame; 51 import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream; 52 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; 53 import org.eclipse.jdt.internal.compiler.impl.Constant; 54 import org.eclipse.jdt.internal.compiler.impl.StringConstant; 55 import org.eclipse.jdt.internal.compiler.lookup.Binding; 56 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; 57 import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding; 58 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; 59 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; 60 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; 61 import org.eclipse.jdt.internal.compiler.lookup.NestedTypeBinding; 62 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; 63 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; 64 import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding; 65 import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding; 66 import org.eclipse.jdt.internal.compiler.lookup.TagBits; 67 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 68 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; 69 import org.eclipse.jdt.internal.compiler.lookup.TypeIds; 70 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; 71 import org.eclipse.jdt.internal.compiler.util.Messages; 72 import org.eclipse.jdt.internal.compiler.util.Util; 73 74 92 public class ClassFile 93 implements TypeConstants, TypeIds { 94 95 private byte[] bytes; 96 public CodeStream codeStream; 97 public ConstantPool constantPool; 98 99 public int constantPoolOffset; 100 101 public byte[] contents; 103 104 public int contentsOffset; 105 106 protected boolean creatingProblemType; 107 108 public ClassFile enclosingClassFile; 109 public byte[] header; 110 public int headerOffset; 112 public Set innerClassesBindings; 113 public int methodCount; 114 public int methodCountOffset; 115 public boolean isShared = false; 117 public int produceAttributes; 120 public SourceTypeBinding referenceBinding; 121 public long targetJDK; 122 public static final int INITIAL_CONTENTS_SIZE = 400; 123 public static final int INITIAL_HEADER_SIZE = 1500; 124 public static final int INNER_CLASSES_SIZE = 5; 125 126 140 public static String buildAllDirectoriesInto( 141 String outputPath, 142 String relativeFileName) 143 throws IOException { 144 char fileSeparatorChar = File.separatorChar; 145 String fileSeparator = File.separator; 146 File f; 147 outputPath = outputPath.replace('/', fileSeparatorChar); 148 relativeFileName = relativeFileName.replace('/', fileSeparatorChar); 151 String outputDirPath, fileName; 152 int separatorIndex = relativeFileName.lastIndexOf(fileSeparatorChar); 153 if (separatorIndex == -1) { 154 if (outputPath.endsWith(fileSeparator)) { 155 outputDirPath = outputPath.substring(0, outputPath.length() - 1); 156 fileName = outputPath + relativeFileName; 157 } else { 158 outputDirPath = outputPath; 159 fileName = outputPath + fileSeparator + relativeFileName; 160 } 161 } else { 162 if (outputPath.endsWith(fileSeparator)) { 163 outputDirPath = outputPath + 164 relativeFileName.substring(0, separatorIndex); 165 fileName = outputPath + relativeFileName; 166 } else { 167 outputDirPath = outputPath + fileSeparator + 168 relativeFileName.substring(0, separatorIndex); 169 fileName = outputPath + fileSeparator + relativeFileName; 170 } 171 } 172 f = new File (outputDirPath); 173 f.mkdirs(); 174 if (f.isDirectory()) { 175 return fileName; 176 } else { 177 if (outputPath.endsWith(fileSeparator)) { 180 outputPath = outputPath.substring(0, outputPath.length() - 1); 181 } 182 f = new File (outputPath); 183 boolean checkFileType = false; 184 if (f.exists()) { 185 checkFileType = true; } else { 187 if (!f.mkdirs()) { 189 if (f.exists()) { 190 checkFileType = true; 192 } else { 193 throw new IOException (Messages.bind( 195 Messages.output_notValidAll, f.getAbsolutePath())); 196 } 197 } 198 } 199 if (checkFileType) { 200 if (!f.isDirectory()) { 201 throw new IOException (Messages.bind( 202 Messages.output_isFile, f.getAbsolutePath())); 203 } 204 } 205 StringBuffer outDir = new StringBuffer (outputPath); 206 outDir.append(fileSeparator); 207 StringTokenizer tokenizer = 208 new StringTokenizer (relativeFileName, fileSeparator); 209 String token = tokenizer.nextToken(); 210 while (tokenizer.hasMoreTokens()) { 211 f = new File (outDir.append(token).append(fileSeparator).toString()); 212 checkFileType = false; if (f.exists()) { 214 checkFileType = true; } else { 217 if (!f.mkdir()) { 219 if (f.exists()) { 220 checkFileType = true; 222 } else { 223 throw new IOException (Messages.bind( 225 Messages.output_notValid, 226 outDir.substring(outputPath.length() + 1, 227 outDir.length() - 1), 228 outputPath)); 229 } 230 } 231 } 232 if (checkFileType) { 233 if (!f.isDirectory()) { 234 throw new IOException (Messages.bind( 235 Messages.output_isFile, f.getAbsolutePath())); 236 } 237 } 238 token = tokenizer.nextToken(); 239 } 240 return outDir.append(token).toString(); 242 } 243 } 244 251 public static void createProblemType( 252 TypeDeclaration typeDeclaration, 253 CompilationResult unitResult) { 254 SourceTypeBinding typeBinding = typeDeclaration.binding; 255 ClassFile classFile = ClassFile.getNewInstance(typeBinding); 256 classFile.initialize(typeBinding, null, true); 257 258 if (typeBinding.hasMemberTypes()) { 259 ReferenceBinding[] members = typeBinding.memberTypes; 261 for (int i = 0, l = members.length; i < l; i++) 262 classFile.recordInnerClasses(members[i]); 263 } 264 if (typeBinding.isNestedType()) { 268 classFile.recordInnerClasses(typeBinding); 269 } 270 271 FieldBinding[] fields = typeBinding.fields(); 273 if ((fields != null) && (fields != Binding.NO_FIELDS)) { 274 classFile.addFieldInfos(); 275 } else { 276 classFile.contents[classFile.contentsOffset++] = 0; 278 classFile.contents[classFile.contentsOffset++] = 0; 279 } 280 classFile.setForMethodInfos(); 282 int problemsLength; 284 CategorizedProblem[] problems = unitResult.getErrors(); 285 if (problems == null) { 286 problems = new CategorizedProblem[0]; 287 } 288 CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length]; 289 System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); 290 291 AbstractMethodDeclaration[] methodDecls = typeDeclaration.methods; 292 if (methodDecls != null) { 293 if (typeBinding.isInterface()) { 294 classFile.addProblemClinit(problemsCopy); 297 for (int i = 0, length = methodDecls.length; i < length; i++) { 298 AbstractMethodDeclaration methodDecl = methodDecls[i]; 299 MethodBinding method = methodDecl.binding; 300 if (method == null || method.isConstructor()) continue; 301 classFile.addAbstractMethod(methodDecl, method); 302 } 303 } else { 304 for (int i = 0, length = methodDecls.length; i < length; i++) { 305 AbstractMethodDeclaration methodDecl = methodDecls[i]; 306 MethodBinding method = methodDecl.binding; 307 if (method == null) continue; 308 if (method.isConstructor()) { 309 classFile.addProblemConstructor(methodDecl, method, problemsCopy); 310 } else { 311 classFile.addProblemMethod(methodDecl, method, problemsCopy); 312 } 313 } 314 } 315 classFile.addDefaultAbstractMethods(); 317 } 318 319 if (typeDeclaration.memberTypes != null) { 321 for (int i = 0, max = typeDeclaration.memberTypes.length; i < max; i++) { 322 TypeDeclaration memberType = typeDeclaration.memberTypes[i]; 323 if (memberType.binding != null) { 324 ClassFile.createProblemType(memberType, unitResult); 325 } 326 } 327 } 328 classFile.addAttributes(); 329 unitResult.record(typeBinding.constantPoolName(), classFile); 330 } 331 public static ClassFile getNewInstance(SourceTypeBinding typeBinding) { 332 LookupEnvironment env = typeBinding.scope.environment(); 333 return env.classFilePool.acquire(typeBinding); 334 } 335 336 348 public static void writeToDisk( 349 boolean generatePackagesStructure, 350 String outputPath, 351 String relativeFileName, 352 ClassFile classFile) throws IOException { 353 354 BufferedOutputStream output = null; 355 if (generatePackagesStructure) { 356 output = new BufferedOutputStream ( 357 new FileOutputStream ( 358 new File (buildAllDirectoriesInto(outputPath, relativeFileName)))); 359 } else { 360 String fileName = null; 361 char fileSeparatorChar = File.separatorChar; 362 String fileSeparator = File.separator; 363 outputPath = outputPath.replace('/', fileSeparatorChar); 365 int indexOfPackageSeparator = relativeFileName.lastIndexOf(fileSeparatorChar); 367 if (indexOfPackageSeparator == -1) { 368 if (outputPath.endsWith(fileSeparator)) { 369 fileName = outputPath + relativeFileName; 370 } else { 371 fileName = outputPath + fileSeparator + relativeFileName; 372 } 373 } else { 374 int length = relativeFileName.length(); 375 if (outputPath.endsWith(fileSeparator)) { 376 fileName = outputPath + relativeFileName.substring(indexOfPackageSeparator + 1, length); 377 } else { 378 fileName = outputPath + fileSeparator + relativeFileName.substring(indexOfPackageSeparator + 1, length); 379 } 380 } 381 output = new BufferedOutputStream ( 382 new FileOutputStream ( 383 new File (fileName))); 384 } 385 try { 386 output.write(classFile.header, 0, classFile.headerOffset); 388 output.write(classFile.contents, 0, classFile.contentsOffset); 389 output.flush(); 390 } catch(IOException e) { 391 throw e; 392 } finally { 393 output.close(); 394 } 395 } 396 397 401 protected ClassFile() { 402 } 404 405 public ClassFile(SourceTypeBinding typeBinding) { 406 this.constantPool = new ConstantPool(this); 408 final CompilerOptions options = typeBinding.scope.compilerOptions(); 409 this.targetJDK = options.targetJDK; 410 this.produceAttributes = options.produceDebugAttributes; 411 this.referenceBinding = typeBinding; 412 if (this.targetJDK >= ClassFileConstants.JDK1_6) { 413 this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP; 414 this.codeStream = new StackMapFrameCodeStream(this); 415 } else { 416 this.codeStream = new CodeStream(this); 417 } 418 this.initByteArrays(); 419 } 420 421 428 public void addAbstractMethod( 429 AbstractMethodDeclaration method, 430 MethodBinding methodBinding) { 431 432 methodBinding.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract; 434 435 this.generateMethodInfoHeader(methodBinding); 436 int methodAttributeOffset = this.contentsOffset; 437 int attributeNumber = this.generateMethodInfoAttribute(methodBinding); 438 this.completeMethodInfo(methodAttributeOffset, attributeNumber); 439 } 440 441 449 public void addAttributes() { 450 contents[methodCountOffset++] = (byte) (methodCount >> 8); 452 contents[methodCountOffset] = (byte) methodCount; 453 454 int attributeNumber = 0; 455 int attributeOffset = contentsOffset; 457 contentsOffset += 2; 458 459 if ((produceAttributes & ClassFileConstants.ATTR_SOURCE) != 0) { 461 String fullFileName = 462 new String (referenceBinding.scope.referenceCompilationUnit().getFileName()); 463 fullFileName = fullFileName.replace('\\', '/'); 464 int lastIndex = fullFileName.lastIndexOf('/'); 465 if (lastIndex != -1) { 466 fullFileName = fullFileName.substring(lastIndex + 1, fullFileName.length()); 467 } 468 if (contentsOffset + 8 >= contents.length) { 471 resizeContents(8); 472 } 473 int sourceAttributeNameIndex = 474 constantPool.literalIndex(AttributeNamesConstants.SourceName); 475 contents[contentsOffset++] = (byte) (sourceAttributeNameIndex >> 8); 476 contents[contentsOffset++] = (byte) sourceAttributeNameIndex; 477 contents[contentsOffset++] = 0; 480 contents[contentsOffset++] = 0; 481 contents[contentsOffset++] = 0; 482 contents[contentsOffset++] = 2; 483 int fileNameIndex = constantPool.literalIndex(fullFileName.toCharArray()); 485 contents[contentsOffset++] = (byte) (fileNameIndex >> 8); 486 contents[contentsOffset++] = (byte) fileNameIndex; 487 attributeNumber++; 488 } 489 if (referenceBinding.isDeprecated()) { 491 if (contentsOffset + 6 >= contents.length) { 494 resizeContents(6); 495 } 496 int deprecatedAttributeNameIndex = 497 constantPool.literalIndex(AttributeNamesConstants.DeprecatedName); 498 contents[contentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8); 499 contents[contentsOffset++] = (byte) deprecatedAttributeNameIndex; 500 contents[contentsOffset++] = 0; 502 contents[contentsOffset++] = 0; 503 contents[contentsOffset++] = 0; 504 contents[contentsOffset++] = 0; 505 attributeNumber++; 506 } 507 char[] genericSignature = referenceBinding.genericSignature(); 509 if (genericSignature != null) { 510 if (contentsOffset + 8 >= contents.length) { 513 resizeContents(8); 514 } 515 int signatureAttributeNameIndex = 516 constantPool.literalIndex(AttributeNamesConstants.SignatureName); 517 contents[contentsOffset++] = (byte) (signatureAttributeNameIndex >> 8); 518 contents[contentsOffset++] = (byte) signatureAttributeNameIndex; 519 contents[contentsOffset++] = 0; 521 contents[contentsOffset++] = 0; 522 contents[contentsOffset++] = 0; 523 contents[contentsOffset++] = 2; 524 int signatureIndex = 525 constantPool.literalIndex(genericSignature); 526 contents[contentsOffset++] = (byte) (signatureIndex >> 8); 527 contents[contentsOffset++] = (byte) signatureIndex; 528 attributeNumber++; 529 } 530 if (targetJDK >= ClassFileConstants.JDK1_5 531 && this.referenceBinding.isNestedType() 532 && !this.referenceBinding.isMemberType()) { 533 if (contentsOffset + 10 >= contents.length) { 535 resizeContents(10); 536 } 537 int enclosingMethodAttributeNameIndex = 538 constantPool.literalIndex(AttributeNamesConstants.EnclosingMethodName); 539 contents[contentsOffset++] = (byte) (enclosingMethodAttributeNameIndex >> 8); 540 contents[contentsOffset++] = (byte) enclosingMethodAttributeNameIndex; 541 contents[contentsOffset++] = 0; 543 contents[contentsOffset++] = 0; 544 contents[contentsOffset++] = 0; 545 contents[contentsOffset++] = 4; 546 547 int enclosingTypeIndex = constantPool.literalIndexForType(this.referenceBinding.enclosingType().constantPoolName()); 548 contents[contentsOffset++] = (byte) (enclosingTypeIndex >> 8); 549 contents[contentsOffset++] = (byte) enclosingTypeIndex; 550 byte methodIndexByte1 = 0; 551 byte methodIndexByte2 = 0; 552 if (this.referenceBinding instanceof LocalTypeBinding) { 553 MethodBinding methodBinding = ((LocalTypeBinding) this.referenceBinding).enclosingMethod; 554 if (methodBinding != null) { 555 int enclosingMethodIndex = constantPool.literalIndexForNameAndType(methodBinding.selector, methodBinding.signature(this)); 556 methodIndexByte1 = (byte) (enclosingMethodIndex >> 8); 557 methodIndexByte2 = (byte) enclosingMethodIndex; 558 } 559 } 560 contents[contentsOffset++] = methodIndexByte1; 561 contents[contentsOffset++] = methodIndexByte2; 562 attributeNumber++; 563 } 564 if (this.targetJDK >= ClassFileConstants.JDK1_5 && !this.creatingProblemType) { 565 TypeDeclaration typeDeclaration = referenceBinding.scope.referenceContext; 566 if (typeDeclaration != null) { 567 final Annotation[] annotations = typeDeclaration.annotations; 568 if (annotations != null) { 569 attributeNumber += generateRuntimeAnnotations(annotations); 570 } 571 } 572 } 573 574 if (this.referenceBinding.isHierarchyInconsistent()) { 575 if (contentsOffset + 6 >= contents.length) { 577 resizeContents(6); 578 } 579 int inconsistentHierarchyNameIndex = 580 constantPool.literalIndex(AttributeNamesConstants.InconsistentHierarchy); 581 contents[contentsOffset++] = (byte) (inconsistentHierarchyNameIndex >> 8); 582 contents[contentsOffset++] = (byte) inconsistentHierarchyNameIndex; 583 contents[contentsOffset++] = 0; 585 contents[contentsOffset++] = 0; 586 contents[contentsOffset++] = 0; 587 contents[contentsOffset++] = 0; 588 attributeNumber++; 589 } 590 int numberOfInnerClasses = this.innerClassesBindings == null ? 0 : this.innerClassesBindings.size(); 592 if (numberOfInnerClasses != 0) { 593 ReferenceBinding[] innerClasses = new ReferenceBinding[numberOfInnerClasses]; 594 this.innerClassesBindings.toArray(innerClasses); 595 Arrays.sort(innerClasses, new Comparator () { 596 public int compare(Object o1, Object o2) { 597 TypeBinding binding1 = (TypeBinding) o1; 598 TypeBinding binding2 = (TypeBinding) o2; 599 return CharOperation.compareTo(binding1.constantPoolName(), binding2.constantPoolName()); 600 } 601 }); 602 int exSize = 8 * numberOfInnerClasses + 8; 604 if (exSize + contentsOffset >= this.contents.length) { 605 resizeContents(exSize); 606 } 607 int attributeNameIndex = 610 constantPool.literalIndex(AttributeNamesConstants.InnerClassName); 611 contents[contentsOffset++] = (byte) (attributeNameIndex >> 8); 612 contents[contentsOffset++] = (byte) attributeNameIndex; 613 int value = (numberOfInnerClasses << 3) + 2; 614 contents[contentsOffset++] = (byte) (value >> 24); 615 contents[contentsOffset++] = (byte) (value >> 16); 616 contents[contentsOffset++] = (byte) (value >> 8); 617 contents[contentsOffset++] = (byte) value; 618 contents[contentsOffset++] = (byte) (numberOfInnerClasses >> 8); 619 contents[contentsOffset++] = (byte) numberOfInnerClasses; 620 for (int i = 0; i < numberOfInnerClasses; i++) { 621 ReferenceBinding innerClass = innerClasses[i]; 622 int accessFlags = innerClass.getAccessFlags(); 623 int innerClassIndex = constantPool.literalIndexForType(innerClass.constantPoolName()); 624 contents[contentsOffset++] = (byte) (innerClassIndex >> 8); 626 contents[contentsOffset++] = (byte) innerClassIndex; 627 if (innerClass.isMemberType()) { 629 int outerClassIndex = constantPool.literalIndexForType(innerClass.enclosingType().constantPoolName()); 631 contents[contentsOffset++] = (byte) (outerClassIndex >> 8); 632 contents[contentsOffset++] = (byte) outerClassIndex; 633 } else { 634 contents[contentsOffset++] = 0; 636 contents[contentsOffset++] = 0; 637 } 638 if (!innerClass.isAnonymousType()) { 640 int nameIndex = constantPool.literalIndex(innerClass.sourceName()); 641 contents[contentsOffset++] = (byte) (nameIndex >> 8); 642 contents[contentsOffset++] = (byte) nameIndex; 643 } else { 644 contents[contentsOffset++] = 0; 646 contents[contentsOffset++] = 0; 647 } 648 if (innerClass.isAnonymousType()) { 650 accessFlags &= ~ClassFileConstants.AccFinal; 651 } else if (innerClass.isMemberType() && innerClass.isInterface()) { 652 accessFlags |= ClassFileConstants.AccStatic; } 654 contents[contentsOffset++] = (byte) (accessFlags >> 8); 655 contents[contentsOffset++] = (byte) accessFlags; 656 } 657 attributeNumber++; 658 } 659 if (attributeOffset + 2 >= this.contents.length) { 661 resizeContents(2); 662 } 663 contents[attributeOffset++] = (byte) (attributeNumber >> 8); 664 contents[attributeOffset] = (byte) attributeNumber; 665 666 header = constantPool.poolContent; 668 headerOffset = constantPool.currentOffset; 669 int constantPoolCount = constantPool.currentIndex; 670 header[constantPoolOffset++] = (byte) (constantPoolCount >> 8); 671 header[constantPoolOffset] = (byte) constantPoolCount; 672 } 673 674 679 public void addDefaultAbstractMethods() { MethodBinding[] defaultAbstractMethods = 681 referenceBinding.getDefaultAbstractMethods(); 682 for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) { 683 generateMethodInfoHeader(defaultAbstractMethods[i]); 684 int methodAttributeOffset = contentsOffset; 685 int attributeNumber = generateMethodInfoAttribute(defaultAbstractMethods[i]); 686 completeMethodInfo(methodAttributeOffset, attributeNumber); 687 } 688 } 689 690 private int addFieldAttributes(FieldBinding fieldBinding, int fieldAttributeOffset) { 691 int attributesNumber = 0; 692 Constant fieldConstant = fieldBinding.constant(); 695 if (fieldConstant != Constant.NotAConstant){ 696 if (contentsOffset + 8 >= contents.length) { 697 resizeContents(8); 698 } 699 int constantValueNameIndex = 701 constantPool.literalIndex(AttributeNamesConstants.ConstantValueName); 702 contents[contentsOffset++] = (byte) (constantValueNameIndex >> 8); 703 contents[contentsOffset++] = (byte) constantValueNameIndex; 704 contents[contentsOffset++] = 0; 706 contents[contentsOffset++] = 0; 707 contents[contentsOffset++] = 0; 708 contents[contentsOffset++] = 2; 709 attributesNumber++; 710 switch (fieldConstant.typeID()) { 712 case T_boolean : 713 int booleanValueIndex = 714 constantPool.literalIndex(fieldConstant.booleanValue() ? 1 : 0); 715 contents[contentsOffset++] = (byte) (booleanValueIndex >> 8); 716 contents[contentsOffset++] = (byte) booleanValueIndex; 717 break; 718 case T_byte : 719 case T_char : 720 case T_int : 721 case T_short : 722 int integerValueIndex = 723 constantPool.literalIndex(fieldConstant.intValue()); 724 contents[contentsOffset++] = (byte) (integerValueIndex >> 8); 725 contents[contentsOffset++] = (byte) integerValueIndex; 726 break; 727 case T_float : 728 int floatValueIndex = 729 constantPool.literalIndex(fieldConstant.floatValue()); 730 contents[contentsOffset++] = (byte) (floatValueIndex >> 8); 731 contents[contentsOffset++] = (byte) floatValueIndex; 732 break; 733 case T_double : 734 int doubleValueIndex = 735 constantPool.literalIndex(fieldConstant.doubleValue()); 736 contents[contentsOffset++] = (byte) (doubleValueIndex >> 8); 737 contents[contentsOffset++] = (byte) doubleValueIndex; 738 break; 739 case T_long : 740 int longValueIndex = 741 constantPool.literalIndex(fieldConstant.longValue()); 742 contents[contentsOffset++] = (byte) (longValueIndex >> 8); 743 contents[contentsOffset++] = (byte) longValueIndex; 744 break; 745 case T_JavaLangString : 746 int stringValueIndex = 747 constantPool.literalIndex( 748 ((StringConstant) fieldConstant).stringValue()); 749 if (stringValueIndex == -1) { 750 if (!creatingProblemType) { 751 TypeDeclaration typeDeclaration = referenceBinding.scope.referenceContext; 753 FieldDeclaration[] fieldDecls = typeDeclaration.fields; 754 for (int i = 0, max = fieldDecls.length; i < max; i++) { 755 if (fieldDecls[i].binding == fieldBinding) { 756 typeDeclaration.scope.problemReporter().stringConstantIsExceedingUtf8Limit( 758 fieldDecls[i]); 759 } 760 } 761 } else { 762 contentsOffset = fieldAttributeOffset; 764 } 765 } else { 766 contents[contentsOffset++] = (byte) (stringValueIndex >> 8); 767 contents[contentsOffset++] = (byte) stringValueIndex; 768 } 769 } 770 } 771 if (this.targetJDK < ClassFileConstants.JDK1_5 && fieldBinding.isSynthetic()) { 772 if (contentsOffset + 6 >= contents.length) { 773 resizeContents(6); 774 } 775 int syntheticAttributeNameIndex = 776 constantPool.literalIndex(AttributeNamesConstants.SyntheticName); 777 contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8); 778 contents[contentsOffset++] = (byte) syntheticAttributeNameIndex; 779 contents[contentsOffset++] = 0; 781 contents[contentsOffset++] = 0; 782 contents[contentsOffset++] = 0; 783 contents[contentsOffset++] = 0; 784 attributesNumber++; 785 } 786 if (fieldBinding.isDeprecated()) { 787 if (contentsOffset + 6 >= contents.length) { 788 resizeContents(6); 789 } 790 int deprecatedAttributeNameIndex = 791 constantPool.literalIndex(AttributeNamesConstants.DeprecatedName); 792 contents[contentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8); 793 contents[contentsOffset++] = (byte) deprecatedAttributeNameIndex; 794 contents[contentsOffset++] = 0; 796 contents[contentsOffset++] = 0; 797 contents[contentsOffset++] = 0; 798 contents[contentsOffset++] = 0; 799 attributesNumber++; 800 } 801 char[] genericSignature = fieldBinding.genericSignature(); 803 if (genericSignature != null) { 804 if (contentsOffset + 8 >= contents.length) { 807 resizeContents(8); 808 } 809 int signatureAttributeNameIndex = 810 constantPool.literalIndex(AttributeNamesConstants.SignatureName); 811 contents[contentsOffset++] = (byte) (signatureAttributeNameIndex >> 8); 812 contents[contentsOffset++] = (byte) signatureAttributeNameIndex; 813 contents[contentsOffset++] = 0; 815 contents[contentsOffset++] = 0; 816 contents[contentsOffset++] = 0; 817 contents[contentsOffset++] = 2; 818 int signatureIndex = 819 constantPool.literalIndex(genericSignature); 820 contents[contentsOffset++] = (byte) (signatureIndex >> 8); 821 contents[contentsOffset++] = (byte) signatureIndex; 822 attributesNumber++; 823 } 824 if (this.targetJDK >= ClassFileConstants.JDK1_5 && !this.creatingProblemType) { 825 FieldDeclaration fieldDeclaration = fieldBinding.sourceField(); 826 if (fieldDeclaration != null) { 827 Annotation[] annotations = fieldDeclaration.annotations; 828 if (annotations != null) { 829 attributesNumber += generateRuntimeAnnotations(annotations); 830 } 831 } 832 } 833 return attributesNumber; 834 } 835 836 841 private void addFieldInfo(FieldBinding fieldBinding) { 842 if (contentsOffset + 8 >= contents.length) { 845 resizeContents(8); 846 } 847 int accessFlags = fieldBinding.getAccessFlags(); 850 if (targetJDK < ClassFileConstants.JDK1_5) { 851 accessFlags &= ~ClassFileConstants.AccSynthetic; 853 } 854 contents[contentsOffset++] = (byte) (accessFlags >> 8); 855 contents[contentsOffset++] = (byte) accessFlags; 856 int nameIndex = constantPool.literalIndex(fieldBinding.name); 858 contents[contentsOffset++] = (byte) (nameIndex >> 8); 859 contents[contentsOffset++] = (byte) nameIndex; 860 int descriptorIndex = constantPool.literalIndex(fieldBinding.type); 862 contents[contentsOffset++] = (byte) (descriptorIndex >> 8); 863 contents[contentsOffset++] = (byte) descriptorIndex; 864 int fieldAttributeOffset = contentsOffset; 865 int attributeNumber = 0; 866 contentsOffset += 2; 868 attributeNumber += addFieldAttributes(fieldBinding, fieldAttributeOffset); 869 if (contentsOffset + 2 >= contents.length) { 870 resizeContents(2); 871 } 872 contents[fieldAttributeOffset++] = (byte) (attributeNumber >> 8); 873 contents[fieldAttributeOffset] = (byte) attributeNumber; 874 } 875 882 889 public void addFieldInfos() { 890 SourceTypeBinding currentBinding = referenceBinding; 891 FieldBinding[] syntheticFields = currentBinding.syntheticFields(); 892 int fieldCount = 893 currentBinding.fieldCount() 894 + (syntheticFields == null ? 0 : syntheticFields.length); 895 896 if (fieldCount > 0xFFFF) { 898 referenceBinding.scope.problemReporter().tooManyFields(referenceBinding.scope.referenceType()); 899 } 900 contents[contentsOffset++] = (byte) (fieldCount >> 8); 901 contents[contentsOffset++] = (byte) fieldCount; 902 903 FieldDeclaration[] fieldDecls = currentBinding.scope.referenceContext.fields; 904 for (int i = 0, max = fieldDecls == null ? 0 : fieldDecls.length; i < max; i++) { 905 FieldDeclaration fieldDecl = fieldDecls[i]; 906 if (fieldDecl.binding != null) { 907 addFieldInfo(fieldDecl.binding); 908 } 909 } 910 911 if (syntheticFields != null) { 912 for (int i = 0, max = syntheticFields.length; i < max; i++) { 913 addFieldInfo(syntheticFields[i]); 914 } 915 } 916 } 917 private void addMissingAbstractProblemMethod(MethodDeclaration methodDeclaration, MethodBinding methodBinding, CategorizedProblem problem, CompilationResult compilationResult) { 918 generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract)); 920 int methodAttributeOffset = contentsOffset; 921 int attributeNumber = generateMethodInfoAttribute(methodBinding); 922 923 attributeNumber++; 925 926 int codeAttributeOffset = contentsOffset; 927 generateCodeAttributeHeader(); 928 StringBuffer buffer = new StringBuffer (25); 929 buffer.append("\t" + problem.getMessage() + "\n" ); buffer.insert(0, Messages.compilation_unresolvedProblem); 931 String problemString = buffer.toString(); 932 933 codeStream.init(this); 934 codeStream.preserveUnusedLocals = true; 935 codeStream.initializeMaxLocals(methodBinding); 936 937 codeStream.generateCodeAttributeForProblemMethod(problemString); 939 940 completeCodeAttributeForMissingAbstractProblemMethod( 941 methodBinding, 942 codeAttributeOffset, 943 compilationResult.getLineSeparatorPositions(), 944 problem.getSourceLineNumber()); 945 946 completeMethodInfo(methodAttributeOffset, attributeNumber); 947 } 948 949 955 public void addProblemClinit(CategorizedProblem[] problems) { 956 generateMethodInfoHeaderForClinit(); 957 contentsOffset -= 2; 959 int attributeOffset = contentsOffset; 960 contentsOffset += 2; 961 int attributeNumber = 0; 962 963 int codeAttributeOffset = contentsOffset; 964 generateCodeAttributeHeader(); 965 codeStream.resetForProblemClinit(this); 966 String problemString = "" ; int problemLine = 0; 968 if (problems != null) { 969 int max = problems.length; 970 StringBuffer buffer = new StringBuffer (25); 971 int count = 0; 972 for (int i = 0; i < max; i++) { 973 CategorizedProblem problem = problems[i]; 974 if ((problem != null) && (problem.isError())) { 975 buffer.append("\t" +problem.getMessage() + "\n" ); count++; 977 if (problemLine == 0) { 978 problemLine = problem.getSourceLineNumber(); 979 } 980 problems[i] = null; 981 } 982 } if (count > 1) { 984 buffer.insert(0, Messages.compilation_unresolvedProblems); 985 } else { 986 buffer.insert(0, Messages.compilation_unresolvedProblem); 987 } 988 problemString = buffer.toString(); 989 } 990 991 codeStream.generateCodeAttributeForProblemMethod(problemString); 993 attributeNumber++; completeCodeAttributeForClinit( 995 codeAttributeOffset, 996 problemLine); 997 if (contentsOffset + 2 >= contents.length) { 998 resizeContents(2); 999 } 1000 contents[attributeOffset++] = (byte) (attributeNumber >> 8); 1001 contents[attributeOffset] = (byte) attributeNumber; 1002 } 1003 1004 1012 public void addProblemConstructor( 1013 AbstractMethodDeclaration method, 1014 MethodBinding methodBinding, 1015 CategorizedProblem[] problems) { 1016 1017 generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract)); 1019 int methodAttributeOffset = contentsOffset; 1020 int attributeNumber = generateMethodInfoAttribute(methodBinding, true); 1021 1022 attributeNumber++; 1024 int codeAttributeOffset = contentsOffset; 1025 generateCodeAttributeHeader(); 1026 codeStream.reset(method, this); 1027 String problemString = "" ; int problemLine = 0; 1029 if (problems != null) { 1030 int max = problems.length; 1031 StringBuffer buffer = new StringBuffer (25); 1032 int count = 0; 1033 for (int i = 0; i < max; i++) { 1034 CategorizedProblem problem = problems[i]; 1035 if ((problem != null) && (problem.isError())) { 1036 buffer.append("\t" +problem.getMessage() + "\n" ); count++; 1038 if (problemLine == 0) { 1039 problemLine = problem.getSourceLineNumber(); 1040 } 1041 } 1042 } if (count > 1) { 1044 buffer.insert(0, Messages.compilation_unresolvedProblems); 1045 } else { 1046 buffer.insert(0, Messages.compilation_unresolvedProblem); 1047 } 1048 problemString = buffer.toString(); 1049 } 1050 1051 codeStream.generateCodeAttributeForProblemMethod(problemString); 1053 completeCodeAttributeForProblemMethod( 1054 method, 1055 methodBinding, 1056 codeAttributeOffset, 1057 ((SourceTypeBinding) methodBinding.declaringClass) 1058 .scope 1059 .referenceCompilationUnit() 1060 .compilationResult 1061 .getLineSeparatorPositions(), 1062 problemLine); 1063 completeMethodInfo(methodAttributeOffset, attributeNumber); 1064 } 1065 1066 1076 public void addProblemConstructor( 1077 AbstractMethodDeclaration method, 1078 MethodBinding methodBinding, 1079 CategorizedProblem[] problems, 1080 int savedOffset) { 1081 contentsOffset = savedOffset; 1083 methodCount--; addProblemConstructor(method, methodBinding, problems); 1085 } 1086 1087 1095 public void addProblemMethod( 1096 AbstractMethodDeclaration method, 1097 MethodBinding methodBinding, 1098 CategorizedProblem[] problems) { 1099 if (methodBinding.isAbstract() && methodBinding.declaringClass.isInterface()) { 1100 method.abort(ProblemSeverities.AbortType, null); 1101 } 1102 generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract)); 1104 int methodAttributeOffset = contentsOffset; 1105 int attributeNumber = generateMethodInfoAttribute(methodBinding, true); 1106 1107 attributeNumber++; 1109 1110 int codeAttributeOffset = contentsOffset; 1111 generateCodeAttributeHeader(); 1112 codeStream.reset(method, this); 1113 String problemString = "" ; int problemLine = 0; 1115 if (problems != null) { 1116 int max = problems.length; 1117 StringBuffer buffer = new StringBuffer (25); 1118 int count = 0; 1119 for (int i = 0; i < max; i++) { 1120 CategorizedProblem problem = problems[i]; 1121 if ((problem != null) 1122 && (problem.isError()) 1123 && (problem.getSourceStart() >= method.declarationSourceStart) 1124 && (problem.getSourceEnd() <= method.declarationSourceEnd)) { 1125 buffer.append("\t" +problem.getMessage() + "\n" ); count++; 1127 if (problemLine == 0) { 1128 problemLine = problem.getSourceLineNumber(); 1129 } 1130 problems[i] = null; 1131 } 1132 } if (count > 1) { 1134 buffer.insert(0, Messages.compilation_unresolvedProblems); 1135 } else { 1136 buffer.insert(0, Messages.compilation_unresolvedProblem); 1137 } 1138 problemString = buffer.toString(); 1139 } 1140 1141 codeStream.generateCodeAttributeForProblemMethod(problemString); 1143 completeCodeAttributeForProblemMethod( 1144 method, 1145 methodBinding, 1146 codeAttributeOffset, 1147 ((SourceTypeBinding) methodBinding.declaringClass) 1148 .scope 1149 .referenceCompilationUnit() 1150 .compilationResult 1151 .getLineSeparatorPositions(), 1152 problemLine); 1153 completeMethodInfo(methodAttributeOffset, attributeNumber); 1154 } 1155 1156 1166 public void addProblemMethod( 1167 AbstractMethodDeclaration method, 1168 MethodBinding methodBinding, 1169 CategorizedProblem[] problems, 1170 int savedOffset) { 1171 contentsOffset = savedOffset; 1173 methodCount--; addProblemMethod(method, methodBinding, problems); 1175 } 1176 1177 1184 public void addSpecialMethods() { 1185 1186 1188 generateMissingAbstractMethods(referenceBinding.scope.referenceType().missingAbstractMethods, referenceBinding.scope.referenceCompilationUnit().compilationResult); 1190 1191 MethodBinding[] defaultAbstractMethods = this.referenceBinding.getDefaultAbstractMethods(); 1192 for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) { 1193 generateMethodInfoHeader(defaultAbstractMethods[i]); 1194 int methodAttributeOffset = contentsOffset; 1195 int attributeNumber = generateMethodInfoAttribute(defaultAbstractMethods[i]); 1196 completeMethodInfo(methodAttributeOffset, attributeNumber); 1197 } 1198 SyntheticMethodBinding[] syntheticMethods = this.referenceBinding.syntheticMethods(); 1200 if (syntheticMethods != null) { 1201 for (int i = 0, max = syntheticMethods.length; i < max; i++) { 1202 SyntheticMethodBinding syntheticMethod = syntheticMethods[i]; 1203 switch (syntheticMethod.kind) { 1204 case SyntheticMethodBinding.FieldReadAccess : 1205 addSyntheticFieldReadAccessMethod(syntheticMethod); 1208 break; 1209 case SyntheticMethodBinding.FieldWriteAccess : 1210 addSyntheticFieldWriteAccessMethod(syntheticMethod); 1213 break; 1214 case SyntheticMethodBinding.MethodAccess : 1215 case SyntheticMethodBinding.SuperMethodAccess : 1216 case SyntheticMethodBinding.BridgeMethod : 1217 addSyntheticMethodAccessMethod(syntheticMethod); 1219 break; 1220 case SyntheticMethodBinding.ConstructorAccess : 1221 addSyntheticConstructorAccessMethod(syntheticMethod); 1223 break; 1224 case SyntheticMethodBinding.EnumValues : 1225 addSyntheticEnumValuesMethod(syntheticMethod); 1227 break; 1228 case SyntheticMethodBinding.EnumValueOf : 1229 addSyntheticEnumValueOfMethod(syntheticMethod); 1231 break; 1232 case SyntheticMethodBinding.SwitchTable : 1233 addSyntheticSwitchTable(syntheticMethod); 1235 } 1236 } 1237 } 1238 } 1239 1240 1246 public void addSyntheticConstructorAccessMethod(SyntheticMethodBinding methodBinding) { 1247 generateMethodInfoHeader(methodBinding); 1248 int methodAttributeOffset = this.contentsOffset; 1249 int attributeNumber = generateMethodInfoAttribute(methodBinding); 1251 int codeAttributeOffset = contentsOffset; 1253 attributeNumber++; generateCodeAttributeHeader(); 1255 codeStream.init(this); 1256 codeStream.generateSyntheticBodyForConstructorAccess(methodBinding); 1257 completeCodeAttributeForSyntheticMethod( 1258 methodBinding, 1259 codeAttributeOffset, 1260 ((SourceTypeBinding) methodBinding.declaringClass) 1261 .scope 1262 .referenceCompilationUnit() 1263 .compilationResult 1264 .getLineSeparatorPositions()); 1265 contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); 1267 contents[methodAttributeOffset] = (byte) attributeNumber; 1268 } 1269 1270 1276 public void addSyntheticEnumValueOfMethod(SyntheticMethodBinding methodBinding) { 1277 generateMethodInfoHeader(methodBinding); 1278 int methodAttributeOffset = this.contentsOffset; 1279 int attributeNumber = generateMethodInfoAttribute(methodBinding); 1281 int codeAttributeOffset = contentsOffset; 1283 attributeNumber++; generateCodeAttributeHeader(); 1285 codeStream.init(this); 1286 codeStream.generateSyntheticBodyForEnumValueOf(methodBinding); 1287 completeCodeAttributeForSyntheticMethod( 1288 methodBinding, 1289 codeAttributeOffset, 1290 ((SourceTypeBinding) methodBinding.declaringClass) 1291 .scope 1292 .referenceCompilationUnit() 1293 .compilationResult 1294 .getLineSeparatorPositions()); 1295 contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); 1297 contents[methodAttributeOffset] = (byte) attributeNumber; 1298 } 1299 1300 1306 public void addSyntheticEnumValuesMethod(SyntheticMethodBinding methodBinding) { 1307 generateMethodInfoHeader(methodBinding); 1308 int methodAttributeOffset = this.contentsOffset; 1309 int attributeNumber = generateMethodInfoAttribute(methodBinding); 1311 int codeAttributeOffset = contentsOffset; 1313 attributeNumber++; generateCodeAttributeHeader(); 1315 codeStream.init(this); 1316 codeStream.generateSyntheticBodyForEnumValues(methodBinding); 1317 completeCodeAttributeForSyntheticMethod( 1318 methodBinding, 1319 codeAttributeOffset, 1320 ((SourceTypeBinding) methodBinding.declaringClass) 1321 .scope 1322 .referenceCompilationUnit() 1323 .compilationResult 1324 .getLineSeparatorPositions()); 1325 contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); 1327 contents[methodAttributeOffset] = (byte) attributeNumber; 1328 } 1329 1330 1337 public void addSyntheticFieldReadAccessMethod(SyntheticMethodBinding methodBinding) { 1338 generateMethodInfoHeader(methodBinding); 1339 int methodAttributeOffset = this.contentsOffset; 1340 int attributeNumber = generateMethodInfoAttribute(methodBinding); 1342 int codeAttributeOffset = contentsOffset; 1344 attributeNumber++; generateCodeAttributeHeader(); 1346 codeStream.init(this); 1347 codeStream.generateSyntheticBodyForFieldReadAccess(methodBinding); 1348 completeCodeAttributeForSyntheticMethod( 1349 methodBinding, 1350 codeAttributeOffset, 1351 ((SourceTypeBinding) methodBinding.declaringClass) 1352 .scope 1353 .referenceCompilationUnit() 1354 .compilationResult 1355 .getLineSeparatorPositions()); 1356 contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); 1358 contents[methodAttributeOffset] = (byte) attributeNumber; 1359 } 1360 1367 public void addSyntheticFieldWriteAccessMethod(SyntheticMethodBinding methodBinding) { 1368 generateMethodInfoHeader(methodBinding); 1369 int methodAttributeOffset = this.contentsOffset; 1370 int attributeNumber = generateMethodInfoAttribute(methodBinding); 1372 int codeAttributeOffset = contentsOffset; 1374 attributeNumber++; generateCodeAttributeHeader(); 1376 codeStream.init(this); 1377 codeStream.generateSyntheticBodyForFieldWriteAccess(methodBinding); 1378 completeCodeAttributeForSyntheticMethod( 1379 methodBinding, 1380 codeAttributeOffset, 1381 ((SourceTypeBinding) methodBinding.declaringClass) 1382 .scope 1383 .referenceCompilationUnit() 1384 .compilationResult 1385 .getLineSeparatorPositions()); 1386 contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); 1388 contents[methodAttributeOffset] = (byte) attributeNumber; 1389 } 1390 1391 1397 public void addSyntheticMethodAccessMethod(SyntheticMethodBinding methodBinding) { 1398 generateMethodInfoHeader(methodBinding); 1399 int methodAttributeOffset = this.contentsOffset; 1400 int attributeNumber = generateMethodInfoAttribute(methodBinding); 1402 int codeAttributeOffset = contentsOffset; 1404 attributeNumber++; generateCodeAttributeHeader(); 1406 codeStream.init(this); 1407 codeStream.generateSyntheticBodyForMethodAccess(methodBinding); 1408 completeCodeAttributeForSyntheticMethod( 1409 methodBinding, 1410 codeAttributeOffset, 1411 ((SourceTypeBinding) methodBinding.declaringClass) 1412 .scope 1413 .referenceCompilationUnit() 1414 .compilationResult 1415 .getLineSeparatorPositions()); 1416 contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); 1418 contents[methodAttributeOffset] = (byte) attributeNumber; 1419 } 1420 1421 public void addSyntheticSwitchTable(SyntheticMethodBinding methodBinding) { 1422 generateMethodInfoHeader(methodBinding); 1423 int methodAttributeOffset = this.contentsOffset; 1424 int attributeNumber = generateMethodInfoAttribute(methodBinding); 1426 int codeAttributeOffset = contentsOffset; 1428 attributeNumber++; generateCodeAttributeHeader(); 1430 codeStream.init(this); 1431 codeStream.generateSyntheticBodyForSwitchTable(methodBinding); 1432 completeCodeAttributeForSyntheticMethod( 1433 true, 1434 methodBinding, 1435 codeAttributeOffset, 1436 ((SourceTypeBinding) methodBinding.declaringClass) 1437 .scope 1438 .referenceCompilationUnit() 1439 .compilationResult 1440 .getLineSeparatorPositions()); 1441 contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); 1443 contents[methodAttributeOffset] = (byte) attributeNumber; 1444 } 1445 1446 1458 public void completeCodeAttribute(int codeAttributeOffset) { 1459 this.contents = codeStream.bCodeStream; 1461 int localContentsOffset = codeStream.classFileOffset; 1462 int code_length = codeStream.position; 1467 if (code_length > 65535) { 1468 codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit( 1469 codeStream.methodDeclaration); 1470 } 1471 if (localContentsOffset + 20 >= this.contents.length) { 1472 resizeContents(20); 1473 } 1474 int max_stack = codeStream.stackMax; 1475 this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8); 1476 this.contents[codeAttributeOffset + 7] = (byte) max_stack; 1477 int max_locals = codeStream.maxLocals; 1478 this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8); 1479 this.contents[codeAttributeOffset + 9] = (byte) max_locals; 1480 this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24); 1481 this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16); 1482 this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8); 1483 this.contents[codeAttributeOffset + 13] = (byte) code_length; 1484 1485 ExceptionLabel[] exceptionLabels = codeStream.exceptionLabels; 1487 int exceptionHandlersCount = 0; for (int i = 0, length = codeStream.exceptionLabelsCounter; i < length; i++) { 1489 exceptionHandlersCount += codeStream.exceptionLabels[i].count / 2; 1490 } 1491 int exSize = exceptionHandlersCount * 8 + 2; 1492 if (exSize + localContentsOffset >= this.contents.length) { 1493 resizeContents(exSize); 1494 } 1495 this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8); 1498 this.contents[localContentsOffset++] = (byte) exceptionHandlersCount; 1499 for (int i = 0, max = codeStream.exceptionLabelsCounter; i < max; i++) { 1500 ExceptionLabel exceptionLabel = exceptionLabels[i]; 1501 if (exceptionLabel != null) { 1502 int iRange = 0, maxRange = exceptionLabel.count; 1503 if ((maxRange & 1) != 0) { 1504 codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError( 1505 Messages.bind(Messages.abort_invalidExceptionAttribute, new String (codeStream.methodDeclaration.selector)), 1506 codeStream.methodDeclaration); 1507 } 1508 while (iRange < maxRange) { 1509 int start = exceptionLabel.ranges[iRange++]; this.contents[localContentsOffset++] = (byte) (start >> 8); 1511 this.contents[localContentsOffset++] = (byte) start; 1512 int end = exceptionLabel.ranges[iRange++]; this.contents[localContentsOffset++] = (byte) (end >> 8); 1514 this.contents[localContentsOffset++] = (byte) end; 1515 int handlerPC = exceptionLabel.position; 1516 this.contents[localContentsOffset++] = (byte) (handlerPC >> 8); 1517 this.contents[localContentsOffset++] = (byte) handlerPC; 1518 if (exceptionLabel.exceptionType == null) { 1519 this.contents[localContentsOffset++] = 0; 1521 this.contents[localContentsOffset++] = 0; 1522 } else { 1523 int nameIndex; 1524 if (exceptionLabel.exceptionType == TypeBinding.NULL) { 1525 1526 nameIndex = constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName); 1527 } else { 1528 nameIndex = constantPool.literalIndexForType(exceptionLabel.exceptionType); 1529 } 1530 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 1531 this.contents[localContentsOffset++] = (byte) nameIndex; 1532 } 1533 } 1534 } 1535 } 1536 int codeAttributeAttributeOffset = localContentsOffset; 1538 int attributeNumber = 0; 1539 localContentsOffset += 2; 1541 if (localContentsOffset + 2 >= this.contents.length) { 1542 resizeContents(2); 1543 } 1544 1545 if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) { 1547 1553 int[] pcToSourceMapTable; 1554 if (((pcToSourceMapTable = codeStream.pcToSourceMap) != null) 1555 && (codeStream.pcToSourceMapSize != 0)) { 1556 int lineNumberNameIndex = 1557 constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName); 1558 if (localContentsOffset + 8 >= this.contents.length) { 1559 resizeContents(8); 1560 } 1561 this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8); 1562 this.contents[localContentsOffset++] = (byte) lineNumberNameIndex; 1563 int lineNumberTableOffset = localContentsOffset; 1564 localContentsOffset += 6; 1565 int numberOfEntries = 0; 1567 int length = codeStream.pcToSourceMapSize; 1568 for (int i = 0; i < length;) { 1569 if (localContentsOffset + 4 >= this.contents.length) { 1571 resizeContents(4); 1572 } 1573 int pc = pcToSourceMapTable[i++]; 1574 this.contents[localContentsOffset++] = (byte) (pc >> 8); 1575 this.contents[localContentsOffset++] = (byte) pc; 1576 int lineNumber = pcToSourceMapTable[i++]; 1577 this.contents[localContentsOffset++] = (byte) (lineNumber >> 8); 1578 this.contents[localContentsOffset++] = (byte) lineNumber; 1579 numberOfEntries++; 1580 } 1581 int lineNumberAttr_length = numberOfEntries * 4 + 2; 1583 this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 24); 1584 this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 16); 1585 this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 8); 1586 this.contents[lineNumberTableOffset++] = (byte) lineNumberAttr_length; 1587 this.contents[lineNumberTableOffset++] = (byte) (numberOfEntries >> 8); 1588 this.contents[lineNumberTableOffset++] = (byte) numberOfEntries; 1589 attributeNumber++; 1590 } 1591 } 1592 if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) { 1594 int numberOfEntries = 0; 1595 int localVariableNameIndex = 1596 constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName); 1597 final boolean methodDeclarationIsStatic = codeStream.methodDeclaration.isStatic(); 1598 int maxOfEntries = 8 + 10 * (methodDeclarationIsStatic ? 0 : 1); 1599 for (int i = 0; i < codeStream.allLocalsCounter; i++) { 1600 maxOfEntries += 10 * codeStream.locals[i].initializationCount; 1601 } 1602 if (localContentsOffset + maxOfEntries >= this.contents.length) { 1604 resizeContents(maxOfEntries); 1605 } 1606 this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8); 1607 this.contents[localContentsOffset++] = (byte) localVariableNameIndex; 1608 int localVariableTableOffset = localContentsOffset; 1609 localContentsOffset += 6; 1611 int nameIndex; 1612 int descriptorIndex; 1613 SourceTypeBinding declaringClassBinding = null; 1614 if (!methodDeclarationIsStatic) { 1615 numberOfEntries++; 1616 this.contents[localContentsOffset++] = 0; this.contents[localContentsOffset++] = 0; 1618 this.contents[localContentsOffset++] = (byte) (code_length >> 8); 1619 this.contents[localContentsOffset++] = (byte) code_length; 1620 nameIndex = constantPool.literalIndex(ConstantPool.This); 1621 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 1622 this.contents[localContentsOffset++] = (byte) nameIndex; 1623 declaringClassBinding = (SourceTypeBinding) codeStream.methodDeclaration.binding.declaringClass; 1624 descriptorIndex = 1625 constantPool.literalIndex( 1626 declaringClassBinding.signature()); 1627 this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); 1628 this.contents[localContentsOffset++] = (byte) descriptorIndex; 1629 this.contents[localContentsOffset++] = 0; this.contents[localContentsOffset++] = 0; 1631 } 1632 int genericLocalVariablesCounter = 0; 1634 LocalVariableBinding[] genericLocalVariables = null; 1635 int numberOfGenericEntries = 0; 1636 1637 for (int i = 0, max = codeStream.allLocalsCounter; i < max; i++) { 1638 LocalVariableBinding localVariable = codeStream.locals[i]; 1639 final TypeBinding localVariableTypeBinding = localVariable.type; 1640 boolean isParameterizedType = localVariableTypeBinding.isParameterizedType() || localVariableTypeBinding.isTypeVariable(); 1641 if (localVariable.initializationCount != 0 && isParameterizedType) { 1642 if (genericLocalVariables == null) { 1643 genericLocalVariables = new LocalVariableBinding[max]; 1645 } 1646 genericLocalVariables[genericLocalVariablesCounter++] = localVariable; 1647 } 1648 for (int j = 0; j < localVariable.initializationCount; j++) { 1649 int startPC = localVariable.initializationPCs[j << 1]; 1650 int endPC = localVariable.initializationPCs[(j << 1) + 1]; 1651 if (startPC != endPC) { if (endPC == -1) { 1653 localVariable.declaringScope.problemReporter().abortDueToInternalError( 1654 Messages.bind(Messages.abort_invalidAttribute, new String (localVariable.name)), 1655 (ASTNode) localVariable.declaringScope.methodScope().referenceContext); 1656 } 1657 if (isParameterizedType) { 1658 numberOfGenericEntries++; 1659 } 1660 numberOfEntries++; 1662 this.contents[localContentsOffset++] = (byte) (startPC >> 8); 1663 this.contents[localContentsOffset++] = (byte) startPC; 1664 int length = endPC - startPC; 1665 this.contents[localContentsOffset++] = (byte) (length >> 8); 1666 this.contents[localContentsOffset++] = (byte) length; 1667 nameIndex = constantPool.literalIndex(localVariable.name); 1668 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 1669 this.contents[localContentsOffset++] = (byte) nameIndex; 1670 descriptorIndex = constantPool.literalIndex(localVariableTypeBinding.signature()); 1671 this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); 1672 this.contents[localContentsOffset++] = (byte) descriptorIndex; 1673 int resolvedPosition = localVariable.resolvedPosition; 1674 this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8); 1675 this.contents[localContentsOffset++] = (byte) resolvedPosition; 1676 } 1677 } 1678 } 1679 int value = numberOfEntries * 10 + 2; 1680 this.contents[localVariableTableOffset++] = (byte) (value >> 24); 1681 this.contents[localVariableTableOffset++] = (byte) (value >> 16); 1682 this.contents[localVariableTableOffset++] = (byte) (value >> 8); 1683 this.contents[localVariableTableOffset++] = (byte) value; 1684 this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8); 1685 this.contents[localVariableTableOffset] = (byte) numberOfEntries; 1686 attributeNumber++; 1687 1688 final boolean currentInstanceIsGeneric = 1689 !methodDeclarationIsStatic 1690 && declaringClassBinding != null 1691 && declaringClassBinding.typeVariables != Binding.NO_TYPE_VARIABLES; 1692 if (genericLocalVariablesCounter != 0 || currentInstanceIsGeneric) { 1693 numberOfGenericEntries += (currentInstanceIsGeneric ? 1 : 0); 1695 maxOfEntries = 8 + numberOfGenericEntries * 10; 1696 if (localContentsOffset + maxOfEntries >= this.contents.length) { 1698 resizeContents(maxOfEntries); 1699 } 1700 int localVariableTypeNameIndex = 1701 constantPool.literalIndex(AttributeNamesConstants.LocalVariableTypeTableName); 1702 this.contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8); 1703 this.contents[localContentsOffset++] = (byte) localVariableTypeNameIndex; 1704 value = numberOfGenericEntries * 10 + 2; 1705 this.contents[localContentsOffset++] = (byte) (value >> 24); 1706 this.contents[localContentsOffset++] = (byte) (value >> 16); 1707 this.contents[localContentsOffset++] = (byte) (value >> 8); 1708 this.contents[localContentsOffset++] = (byte) value; 1709 this.contents[localContentsOffset++] = (byte) (numberOfGenericEntries >> 8); 1710 this.contents[localContentsOffset++] = (byte) numberOfGenericEntries; 1711 if (currentInstanceIsGeneric) { 1712 this.contents[localContentsOffset++] = 0; this.contents[localContentsOffset++] = 0; 1714 this.contents[localContentsOffset++] = (byte) (code_length >> 8); 1715 this.contents[localContentsOffset++] = (byte) code_length; 1716 nameIndex = constantPool.literalIndex(ConstantPool.This); 1717 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 1718 this.contents[localContentsOffset++] = (byte) nameIndex; 1719 descriptorIndex = constantPool.literalIndex(declaringClassBinding.genericTypeSignature()); 1720 this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); 1721 this.contents[localContentsOffset++] = (byte) descriptorIndex; 1722 this.contents[localContentsOffset++] = 0; this.contents[localContentsOffset++] = 0; 1724 } 1725 1726 for (int i = 0; i < genericLocalVariablesCounter; i++) { 1727 LocalVariableBinding localVariable = genericLocalVariables[i]; 1728 for (int j = 0; j < localVariable.initializationCount; j++) { 1729 int startPC = localVariable.initializationPCs[j << 1]; 1730 int endPC = localVariable.initializationPCs[(j << 1) + 1]; 1731 if (startPC != endPC) { 1732 this.contents[localContentsOffset++] = (byte) (startPC >> 8); 1735 this.contents[localContentsOffset++] = (byte) startPC; 1736 int length = endPC - startPC; 1737 this.contents[localContentsOffset++] = (byte) (length >> 8); 1738 this.contents[localContentsOffset++] = (byte) length; 1739 nameIndex = constantPool.literalIndex(localVariable.name); 1740 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 1741 this.contents[localContentsOffset++] = (byte) nameIndex; 1742 descriptorIndex = constantPool.literalIndex(localVariable.type.genericTypeSignature()); 1743 this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); 1744 this.contents[localContentsOffset++] = (byte) descriptorIndex; 1745 int resolvedPosition = localVariable.resolvedPosition; 1746 this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8); 1747 this.contents[localContentsOffset++] = (byte) resolvedPosition; 1748 } 1749 } 1750 } 1751 attributeNumber++; 1752 } 1753 } 1754 1755 if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { 1756 final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; 1757 final int framesPositionsSize = framesPositions.size(); 1758 int numberOfFrames = framesPositionsSize - 1; if (numberOfFrames > 0) { 1760 ArrayList framePositions = new ArrayList (framesPositionsSize); 1761 framePositions.addAll(framesPositions); 1762 Collections.sort(framePositions); 1763 int stackMapTableAttributeOffset = localContentsOffset; 1764 if (localContentsOffset + 8 >= this.contents.length) { 1766 resizeContents(8); 1767 } 1768 int stackMapTableAttributeNameIndex = 1769 constantPool.literalIndex(AttributeNamesConstants.StackMapTableName); 1770 this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8); 1771 this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex; 1772 1773 int stackMapTableAttributeLengthOffset = localContentsOffset; 1774 localContentsOffset += 4; 1776 if (localContentsOffset + 4 >= this.contents.length) { 1777 resizeContents(4); 1778 } 1779 numberOfFrames = 0; 1780 int numberOfFramesOffset = localContentsOffset; 1781 localContentsOffset += 2; 1782 if (localContentsOffset + 2 >= this.contents.length) { 1783 resizeContents(2); 1784 } 1785 ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; 1786 StackMapFrame currentFrame = (StackMapFrame) frames.get(0); 1787 StackMapFrame prevFrame = null; 1788 int framesSize = frames.size(); 1789 int frameIndex = 0; 1790 for (int j = 0; j < framesPositionsSize && ((Integer ) framePositions.get(j)).intValue() < code_length; j++) { 1791 prevFrame = currentFrame; 1793 currentFrame = null; 1794 for (; frameIndex < framesSize; frameIndex++) { 1795 currentFrame = (StackMapFrame) frames.get(frameIndex); 1796 if (currentFrame.pc == ((Integer ) framePositions.get(j)).intValue()) { 1797 break; 1798 } 1799 } 1800 if (currentFrame == null) break; 1801 numberOfFrames++; 1804 int offsetDelta = currentFrame.getOffsetDelta(prevFrame); 1805 switch (currentFrame.getFrameType(prevFrame)) { 1806 case StackMapFrame.APPEND_FRAME : 1807 if (localContentsOffset + 3 >= this.contents.length) { 1808 resizeContents(3); 1809 } 1810 int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); 1811 this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals); 1812 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 1813 this.contents[localContentsOffset++] = (byte) offsetDelta; 1814 int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals); 1815 int numberOfLocals = currentFrame.getNumberOfLocals(); 1816 for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) { 1817 if (localContentsOffset + 6 >= this.contents.length) { 1818 resizeContents(6); 1819 } 1820 VerificationTypeInfo info = currentFrame.locals[i]; 1821 if (info == null) { 1822 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 1823 } else { 1824 switch(info.id()) { 1825 case T_boolean : 1826 case T_byte : 1827 case T_char : 1828 case T_int : 1829 case T_short : 1830 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 1831 break; 1832 case T_float : 1833 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 1834 break; 1835 case T_long : 1836 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 1837 i++; 1838 break; 1839 case T_double : 1840 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 1841 i++; 1842 break; 1843 case T_null : 1844 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 1845 break; 1846 default: 1847 this.contents[localContentsOffset++] = (byte) info.tag; 1848 switch (info.tag) { 1849 case VerificationTypeInfo.ITEM_UNINITIALIZED : 1850 int offset = info.offset; 1851 this.contents[localContentsOffset++] = (byte) (offset >> 8); 1852 this.contents[localContentsOffset++] = (byte) offset; 1853 break; 1854 case VerificationTypeInfo.ITEM_OBJECT : 1855 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 1856 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 1857 this.contents[localContentsOffset++] = (byte) indexForType; 1858 } 1859 } 1860 numberOfDifferentLocals--; 1861 } 1862 } 1863 break; 1864 case StackMapFrame.SAME_FRAME : 1865 if (localContentsOffset + 1 >= this.contents.length) { 1866 resizeContents(1); 1867 } 1868 this.contents[localContentsOffset++] = (byte) offsetDelta; 1869 break; 1870 case StackMapFrame.SAME_FRAME_EXTENDED : 1871 if (localContentsOffset + 3 >= this.contents.length) { 1872 resizeContents(3); 1873 } 1874 this.contents[localContentsOffset++] = (byte) 251; 1875 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 1876 this.contents[localContentsOffset++] = (byte) offsetDelta; 1877 break; 1878 case StackMapFrame.CHOP_FRAME : 1879 if (localContentsOffset + 3 >= this.contents.length) { 1880 resizeContents(3); 1881 } 1882 numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); 1883 this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals); 1884 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 1885 this.contents[localContentsOffset++] = (byte) offsetDelta; 1886 break; 1887 case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS : 1888 if (localContentsOffset + 4 >= this.contents.length) { 1889 resizeContents(4); 1890 } 1891 this.contents[localContentsOffset++] = (byte) (offsetDelta + 64); 1892 if (currentFrame.stackItems[0] == null) { 1893 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 1894 } else { 1895 switch(currentFrame.stackItems[0].id()) { 1896 case T_boolean : 1897 case T_byte : 1898 case T_char : 1899 case T_int : 1900 case T_short : 1901 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 1902 break; 1903 case T_float : 1904 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 1905 break; 1906 case T_long : 1907 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 1908 break; 1909 case T_double : 1910 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 1911 break; 1912 case T_null : 1913 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 1914 break; 1915 default: 1916 VerificationTypeInfo info = currentFrame.stackItems[0]; 1917 byte tag = (byte) info.tag; 1918 this.contents[localContentsOffset++] = tag; 1919 switch (tag) { 1920 case VerificationTypeInfo.ITEM_UNINITIALIZED : 1921 int offset = info.offset; 1922 this.contents[localContentsOffset++] = (byte) (offset >> 8); 1923 this.contents[localContentsOffset++] = (byte) offset; 1924 break; 1925 case VerificationTypeInfo.ITEM_OBJECT : 1926 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 1927 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 1928 this.contents[localContentsOffset++] = (byte) indexForType; 1929 } 1930 } 1931 } 1932 break; 1933 case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED : 1934 if (localContentsOffset + 6 >= this.contents.length) { 1935 resizeContents(6); 1936 } 1937 this.contents[localContentsOffset++] = (byte) 247; 1938 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 1939 this.contents[localContentsOffset++] = (byte) offsetDelta; 1940 if (currentFrame.stackItems[0] == null) { 1941 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 1942 } else { 1943 switch(currentFrame.stackItems[0].id()) { 1944 case T_boolean : 1945 case T_byte : 1946 case T_char : 1947 case T_int : 1948 case T_short : 1949 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 1950 break; 1951 case T_float : 1952 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 1953 break; 1954 case T_long : 1955 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 1956 break; 1957 case T_double : 1958 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 1959 break; 1960 case T_null : 1961 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 1962 break; 1963 default: 1964 VerificationTypeInfo info = currentFrame.stackItems[0]; 1965 byte tag = (byte) info.tag; 1966 this.contents[localContentsOffset++] = tag; 1967 switch (tag) { 1968 case VerificationTypeInfo.ITEM_UNINITIALIZED : 1969 int offset = info.offset; 1970 this.contents[localContentsOffset++] = (byte) (offset >> 8); 1971 this.contents[localContentsOffset++] = (byte) offset; 1972 break; 1973 case VerificationTypeInfo.ITEM_OBJECT : 1974 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 1975 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 1976 this.contents[localContentsOffset++] = (byte) indexForType; 1977 } 1978 } 1979 } 1980 break; 1981 default : 1982 if (localContentsOffset + 5 >= this.contents.length) { 1984 resizeContents(5); 1985 } 1986 this.contents[localContentsOffset++] = (byte) 255; 1987 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 1988 this.contents[localContentsOffset++] = (byte) offsetDelta; 1989 int numberOfLocalOffset = localContentsOffset; 1990 localContentsOffset += 2; int numberOfLocalEntries = 0; 1992 numberOfLocals = currentFrame.getNumberOfLocals(); 1993 int numberOfEntries = 0; 1994 int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length; 1995 for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) { 1996 if (localContentsOffset + 3 >= this.contents.length) { 1997 resizeContents(3); 1998 } 1999 VerificationTypeInfo info = currentFrame.locals[i]; 2000 if (info == null) { 2001 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 2002 } else { 2003 switch(info.id()) { 2004 case T_boolean : 2005 case T_byte : 2006 case T_char : 2007 case T_int : 2008 case T_short : 2009 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 2010 break; 2011 case T_float : 2012 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 2013 break; 2014 case T_long : 2015 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 2016 i++; 2017 break; 2018 case T_double : 2019 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 2020 i++; 2021 break; 2022 case T_null : 2023 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 2024 break; 2025 default: 2026 this.contents[localContentsOffset++] = (byte) info.tag; 2027 switch (info.tag) { 2028 case VerificationTypeInfo.ITEM_UNINITIALIZED : 2029 int offset = info.offset; 2030 this.contents[localContentsOffset++] = (byte) (offset >> 8); 2031 this.contents[localContentsOffset++] = (byte) offset; 2032 break; 2033 case VerificationTypeInfo.ITEM_OBJECT : 2034 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 2035 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 2036 this.contents[localContentsOffset++] = (byte) indexForType; 2037 } 2038 } 2039 numberOfLocalEntries++; 2040 } 2041 numberOfEntries++; 2042 } 2043 if (localContentsOffset + 4 >= this.contents.length) { 2044 resizeContents(4); 2045 } 2046 this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8); 2047 this.contents[numberOfLocalOffset] = (byte) numberOfEntries; 2048 int numberOfStackItems = currentFrame.numberOfStackItems; 2049 this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8); 2050 this.contents[localContentsOffset++] = (byte) numberOfStackItems; 2051 for (int i = 0; i < numberOfStackItems; i++) { 2052 if (localContentsOffset + 3 >= this.contents.length) { 2053 resizeContents(3); 2054 } 2055 VerificationTypeInfo info = currentFrame.stackItems[i]; 2056 if (info == null) { 2057 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 2058 } else { 2059 switch(info.id()) { 2060 case T_boolean : 2061 case T_byte : 2062 case T_char : 2063 case T_int : 2064 case T_short : 2065 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 2066 break; 2067 case T_float : 2068 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 2069 break; 2070 case T_long : 2071 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 2072 break; 2073 case T_double : 2074 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 2075 break; 2076 case T_null : 2077 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 2078 break; 2079 default: 2080 this.contents[localContentsOffset++] = (byte) info.tag; 2081 switch (info.tag) { 2082 case VerificationTypeInfo.ITEM_UNINITIALIZED : 2083 int offset = info.offset; 2084 this.contents[localContentsOffset++] = (byte) (offset >> 8); 2085 this.contents[localContentsOffset++] = (byte) offset; 2086 break; 2087 case VerificationTypeInfo.ITEM_OBJECT : 2088 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 2089 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 2090 this.contents[localContentsOffset++] = (byte) indexForType; 2091 } 2092 } 2093 } 2094 } 2095 } 2096 } 2097 2098 if (numberOfFrames != 0) { 2099 this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8); 2100 this.contents[numberOfFramesOffset] = (byte) numberOfFrames; 2101 2102 int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4; 2103 this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24); 2104 this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16); 2105 this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8); 2106 this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength; 2107 attributeNumber++; 2108 } else { 2109 localContentsOffset = stackMapTableAttributeOffset; 2110 } 2111 } 2112 } 2113 2114 this.contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8); 2115 this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber; 2116 2117 int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6); 2119 this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); 2120 this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); 2121 this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); 2122 this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; 2123 contentsOffset = localContentsOffset; 2124 } 2125 2126 2138 public void completeCodeAttributeForClinit(int codeAttributeOffset) { 2139 this.contents = codeStream.bCodeStream; 2141 int localContentsOffset = codeStream.classFileOffset; 2142 int code_length = codeStream.position; 2147 if (code_length > 65535) { 2148 codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit( 2149 codeStream.methodDeclaration.scope.referenceType()); 2150 } 2151 if (localContentsOffset + 20 >= this.contents.length) { 2152 resizeContents(20); 2153 } 2154 int max_stack = codeStream.stackMax; 2155 this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8); 2156 this.contents[codeAttributeOffset + 7] = (byte) max_stack; 2157 int max_locals = codeStream.maxLocals; 2158 this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8); 2159 this.contents[codeAttributeOffset + 9] = (byte) max_locals; 2160 this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24); 2161 this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16); 2162 this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8); 2163 this.contents[codeAttributeOffset + 13] = (byte) code_length; 2164 2165 ExceptionLabel[] exceptionLabels = codeStream.exceptionLabels; 2167 int exceptionHandlersCount = 0; for (int i = 0, length = codeStream.exceptionLabelsCounter; i < length; i++) { 2169 exceptionHandlersCount += codeStream.exceptionLabels[i].count / 2; 2170 } 2171 int exSize = exceptionHandlersCount * 8 + 2; 2172 if (exSize + localContentsOffset >= this.contents.length) { 2173 resizeContents(exSize); 2174 } 2175 this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8); 2178 this.contents[localContentsOffset++] = (byte) exceptionHandlersCount; 2179 for (int i = 0, max = codeStream.exceptionLabelsCounter; i < max; i++) { 2180 ExceptionLabel exceptionLabel = exceptionLabels[i]; 2181 if (exceptionLabel != null) { 2182 int iRange = 0, maxRange = exceptionLabel.count; 2183 if ((maxRange & 1) != 0) { 2184 codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError( 2185 Messages.bind(Messages.abort_invalidExceptionAttribute, new String (codeStream.methodDeclaration.selector)), 2186 codeStream.methodDeclaration); 2187 } 2188 while (iRange < maxRange) { 2189 int start = exceptionLabel.ranges[iRange++]; this.contents[localContentsOffset++] = (byte) (start >> 8); 2191 this.contents[localContentsOffset++] = (byte) start; 2192 int end = exceptionLabel.ranges[iRange++]; this.contents[localContentsOffset++] = (byte) (end >> 8); 2194 this.contents[localContentsOffset++] = (byte) end; 2195 int handlerPC = exceptionLabel.position; 2196 this.contents[localContentsOffset++] = (byte) (handlerPC >> 8); 2197 this.contents[localContentsOffset++] = (byte) handlerPC; 2198 if (exceptionLabel.exceptionType == null) { 2199 this.contents[localContentsOffset++] = 0; 2201 this.contents[localContentsOffset++] = 0; 2202 } else { 2203 int nameIndex; 2204 if (exceptionLabel.exceptionType == TypeBinding.NULL) { 2205 2206 nameIndex = constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName); 2207 } else { 2208 nameIndex = constantPool.literalIndexForType(exceptionLabel.exceptionType); 2209 } 2210 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 2211 this.contents[localContentsOffset++] = (byte) nameIndex; 2212 } 2213 } 2214 } 2215 } 2216 int codeAttributeAttributeOffset = localContentsOffset; 2218 int attributeNumber = 0; 2219 localContentsOffset += 2; 2221 if (localContentsOffset + 2 >= this.contents.length) { 2222 resizeContents(2); 2223 } 2224 2225 if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) { 2227 2233 int[] pcToSourceMapTable; 2234 if (((pcToSourceMapTable = codeStream.pcToSourceMap) != null) 2235 && (codeStream.pcToSourceMapSize != 0)) { 2236 int lineNumberNameIndex = 2237 constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName); 2238 if (localContentsOffset + 8 >= this.contents.length) { 2239 resizeContents(8); 2240 } 2241 this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8); 2242 this.contents[localContentsOffset++] = (byte) lineNumberNameIndex; 2243 int lineNumberTableOffset = localContentsOffset; 2244 localContentsOffset += 6; 2245 int numberOfEntries = 0; 2247 int length = codeStream.pcToSourceMapSize; 2248 for (int i = 0; i < length;) { 2249 if (localContentsOffset + 4 >= this.contents.length) { 2251 resizeContents(4); 2252 } 2253 int pc = pcToSourceMapTable[i++]; 2254 this.contents[localContentsOffset++] = (byte) (pc >> 8); 2255 this.contents[localContentsOffset++] = (byte) pc; 2256 int lineNumber = pcToSourceMapTable[i++]; 2257 this.contents[localContentsOffset++] = (byte) (lineNumber >> 8); 2258 this.contents[localContentsOffset++] = (byte) lineNumber; 2259 numberOfEntries++; 2260 } 2261 int lineNumberAttr_length = numberOfEntries * 4 + 2; 2263 this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 24); 2264 this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 16); 2265 this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 8); 2266 this.contents[lineNumberTableOffset++] = (byte) lineNumberAttr_length; 2267 this.contents[lineNumberTableOffset++] = (byte) (numberOfEntries >> 8); 2268 this.contents[lineNumberTableOffset++] = (byte) numberOfEntries; 2269 attributeNumber++; 2270 } 2271 } 2272 if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) { 2274 int numberOfEntries = 0; 2275 if ((codeStream.pcToSourceMap != null) 2277 && (codeStream.pcToSourceMapSize != 0)) { 2278 int localVariableNameIndex = 2279 constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName); 2280 if (localContentsOffset + 8 >= this.contents.length) { 2281 resizeContents(8); 2282 } 2283 this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8); 2284 this.contents[localContentsOffset++] = (byte) localVariableNameIndex; 2285 int localVariableTableOffset = localContentsOffset; 2286 localContentsOffset += 6; 2287 2288 int nameIndex; 2290 int descriptorIndex; 2291 2292 int genericLocalVariablesCounter = 0; 2294 LocalVariableBinding[] genericLocalVariables = null; 2295 int numberOfGenericEntries = 0; 2296 2297 for (int i = 0, max = codeStream.allLocalsCounter; i < max; i++) { 2298 LocalVariableBinding localVariable = codeStream.locals[i]; 2299 final TypeBinding localVariableTypeBinding = localVariable.type; 2300 boolean isParameterizedType = localVariableTypeBinding.isParameterizedType() || localVariableTypeBinding.isTypeVariable(); 2301 if (localVariable.initializationCount != 0 && isParameterizedType) { 2302 if (genericLocalVariables == null) { 2303 genericLocalVariables = new LocalVariableBinding[max]; 2305 } 2306 genericLocalVariables[genericLocalVariablesCounter++] = localVariable; 2307 } 2308 for (int j = 0; j < localVariable.initializationCount; j++) { 2309 int startPC = localVariable.initializationPCs[j << 1]; 2310 int endPC = localVariable.initializationPCs[(j << 1) + 1]; 2311 if (startPC != endPC) { if (endPC == -1) { 2313 localVariable.declaringScope.problemReporter().abortDueToInternalError( 2314 Messages.bind(Messages.abort_invalidAttribute, new String (localVariable.name)), 2315 (ASTNode) localVariable.declaringScope.methodScope().referenceContext); 2316 } 2317 if (localContentsOffset + 10 >= this.contents.length) { 2318 resizeContents(10); 2319 } 2320 numberOfEntries++; 2322 if (isParameterizedType) { 2323 numberOfGenericEntries++; 2324 } 2325 this.contents[localContentsOffset++] = (byte) (startPC >> 8); 2326 this.contents[localContentsOffset++] = (byte) startPC; 2327 int length = endPC - startPC; 2328 this.contents[localContentsOffset++] = (byte) (length >> 8); 2329 this.contents[localContentsOffset++] = (byte) length; 2330 nameIndex = constantPool.literalIndex(localVariable.name); 2331 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 2332 this.contents[localContentsOffset++] = (byte) nameIndex; 2333 descriptorIndex = constantPool.literalIndex(localVariableTypeBinding.signature()); 2334 this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); 2335 this.contents[localContentsOffset++] = (byte) descriptorIndex; 2336 int resolvedPosition = localVariable.resolvedPosition; 2337 this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8); 2338 this.contents[localContentsOffset++] = (byte) resolvedPosition; 2339 } 2340 } 2341 } 2342 int value = numberOfEntries * 10 + 2; 2343 this.contents[localVariableTableOffset++] = (byte) (value >> 24); 2344 this.contents[localVariableTableOffset++] = (byte) (value >> 16); 2345 this.contents[localVariableTableOffset++] = (byte) (value >> 8); 2346 this.contents[localVariableTableOffset++] = (byte) value; 2347 this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8); 2348 this.contents[localVariableTableOffset] = (byte) numberOfEntries; 2349 attributeNumber++; 2350 2351 if (genericLocalVariablesCounter != 0) { 2352 int maxOfEntries = 8 + numberOfGenericEntries * 10; 2355 2356 if (localContentsOffset + maxOfEntries >= this.contents.length) { 2357 resizeContents(maxOfEntries); 2358 } 2359 int localVariableTypeNameIndex = 2360 constantPool.literalIndex(AttributeNamesConstants.LocalVariableTypeTableName); 2361 this.contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8); 2362 this.contents[localContentsOffset++] = (byte) localVariableTypeNameIndex; 2363 value = numberOfGenericEntries * 10 + 2; 2364 this.contents[localContentsOffset++] = (byte) (value >> 24); 2365 this.contents[localContentsOffset++] = (byte) (value >> 16); 2366 this.contents[localContentsOffset++] = (byte) (value >> 8); 2367 this.contents[localContentsOffset++] = (byte) value; 2368 this.contents[localContentsOffset++] = (byte) (numberOfGenericEntries >> 8); 2369 this.contents[localContentsOffset++] = (byte) numberOfGenericEntries; 2370 for (int i = 0; i < genericLocalVariablesCounter; i++) { 2371 LocalVariableBinding localVariable = genericLocalVariables[i]; 2372 for (int j = 0; j < localVariable.initializationCount; j++) { 2373 int startPC = localVariable.initializationPCs[j << 1]; 2374 int endPC = localVariable.initializationPCs[(j << 1) + 1]; 2375 if (startPC != endPC) { this.contents[localContentsOffset++] = (byte) (startPC >> 8); 2378 this.contents[localContentsOffset++] = (byte) startPC; 2379 int length = endPC - startPC; 2380 this.contents[localContentsOffset++] = (byte) (length >> 8); 2381 this.contents[localContentsOffset++] = (byte) length; 2382 nameIndex = constantPool.literalIndex(localVariable.name); 2383 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 2384 this.contents[localContentsOffset++] = (byte) nameIndex; 2385 descriptorIndex = constantPool.literalIndex(localVariable.type.genericTypeSignature()); 2386 this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); 2387 this.contents[localContentsOffset++] = (byte) descriptorIndex; 2388 int resolvedPosition = localVariable.resolvedPosition; 2389 this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8); 2390 this.contents[localContentsOffset++] = (byte) resolvedPosition; 2391 } 2392 } 2393 } 2394 attributeNumber++; 2395 } 2396 } 2397 } 2398 2399 if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { 2400 final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; 2401 final int framesPositionsSize = framesPositions.size(); 2402 int numberOfFrames = framesPositionsSize - 1; if (numberOfFrames > 0) { 2404 ArrayList framePositions = new ArrayList (framesPositionsSize); 2405 framePositions.addAll(framesPositions); 2406 Collections.sort(framePositions); 2407 if (localContentsOffset + 8 >= this.contents.length) { 2409 resizeContents(8); 2410 } 2411 int stackMapTableAttributeNameIndex = 2412 constantPool.literalIndex(AttributeNamesConstants.StackMapTableName); 2413 this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8); 2414 this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex; 2415 2416 int stackMapTableAttributeLengthOffset = localContentsOffset; 2417 localContentsOffset += 4; 2419 numberOfFrames = 0; 2420 int numberOfFramesOffset = localContentsOffset; 2421 localContentsOffset += 2; 2422 ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; 2424 StackMapFrame currentFrame = (StackMapFrame) frames.get(0); 2425 StackMapFrame prevFrame = null; 2426 int framesSize = frames.size(); 2427 int frameIndex = 0; 2428 for (int j = 0; j < framesPositionsSize && ((Integer ) framePositions.get(j)).intValue() < code_length; j++) { 2429 prevFrame = currentFrame; 2431 currentFrame = null; 2432 for (; frameIndex < framesSize; frameIndex++) { 2433 currentFrame = (StackMapFrame) frames.get(frameIndex); 2434 if (currentFrame.pc == ((Integer ) framePositions.get(j)).intValue()) { 2435 break; 2436 } 2437 } 2438 if (currentFrame == null) break; 2439 numberOfFrames++; 2440 int offsetDelta = currentFrame.getOffsetDelta(prevFrame); 2441 switch (currentFrame.getFrameType(prevFrame)) { 2442 case StackMapFrame.APPEND_FRAME : 2443 if (localContentsOffset + 3 >= this.contents.length) { 2444 resizeContents(3); 2445 } 2446 int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); 2447 this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals); 2448 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 2449 this.contents[localContentsOffset++] = (byte) offsetDelta; 2450 int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals); 2451 int numberOfLocals = currentFrame.getNumberOfLocals(); 2452 for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) { 2453 if (localContentsOffset + 6 >= this.contents.length) { 2454 resizeContents(6); 2455 } 2456 VerificationTypeInfo info = currentFrame.locals[i]; 2457 if (info == null) { 2458 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 2459 } else { 2460 switch(info.id()) { 2461 case T_boolean : 2462 case T_byte : 2463 case T_char : 2464 case T_int : 2465 case T_short : 2466 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 2467 break; 2468 case T_float : 2469 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 2470 break; 2471 case T_long : 2472 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 2473 i++; 2474 break; 2475 case T_double : 2476 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 2477 i++; 2478 break; 2479 case T_null : 2480 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 2481 break; 2482 default: 2483 this.contents[localContentsOffset++] = (byte) info.tag; 2484 switch (info.tag) { 2485 case VerificationTypeInfo.ITEM_UNINITIALIZED : 2486 int offset = info.offset; 2487 this.contents[localContentsOffset++] = (byte) (offset >> 8); 2488 this.contents[localContentsOffset++] = (byte) offset; 2489 break; 2490 case VerificationTypeInfo.ITEM_OBJECT : 2491 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 2492 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 2493 this.contents[localContentsOffset++] = (byte) indexForType; 2494 } 2495 } 2496 numberOfDifferentLocals--; 2497 } 2498 } 2499 break; 2500 case StackMapFrame.SAME_FRAME : 2501 if (localContentsOffset + 1 >= this.contents.length) { 2502 resizeContents(1); 2503 } 2504 this.contents[localContentsOffset++] = (byte) offsetDelta; 2505 break; 2506 case StackMapFrame.SAME_FRAME_EXTENDED : 2507 if (localContentsOffset + 3 >= this.contents.length) { 2508 resizeContents(3); 2509 } 2510 this.contents[localContentsOffset++] = (byte) 251; 2511 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 2512 this.contents[localContentsOffset++] = (byte) offsetDelta; 2513 break; 2514 case StackMapFrame.CHOP_FRAME : 2515 if (localContentsOffset + 3 >= this.contents.length) { 2516 resizeContents(3); 2517 } 2518 numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); 2519 this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals); 2520 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 2521 this.contents[localContentsOffset++] = (byte) offsetDelta; 2522 break; 2523 case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS : 2524 if (localContentsOffset + 4 >= this.contents.length) { 2525 resizeContents(4); 2526 } 2527 this.contents[localContentsOffset++] = (byte) (offsetDelta + 64); 2528 if (currentFrame.stackItems[0] == null) { 2529 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 2530 } else { 2531 switch(currentFrame.stackItems[0].id()) { 2532 case T_boolean : 2533 case T_byte : 2534 case T_char : 2535 case T_int : 2536 case T_short : 2537 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 2538 break; 2539 case T_float : 2540 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 2541 break; 2542 case T_long : 2543 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 2544 break; 2545 case T_double : 2546 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 2547 break; 2548 case T_null : 2549 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 2550 break; 2551 default: 2552 VerificationTypeInfo info = currentFrame.stackItems[0]; 2553 this.contents[localContentsOffset++] = (byte) info.tag; 2554 switch (info.tag) { 2555 case VerificationTypeInfo.ITEM_UNINITIALIZED : 2556 int offset = info.offset; 2557 this.contents[localContentsOffset++] = (byte) (offset >> 8); 2558 this.contents[localContentsOffset++] = (byte) offset; 2559 break; 2560 case VerificationTypeInfo.ITEM_OBJECT : 2561 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 2562 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 2563 this.contents[localContentsOffset++] = (byte) indexForType; 2564 } 2565 } 2566 } 2567 break; 2568 case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED : 2569 if (localContentsOffset + 6 >= this.contents.length) { 2570 resizeContents(6); 2571 } 2572 this.contents[localContentsOffset++] = (byte) 247; 2573 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 2574 this.contents[localContentsOffset++] = (byte) offsetDelta; 2575 if (currentFrame.stackItems[0] == null) { 2576 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 2577 } else { 2578 switch(currentFrame.stackItems[0].id()) { 2579 case T_boolean : 2580 case T_byte : 2581 case T_char : 2582 case T_int : 2583 case T_short : 2584 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 2585 break; 2586 case T_float : 2587 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 2588 break; 2589 case T_long : 2590 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 2591 break; 2592 case T_double : 2593 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 2594 break; 2595 case T_null : 2596 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 2597 break; 2598 default: 2599 VerificationTypeInfo info = currentFrame.stackItems[0]; 2600 this.contents[localContentsOffset++] = (byte) info.tag; 2601 switch (info.tag) { 2602 case VerificationTypeInfo.ITEM_UNINITIALIZED : 2603 int offset = info.offset; 2604 this.contents[localContentsOffset++] = (byte) (offset >> 8); 2605 this.contents[localContentsOffset++] = (byte) offset; 2606 break; 2607 case VerificationTypeInfo.ITEM_OBJECT : 2608 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 2609 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 2610 this.contents[localContentsOffset++] = (byte) indexForType; 2611 } 2612 } 2613 } 2614 break; 2615 default : 2616 if (localContentsOffset + 5 >= this.contents.length) { 2618 resizeContents(5); 2619 } 2620 this.contents[localContentsOffset++] = (byte) 255; 2621 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 2622 this.contents[localContentsOffset++] = (byte) offsetDelta; 2623 int numberOfLocalOffset = localContentsOffset; 2624 localContentsOffset += 2; int numberOfLocalEntries = 0; 2626 numberOfLocals = currentFrame.getNumberOfLocals(); 2627 int numberOfEntries = 0; 2628 int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length; 2629 for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) { 2630 if (localContentsOffset + 3 >= this.contents.length) { 2631 resizeContents(3); 2632 } 2633 VerificationTypeInfo info = currentFrame.locals[i]; 2634 if (info == null) { 2635 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 2636 } else { 2637 switch(info.id()) { 2638 case T_boolean : 2639 case T_byte : 2640 case T_char : 2641 case T_int : 2642 case T_short : 2643 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 2644 break; 2645 case T_float : 2646 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 2647 break; 2648 case T_long : 2649 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 2650 i++; 2651 break; 2652 case T_double : 2653 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 2654 i++; 2655 break; 2656 case T_null : 2657 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 2658 break; 2659 default: 2660 this.contents[localContentsOffset++] = (byte) info.tag; 2661 switch (info.tag) { 2662 case VerificationTypeInfo.ITEM_UNINITIALIZED : 2663 int offset = info.offset; 2664 this.contents[localContentsOffset++] = (byte) (offset >> 8); 2665 this.contents[localContentsOffset++] = (byte) offset; 2666 break; 2667 case VerificationTypeInfo.ITEM_OBJECT : 2668 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 2669 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 2670 this.contents[localContentsOffset++] = (byte) indexForType; 2671 } 2672 } 2673 numberOfLocalEntries++; 2674 } 2675 numberOfEntries++; 2676 } 2677 if (localContentsOffset + 4 >= this.contents.length) { 2678 resizeContents(4); 2679 } 2680 this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8); 2681 this.contents[numberOfLocalOffset] = (byte) numberOfEntries; 2682 int numberOfStackItems = currentFrame.numberOfStackItems; 2683 this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8); 2684 this.contents[localContentsOffset++] = (byte) numberOfStackItems; 2685 for (int i = 0; i < numberOfStackItems; i++) { 2686 if (localContentsOffset + 3 >= this.contents.length) { 2687 resizeContents(3); 2688 } 2689 VerificationTypeInfo info = currentFrame.stackItems[i]; 2690 if (info == null) { 2691 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 2692 } else { 2693 switch(info.id()) { 2694 case T_boolean : 2695 case T_byte : 2696 case T_char : 2697 case T_int : 2698 case T_short : 2699 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 2700 break; 2701 case T_float : 2702 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 2703 break; 2704 case T_long : 2705 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 2706 break; 2707 case T_double : 2708 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 2709 break; 2710 case T_null : 2711 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 2712 break; 2713 default: 2714 this.contents[localContentsOffset++] = (byte) info.tag; 2715 switch (info.tag) { 2716 case VerificationTypeInfo.ITEM_UNINITIALIZED : 2717 int offset = info.offset; 2718 this.contents[localContentsOffset++] = (byte) (offset >> 8); 2719 this.contents[localContentsOffset++] = (byte) offset; 2720 break; 2721 case VerificationTypeInfo.ITEM_OBJECT : 2722 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 2723 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 2724 this.contents[localContentsOffset++] = (byte) indexForType; 2725 } 2726 } 2727 } 2728 } 2729 } 2730 } 2731 2732 this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8); 2733 this.contents[numberOfFramesOffset] = (byte) numberOfFrames; 2734 2735 int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4; 2736 this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24); 2737 this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16); 2738 this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8); 2739 this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength; 2740 attributeNumber++; 2741 } 2742 } 2743 2744 if (codeAttributeAttributeOffset + 2 >= this.contents.length) { 2747 resizeContents(2); 2748 } 2749 this.contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8); 2750 this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber; 2751 int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6); 2753 this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); 2754 this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); 2755 this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); 2756 this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; 2757 contentsOffset = localContentsOffset; 2758 } 2759 2760 2770 public void completeCodeAttributeForClinit( 2771 int codeAttributeOffset, 2772 int problemLine) { 2773 this.contents = codeStream.bCodeStream; 2775 int localContentsOffset = codeStream.classFileOffset; 2776 int code_length = codeStream.position; 2781 if (code_length > 65535) { 2782 codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit( 2783 codeStream.methodDeclaration.scope.referenceType()); 2784 } 2785 if (localContentsOffset + 20 >= this.contents.length) { 2786 resizeContents(20); 2787 } 2788 int max_stack = codeStream.stackMax; 2789 this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8); 2790 this.contents[codeAttributeOffset + 7] = (byte) max_stack; 2791 int max_locals = codeStream.maxLocals; 2792 this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8); 2793 this.contents[codeAttributeOffset + 9] = (byte) max_locals; 2794 this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24); 2795 this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16); 2796 this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8); 2797 this.contents[codeAttributeOffset + 13] = (byte) code_length; 2798 2799 this.contents[localContentsOffset++] = 0; 2801 this.contents[localContentsOffset++] = 0; 2802 2803 int codeAttributeAttributeOffset = localContentsOffset; 2805 int attributeNumber = 0; localContentsOffset += 2; if (localContentsOffset + 2 >= this.contents.length) { 2808 resizeContents(2); 2809 } 2810 2811 if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) { 2813 if (localContentsOffset + 20 >= this.contents.length) { 2814 resizeContents(20); 2815 } 2816 2822 int lineNumberNameIndex = 2823 constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName); 2824 this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8); 2825 this.contents[localContentsOffset++] = (byte) lineNumberNameIndex; 2826 this.contents[localContentsOffset++] = 0; 2827 this.contents[localContentsOffset++] = 0; 2828 this.contents[localContentsOffset++] = 0; 2829 this.contents[localContentsOffset++] = 6; 2830 this.contents[localContentsOffset++] = 0; 2831 this.contents[localContentsOffset++] = 1; 2832 this.contents[localContentsOffset++] = 0; 2834 this.contents[localContentsOffset++] = 0; 2835 this.contents[localContentsOffset++] = (byte) (problemLine >> 8); 2836 this.contents[localContentsOffset++] = (byte) problemLine; 2837 attributeNumber++; 2839 } 2840 if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) { 2842 int localVariableNameIndex = 2843 constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName); 2844 if (localContentsOffset + 8 >= this.contents.length) { 2845 resizeContents(8); 2846 } 2847 this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8); 2848 this.contents[localContentsOffset++] = (byte) localVariableNameIndex; 2849 this.contents[localContentsOffset++] = 0; 2850 this.contents[localContentsOffset++] = 0; 2851 this.contents[localContentsOffset++] = 0; 2852 this.contents[localContentsOffset++] = 2; 2853 this.contents[localContentsOffset++] = 0; 2854 this.contents[localContentsOffset++] = 0; 2855 attributeNumber++; 2856 } 2857 2858 if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { 2859 final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; 2860 final int framesPositionsSize = framesPositions.size(); 2861 int numberOfFrames = framesPositionsSize - 1; if (numberOfFrames > 0) { 2863 ArrayList framePositions = new ArrayList (framesPositionsSize); 2864 framePositions.addAll(framesPositions); 2865 Collections.sort(framePositions); 2866 if (localContentsOffset + 8 >= this.contents.length) { 2868 resizeContents(8); 2869 } 2870 int stackMapTableAttributeNameIndex = 2871 constantPool.literalIndex(AttributeNamesConstants.StackMapTableName); 2872 this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8); 2873 this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex; 2874 2875 int stackMapTableAttributeLengthOffset = localContentsOffset; 2876 localContentsOffset += 4; 2878 numberOfFrames = 0; 2879 int numberOfFramesOffset = localContentsOffset; 2880 localContentsOffset += 2; 2881 ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; 2883 StackMapFrame currentFrame = (StackMapFrame) frames.get(0); 2884 StackMapFrame prevFrame = null; 2885 int framesSize = frames.size(); 2886 int frameIndex = 0; 2887 for (int j = 0; j < framesPositionsSize && ((Integer ) framePositions.get(j)).intValue() < code_length; j++) { 2888 prevFrame = currentFrame; 2890 currentFrame = null; 2891 for (; frameIndex < framesSize; frameIndex++) { 2892 currentFrame = (StackMapFrame) frames.get(frameIndex); 2893 if (currentFrame.pc == ((Integer ) framePositions.get(j)).intValue()) { 2894 break; 2895 } 2896 } 2897 if (currentFrame == null) break; 2898 numberOfFrames++; 2901 int offsetDelta = currentFrame.getOffsetDelta(prevFrame); 2902 switch (currentFrame.getFrameType(prevFrame)) { 2903 case StackMapFrame.APPEND_FRAME : 2904 if (localContentsOffset + 3 >= this.contents.length) { 2905 resizeContents(3); 2906 } 2907 int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); 2908 this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals); 2909 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 2910 this.contents[localContentsOffset++] = (byte) offsetDelta; 2911 int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals); 2912 int numberOfLocals = currentFrame.getNumberOfLocals(); 2913 for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) { 2914 if (localContentsOffset + 6 >= this.contents.length) { 2915 resizeContents(6); 2916 } 2917 VerificationTypeInfo info = currentFrame.locals[i]; 2918 if (info == null) { 2919 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 2920 } else { 2921 switch(info.id()) { 2922 case T_boolean : 2923 case T_byte : 2924 case T_char : 2925 case T_int : 2926 case T_short : 2927 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 2928 break; 2929 case T_float : 2930 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 2931 break; 2932 case T_long : 2933 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 2934 i++; 2935 break; 2936 case T_double : 2937 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 2938 i++; 2939 break; 2940 case T_null : 2941 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 2942 break; 2943 default: 2944 this.contents[localContentsOffset++] = (byte) info.tag; 2945 switch (info.tag) { 2946 case VerificationTypeInfo.ITEM_UNINITIALIZED : 2947 int offset = info.offset; 2948 this.contents[localContentsOffset++] = (byte) (offset >> 8); 2949 this.contents[localContentsOffset++] = (byte) offset; 2950 break; 2951 case VerificationTypeInfo.ITEM_OBJECT : 2952 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 2953 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 2954 this.contents[localContentsOffset++] = (byte) indexForType; 2955 } 2956 } 2957 numberOfDifferentLocals--; 2958 } 2959 } 2960 break; 2961 case StackMapFrame.SAME_FRAME : 2962 if (localContentsOffset + 1 >= this.contents.length) { 2963 resizeContents(1); 2964 } 2965 this.contents[localContentsOffset++] = (byte) offsetDelta; 2966 break; 2967 case StackMapFrame.SAME_FRAME_EXTENDED : 2968 if (localContentsOffset + 3 >= this.contents.length) { 2969 resizeContents(3); 2970 } 2971 this.contents[localContentsOffset++] = (byte) 251; 2972 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 2973 this.contents[localContentsOffset++] = (byte) offsetDelta; 2974 break; 2975 case StackMapFrame.CHOP_FRAME : 2976 if (localContentsOffset + 3 >= this.contents.length) { 2977 resizeContents(3); 2978 } 2979 numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); 2980 this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals); 2981 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 2982 this.contents[localContentsOffset++] = (byte) offsetDelta; 2983 break; 2984 case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS : 2985 if (localContentsOffset + 4 >= this.contents.length) { 2986 resizeContents(4); 2987 } 2988 this.contents[localContentsOffset++] = (byte) (offsetDelta + 64); 2989 if (currentFrame.stackItems[0] == null) { 2990 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 2991 } else { 2992 switch(currentFrame.stackItems[0].id()) { 2993 case T_boolean : 2994 case T_byte : 2995 case T_char : 2996 case T_int : 2997 case T_short : 2998 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 2999 break; 3000 case T_float : 3001 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 3002 break; 3003 case T_long : 3004 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 3005 break; 3006 case T_double : 3007 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 3008 break; 3009 case T_null : 3010 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 3011 break; 3012 default: 3013 VerificationTypeInfo info = currentFrame.stackItems[0]; 3014 this.contents[localContentsOffset++] = (byte) info.tag; 3015 switch (info.tag) { 3016 case VerificationTypeInfo.ITEM_UNINITIALIZED : 3017 int offset = info.offset; 3018 this.contents[localContentsOffset++] = (byte) (offset >> 8); 3019 this.contents[localContentsOffset++] = (byte) offset; 3020 break; 3021 case VerificationTypeInfo.ITEM_OBJECT : 3022 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 3023 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 3024 this.contents[localContentsOffset++] = (byte) indexForType; 3025 } 3026 } 3027 } 3028 break; 3029 case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED : 3030 if (localContentsOffset + 6 >= this.contents.length) { 3031 resizeContents(6); 3032 } 3033 this.contents[localContentsOffset++] = (byte) 247; 3034 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 3035 this.contents[localContentsOffset++] = (byte) offsetDelta; 3036 if (currentFrame.stackItems[0] == null) { 3037 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 3038 } else { 3039 switch(currentFrame.stackItems[0].id()) { 3040 case T_boolean : 3041 case T_byte : 3042 case T_char : 3043 case T_int : 3044 case T_short : 3045 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 3046 break; 3047 case T_float : 3048 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 3049 break; 3050 case T_long : 3051 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 3052 break; 3053 case T_double : 3054 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 3055 break; 3056 case T_null : 3057 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 3058 break; 3059 default: 3060 VerificationTypeInfo info = currentFrame.stackItems[0]; 3061 this.contents[localContentsOffset++] = (byte) info.tag; 3062 switch (info.tag) { 3063 case VerificationTypeInfo.ITEM_UNINITIALIZED : 3064 int offset = info.offset; 3065 this.contents[localContentsOffset++] = (byte) (offset >> 8); 3066 this.contents[localContentsOffset++] = (byte) offset; 3067 break; 3068 case VerificationTypeInfo.ITEM_OBJECT : 3069 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 3070 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 3071 this.contents[localContentsOffset++] = (byte) indexForType; 3072 } 3073 } 3074 } 3075 break; 3076 default : 3077 if (localContentsOffset + 5 >= this.contents.length) { 3079 resizeContents(5); 3080 } 3081 this.contents[localContentsOffset++] = (byte) 255; 3082 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 3083 this.contents[localContentsOffset++] = (byte) offsetDelta; 3084 int numberOfLocalOffset = localContentsOffset; 3085 localContentsOffset += 2; int numberOfLocalEntries = 0; 3087 numberOfLocals = currentFrame.getNumberOfLocals(); 3088 int numberOfEntries = 0; 3089 int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length; 3090 for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) { 3091 if (localContentsOffset + 3 >= this.contents.length) { 3092 resizeContents(3); 3093 } 3094 VerificationTypeInfo info = currentFrame.locals[i]; 3095 if (info == null) { 3096 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 3097 } else { 3098 switch(info.id()) { 3099 case T_boolean : 3100 case T_byte : 3101 case T_char : 3102 case T_int : 3103 case T_short : 3104 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 3105 break; 3106 case T_float : 3107 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 3108 break; 3109 case T_long : 3110 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 3111 i++; 3112 break; 3113 case T_double : 3114 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 3115 i++; 3116 break; 3117 case T_null : 3118 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 3119 break; 3120 default: 3121 this.contents[localContentsOffset++] = (byte) info.tag; 3122 switch (info.tag) { 3123 case VerificationTypeInfo.ITEM_UNINITIALIZED : 3124 int offset = info.offset; 3125 this.contents[localContentsOffset++] = (byte) (offset >> 8); 3126 this.contents[localContentsOffset++] = (byte) offset; 3127 break; 3128 case VerificationTypeInfo.ITEM_OBJECT : 3129 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 3130 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 3131 this.contents[localContentsOffset++] = (byte) indexForType; 3132 } 3133 } 3134 numberOfLocalEntries++; 3135 } 3136 numberOfEntries++; 3137 } 3138 if (localContentsOffset + 4 >= this.contents.length) { 3139 resizeContents(4); 3140 } 3141 this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8); 3142 this.contents[numberOfLocalOffset] = (byte) numberOfEntries; 3143 int numberOfStackItems = currentFrame.numberOfStackItems; 3144 this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8); 3145 this.contents[localContentsOffset++] = (byte) numberOfStackItems; 3146 for (int i = 0; i < numberOfStackItems; i++) { 3147 if (localContentsOffset + 3 >= this.contents.length) { 3148 resizeContents(3); 3149 } 3150 VerificationTypeInfo info = currentFrame.stackItems[i]; 3151 if (info == null) { 3152 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 3153 } else { 3154 switch(info.id()) { 3155 case T_boolean : 3156 case T_byte : 3157 case T_char : 3158 case T_int : 3159 case T_short : 3160 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 3161 break; 3162 case T_float : 3163 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 3164 break; 3165 case T_long : 3166 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 3167 break; 3168 case T_double : 3169 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 3170 break; 3171 case T_null : 3172 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 3173 break; 3174 default: 3175 this.contents[localContentsOffset++] = (byte) info.tag; 3176 switch (info.tag) { 3177 case VerificationTypeInfo.ITEM_UNINITIALIZED : 3178 int offset = info.offset; 3179 this.contents[localContentsOffset++] = (byte) (offset >> 8); 3180 this.contents[localContentsOffset++] = (byte) offset; 3181 break; 3182 case VerificationTypeInfo.ITEM_OBJECT : 3183 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 3184 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 3185 this.contents[localContentsOffset++] = (byte) indexForType; 3186 } 3187 } 3188 } 3189 } 3190 } 3191 } 3192 3193 this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8); 3194 this.contents[numberOfFramesOffset] = (byte) numberOfFrames; 3195 3196 int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4; 3197 this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24); 3198 this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16); 3199 this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8); 3200 this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength; 3201 attributeNumber++; 3202 } 3203 } 3204 3205 if (codeAttributeAttributeOffset + 2 >= this.contents.length) { 3208 resizeContents(2); 3209 } 3210 this.contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8); 3211 this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber; 3212 int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6); 3214 this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); 3215 this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); 3216 this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); 3217 this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; 3218 contentsOffset = localContentsOffset; 3219 } 3220 3221 3224 public void completeCodeAttributeForMissingAbstractProblemMethod( 3225 MethodBinding binding, 3226 int codeAttributeOffset, 3227 int[] startLineIndexes, 3228 int problemLine) { 3229 this.contents = codeStream.bCodeStream; 3231 int localContentsOffset = codeStream.classFileOffset; 3232 int max_stack = codeStream.stackMax; 3234 this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8); 3235 this.contents[codeAttributeOffset + 7] = (byte) max_stack; 3236 int max_locals = codeStream.maxLocals; 3237 this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8); 3238 this.contents[codeAttributeOffset + 9] = (byte) max_locals; 3239 int code_length = codeStream.position; 3240 this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24); 3241 this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16); 3242 this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8); 3243 this.contents[codeAttributeOffset + 13] = (byte) code_length; 3244 if (localContentsOffset + 50 >= this.contents.length) { 3246 resizeContents(50); 3247 } 3248 this.contents[localContentsOffset++] = 0; 3249 this.contents[localContentsOffset++] = 0; 3250 int codeAttributeAttributeOffset = localContentsOffset; 3252 int attributeNumber = 0; localContentsOffset += 2; if (localContentsOffset + 2 >= this.contents.length) { 3255 resizeContents(2); 3256 } 3257 3258 if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) { 3259 if (localContentsOffset + 12 >= this.contents.length) { 3260 resizeContents(12); 3261 } 3262 3268 int lineNumberNameIndex = 3269 constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName); 3270 this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8); 3271 this.contents[localContentsOffset++] = (byte) lineNumberNameIndex; 3272 this.contents[localContentsOffset++] = 0; 3273 this.contents[localContentsOffset++] = 0; 3274 this.contents[localContentsOffset++] = 0; 3275 this.contents[localContentsOffset++] = 6; 3276 this.contents[localContentsOffset++] = 0; 3277 this.contents[localContentsOffset++] = 1; 3278 if (problemLine == 0) { 3279 problemLine = Util.getLineNumber(binding.sourceStart(), startLineIndexes, 0, startLineIndexes.length-1); 3280 } 3281 this.contents[localContentsOffset++] = 0; 3283 this.contents[localContentsOffset++] = 0; 3284 this.contents[localContentsOffset++] = (byte) (problemLine >> 8); 3285 this.contents[localContentsOffset++] = (byte) problemLine; 3286 attributeNumber++; 3288 } 3289 3290 if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { 3291 final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; 3292 final int framesPositionsSize = framesPositions.size(); 3293 int numberOfFrames = framesPositionsSize - 1; if (numberOfFrames > 0) { 3295 ArrayList framePositions = new ArrayList (framesPositionsSize); 3296 framePositions.addAll(framesPositions); 3297 Collections.sort(framePositions); 3298 if (localContentsOffset + 8 >= this.contents.length) { 3300 resizeContents(8); 3301 } 3302 int stackMapTableAttributeNameIndex = 3303 constantPool.literalIndex(AttributeNamesConstants.StackMapTableName); 3304 this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8); 3305 this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex; 3306 3307 int stackMapTableAttributeLengthOffset = localContentsOffset; 3308 localContentsOffset += 4; 3310 numberOfFrames = 0; 3311 int numberOfFramesOffset = localContentsOffset; 3312 localContentsOffset += 2; 3313 ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; 3315 StackMapFrame currentFrame = (StackMapFrame) frames.get(0); 3316 StackMapFrame prevFrame = null; 3317 int framesSize = frames.size(); 3318 int frameIndex = 0; 3319 for (int j = 0; j < framesPositionsSize && ((Integer ) framePositions.get(j)).intValue() < code_length; j++) { 3320 prevFrame = currentFrame; 3322 currentFrame = null; 3323 for (; frameIndex < framesSize; frameIndex++) { 3324 currentFrame = (StackMapFrame) frames.get(frameIndex); 3325 if (currentFrame.pc == ((Integer ) framePositions.get(j)).intValue()) { 3326 break; 3327 } 3328 } 3329 if (currentFrame == null) break; 3330 numberOfFrames++; 3331 int offsetDelta = currentFrame.getOffsetDelta(prevFrame); 3332 switch (currentFrame.getFrameType(prevFrame)) { 3333 case StackMapFrame.APPEND_FRAME : 3334 if (localContentsOffset + 3 >= this.contents.length) { 3335 resizeContents(3); 3336 } 3337 int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); 3338 this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals); 3339 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 3340 this.contents[localContentsOffset++] = (byte) offsetDelta; 3341 int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals); 3342 int numberOfLocals = currentFrame.getNumberOfLocals(); 3343 for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) { 3344 if (localContentsOffset + 6 >= this.contents.length) { 3345 resizeContents(6); 3346 } 3347 VerificationTypeInfo info = currentFrame.locals[i]; 3348 if (info == null) { 3349 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 3350 } else { 3351 switch(info.id()) { 3352 case T_boolean : 3353 case T_byte : 3354 case T_char : 3355 case T_int : 3356 case T_short : 3357 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 3358 break; 3359 case T_float : 3360 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 3361 break; 3362 case T_long : 3363 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 3364 i++; 3365 break; 3366 case T_double : 3367 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 3368 i++; 3369 break; 3370 case T_null : 3371 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 3372 break; 3373 default: 3374 this.contents[localContentsOffset++] = (byte) info.tag; 3375 switch (info.tag) { 3376 case VerificationTypeInfo.ITEM_UNINITIALIZED : 3377 int offset = info.offset; 3378 this.contents[localContentsOffset++] = (byte) (offset >> 8); 3379 this.contents[localContentsOffset++] = (byte) offset; 3380 break; 3381 case VerificationTypeInfo.ITEM_OBJECT : 3382 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 3383 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 3384 this.contents[localContentsOffset++] = (byte) indexForType; 3385 } 3386 } 3387 numberOfDifferentLocals--; 3388 } 3389 } 3390 break; 3391 case StackMapFrame.SAME_FRAME : 3392 if (localContentsOffset + 1 >= this.contents.length) { 3393 resizeContents(1); 3394 } 3395 this.contents[localContentsOffset++] = (byte) offsetDelta; 3396 break; 3397 case StackMapFrame.SAME_FRAME_EXTENDED : 3398 if (localContentsOffset + 3 >= this.contents.length) { 3399 resizeContents(3); 3400 } 3401 this.contents[localContentsOffset++] = (byte) 251; 3402 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 3403 this.contents[localContentsOffset++] = (byte) offsetDelta; 3404 break; 3405 case StackMapFrame.CHOP_FRAME : 3406 if (localContentsOffset + 3 >= this.contents.length) { 3407 resizeContents(3); 3408 } 3409 numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); 3410 this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals); 3411 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 3412 this.contents[localContentsOffset++] = (byte) offsetDelta; 3413 break; 3414 case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS : 3415 if (localContentsOffset + 4 >= this.contents.length) { 3416 resizeContents(4); 3417 } 3418 this.contents[localContentsOffset++] = (byte) (offsetDelta + 64); 3419 if (currentFrame.stackItems[0] == null) { 3420 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 3421 } else { 3422 switch(currentFrame.stackItems[0].id()) { 3423 case T_boolean : 3424 case T_byte : 3425 case T_char : 3426 case T_int : 3427 case T_short : 3428 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 3429 break; 3430 case T_float : 3431 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 3432 break; 3433 case T_long : 3434 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 3435 break; 3436 case T_double : 3437 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 3438 break; 3439 case T_null : 3440 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 3441 break; 3442 default: 3443 VerificationTypeInfo info = currentFrame.stackItems[0]; 3444 this.contents[localContentsOffset++] = (byte) info.tag; 3445 switch (info.tag) { 3446 case VerificationTypeInfo.ITEM_UNINITIALIZED : 3447 int offset = info.offset; 3448 this.contents[localContentsOffset++] = (byte) (offset >> 8); 3449 this.contents[localContentsOffset++] = (byte) offset; 3450 break; 3451 case VerificationTypeInfo.ITEM_OBJECT : 3452 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 3453 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 3454 this.contents[localContentsOffset++] = (byte) indexForType; 3455 } 3456 } 3457 } 3458 break; 3459 case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED : 3460 if (localContentsOffset + 6 >= this.contents.length) { 3461 resizeContents(6); 3462 } 3463 this.contents[localContentsOffset++] = (byte) 247; 3464 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 3465 this.contents[localContentsOffset++] = (byte) offsetDelta; 3466 if (currentFrame.stackItems[0] == null) { 3467 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 3468 } else { 3469 switch(currentFrame.stackItems[0].id()) { 3470 case T_boolean : 3471 case T_byte : 3472 case T_char : 3473 case T_int : 3474 case T_short : 3475 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 3476 break; 3477 case T_float : 3478 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 3479 break; 3480 case T_long : 3481 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 3482 break; 3483 case T_double : 3484 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 3485 break; 3486 case T_null : 3487 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 3488 break; 3489 default: 3490 VerificationTypeInfo info = currentFrame.stackItems[0]; 3491 this.contents[localContentsOffset++] = (byte) info.tag; 3492 switch (info.tag) { 3493 case VerificationTypeInfo.ITEM_UNINITIALIZED : 3494 int offset = info.offset; 3495 this.contents[localContentsOffset++] = (byte) (offset >> 8); 3496 this.contents[localContentsOffset++] = (byte) offset; 3497 break; 3498 case VerificationTypeInfo.ITEM_OBJECT : 3499 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 3500 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 3501 this.contents[localContentsOffset++] = (byte) indexForType; 3502 } 3503 } 3504 } 3505 break; 3506 default : 3507 if (localContentsOffset + 5 >= this.contents.length) { 3509 resizeContents(5); 3510 } 3511 this.contents[localContentsOffset++] = (byte) 255; 3512 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 3513 this.contents[localContentsOffset++] = (byte) offsetDelta; 3514 int numberOfLocalOffset = localContentsOffset; 3515 localContentsOffset += 2; int numberOfLocalEntries = 0; 3517 numberOfLocals = currentFrame.getNumberOfLocals(); 3518 int numberOfEntries = 0; 3519 int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length; 3520 for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) { 3521 if (localContentsOffset + 3 >= this.contents.length) { 3522 resizeContents(3); 3523 } 3524 VerificationTypeInfo info = currentFrame.locals[i]; 3525 if (info == null) { 3526 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 3527 } else { 3528 switch(info.id()) { 3529 case T_boolean : 3530 case T_byte : 3531 case T_char : 3532 case T_int : 3533 case T_short : 3534 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 3535 break; 3536 case T_float : 3537 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 3538 break; 3539 case T_long : 3540 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 3541 i++; 3542 break; 3543 case T_double : 3544 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 3545 i++; 3546 break; 3547 case T_null : 3548 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 3549 break; 3550 default: 3551 this.contents[localContentsOffset++] = (byte) info.tag; 3552 switch (info.tag) { 3553 case VerificationTypeInfo.ITEM_UNINITIALIZED : 3554 int offset = info.offset; 3555 this.contents[localContentsOffset++] = (byte) (offset >> 8); 3556 this.contents[localContentsOffset++] = (byte) offset; 3557 break; 3558 case VerificationTypeInfo.ITEM_OBJECT : 3559 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 3560 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 3561 this.contents[localContentsOffset++] = (byte) indexForType; 3562 } 3563 } 3564 numberOfLocalEntries++; 3565 } 3566 numberOfEntries++; 3567 } 3568 if (localContentsOffset + 4 >= this.contents.length) { 3569 resizeContents(4); 3570 } 3571 this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8); 3572 this.contents[numberOfLocalOffset] = (byte) numberOfEntries; 3573 int numberOfStackItems = currentFrame.numberOfStackItems; 3574 this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8); 3575 this.contents[localContentsOffset++] = (byte) numberOfStackItems; 3576 for (int i = 0; i < numberOfStackItems; i++) { 3577 if (localContentsOffset + 3 >= this.contents.length) { 3578 resizeContents(3); 3579 } 3580 VerificationTypeInfo info = currentFrame.stackItems[i]; 3581 if (info == null) { 3582 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 3583 } else { 3584 switch(info.id()) { 3585 case T_boolean : 3586 case T_byte : 3587 case T_char : 3588 case T_int : 3589 case T_short : 3590 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 3591 break; 3592 case T_float : 3593 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 3594 break; 3595 case T_long : 3596 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 3597 break; 3598 case T_double : 3599 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 3600 break; 3601 case T_null : 3602 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 3603 break; 3604 default: 3605 this.contents[localContentsOffset++] = (byte) info.tag; 3606 switch (info.tag) { 3607 case VerificationTypeInfo.ITEM_UNINITIALIZED : 3608 int offset = info.offset; 3609 this.contents[localContentsOffset++] = (byte) (offset >> 8); 3610 this.contents[localContentsOffset++] = (byte) offset; 3611 break; 3612 case VerificationTypeInfo.ITEM_OBJECT : 3613 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 3614 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 3615 this.contents[localContentsOffset++] = (byte) indexForType; 3616 } 3617 } 3618 } 3619 } 3620 } 3621 } 3622 3623 this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8); 3624 this.contents[numberOfFramesOffset] = (byte) numberOfFrames; 3625 3626 int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4; 3627 this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24); 3628 this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16); 3629 this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8); 3630 this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength; 3631 attributeNumber++; 3632 } 3633 } 3634 3635 if (codeAttributeAttributeOffset + 2 >= this.contents.length) { 3638 resizeContents(2); 3639 } 3640 this.contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8); 3641 this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber; 3642 int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6); 3644 this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); 3645 this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); 3646 this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); 3647 this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; 3648 contentsOffset = localContentsOffset; 3649 } 3650 3651 3663 public void completeCodeAttributeForProblemMethod( 3664 AbstractMethodDeclaration method, 3665 MethodBinding binding, 3666 int codeAttributeOffset, 3667 int[] startLineIndexes, 3668 int problemLine) { 3669 this.contents = codeStream.bCodeStream; 3671 int localContentsOffset = codeStream.classFileOffset; 3672 int max_stack = codeStream.stackMax; 3674 this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8); 3675 this.contents[codeAttributeOffset + 7] = (byte) max_stack; 3676 int max_locals = codeStream.maxLocals; 3677 this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8); 3678 this.contents[codeAttributeOffset + 9] = (byte) max_locals; 3679 int code_length = codeStream.position; 3680 this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24); 3681 this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16); 3682 this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8); 3683 this.contents[codeAttributeOffset + 13] = (byte) code_length; 3684 if (localContentsOffset + 50 >= this.contents.length) { 3686 resizeContents(50); 3687 } 3688 3689 this.contents[localContentsOffset++] = 0; 3691 this.contents[localContentsOffset++] = 0; 3692 int codeAttributeAttributeOffset = localContentsOffset; 3694 int attributeNumber = 0; localContentsOffset += 2; if (localContentsOffset + 2 >= this.contents.length) { 3697 resizeContents(2); 3698 } 3699 3700 if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) { 3701 if (localContentsOffset + 20 >= this.contents.length) { 3702 resizeContents(20); 3703 } 3704 3710 int lineNumberNameIndex = 3711 constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName); 3712 this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8); 3713 this.contents[localContentsOffset++] = (byte) lineNumberNameIndex; 3714 this.contents[localContentsOffset++] = 0; 3715 this.contents[localContentsOffset++] = 0; 3716 this.contents[localContentsOffset++] = 0; 3717 this.contents[localContentsOffset++] = 6; 3718 this.contents[localContentsOffset++] = 0; 3719 this.contents[localContentsOffset++] = 1; 3720 if (problemLine == 0) { 3721 problemLine = Util.getLineNumber(binding.sourceStart(), startLineIndexes, 0, startLineIndexes.length-1); 3722 } 3723 this.contents[localContentsOffset++] = 0; 3725 this.contents[localContentsOffset++] = 0; 3726 this.contents[localContentsOffset++] = (byte) (problemLine >> 8); 3727 this.contents[localContentsOffset++] = (byte) problemLine; 3728 attributeNumber++; 3730 } 3731 if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) { 3733 int argSize; 3735 int numberOfEntries = 0; 3736 int localVariableNameIndex = 3738 constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName); 3739 if (localContentsOffset + 8 >= this.contents.length) { 3740 resizeContents(8); 3741 } 3742 this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8); 3743 this.contents[localContentsOffset++] = (byte) localVariableNameIndex; 3744 int localVariableTableOffset = localContentsOffset; 3745 localContentsOffset += 6; 3746 int descriptorIndex; 3748 int nameIndex; 3749 SourceTypeBinding declaringClassBinding = null; 3750 final boolean methodDeclarationIsStatic = codeStream.methodDeclaration.isStatic(); 3751 if (!methodDeclarationIsStatic) { 3752 numberOfEntries++; 3753 if (localContentsOffset + 10 >= this.contents.length) { 3754 resizeContents(10); 3755 } 3756 this.contents[localContentsOffset++] = 0; 3757 this.contents[localContentsOffset++] = 0; 3758 this.contents[localContentsOffset++] = (byte) (code_length >> 8); 3759 this.contents[localContentsOffset++] = (byte) code_length; 3760 nameIndex = constantPool.literalIndex(ConstantPool.This); 3761 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 3762 this.contents[localContentsOffset++] = (byte) nameIndex; 3763 declaringClassBinding = (SourceTypeBinding) codeStream.methodDeclaration.binding.declaringClass; 3764 descriptorIndex = 3765 constantPool.literalIndex(declaringClassBinding.signature()); 3766 this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); 3767 this.contents[localContentsOffset++] = (byte) descriptorIndex; 3768 this.contents[localContentsOffset++] = 0; 3770 this.contents[localContentsOffset++] = 0; 3771 } 3772 int genericLocalVariablesCounter = 0; 3774 LocalVariableBinding[] genericLocalVariables = null; 3775 int numberOfGenericEntries = 0; 3776 3777 if (binding.isConstructor()) { 3778 ReferenceBinding declaringClass = binding.declaringClass; 3779 if (declaringClass.isNestedType()) { 3780 NestedTypeBinding methodDeclaringClass = (NestedTypeBinding) declaringClass; 3781 argSize = methodDeclaringClass.enclosingInstancesSlotSize; 3782 SyntheticArgumentBinding[] syntheticArguments; 3783 if ((syntheticArguments = methodDeclaringClass.syntheticEnclosingInstances()) != null) { 3784 for (int i = 0, max = syntheticArguments.length; i < max; i++) { 3785 LocalVariableBinding localVariable = syntheticArguments[i]; 3786 final TypeBinding localVariableTypeBinding = localVariable.type; 3787 if (localVariableTypeBinding.isParameterizedType() || localVariableTypeBinding.isTypeVariable()) { 3788 if (genericLocalVariables == null) { 3789 genericLocalVariables = new LocalVariableBinding[max]; 3791 } 3792 genericLocalVariables[genericLocalVariablesCounter++] = localVariable; 3793 numberOfGenericEntries++; 3794 } 3795 if (localContentsOffset + 10 >= this.contents.length) { 3796 resizeContents(10); 3797 } 3798 numberOfEntries++; 3800 this.contents[localContentsOffset++] = 0; 3801 this.contents[localContentsOffset++] = 0; 3802 this.contents[localContentsOffset++] = (byte) (code_length >> 8); 3803 this.contents[localContentsOffset++] = (byte) code_length; 3804 nameIndex = constantPool.literalIndex(localVariable.name); 3805 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 3806 this.contents[localContentsOffset++] = (byte) nameIndex; 3807 descriptorIndex = constantPool.literalIndex(localVariableTypeBinding.signature()); 3808 this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); 3809 this.contents[localContentsOffset++] = (byte) descriptorIndex; 3810 int resolvedPosition = localVariable.resolvedPosition; 3811 this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8); 3812 this.contents[localContentsOffset++] = (byte) resolvedPosition; 3813 } 3814 } 3815 } else { 3816 argSize = 1; 3817 } 3818 } else { 3819 argSize = binding.isStatic() ? 0 : 1; 3820 } 3821 3822 int genericArgumentsCounter = 0; 3823 int[] genericArgumentsNameIndexes = null; 3824 int[] genericArgumentsResolvedPositions = null; 3825 TypeBinding[] genericArgumentsTypeBindings = null; 3826 3827 if (method.binding != null) { 3828 TypeBinding[] parameters = method.binding.parameters; 3829 Argument[] arguments = method.arguments; 3830 if ((parameters != null) && (arguments != null)) { 3831 for (int i = 0, max = parameters.length; i < max; i++) { 3832 TypeBinding argumentBinding = parameters[i]; 3833 if (localContentsOffset + 10 >= this.contents.length) { 3834 resizeContents(10); 3835 } 3836 numberOfEntries++; 3838 this.contents[localContentsOffset++] = 0; 3839 this.contents[localContentsOffset++] = 0; 3840 this.contents[localContentsOffset++] = (byte) (code_length >> 8); 3841 this.contents[localContentsOffset++] = (byte) code_length; 3842 nameIndex = constantPool.literalIndex(arguments[i].name); 3843 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 3844 this.contents[localContentsOffset++] = (byte) nameIndex; 3845 int resolvedPosition = argSize; 3846 if (argumentBinding.isParameterizedType() || argumentBinding.isTypeVariable()) { 3847 if (genericArgumentsCounter == 0) { 3848 genericArgumentsNameIndexes = new int[max]; 3850 genericArgumentsResolvedPositions = new int[max]; 3851 genericArgumentsTypeBindings = new TypeBinding[max]; 3852 } 3853 genericArgumentsNameIndexes[genericArgumentsCounter] = nameIndex; 3854 genericArgumentsResolvedPositions[genericArgumentsCounter] = resolvedPosition; 3855 genericArgumentsTypeBindings[genericArgumentsCounter++] = argumentBinding; 3856 } 3857 descriptorIndex = constantPool.literalIndex(argumentBinding.signature()); 3858 this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); 3859 this.contents[localContentsOffset++] = (byte) descriptorIndex; 3860 if ((argumentBinding == TypeBinding.LONG) 3861 || (argumentBinding == TypeBinding.DOUBLE)) 3862 argSize += 2; 3863 else 3864 argSize++; 3865 this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8); 3866 this.contents[localContentsOffset++] = (byte) resolvedPosition; 3867 } 3868 } 3869 } 3870 int value = numberOfEntries * 10 + 2; 3871 this.contents[localVariableTableOffset++] = (byte) (value >> 24); 3872 this.contents[localVariableTableOffset++] = (byte) (value >> 16); 3873 this.contents[localVariableTableOffset++] = (byte) (value >> 8); 3874 this.contents[localVariableTableOffset++] = (byte) value; 3875 this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8); 3876 this.contents[localVariableTableOffset] = (byte) numberOfEntries; 3877 attributeNumber++; 3878 3879 final boolean currentInstanceIsGeneric = 3880 !methodDeclarationIsStatic 3881 && declaringClassBinding != null 3882 && declaringClassBinding.typeVariables != Binding.NO_TYPE_VARIABLES; 3883 if (genericLocalVariablesCounter != 0 || genericArgumentsCounter != 0 || currentInstanceIsGeneric) { 3884 numberOfEntries = numberOfGenericEntries + genericArgumentsCounter + (currentInstanceIsGeneric ? 1 : 0); 3886 int maxOfEntries = 8 + numberOfEntries * 10; 3888 if (localContentsOffset + maxOfEntries >= this.contents.length) { 3889 resizeContents(maxOfEntries); 3890 } 3891 int localVariableTypeNameIndex = 3892 constantPool.literalIndex(AttributeNamesConstants.LocalVariableTypeTableName); 3893 this.contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8); 3894 this.contents[localContentsOffset++] = (byte) localVariableTypeNameIndex; 3895 value = numberOfEntries * 10 + 2; 3896 this.contents[localContentsOffset++] = (byte) (value >> 24); 3897 this.contents[localContentsOffset++] = (byte) (value >> 16); 3898 this.contents[localContentsOffset++] = (byte) (value >> 8); 3899 this.contents[localContentsOffset++] = (byte) value; 3900 this.contents[localContentsOffset++] = (byte) (numberOfEntries >> 8); 3901 this.contents[localContentsOffset++] = (byte) numberOfEntries; 3902 if (currentInstanceIsGeneric) { 3903 numberOfEntries++; 3904 this.contents[localContentsOffset++] = 0; this.contents[localContentsOffset++] = 0; 3906 this.contents[localContentsOffset++] = (byte) (code_length >> 8); 3907 this.contents[localContentsOffset++] = (byte) code_length; 3908 nameIndex = constantPool.literalIndex(ConstantPool.This); 3909 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 3910 this.contents[localContentsOffset++] = (byte) nameIndex; 3911 descriptorIndex = constantPool.literalIndex(declaringClassBinding.genericTypeSignature()); 3912 this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); 3913 this.contents[localContentsOffset++] = (byte) descriptorIndex; 3914 this.contents[localContentsOffset++] = 0; this.contents[localContentsOffset++] = 0; 3916 } 3917 3918 for (int i = 0; i < genericLocalVariablesCounter; i++) { 3919 LocalVariableBinding localVariable = genericLocalVariables[i]; 3920 this.contents[localContentsOffset++] = 0; 3921 this.contents[localContentsOffset++] = 0; 3922 this.contents[localContentsOffset++] = (byte) (code_length >> 8); 3923 this.contents[localContentsOffset++] = (byte) code_length; 3924 nameIndex = constantPool.literalIndex(localVariable.name); 3925 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 3926 this.contents[localContentsOffset++] = (byte) nameIndex; 3927 descriptorIndex = constantPool.literalIndex(localVariable.type.genericTypeSignature()); 3928 this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); 3929 this.contents[localContentsOffset++] = (byte) descriptorIndex; 3930 int resolvedPosition = localVariable.resolvedPosition; 3931 this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8); 3932 this.contents[localContentsOffset++] = (byte) resolvedPosition; 3933 } 3934 for (int i = 0; i < genericArgumentsCounter; i++) { 3935 this.contents[localContentsOffset++] = 0; 3936 this.contents[localContentsOffset++] = 0; 3937 this.contents[localContentsOffset++] = (byte) (code_length >> 8); 3938 this.contents[localContentsOffset++] = (byte) code_length; 3939 nameIndex = genericArgumentsNameIndexes[i]; 3940 this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); 3941 this.contents[localContentsOffset++] = (byte) nameIndex; 3942 descriptorIndex = constantPool.literalIndex(genericArgumentsTypeBindings[i].genericTypeSignature()); 3943 this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); 3944 this.contents[localContentsOffset++] = (byte) descriptorIndex; 3945 int resolvedPosition = genericArgumentsResolvedPositions[i]; 3946 this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8); 3947 this.contents[localContentsOffset++] = (byte) resolvedPosition; 3948 } 3949 attributeNumber++; 3950 } 3951 } 3952 3953 if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { 3954 final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; 3955 final int framesPositionsSize = framesPositions.size(); 3956 int numberOfFrames = framesPositionsSize - 1; if (numberOfFrames > 0) { 3958 ArrayList framePositions = new ArrayList (framesPositionsSize); 3959 framePositions.addAll(framesPositions); 3960 Collections.sort(framePositions); 3961 if (localContentsOffset + 8 >= this.contents.length) { 3963 resizeContents(8); 3964 } 3965 int stackMapTableAttributeNameIndex = 3966 constantPool.literalIndex(AttributeNamesConstants.StackMapTableName); 3967 this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8); 3968 this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex; 3969 3970 int stackMapTableAttributeLengthOffset = localContentsOffset; 3971 localContentsOffset += 4; 3973 numberOfFrames = 0; 3974 int numberOfFramesOffset = localContentsOffset; 3975 localContentsOffset += 2; 3976 ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; 3978 StackMapFrame currentFrame = (StackMapFrame) frames.get(0); 3979 StackMapFrame prevFrame = null; 3980 int framesSize = frames.size(); 3981 int frameIndex = 0; 3982 for (int j = 0; j < framesPositionsSize && ((Integer ) framePositions.get(j)).intValue() < code_length; j++) { 3983 prevFrame = currentFrame; 3985 currentFrame = null; 3986 for (; frameIndex < framesSize; frameIndex++) { 3987 currentFrame = (StackMapFrame) frames.get(frameIndex); 3988 if (currentFrame.pc == ((Integer ) framePositions.get(j)).intValue()) { 3989 break; 3990 } 3991 } 3992 if (currentFrame == null) break; 3993 numberOfFrames++; 3994 int offsetDelta = currentFrame.getOffsetDelta(prevFrame); 3995 switch (currentFrame.getFrameType(prevFrame)) { 3996 case StackMapFrame.APPEND_FRAME : 3997 if (localContentsOffset + 3 >= this.contents.length) { 3998 resizeContents(3); 3999 } 4000 int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); 4001 this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals); 4002 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 4003 this.contents[localContentsOffset++] = (byte) offsetDelta; 4004 int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals); 4005 int numberOfLocals = currentFrame.getNumberOfLocals(); 4006 for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) { 4007 if (localContentsOffset + 6 >= this.contents.length) { 4008 resizeContents(6); 4009 } 4010 VerificationTypeInfo info = currentFrame.locals[i]; 4011 if (info == null) { 4012 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 4013 } else { 4014 switch(info.id()) { 4015 case T_boolean : 4016 case T_byte : 4017 case T_char : 4018 case T_int : 4019 case T_short : 4020 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 4021 break; 4022 case T_float : 4023 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 4024 break; 4025 case T_long : 4026 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 4027 i++; 4028 break; 4029 case T_double : 4030 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 4031 i++; 4032 break; 4033 case T_null : 4034 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 4035 break; 4036 default: 4037 this.contents[localContentsOffset++] = (byte) info.tag; 4038 switch (info.tag) { 4039 case VerificationTypeInfo.ITEM_UNINITIALIZED : 4040 int offset = info.offset; 4041 this.contents[localContentsOffset++] = (byte) (offset >> 8); 4042 this.contents[localContentsOffset++] = (byte) offset; 4043 break; 4044 case VerificationTypeInfo.ITEM_OBJECT : 4045 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 4046 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 4047 this.contents[localContentsOffset++] = (byte) indexForType; 4048 } 4049 } 4050 numberOfDifferentLocals--; 4051 } 4052 } 4053 break; 4054 case StackMapFrame.SAME_FRAME : 4055 if (localContentsOffset + 1 >= this.contents.length) { 4056 resizeContents(1); 4057 } 4058 this.contents[localContentsOffset++] = (byte) offsetDelta; 4059 break; 4060 case StackMapFrame.SAME_FRAME_EXTENDED : 4061 if (localContentsOffset + 3 >= this.contents.length) { 4062 resizeContents(3); 4063 } 4064 this.contents[localContentsOffset++] = (byte) 251; 4065 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 4066 this.contents[localContentsOffset++] = (byte) offsetDelta; 4067 break; 4068 case StackMapFrame.CHOP_FRAME : 4069 if (localContentsOffset + 3 >= this.contents.length) { 4070 resizeContents(3); 4071 } 4072 numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); 4073 this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals); 4074 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 4075 this.contents[localContentsOffset++] = (byte) offsetDelta; 4076 break; 4077 case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS : 4078 if (localContentsOffset + 4 >= this.contents.length) { 4079 resizeContents(4); 4080 } 4081 this.contents[localContentsOffset++] = (byte) (offsetDelta + 64); 4082 if (currentFrame.stackItems[0] == null) { 4083 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 4084 } else { 4085 switch(currentFrame.stackItems[0].id()) { 4086 case T_boolean : 4087 case T_byte : 4088 case T_char : 4089 case T_int : 4090 case T_short : 4091 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 4092 break; 4093 case T_float : 4094 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 4095 break; 4096 case T_long : 4097 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 4098 break; 4099 case T_double : 4100 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 4101 break; 4102 case T_null : 4103 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 4104 break; 4105 default: 4106 VerificationTypeInfo info = currentFrame.stackItems[0]; 4107 this.contents[localContentsOffset++] = (byte) info.tag; 4108 switch (info.tag) { 4109 case VerificationTypeInfo.ITEM_UNINITIALIZED : 4110 int offset = info.offset; 4111 this.contents[localContentsOffset++] = (byte) (offset >> 8); 4112 this.contents[localContentsOffset++] = (byte) offset; 4113 break; 4114 case VerificationTypeInfo.ITEM_OBJECT : 4115 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 4116 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 4117 this.contents[localContentsOffset++] = (byte) indexForType; 4118 } 4119 } 4120 } 4121 break; 4122 case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED : 4123 if (localContentsOffset + 6 >= this.contents.length) { 4124 resizeContents(6); 4125 } 4126 this.contents[localContentsOffset++] = (byte) 247; 4127 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 4128 this.contents[localContentsOffset++] = (byte) offsetDelta; 4129 if (currentFrame.stackItems[0] == null) { 4130 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 4131 } else { 4132 switch(currentFrame.stackItems[0].id()) { 4133 case T_boolean : 4134 case T_byte : 4135 case T_char : 4136 case T_int : 4137 case T_short : 4138 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 4139 break; 4140 case T_float : 4141 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 4142 break; 4143 case T_long : 4144 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 4145 break; 4146 case T_double : 4147 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 4148 break; 4149 case T_null : 4150 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 4151 break; 4152 default: 4153 VerificationTypeInfo info = currentFrame.stackItems[0]; 4154 this.contents[localContentsOffset++] = (byte) info.tag; 4155 switch (info.tag) { 4156 case VerificationTypeInfo.ITEM_UNINITIALIZED : 4157 int offset = info.offset; 4158 this.contents[localContentsOffset++] = (byte) (offset >> 8); 4159 this.contents[localContentsOffset++] = (byte) offset; 4160 break; 4161 case VerificationTypeInfo.ITEM_OBJECT : 4162 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 4163 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 4164 this.contents[localContentsOffset++] = (byte) indexForType; 4165 } 4166 } 4167 } 4168 break; 4169 default : 4170 if (localContentsOffset + 5 >= this.contents.length) { 4172 resizeContents(5); 4173 } 4174 this.contents[localContentsOffset++] = (byte) 255; 4175 this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); 4176 this.contents[localContentsOffset++] = (byte) offsetDelta; 4177 int numberOfLocalOffset = localContentsOffset; 4178 localContentsOffset += 2; int numberOfLocalEntries = 0; 4180 numberOfLocals = currentFrame.getNumberOfLocals(); 4181 int numberOfEntries = 0; 4182 int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length; 4183 for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) { 4184 if (localContentsOffset + 3 >= this.contents.length) { 4185 resizeContents(3); 4186 } 4187 VerificationTypeInfo info = currentFrame.locals[i]; 4188 if (info == null) { 4189 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 4190 } else { 4191 switch(info.id()) { 4192 case T_boolean : 4193 case T_byte : 4194 case T_char : 4195 case T_int : 4196 case T_short : 4197 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; 4198 break; 4199 case T_float : 4200 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; 4201 break; 4202 case T_long : 4203 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; 4204 i++; 4205 break; 4206 case T_double : 4207 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; 4208 i++; 4209 break; 4210 case T_null : 4211 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; 4212 break; 4213 default: 4214 this.contents[localContentsOffset++] = (byte) info.tag; 4215 switch (info.tag) { 4216 case VerificationTypeInfo.ITEM_UNINITIALIZED : 4217 int offset = info.offset; 4218 this.contents[localContentsOffset++] = (byte) (offset >> 8); 4219 this.contents[localContentsOffset++] = (byte) offset; 4220 break; 4221 case VerificationTypeInfo.ITEM_OBJECT : 4222 int indexForType = constantPool.literalIndexForType(info.constantPoolName()); 4223 this.contents[localContentsOffset++] = (byte) (indexForType >> 8); 4224 this.contents[localContentsOffset++] = (byte) indexForType; 4225 } 4226 } 4227 numberOfLocalEntries++; 4228 } 4229 numberOfEntries++; 4230 } 4231 if (localContentsOffset + 4 >= this.contents.length) { 4232 resizeContents(4); 4233 } 4234 this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8); 4235 this.contents[numberOfLocalOffset] = (byte) numberOfEntries; 4236 int numberOfStackItems = currentFrame.numberOfStackItems; 4237 this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8); 4238 this.contents[localContentsOffset++] = (byte) numberOfStackItems; 4239 for (int i = 0; i < numberOfStackItems; i++) { 4240 if (localContentsOffset + 3 >= this.contents.length) { 4241 resizeContents(3); 4242 } 4243 VerificationTypeInfo info = currentFrame.stackItems[i]; 4244 if (info == null) { 4245 this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; 4246 } else { 4247 switch(info.id()) { 4248 case T_boolean : 4249 case T_byte : 4250 case T_char : 4251 case T_int : 4252 case T_short : 4253 |