Source Code Cross Referenced for ClassFile.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » compiler » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.internal.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.jdt.internal.compiler;
0011:
0012:        import java.io.BufferedOutputStream;
0013:        import java.io.File;
0014:        import java.io.FileOutputStream;
0015:        import java.io.IOException;
0016:        import java.util.ArrayList;
0017:        import java.util.Arrays;
0018:        import java.util.Comparator;
0019:        import java.util.HashSet;
0020:        import java.util.Set;
0021:        import java.util.StringTokenizer;
0022:
0023:        import org.eclipse.jdt.core.compiler.CategorizedProblem;
0024:        import org.eclipse.jdt.core.compiler.CharOperation;
0025:        import org.eclipse.jdt.core.compiler.IProblem;
0026:        import org.eclipse.jdt.internal.compiler.ast.ASTNode;
0027:        import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
0028:        import org.eclipse.jdt.internal.compiler.ast.Annotation;
0029:        import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
0030:        import org.eclipse.jdt.internal.compiler.ast.Argument;
0031:        import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
0032:        import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
0033:        import org.eclipse.jdt.internal.compiler.ast.Expression;
0034:        import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
0035:        import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
0036:        import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
0037:        import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
0038:        import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
0039:        import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
0040:        import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
0041:        import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
0042:        import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
0043:        import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
0044:        import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
0045:        import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
0046:        import org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel;
0047:        import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
0048:        import org.eclipse.jdt.internal.compiler.codegen.StackMapFrame;
0049:        import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream;
0050:        import org.eclipse.jdt.internal.compiler.codegen.VerificationTypeInfo;
0051:        import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.ExceptionMarker;
0052:        import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.StackMarker;
0053:        import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
0054:        import org.eclipse.jdt.internal.compiler.impl.Constant;
0055:        import org.eclipse.jdt.internal.compiler.impl.StringConstant;
0056:        import org.eclipse.jdt.internal.compiler.lookup.Binding;
0057:        import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
0058:        import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
0059:        import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
0060:        import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
0061:        import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
0062:        import org.eclipse.jdt.internal.compiler.lookup.NestedTypeBinding;
0063:        import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
0064:        import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
0065:        import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding;
0066:        import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
0067:        import org.eclipse.jdt.internal.compiler.lookup.TagBits;
0068:        import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
0069:        import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
0070:        import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
0071:        import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
0072:        import org.eclipse.jdt.internal.compiler.util.Messages;
0073:        import org.eclipse.jdt.internal.compiler.util.Util;
0074:
0075:        /**
0076:         * Represents a class file wrapper on bytes, it is aware of its actual
0077:         * type name.
0078:         *
0079:         * Public APIs are listed below:
0080:         *
0081:         * byte[] getBytes();
0082:         *		Answer the actual bytes of the class file
0083:         *
0084:         * char[][] getCompoundName();
0085:         * 		Answer the compound name of the class file.
0086:         * 		For example, {{java}, {util}, {Hashtable}}.
0087:         *
0088:         * byte[] getReducedBytes();
0089:         * 		Answer a smaller byte format, which is only contains some structural
0090:         *      information. Those bytes are decodable with a regular class file reader,
0091:         *      such as DietClassFileReader
0092:         */
0093:        public class ClassFile implements  TypeConstants, TypeIds {
0094:
0095:            private byte[] bytes;
0096:            public CodeStream codeStream;
0097:            public ConstantPool constantPool;
0098:
0099:            public int constantPoolOffset;
0100:
0101:            // the header contains all the bytes till the end of the constant pool
0102:            public byte[] contents;
0103:
0104:            public int contentsOffset;
0105:
0106:            protected boolean creatingProblemType;
0107:
0108:            public ClassFile enclosingClassFile;
0109:            public byte[] header;
0110:            // that collection contains all the remaining bytes of the .class file
0111:            public int headerOffset;
0112:            public Set innerClassesBindings;
0113:            public int methodCount;
0114:            public int methodCountOffset;
0115:            // pool managment
0116:            public boolean isShared = false;
0117:            // used to generate private access methods
0118:            // debug and stack map attributes
0119:            public int produceAttributes;
0120:            public SourceTypeBinding referenceBinding;
0121:            public long targetJDK;
0122:            public static final int INITIAL_CONTENTS_SIZE = 400;
0123:            public static final int INITIAL_HEADER_SIZE = 1500;
0124:            public static final int INNER_CLASSES_SIZE = 5;
0125:
0126:            /**
0127:             * INTERNAL USE-ONLY
0128:             * Build all the directories and subdirectories corresponding to the packages names
0129:             * into the directory specified in parameters.
0130:             *
0131:             * outputPath is formed like:
0132:             *	   c:\temp\ the last character is a file separator
0133:             * relativeFileName is formed like:
0134:             *     java\lang\String.class *
0135:             *
0136:             * @param outputPath java.lang.String
0137:             * @param relativeFileName java.lang.String
0138:             * @return java.lang.String
0139:             */
0140:            public static String buildAllDirectoriesInto(String outputPath,
0141:                    String relativeFileName) throws IOException {
0142:                char fileSeparatorChar = File.separatorChar;
0143:                String fileSeparator = File.separator;
0144:                File f;
0145:                outputPath = outputPath.replace('/', fileSeparatorChar);
0146:                // these could be optimized out if we normalized paths once and for
0147:                // all
0148:                relativeFileName = relativeFileName.replace('/',
0149:                        fileSeparatorChar);
0150:                String outputDirPath, fileName;
0151:                int separatorIndex = relativeFileName
0152:                        .lastIndexOf(fileSeparatorChar);
0153:                if (separatorIndex == -1) {
0154:                    if (outputPath.endsWith(fileSeparator)) {
0155:                        outputDirPath = outputPath.substring(0, outputPath
0156:                                .length() - 1);
0157:                        fileName = outputPath + relativeFileName;
0158:                    } else {
0159:                        outputDirPath = outputPath;
0160:                        fileName = outputPath + fileSeparator
0161:                                + relativeFileName;
0162:                    }
0163:                } else {
0164:                    if (outputPath.endsWith(fileSeparator)) {
0165:                        outputDirPath = outputPath
0166:                                + relativeFileName.substring(0, separatorIndex);
0167:                        fileName = outputPath + relativeFileName;
0168:                    } else {
0169:                        outputDirPath = outputPath + fileSeparator
0170:                                + relativeFileName.substring(0, separatorIndex);
0171:                        fileName = outputPath + fileSeparator
0172:                                + relativeFileName;
0173:                    }
0174:                }
0175:                f = new File(outputDirPath);
0176:                f.mkdirs();
0177:                if (f.isDirectory()) {
0178:                    return fileName;
0179:                } else {
0180:                    // the directory creation failed for some reason - retry using
0181:                    // a slower algorithm so as to refine the diagnostic
0182:                    if (outputPath.endsWith(fileSeparator)) {
0183:                        outputPath = outputPath.substring(0, outputPath
0184:                                .length() - 1);
0185:                    }
0186:                    f = new File(outputPath);
0187:                    boolean checkFileType = false;
0188:                    if (f.exists()) {
0189:                        checkFileType = true; // pre-existed
0190:                    } else {
0191:                        // we have to create that directory
0192:                        if (!f.mkdirs()) {
0193:                            if (f.exists()) {
0194:                                // someone else created f -- need to check its type
0195:                                checkFileType = true;
0196:                            } else {
0197:                                // no one could create f -- complain
0198:                                throw new IOException(Messages.bind(
0199:                                        Messages.output_notValidAll, f
0200:                                                .getAbsolutePath()));
0201:                            }
0202:                        }
0203:                    }
0204:                    if (checkFileType) {
0205:                        if (!f.isDirectory()) {
0206:                            throw new IOException(Messages
0207:                                    .bind(Messages.output_isFile, f
0208:                                            .getAbsolutePath()));
0209:                        }
0210:                    }
0211:                    StringBuffer outDir = new StringBuffer(outputPath);
0212:                    outDir.append(fileSeparator);
0213:                    StringTokenizer tokenizer = new StringTokenizer(
0214:                            relativeFileName, fileSeparator);
0215:                    String token = tokenizer.nextToken();
0216:                    while (tokenizer.hasMoreTokens()) {
0217:                        f = new File(outDir.append(token).append(fileSeparator)
0218:                                .toString());
0219:                        checkFileType = false; // reset
0220:                        if (f.exists()) {
0221:                            checkFileType = true; // this is suboptimal, but it catches corner cases
0222:                            // in which a regular file pre-exists
0223:                        } else {
0224:                            // we have to create that directory
0225:                            if (!f.mkdir()) {
0226:                                if (f.exists()) {
0227:                                    // someone else created f -- need to check its type
0228:                                    checkFileType = true;
0229:                                } else {
0230:                                    // no one could create f -- complain
0231:                                    throw new IOException(Messages.bind(
0232:                                            Messages.output_notValid,
0233:                                            outDir.substring(outputPath
0234:                                                    .length() + 1, outDir
0235:                                                    .length() - 1), outputPath));
0236:                                }
0237:                            }
0238:                        }
0239:                        if (checkFileType) {
0240:                            if (!f.isDirectory()) {
0241:                                throw new IOException(Messages.bind(
0242:                                        Messages.output_isFile, f
0243:                                                .getAbsolutePath()));
0244:                            }
0245:                        }
0246:                        token = tokenizer.nextToken();
0247:                    }
0248:                    // token contains the last one
0249:                    return outDir.append(token).toString();
0250:                }
0251:            }
0252:
0253:            /**
0254:             * INTERNAL USE-ONLY
0255:             * Request the creation of a ClassFile compatible representation of a problematic type
0256:             *
0257:             * @param typeDeclaration org.eclipse.jdt.internal.compiler.ast.TypeDeclaration
0258:             * @param unitResult org.eclipse.jdt.internal.compiler.CompilationUnitResult
0259:             */
0260:            public static void createProblemType(
0261:                    TypeDeclaration typeDeclaration,
0262:                    CompilationResult unitResult) {
0263:                SourceTypeBinding typeBinding = typeDeclaration.binding;
0264:                ClassFile classFile = ClassFile.getNewInstance(typeBinding);
0265:                classFile.initialize(typeBinding, null, true);
0266:
0267:                if (typeBinding.hasMemberTypes()) {
0268:                    // see bug 180109
0269:                    ReferenceBinding[] members = typeBinding.memberTypes;
0270:                    for (int i = 0, l = members.length; i < l; i++)
0271:                        classFile.recordInnerClasses(members[i]);
0272:                }
0273:                // TODO (olivier) handle cases where a field cannot be generated (name too long)
0274:                // TODO (olivier) handle too many methods
0275:                // inner attributes
0276:                if (typeBinding.isNestedType()) {
0277:                    classFile.recordInnerClasses(typeBinding);
0278:                }
0279:
0280:                // add its fields
0281:                FieldBinding[] fields = typeBinding.fields();
0282:                if ((fields != null) && (fields != Binding.NO_FIELDS)) {
0283:                    classFile.addFieldInfos();
0284:                } else {
0285:                    // we have to set the number of fields to be equals to 0
0286:                    classFile.contents[classFile.contentsOffset++] = 0;
0287:                    classFile.contents[classFile.contentsOffset++] = 0;
0288:                }
0289:                // leave some space for the methodCount
0290:                classFile.setForMethodInfos();
0291:                // add its user defined methods
0292:                int problemsLength;
0293:                CategorizedProblem[] problems = unitResult.getErrors();
0294:                if (problems == null) {
0295:                    problems = new CategorizedProblem[0];
0296:                }
0297:                CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
0298:                System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
0299:
0300:                AbstractMethodDeclaration[] methodDecls = typeDeclaration.methods;
0301:                if (methodDecls != null) {
0302:                    if (typeBinding.isInterface()) {
0303:                        // we cannot create problem methods for an interface. So we have to generate a clinit
0304:                        // which should contain all the problem
0305:                        classFile.addProblemClinit(problemsCopy);
0306:                        for (int i = 0, length = methodDecls.length; i < length; i++) {
0307:                            AbstractMethodDeclaration methodDecl = methodDecls[i];
0308:                            MethodBinding method = methodDecl.binding;
0309:                            if (method == null || method.isConstructor())
0310:                                continue;
0311:                            classFile.addAbstractMethod(methodDecl, method);
0312:                        }
0313:                    } else {
0314:                        for (int i = 0, length = methodDecls.length; i < length; i++) {
0315:                            AbstractMethodDeclaration methodDecl = methodDecls[i];
0316:                            MethodBinding method = methodDecl.binding;
0317:                            if (method == null)
0318:                                continue;
0319:                            if (method.isConstructor()) {
0320:                                classFile.addProblemConstructor(methodDecl,
0321:                                        method, problemsCopy);
0322:                            } else {
0323:                                classFile.addProblemMethod(methodDecl, method,
0324:                                        problemsCopy);
0325:                            }
0326:                        }
0327:                    }
0328:                    // add abstract methods
0329:                    classFile.addDefaultAbstractMethods();
0330:                }
0331:
0332:                // propagate generation of (problem) member types
0333:                if (typeDeclaration.memberTypes != null) {
0334:                    for (int i = 0, max = typeDeclaration.memberTypes.length; i < max; i++) {
0335:                        TypeDeclaration memberType = typeDeclaration.memberTypes[i];
0336:                        if (memberType.binding != null) {
0337:                            ClassFile.createProblemType(memberType, unitResult);
0338:                        }
0339:                    }
0340:                }
0341:                classFile.addAttributes();
0342:                unitResult.record(typeBinding.constantPoolName(), classFile);
0343:            }
0344:
0345:            public static ClassFile getNewInstance(SourceTypeBinding typeBinding) {
0346:                LookupEnvironment env = typeBinding.scope.environment();
0347:                return env.classFilePool.acquire(typeBinding);
0348:            }
0349:
0350:            /**
0351:             * INTERNAL USE-ONLY
0352:             * outputPath is formed like:
0353:             *	   c:\temp\ the last character is a file separator
0354:             * relativeFileName is formed like:
0355:             *     java\lang\String.class
0356:             * @param generatePackagesStructure a flag to know if the packages structure has to be generated.
0357:             * @param outputPath the given output directory
0358:             * @param relativeFileName the given relative file name
0359:             * @param classFile the given classFile to write
0360:             *
0361:             */
0362:            public static void writeToDisk(boolean generatePackagesStructure,
0363:                    String outputPath, String relativeFileName,
0364:                    ClassFile classFile) throws IOException {
0365:
0366:                BufferedOutputStream output = null;
0367:                if (generatePackagesStructure) {
0368:                    output = new BufferedOutputStream(new FileOutputStream(
0369:                            new File(buildAllDirectoriesInto(outputPath,
0370:                                    relativeFileName))));
0371:                } else {
0372:                    String fileName = null;
0373:                    char fileSeparatorChar = File.separatorChar;
0374:                    String fileSeparator = File.separator;
0375:                    // First we ensure that the outputPath exists
0376:                    outputPath = outputPath.replace('/', fileSeparatorChar);
0377:                    // To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
0378:                    int indexOfPackageSeparator = relativeFileName
0379:                            .lastIndexOf(fileSeparatorChar);
0380:                    if (indexOfPackageSeparator == -1) {
0381:                        if (outputPath.endsWith(fileSeparator)) {
0382:                            fileName = outputPath + relativeFileName;
0383:                        } else {
0384:                            fileName = outputPath + fileSeparator
0385:                                    + relativeFileName;
0386:                        }
0387:                    } else {
0388:                        int length = relativeFileName.length();
0389:                        if (outputPath.endsWith(fileSeparator)) {
0390:                            fileName = outputPath
0391:                                    + relativeFileName
0392:                                            .substring(
0393:                                                    indexOfPackageSeparator + 1,
0394:                                                    length);
0395:                        } else {
0396:                            fileName = outputPath
0397:                                    + fileSeparator
0398:                                    + relativeFileName
0399:                                            .substring(
0400:                                                    indexOfPackageSeparator + 1,
0401:                                                    length);
0402:                        }
0403:                    }
0404:                    output = new BufferedOutputStream(new FileOutputStream(
0405:                            new File(fileName)));
0406:                }
0407:                try {
0408:                    // if no IOException occured, output cannot be null
0409:                    output.write(classFile.header, 0, classFile.headerOffset);
0410:                    output.write(classFile.contents, 0,
0411:                            classFile.contentsOffset);
0412:                    output.flush();
0413:                } catch (IOException e) {
0414:                    throw e;
0415:                } finally {
0416:                    output.close();
0417:                }
0418:            }
0419:
0420:            /**
0421:             * INTERNAL USE-ONLY
0422:             * This methods creates a new instance of the receiver.
0423:             */
0424:            protected ClassFile() {
0425:                // default constructor for subclasses
0426:            }
0427:
0428:            public ClassFile(SourceTypeBinding typeBinding) {
0429:                // default constructor for subclasses
0430:                this .constantPool = new ConstantPool(this );
0431:                final CompilerOptions options = typeBinding.scope
0432:                        .compilerOptions();
0433:                this .targetJDK = options.targetJDK;
0434:                this .produceAttributes = options.produceDebugAttributes;
0435:                this .referenceBinding = typeBinding;
0436:                if (this .targetJDK >= ClassFileConstants.JDK1_6) {
0437:                    this .produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE;
0438:                    this .codeStream = new StackMapFrameCodeStream(this );
0439:                } else if (this .targetJDK == ClassFileConstants.CLDC_1_1) {
0440:                    this .targetJDK = ClassFileConstants.JDK1_1; // put back 45.3
0441:                    this .produceAttributes |= ClassFileConstants.ATTR_STACK_MAP;
0442:                    this .codeStream = new StackMapFrameCodeStream(this );
0443:                } else {
0444:                    this .codeStream = new CodeStream(this );
0445:                }
0446:                this .initByteArrays();
0447:            }
0448:
0449:            /**
0450:             * INTERNAL USE-ONLY
0451:             * Generate the byte for a problem method info that correspond to a boggus method.
0452:             *
0453:             * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
0454:             * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
0455:             */
0456:            public void addAbstractMethod(AbstractMethodDeclaration method,
0457:                    MethodBinding methodBinding) {
0458:
0459:                // force the modifiers to be public and abstract
0460:                methodBinding.modifiers = ClassFileConstants.AccPublic
0461:                        | ClassFileConstants.AccAbstract;
0462:
0463:                this .generateMethodInfoHeader(methodBinding);
0464:                int methodAttributeOffset = this .contentsOffset;
0465:                int attributeNumber = this 
0466:                        .generateMethodInfoAttribute(methodBinding);
0467:                this .completeMethodInfo(methodAttributeOffset, attributeNumber);
0468:            }
0469:
0470:            /**
0471:             * INTERNAL USE-ONLY
0472:             * This methods generate all the attributes for the receiver.
0473:             * For a class they could be:
0474:             * - source file attribute
0475:             * - inner classes attribute
0476:             * - deprecated attribute
0477:             */
0478:            public void addAttributes() {
0479:                // update the method count
0480:                contents[methodCountOffset++] = (byte) (methodCount >> 8);
0481:                contents[methodCountOffset] = (byte) methodCount;
0482:
0483:                int attributeNumber = 0;
0484:                // leave two bytes for the number of attributes and store the current offset
0485:                int attributeOffset = contentsOffset;
0486:                contentsOffset += 2;
0487:
0488:                // source attribute
0489:                if ((produceAttributes & ClassFileConstants.ATTR_SOURCE) != 0) {
0490:                    String fullFileName = new String(referenceBinding.scope
0491:                            .referenceCompilationUnit().getFileName());
0492:                    fullFileName = fullFileName.replace('\\', '/');
0493:                    int lastIndex = fullFileName.lastIndexOf('/');
0494:                    if (lastIndex != -1) {
0495:                        fullFileName = fullFileName.substring(lastIndex + 1,
0496:                                fullFileName.length());
0497:                    }
0498:                    // check that there is enough space to write all the bytes for the field info corresponding
0499:                    // to the @fieldBinding
0500:                    if (contentsOffset + 8 >= contents.length) {
0501:                        resizeContents(8);
0502:                    }
0503:                    int sourceAttributeNameIndex = constantPool
0504:                            .literalIndex(AttributeNamesConstants.SourceName);
0505:                    contents[contentsOffset++] = (byte) (sourceAttributeNameIndex >> 8);
0506:                    contents[contentsOffset++] = (byte) sourceAttributeNameIndex;
0507:                    // The length of a source file attribute is 2. This is a fixed-length
0508:                    // attribute
0509:                    contents[contentsOffset++] = 0;
0510:                    contents[contentsOffset++] = 0;
0511:                    contents[contentsOffset++] = 0;
0512:                    contents[contentsOffset++] = 2;
0513:                    // write the source file name
0514:                    int fileNameIndex = constantPool.literalIndex(fullFileName
0515:                            .toCharArray());
0516:                    contents[contentsOffset++] = (byte) (fileNameIndex >> 8);
0517:                    contents[contentsOffset++] = (byte) fileNameIndex;
0518:                    attributeNumber++;
0519:                }
0520:                // Deprecated attribute
0521:                if (referenceBinding.isDeprecated()) {
0522:                    // check that there is enough space to write all the bytes for the field info corresponding
0523:                    // to the @fieldBinding
0524:                    if (contentsOffset + 6 >= contents.length) {
0525:                        resizeContents(6);
0526:                    }
0527:                    int deprecatedAttributeNameIndex = constantPool
0528:                            .literalIndex(AttributeNamesConstants.DeprecatedName);
0529:                    contents[contentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8);
0530:                    contents[contentsOffset++] = (byte) deprecatedAttributeNameIndex;
0531:                    // the length of a deprecated attribute is equals to 0
0532:                    contents[contentsOffset++] = 0;
0533:                    contents[contentsOffset++] = 0;
0534:                    contents[contentsOffset++] = 0;
0535:                    contents[contentsOffset++] = 0;
0536:                    attributeNumber++;
0537:                }
0538:                // add signature attribute
0539:                char[] genericSignature = referenceBinding.genericSignature();
0540:                if (genericSignature != null) {
0541:                    // check that there is enough space to write all the bytes for the field info corresponding
0542:                    // to the @fieldBinding
0543:                    if (contentsOffset + 8 >= contents.length) {
0544:                        resizeContents(8);
0545:                    }
0546:                    int signatureAttributeNameIndex = constantPool
0547:                            .literalIndex(AttributeNamesConstants.SignatureName);
0548:                    contents[contentsOffset++] = (byte) (signatureAttributeNameIndex >> 8);
0549:                    contents[contentsOffset++] = (byte) signatureAttributeNameIndex;
0550:                    // the length of a signature attribute is equals to 2
0551:                    contents[contentsOffset++] = 0;
0552:                    contents[contentsOffset++] = 0;
0553:                    contents[contentsOffset++] = 0;
0554:                    contents[contentsOffset++] = 2;
0555:                    int signatureIndex = constantPool
0556:                            .literalIndex(genericSignature);
0557:                    contents[contentsOffset++] = (byte) (signatureIndex >> 8);
0558:                    contents[contentsOffset++] = (byte) signatureIndex;
0559:                    attributeNumber++;
0560:                }
0561:                if (targetJDK >= ClassFileConstants.JDK1_5
0562:                        && this .referenceBinding.isNestedType()
0563:                        && !this .referenceBinding.isMemberType()) {
0564:                    // add enclosing method attribute (1.5 mode only)
0565:                    if (contentsOffset + 10 >= contents.length) {
0566:                        resizeContents(10);
0567:                    }
0568:                    int enclosingMethodAttributeNameIndex = constantPool
0569:                            .literalIndex(AttributeNamesConstants.EnclosingMethodName);
0570:                    contents[contentsOffset++] = (byte) (enclosingMethodAttributeNameIndex >> 8);
0571:                    contents[contentsOffset++] = (byte) enclosingMethodAttributeNameIndex;
0572:                    // the length of a signature attribute is equals to 2
0573:                    contents[contentsOffset++] = 0;
0574:                    contents[contentsOffset++] = 0;
0575:                    contents[contentsOffset++] = 0;
0576:                    contents[contentsOffset++] = 4;
0577:
0578:                    int enclosingTypeIndex = constantPool
0579:                            .literalIndexForType(this .referenceBinding
0580:                                    .enclosingType().constantPoolName());
0581:                    contents[contentsOffset++] = (byte) (enclosingTypeIndex >> 8);
0582:                    contents[contentsOffset++] = (byte) enclosingTypeIndex;
0583:                    byte methodIndexByte1 = 0;
0584:                    byte methodIndexByte2 = 0;
0585:                    if (this .referenceBinding instanceof  LocalTypeBinding) {
0586:                        MethodBinding methodBinding = ((LocalTypeBinding) this .referenceBinding).enclosingMethod;
0587:                        if (methodBinding != null) {
0588:                            int enclosingMethodIndex = constantPool
0589:                                    .literalIndexForNameAndType(
0590:                                            methodBinding.selector,
0591:                                            methodBinding.signature(this ));
0592:                            methodIndexByte1 = (byte) (enclosingMethodIndex >> 8);
0593:                            methodIndexByte2 = (byte) enclosingMethodIndex;
0594:                        }
0595:                    }
0596:                    contents[contentsOffset++] = methodIndexByte1;
0597:                    contents[contentsOffset++] = methodIndexByte2;
0598:                    attributeNumber++;
0599:                }
0600:                if (this .targetJDK >= ClassFileConstants.JDK1_5
0601:                        && !this .creatingProblemType) {
0602:                    TypeDeclaration typeDeclaration = referenceBinding.scope.referenceContext;
0603:                    if (typeDeclaration != null) {
0604:                        final Annotation[] annotations = typeDeclaration.annotations;
0605:                        if (annotations != null) {
0606:                            attributeNumber += generateRuntimeAnnotations(annotations);
0607:                        }
0608:                    }
0609:                }
0610:
0611:                if (this .referenceBinding.isHierarchyInconsistent()) {
0612:                    // add an attribute for inconsistent hierarchy
0613:                    if (contentsOffset + 6 >= contents.length) {
0614:                        resizeContents(6);
0615:                    }
0616:                    int inconsistentHierarchyNameIndex = constantPool
0617:                            .literalIndex(AttributeNamesConstants.InconsistentHierarchy);
0618:                    contents[contentsOffset++] = (byte) (inconsistentHierarchyNameIndex >> 8);
0619:                    contents[contentsOffset++] = (byte) inconsistentHierarchyNameIndex;
0620:                    // the length of an inconsistent hierarchy attribute is equals to 0
0621:                    contents[contentsOffset++] = 0;
0622:                    contents[contentsOffset++] = 0;
0623:                    contents[contentsOffset++] = 0;
0624:                    contents[contentsOffset++] = 0;
0625:                    attributeNumber++;
0626:                }
0627:                // Inner class attribute
0628:                int numberOfInnerClasses = this .innerClassesBindings == null ? 0
0629:                        : this .innerClassesBindings.size();
0630:                if (numberOfInnerClasses != 0) {
0631:                    ReferenceBinding[] innerClasses = new ReferenceBinding[numberOfInnerClasses];
0632:                    this .innerClassesBindings.toArray(innerClasses);
0633:                    Arrays.sort(innerClasses, new Comparator() {
0634:                        public int compare(Object o1, Object o2) {
0635:                            TypeBinding binding1 = (TypeBinding) o1;
0636:                            TypeBinding binding2 = (TypeBinding) o2;
0637:                            return CharOperation.compareTo(binding1
0638:                                    .constantPoolName(), binding2
0639:                                    .constantPoolName());
0640:                        }
0641:                    });
0642:                    // Generate the inner class attribute
0643:                    int exSize = 8 * numberOfInnerClasses + 8;
0644:                    if (exSize + contentsOffset >= this .contents.length) {
0645:                        resizeContents(exSize);
0646:                    }
0647:                    // Now we now the size of the attribute and the number of entries
0648:                    // attribute name
0649:                    int attributeNameIndex = constantPool
0650:                            .literalIndex(AttributeNamesConstants.InnerClassName);
0651:                    contents[contentsOffset++] = (byte) (attributeNameIndex >> 8);
0652:                    contents[contentsOffset++] = (byte) attributeNameIndex;
0653:                    int value = (numberOfInnerClasses << 3) + 2;
0654:                    contents[contentsOffset++] = (byte) (value >> 24);
0655:                    contents[contentsOffset++] = (byte) (value >> 16);
0656:                    contents[contentsOffset++] = (byte) (value >> 8);
0657:                    contents[contentsOffset++] = (byte) value;
0658:                    contents[contentsOffset++] = (byte) (numberOfInnerClasses >> 8);
0659:                    contents[contentsOffset++] = (byte) numberOfInnerClasses;
0660:                    for (int i = 0; i < numberOfInnerClasses; i++) {
0661:                        ReferenceBinding innerClass = innerClasses[i];
0662:                        int accessFlags = innerClass.getAccessFlags();
0663:                        int innerClassIndex = constantPool
0664:                                .literalIndexForType(innerClass
0665:                                        .constantPoolName());
0666:                        // inner class index
0667:                        contents[contentsOffset++] = (byte) (innerClassIndex >> 8);
0668:                        contents[contentsOffset++] = (byte) innerClassIndex;
0669:                        // outer class index: anonymous and local have no outer class index
0670:                        if (innerClass.isMemberType()) {
0671:                            // member or member of local
0672:                            int outerClassIndex = constantPool
0673:                                    .literalIndexForType(innerClass
0674:                                            .enclosingType().constantPoolName());
0675:                            contents[contentsOffset++] = (byte) (outerClassIndex >> 8);
0676:                            contents[contentsOffset++] = (byte) outerClassIndex;
0677:                        } else {
0678:                            // equals to 0 if the innerClass is not a member type
0679:                            contents[contentsOffset++] = 0;
0680:                            contents[contentsOffset++] = 0;
0681:                        }
0682:                        // name index
0683:                        if (!innerClass.isAnonymousType()) {
0684:                            int nameIndex = constantPool
0685:                                    .literalIndex(innerClass.sourceName());
0686:                            contents[contentsOffset++] = (byte) (nameIndex >> 8);
0687:                            contents[contentsOffset++] = (byte) nameIndex;
0688:                        } else {
0689:                            // equals to 0 if the innerClass is an anonymous type
0690:                            contents[contentsOffset++] = 0;
0691:                            contents[contentsOffset++] = 0;
0692:                        }
0693:                        // access flag
0694:                        if (innerClass.isAnonymousType()) {
0695:                            accessFlags &= ~ClassFileConstants.AccFinal;
0696:                        } else if (innerClass.isMemberType()
0697:                                && innerClass.isInterface()) {
0698:                            accessFlags |= ClassFileConstants.AccStatic; // implicitely static
0699:                        }
0700:                        contents[contentsOffset++] = (byte) (accessFlags >> 8);
0701:                        contents[contentsOffset++] = (byte) accessFlags;
0702:                    }
0703:                    attributeNumber++;
0704:                }
0705:                // update the number of attributes
0706:                if (attributeOffset + 2 >= this .contents.length) {
0707:                    resizeContents(2);
0708:                }
0709:                contents[attributeOffset++] = (byte) (attributeNumber >> 8);
0710:                contents[attributeOffset] = (byte) attributeNumber;
0711:
0712:                // resynchronize all offsets of the classfile
0713:                header = constantPool.poolContent;
0714:                headerOffset = constantPool.currentOffset;
0715:                int constantPoolCount = constantPool.currentIndex;
0716:                header[constantPoolOffset++] = (byte) (constantPoolCount >> 8);
0717:                header[constantPoolOffset] = (byte) constantPoolCount;
0718:            }
0719:
0720:            /**
0721:             * INTERNAL USE-ONLY
0722:             * This methods generate all the default abstract method infos that correpond to
0723:             * the abstract methods inherited from superinterfaces.
0724:             */
0725:            public void addDefaultAbstractMethods() { // default abstract methods
0726:                MethodBinding[] defaultAbstractMethods = referenceBinding
0727:                        .getDefaultAbstractMethods();
0728:                for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) {
0729:                    generateMethodInfoHeader(defaultAbstractMethods[i]);
0730:                    int methodAttributeOffset = contentsOffset;
0731:                    int attributeNumber = generateMethodInfoAttribute(defaultAbstractMethods[i]);
0732:                    completeMethodInfo(methodAttributeOffset, attributeNumber);
0733:                }
0734:            }
0735:
0736:            private int addFieldAttributes(FieldBinding fieldBinding,
0737:                    int fieldAttributeOffset) {
0738:                int attributesNumber = 0;
0739:                // 4.7.2 only static constant fields get a ConstantAttribute
0740:                // Generate the constantValueAttribute
0741:                Constant fieldConstant = fieldBinding.constant();
0742:                if (fieldConstant != Constant.NotAConstant) {
0743:                    if (contentsOffset + 8 >= contents.length) {
0744:                        resizeContents(8);
0745:                    }
0746:                    // Now we generate the constant attribute corresponding to the fieldBinding
0747:                    int constantValueNameIndex = constantPool
0748:                            .literalIndex(AttributeNamesConstants.ConstantValueName);
0749:                    contents[contentsOffset++] = (byte) (constantValueNameIndex >> 8);
0750:                    contents[contentsOffset++] = (byte) constantValueNameIndex;
0751:                    // The attribute length = 2 in case of a constantValue attribute
0752:                    contents[contentsOffset++] = 0;
0753:                    contents[contentsOffset++] = 0;
0754:                    contents[contentsOffset++] = 0;
0755:                    contents[contentsOffset++] = 2;
0756:                    attributesNumber++;
0757:                    // Need to add the constant_value_index
0758:                    switch (fieldConstant.typeID()) {
0759:                    case T_boolean:
0760:                        int booleanValueIndex = constantPool
0761:                                .literalIndex(fieldConstant.booleanValue() ? 1
0762:                                        : 0);
0763:                        contents[contentsOffset++] = (byte) (booleanValueIndex >> 8);
0764:                        contents[contentsOffset++] = (byte) booleanValueIndex;
0765:                        break;
0766:                    case T_byte:
0767:                    case T_char:
0768:                    case T_int:
0769:                    case T_short:
0770:                        int integerValueIndex = constantPool
0771:                                .literalIndex(fieldConstant.intValue());
0772:                        contents[contentsOffset++] = (byte) (integerValueIndex >> 8);
0773:                        contents[contentsOffset++] = (byte) integerValueIndex;
0774:                        break;
0775:                    case T_float:
0776:                        int floatValueIndex = constantPool
0777:                                .literalIndex(fieldConstant.floatValue());
0778:                        contents[contentsOffset++] = (byte) (floatValueIndex >> 8);
0779:                        contents[contentsOffset++] = (byte) floatValueIndex;
0780:                        break;
0781:                    case T_double:
0782:                        int doubleValueIndex = constantPool
0783:                                .literalIndex(fieldConstant.doubleValue());
0784:                        contents[contentsOffset++] = (byte) (doubleValueIndex >> 8);
0785:                        contents[contentsOffset++] = (byte) doubleValueIndex;
0786:                        break;
0787:                    case T_long:
0788:                        int longValueIndex = constantPool
0789:                                .literalIndex(fieldConstant.longValue());
0790:                        contents[contentsOffset++] = (byte) (longValueIndex >> 8);
0791:                        contents[contentsOffset++] = (byte) longValueIndex;
0792:                        break;
0793:                    case T_JavaLangString:
0794:                        int stringValueIndex = constantPool
0795:                                .literalIndex(((StringConstant) fieldConstant)
0796:                                        .stringValue());
0797:                        if (stringValueIndex == -1) {
0798:                            if (!creatingProblemType) {
0799:                                // report an error and abort: will lead to a problem type classfile creation
0800:                                TypeDeclaration typeDeclaration = referenceBinding.scope.referenceContext;
0801:                                FieldDeclaration[] fieldDecls = typeDeclaration.fields;
0802:                                for (int i = 0, max = fieldDecls.length; i < max; i++) {
0803:                                    if (fieldDecls[i].binding == fieldBinding) {
0804:                                        // problem should abort
0805:                                        typeDeclaration.scope
0806:                                                .problemReporter()
0807:                                                .stringConstantIsExceedingUtf8Limit(
0808:                                                        fieldDecls[i]);
0809:                                    }
0810:                                }
0811:                            } else {
0812:                                // already inside a problem type creation : no constant for this field
0813:                                contentsOffset = fieldAttributeOffset;
0814:                            }
0815:                        } else {
0816:                            contents[contentsOffset++] = (byte) (stringValueIndex >> 8);
0817:                            contents[contentsOffset++] = (byte) stringValueIndex;
0818:                        }
0819:                    }
0820:                }
0821:                if (this .targetJDK < ClassFileConstants.JDK1_5
0822:                        && fieldBinding.isSynthetic()) {
0823:                    if (contentsOffset + 6 >= contents.length) {
0824:                        resizeContents(6);
0825:                    }
0826:                    int syntheticAttributeNameIndex = constantPool
0827:                            .literalIndex(AttributeNamesConstants.SyntheticName);
0828:                    contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
0829:                    contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
0830:                    // the length of a synthetic attribute is equals to 0
0831:                    contents[contentsOffset++] = 0;
0832:                    contents[contentsOffset++] = 0;
0833:                    contents[contentsOffset++] = 0;
0834:                    contents[contentsOffset++] = 0;
0835:                    attributesNumber++;
0836:                }
0837:                if (fieldBinding.isDeprecated()) {
0838:                    if (contentsOffset + 6 >= contents.length) {
0839:                        resizeContents(6);
0840:                    }
0841:                    int deprecatedAttributeNameIndex = constantPool
0842:                            .literalIndex(AttributeNamesConstants.DeprecatedName);
0843:                    contents[contentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8);
0844:                    contents[contentsOffset++] = (byte) deprecatedAttributeNameIndex;
0845:                    // the length of a deprecated attribute is equals to 0
0846:                    contents[contentsOffset++] = 0;
0847:                    contents[contentsOffset++] = 0;
0848:                    contents[contentsOffset++] = 0;
0849:                    contents[contentsOffset++] = 0;
0850:                    attributesNumber++;
0851:                }
0852:                // add signature attribute
0853:                char[] genericSignature = fieldBinding.genericSignature();
0854:                if (genericSignature != null) {
0855:                    // check that there is enough space to write all the bytes for the field info corresponding
0856:                    // to the @fieldBinding
0857:                    if (contentsOffset + 8 >= contents.length) {
0858:                        resizeContents(8);
0859:                    }
0860:                    int signatureAttributeNameIndex = constantPool
0861:                            .literalIndex(AttributeNamesConstants.SignatureName);
0862:                    contents[contentsOffset++] = (byte) (signatureAttributeNameIndex >> 8);
0863:                    contents[contentsOffset++] = (byte) signatureAttributeNameIndex;
0864:                    // the length of a signature attribute is equals to 2
0865:                    contents[contentsOffset++] = 0;
0866:                    contents[contentsOffset++] = 0;
0867:                    contents[contentsOffset++] = 0;
0868:                    contents[contentsOffset++] = 2;
0869:                    int signatureIndex = constantPool
0870:                            .literalIndex(genericSignature);
0871:                    contents[contentsOffset++] = (byte) (signatureIndex >> 8);
0872:                    contents[contentsOffset++] = (byte) signatureIndex;
0873:                    attributesNumber++;
0874:                }
0875:                if (this .targetJDK >= ClassFileConstants.JDK1_5
0876:                        && !this .creatingProblemType) {
0877:                    FieldDeclaration fieldDeclaration = fieldBinding
0878:                            .sourceField();
0879:                    if (fieldDeclaration != null) {
0880:                        Annotation[] annotations = fieldDeclaration.annotations;
0881:                        if (annotations != null) {
0882:                            attributesNumber += generateRuntimeAnnotations(annotations);
0883:                        }
0884:                    }
0885:                }
0886:                return attributesNumber;
0887:            }
0888:
0889:            /**
0890:             * INTERNAL USE-ONLY
0891:             * This methods generates the bytes for the given field binding
0892:             * @param fieldBinding the given field binding
0893:             */
0894:            private void addFieldInfo(FieldBinding fieldBinding) {
0895:                // check that there is enough space to write all the bytes for the field info corresponding
0896:                // to the @fieldBinding
0897:                if (contentsOffset + 8 >= contents.length) {
0898:                    resizeContents(8);
0899:                }
0900:                // Now we can generate all entries into the byte array
0901:                // First the accessFlags
0902:                int accessFlags = fieldBinding.getAccessFlags();
0903:                if (targetJDK < ClassFileConstants.JDK1_5) {
0904:                    // pre 1.5, synthetic was an attribute, not a modifier
0905:                    accessFlags &= ~ClassFileConstants.AccSynthetic;
0906:                }
0907:                contents[contentsOffset++] = (byte) (accessFlags >> 8);
0908:                contents[contentsOffset++] = (byte) accessFlags;
0909:                // Then the nameIndex
0910:                int nameIndex = constantPool.literalIndex(fieldBinding.name);
0911:                contents[contentsOffset++] = (byte) (nameIndex >> 8);
0912:                contents[contentsOffset++] = (byte) nameIndex;
0913:                // Then the descriptorIndex
0914:                int descriptorIndex = constantPool
0915:                        .literalIndex(fieldBinding.type);
0916:                contents[contentsOffset++] = (byte) (descriptorIndex >> 8);
0917:                contents[contentsOffset++] = (byte) descriptorIndex;
0918:                int fieldAttributeOffset = contentsOffset;
0919:                int attributeNumber = 0;
0920:                // leave some space for the number of attributes
0921:                contentsOffset += 2;
0922:                attributeNumber += addFieldAttributes(fieldBinding,
0923:                        fieldAttributeOffset);
0924:                if (contentsOffset + 2 >= contents.length) {
0925:                    resizeContents(2);
0926:                }
0927:                contents[fieldAttributeOffset++] = (byte) (attributeNumber >> 8);
0928:                contents[fieldAttributeOffset] = (byte) attributeNumber;
0929:            }
0930:
0931:            /**
0932:             * INTERNAL USE-ONLY
0933:             * This methods generate all the fields infos for the receiver.
0934:             * This includes:
0935:             * - a field info for each defined field of that class
0936:             * - a field info for each synthetic field (e.g. this$0)
0937:             */
0938:            /**
0939:             * INTERNAL USE-ONLY
0940:             * This methods generate all the fields infos for the receiver.
0941:             * This includes:
0942:             * - a field info for each defined field of that class
0943:             * - a field info for each synthetic field (e.g. this$0)
0944:             */
0945:            public void addFieldInfos() {
0946:                SourceTypeBinding currentBinding = referenceBinding;
0947:                FieldBinding[] syntheticFields = currentBinding
0948:                        .syntheticFields();
0949:                int fieldCount = currentBinding.fieldCount()
0950:                        + (syntheticFields == null ? 0 : syntheticFields.length);
0951:
0952:                // write the number of fields
0953:                if (fieldCount > 0xFFFF) {
0954:                    referenceBinding.scope.problemReporter().tooManyFields(
0955:                            referenceBinding.scope.referenceType());
0956:                }
0957:                contents[contentsOffset++] = (byte) (fieldCount >> 8);
0958:                contents[contentsOffset++] = (byte) fieldCount;
0959:
0960:                FieldDeclaration[] fieldDecls = currentBinding.scope.referenceContext.fields;
0961:                for (int i = 0, max = fieldDecls == null ? 0
0962:                        : fieldDecls.length; i < max; i++) {
0963:                    FieldDeclaration fieldDecl = fieldDecls[i];
0964:                    if (fieldDecl.binding != null) {
0965:                        addFieldInfo(fieldDecl.binding);
0966:                    }
0967:                }
0968:
0969:                if (syntheticFields != null) {
0970:                    for (int i = 0, max = syntheticFields.length; i < max; i++) {
0971:                        addFieldInfo(syntheticFields[i]);
0972:                    }
0973:                }
0974:            }
0975:
0976:            private void addMissingAbstractProblemMethod(
0977:                    MethodDeclaration methodDeclaration,
0978:                    MethodBinding methodBinding, CategorizedProblem problem,
0979:                    CompilationResult compilationResult) {
0980:                // always clear the strictfp/native/abstract bit for a problem method
0981:                generateMethodInfoHeader(
0982:                        methodBinding,
0983:                        methodBinding.modifiers
0984:                                & ~(ClassFileConstants.AccStrictfp
0985:                                        | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract));
0986:                int methodAttributeOffset = contentsOffset;
0987:                int attributeNumber = generateMethodInfoAttribute(methodBinding);
0988:
0989:                // Code attribute
0990:                attributeNumber++;
0991:
0992:                int codeAttributeOffset = contentsOffset;
0993:                generateCodeAttributeHeader();
0994:                StringBuffer buffer = new StringBuffer(25);
0995:                buffer.append("\t" + problem.getMessage() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
0996:                buffer.insert(0, Messages.compilation_unresolvedProblem);
0997:                String problemString = buffer.toString();
0998:
0999:                codeStream.init(this );
1000:                codeStream.preserveUnusedLocals = true;
1001:                codeStream.initializeMaxLocals(methodBinding);
1002:
1003:                // return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
1004:                codeStream.generateCodeAttributeForProblemMethod(problemString);
1005:
1006:                completeCodeAttributeForMissingAbstractProblemMethod(
1007:                        methodBinding, codeAttributeOffset, compilationResult
1008:                                .getLineSeparatorPositions(), problem
1009:                                .getSourceLineNumber());
1010:
1011:                completeMethodInfo(methodAttributeOffset, attributeNumber);
1012:            }
1013:
1014:            /**
1015:             * INTERNAL USE-ONLY
1016:             * Generate the byte for a problem clinit method info that correspond to a boggus method.
1017:             *
1018:             * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
1019:             */
1020:            public void addProblemClinit(CategorizedProblem[] problems) {
1021:                generateMethodInfoHeaderForClinit();
1022:                // leave two spaces for the number of attributes
1023:                contentsOffset -= 2;
1024:                int attributeOffset = contentsOffset;
1025:                contentsOffset += 2;
1026:                int attributeNumber = 0;
1027:
1028:                int codeAttributeOffset = contentsOffset;
1029:                generateCodeAttributeHeader();
1030:                codeStream.resetForProblemClinit(this );
1031:                String problemString = ""; //$NON-NLS-1$
1032:                int problemLine = 0;
1033:                if (problems != null) {
1034:                    int max = problems.length;
1035:                    StringBuffer buffer = new StringBuffer(25);
1036:                    int count = 0;
1037:                    for (int i = 0; i < max; i++) {
1038:                        CategorizedProblem problem = problems[i];
1039:                        if ((problem != null) && (problem.isError())) {
1040:                            buffer.append("\t" + problem.getMessage() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
1041:                            count++;
1042:                            if (problemLine == 0) {
1043:                                problemLine = problem.getSourceLineNumber();
1044:                            }
1045:                            problems[i] = null;
1046:                        }
1047:                    } // insert the top line afterwards, once knowing how many problems we have to consider
1048:                    if (count > 1) {
1049:                        buffer.insert(0,
1050:                                Messages.compilation_unresolvedProblems);
1051:                    } else {
1052:                        buffer
1053:                                .insert(0,
1054:                                        Messages.compilation_unresolvedProblem);
1055:                    }
1056:                    problemString = buffer.toString();
1057:                }
1058:
1059:                // return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
1060:                codeStream.generateCodeAttributeForProblemMethod(problemString);
1061:                attributeNumber++; // code attribute
1062:                completeCodeAttributeForClinit(codeAttributeOffset, problemLine);
1063:                if (contentsOffset + 2 >= contents.length) {
1064:                    resizeContents(2);
1065:                }
1066:                contents[attributeOffset++] = (byte) (attributeNumber >> 8);
1067:                contents[attributeOffset] = (byte) attributeNumber;
1068:            }
1069:
1070:            /**
1071:             * INTERNAL USE-ONLY
1072:             * Generate the byte for a problem method info that correspond to a boggus constructor.
1073:             *
1074:             * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
1075:             * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
1076:             * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
1077:             */
1078:            public void addProblemConstructor(AbstractMethodDeclaration method,
1079:                    MethodBinding methodBinding, CategorizedProblem[] problems) {
1080:
1081:                // always clear the strictfp/native/abstract bit for a problem method
1082:                generateMethodInfoHeader(
1083:                        methodBinding,
1084:                        methodBinding.modifiers
1085:                                & ~(ClassFileConstants.AccStrictfp
1086:                                        | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract));
1087:                int methodAttributeOffset = contentsOffset;
1088:                int attributeNumber = generateMethodInfoAttribute(
1089:                        methodBinding, true);
1090:
1091:                // Code attribute
1092:                attributeNumber++;
1093:                int codeAttributeOffset = contentsOffset;
1094:                generateCodeAttributeHeader();
1095:                codeStream.reset(method, this );
1096:                String problemString = ""; //$NON-NLS-1$
1097:                int problemLine = 0;
1098:                if (problems != null) {
1099:                    int max = problems.length;
1100:                    StringBuffer buffer = new StringBuffer(25);
1101:                    int count = 0;
1102:                    for (int i = 0; i < max; i++) {
1103:                        CategorizedProblem problem = problems[i];
1104:                        if ((problem != null) && (problem.isError())) {
1105:                            buffer.append("\t" + problem.getMessage() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
1106:                            count++;
1107:                            if (problemLine == 0) {
1108:                                problemLine = problem.getSourceLineNumber();
1109:                            }
1110:                        }
1111:                    } // insert the top line afterwards, once knowing how many problems we have to consider
1112:                    if (count > 1) {
1113:                        buffer.insert(0,
1114:                                Messages.compilation_unresolvedProblems);
1115:                    } else {
1116:                        buffer
1117:                                .insert(0,
1118:                                        Messages.compilation_unresolvedProblem);
1119:                    }
1120:                    problemString = buffer.toString();
1121:                }
1122:
1123:                // return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
1124:                codeStream.generateCodeAttributeForProblemMethod(problemString);
1125:                completeCodeAttributeForProblemMethod(
1126:                        method,
1127:                        methodBinding,
1128:                        codeAttributeOffset,
1129:                        ((SourceTypeBinding) methodBinding.declaringClass).scope
1130:                                .referenceCompilationUnit().compilationResult
1131:                                .getLineSeparatorPositions(), problemLine);
1132:                completeMethodInfo(methodAttributeOffset, attributeNumber);
1133:            }
1134:
1135:            /**
1136:             * INTERNAL USE-ONLY
1137:             * Generate the byte for a problem method info that correspond to a boggus constructor.
1138:             * Reset the position inside the contents byte array to the savedOffset.
1139:             *
1140:             * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
1141:             * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
1142:             * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
1143:             * @param savedOffset <CODE>int</CODE>
1144:             */
1145:            public void addProblemConstructor(AbstractMethodDeclaration method,
1146:                    MethodBinding methodBinding, CategorizedProblem[] problems,
1147:                    int savedOffset) {
1148:                // we need to move back the contentsOffset to the value at the beginning of the method
1149:                contentsOffset = savedOffset;
1150:                methodCount--; // we need to remove the method that causes the problem
1151:                addProblemConstructor(method, methodBinding, problems);
1152:            }
1153:
1154:            /**
1155:             * INTERNAL USE-ONLY
1156:             * Generate the byte for a problem method info that correspond to a boggus method.
1157:             *
1158:             * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
1159:             * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
1160:             * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
1161:             */
1162:            public void addProblemMethod(AbstractMethodDeclaration method,
1163:                    MethodBinding methodBinding, CategorizedProblem[] problems) {
1164:                if (methodBinding.isAbstract()
1165:                        && methodBinding.declaringClass.isInterface()) {
1166:                    method.abort(ProblemSeverities.AbortType, null);
1167:                }
1168:                // always clear the strictfp/native/abstract bit for a problem method
1169:                generateMethodInfoHeader(
1170:                        methodBinding,
1171:                        methodBinding.modifiers
1172:                                & ~(ClassFileConstants.AccStrictfp
1173:                                        | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract));
1174:                int methodAttributeOffset = contentsOffset;
1175:                int attributeNumber = generateMethodInfoAttribute(
1176:                        methodBinding, true);
1177:
1178:                // Code attribute
1179:                attributeNumber++;
1180:
1181:                int codeAttributeOffset = contentsOffset;
1182:                generateCodeAttributeHeader();
1183:                codeStream.reset(method, this );
1184:                String problemString = ""; //$NON-NLS-1$
1185:                int problemLine = 0;
1186:                if (problems != null) {
1187:                    int max = problems.length;
1188:                    StringBuffer buffer = new StringBuffer(25);
1189:                    int count = 0;
1190:                    for (int i = 0; i < max; i++) {
1191:                        CategorizedProblem problem = problems[i];
1192:                        if ((problem != null)
1193:                                && (problem.isError())
1194:                                && (problem.getSourceStart() >= method.declarationSourceStart)
1195:                                && (problem.getSourceEnd() <= method.declarationSourceEnd)) {
1196:                            buffer.append("\t" + problem.getMessage() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
1197:                            count++;
1198:                            if (problemLine == 0) {
1199:                                problemLine = problem.getSourceLineNumber();
1200:                            }
1201:                            problems[i] = null;
1202:                        }
1203:                    } // insert the top line afterwards, once knowing how many problems we have to consider
1204:                    if (count > 1) {
1205:                        buffer.insert(0,
1206:                                Messages.compilation_unresolvedProblems);
1207:                    } else {
1208:                        buffer
1209:                                .insert(0,
1210:                                        Messages.compilation_unresolvedProblem);
1211:                    }
1212:                    problemString = buffer.toString();
1213:                }
1214:
1215:                // return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
1216:                codeStream.generateCodeAttributeForProblemMethod(problemString);
1217:                completeCodeAttributeForProblemMethod(
1218:                        method,
1219:                        methodBinding,
1220:                        codeAttributeOffset,
1221:                        ((SourceTypeBinding) methodBinding.declaringClass).scope
1222:                                .referenceCompilationUnit().compilationResult
1223:                                .getLineSeparatorPositions(), problemLine);
1224:                completeMethodInfo(methodAttributeOffset, attributeNumber);
1225:            }
1226:
1227:            /**
1228:             * INTERNAL USE-ONLY
1229:             * Generate the byte for a problem method info that correspond to a boggus method.
1230:             * Reset the position inside the contents byte array to the savedOffset.
1231:             *
1232:             * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
1233:             * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
1234:             * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
1235:             * @param savedOffset <CODE>int</CODE>
1236:             */
1237:            public void addProblemMethod(AbstractMethodDeclaration method,
1238:                    MethodBinding methodBinding, CategorizedProblem[] problems,
1239:                    int savedOffset) {
1240:                // we need to move back the contentsOffset to the value at the beginning of the method
1241:                contentsOffset = savedOffset;
1242:                methodCount--; // we need to remove the method that causes the problem
1243:                addProblemMethod(method, methodBinding, problems);
1244:            }
1245:
1246:            /**
1247:             * INTERNAL USE-ONLY
1248:             * Generate the byte for all the special method infos.
1249:             * They are:
1250:             * - synthetic access methods
1251:             * - default abstract methods
1252:             */
1253:            public void addSpecialMethods() {
1254:
1255:                // add all methods (default abstract methods and synthetic)
1256:
1257:                // default abstract methods
1258:                generateMissingAbstractMethods(
1259:                        referenceBinding.scope.referenceType().missingAbstractMethods,
1260:                        referenceBinding.scope.referenceCompilationUnit().compilationResult);
1261:
1262:                MethodBinding[] defaultAbstractMethods = this .referenceBinding
1263:                        .getDefaultAbstractMethods();
1264:                for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) {
1265:                    generateMethodInfoHeader(defaultAbstractMethods[i]);
1266:                    int methodAttributeOffset = contentsOffset;
1267:                    int attributeNumber = generateMethodInfoAttribute(defaultAbstractMethods[i]);
1268:                    completeMethodInfo(methodAttributeOffset, attributeNumber);
1269:                }
1270:                // add synthetic methods infos
1271:                SyntheticMethodBinding[] syntheticMethods = this .referenceBinding
1272:                        .syntheticMethods();
1273:                if (syntheticMethods != null) {
1274:                    for (int i = 0, max = syntheticMethods.length; i < max; i++) {
1275:                        SyntheticMethodBinding syntheticMethod = syntheticMethods[i];
1276:                        switch (syntheticMethod.kind) {
1277:                        case SyntheticMethodBinding.FieldReadAccess:
1278:                            // generate a method info to emulate an reading access to
1279:                            // a non-accessible field
1280:                            addSyntheticFieldReadAccessMethod(syntheticMethod);
1281:                            break;
1282:                        case SyntheticMethodBinding.FieldWriteAccess:
1283:                            // generate a method info to emulate an writing access to
1284:                            // a non-accessible field
1285:                            addSyntheticFieldWriteAccessMethod(syntheticMethod);
1286:                            break;
1287:                        case SyntheticMethodBinding.MethodAccess:
1288:                        case SyntheticMethodBinding.SuperMethodAccess:
1289:                        case SyntheticMethodBinding.BridgeMethod:
1290:                            // generate a method info to emulate an access to a non-accessible method / super-method or bridge method
1291:                            addSyntheticMethodAccessMethod(syntheticMethod);
1292:                            break;
1293:                        case SyntheticMethodBinding.ConstructorAccess:
1294:                            // generate a method info to emulate an access to a non-accessible constructor
1295:                            addSyntheticConstructorAccessMethod(syntheticMethod);
1296:                            break;
1297:                        case SyntheticMethodBinding.EnumValues:
1298:                            // generate a method info to define <enum>#values()
1299:                            addSyntheticEnumValuesMethod(syntheticMethod);
1300:                            break;
1301:                        case SyntheticMethodBinding.EnumValueOf:
1302:                            // generate a method info to define <enum>#valueOf(String)
1303:                            addSyntheticEnumValueOfMethod(syntheticMethod);
1304:                            break;
1305:                        case SyntheticMethodBinding.SwitchTable:
1306:                            // generate a method info to define the switch table synthetic method
1307:                            addSyntheticSwitchTable(syntheticMethod);
1308:                        }
1309:                    }
1310:                }
1311:            }
1312:
1313:            /**
1314:             * INTERNAL USE-ONLY
1315:             * Generate the bytes for a synthetic method that provides an access to a private constructor.
1316:             *
1317:             * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
1318:             */
1319:            public void addSyntheticConstructorAccessMethod(
1320:                    SyntheticMethodBinding methodBinding) {
1321:                generateMethodInfoHeader(methodBinding);
1322:                int methodAttributeOffset = this .contentsOffset;
1323:                // this will add exception attribute, synthetic attribute, deprecated attribute,...
1324:                int attributeNumber = generateMethodInfoAttribute(methodBinding);
1325:                // Code attribute
1326:                int codeAttributeOffset = contentsOffset;
1327:                attributeNumber++; // add code attribute
1328:                generateCodeAttributeHeader();
1329:                codeStream.init(this );
1330:                codeStream
1331:                        .generateSyntheticBodyForConstructorAccess(methodBinding);
1332:                completeCodeAttributeForSyntheticMethod(
1333:                        methodBinding,
1334:                        codeAttributeOffset,
1335:                        ((SourceTypeBinding) methodBinding.declaringClass).scope
1336:                                .referenceCompilationUnit().compilationResult
1337:                                .getLineSeparatorPositions());
1338:                // update the number of attributes
1339:                contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
1340:                contents[methodAttributeOffset] = (byte) attributeNumber;
1341:            }
1342:
1343:            /**
1344:             * INTERNAL USE-ONLY
1345:             *  Generate the bytes for a synthetic method that implements Enum#valueOf(String) for a given enum type
1346:             *
1347:             * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
1348:             */
1349:            public void addSyntheticEnumValueOfMethod(
1350:                    SyntheticMethodBinding methodBinding) {
1351:                generateMethodInfoHeader(methodBinding);
1352:                int methodAttributeOffset = this .contentsOffset;
1353:                // this will add exception attribute, synthetic attribute, deprecated attribute,...
1354:                int attributeNumber = generateMethodInfoAttribute(methodBinding);
1355:                // Code attribute
1356:                int codeAttributeOffset = contentsOffset;
1357:                attributeNumber++; // add code attribute
1358:                generateCodeAttributeHeader();
1359:                codeStream.init(this );
1360:                codeStream.generateSyntheticBodyForEnumValueOf(methodBinding);
1361:                completeCodeAttributeForSyntheticMethod(
1362:                        methodBinding,
1363:                        codeAttributeOffset,
1364:                        ((SourceTypeBinding) methodBinding.declaringClass).scope
1365:                                .referenceCompilationUnit().compilationResult
1366:                                .getLineSeparatorPositions());
1367:                // update the number of attributes
1368:                contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
1369:                contents[methodAttributeOffset] = (byte) attributeNumber;
1370:            }
1371:
1372:            /**
1373:             * INTERNAL USE-ONLY
1374:             *  Generate the bytes for a synthetic method that implements Enum#values() for a given enum type
1375:             *
1376:             * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
1377:             */
1378:            public void addSyntheticEnumValuesMethod(
1379:                    SyntheticMethodBinding methodBinding) {
1380:                generateMethodInfoHeader(methodBinding);
1381:                int methodAttributeOffset = this .contentsOffset;
1382:                // this will add exception attribute, synthetic attribute, deprecated attribute,...
1383:                int attributeNumber = generateMethodInfoAttribute(methodBinding);
1384:                // Code attribute
1385:                int codeAttributeOffset = contentsOffset;
1386:                attributeNumber++; // add code attribute
1387:                generateCodeAttributeHeader();
1388:                codeStream.init(this );
1389:                codeStream.generateSyntheticBodyForEnumValues(methodBinding);
1390:                completeCodeAttributeForSyntheticMethod(
1391:                        methodBinding,
1392:                        codeAttributeOffset,
1393:                        ((SourceTypeBinding) methodBinding.declaringClass).scope
1394:                                .referenceCompilationUnit().compilationResult
1395:                                .getLineSeparatorPositions());
1396:                // update the number of attributes
1397:                contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
1398:                contents[methodAttributeOffset] = (byte) attributeNumber;
1399:            }
1400:
1401:            /**
1402:             * INTERNAL USE-ONLY
1403:             * Generate the byte for a problem method info that correspond to a synthetic method that
1404:             * generate an read access to a private field.
1405:             *
1406:             * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
1407:             */
1408:            public void addSyntheticFieldReadAccessMethod(
1409:                    SyntheticMethodBinding methodBinding) {
1410:                generateMethodInfoHeader(methodBinding);
1411:                int methodAttributeOffset = this .contentsOffset;
1412:                // this will add exception attribute, synthetic attribute, deprecated attribute,...
1413:                int attributeNumber = generateMethodInfoAttribute(methodBinding);
1414:                // Code attribute
1415:                int codeAttributeOffset = contentsOffset;
1416:                attributeNumber++; // add code attribute
1417:                generateCodeAttributeHeader();
1418:                codeStream.init(this );
1419:                codeStream
1420:                        .generateSyntheticBodyForFieldReadAccess(methodBinding);
1421:                completeCodeAttributeForSyntheticMethod(
1422:                        methodBinding,
1423:                        codeAttributeOffset,
1424:                        ((SourceTypeBinding) methodBinding.declaringClass).scope
1425:                                .referenceCompilationUnit().compilationResult
1426:                                .getLineSeparatorPositions());
1427:                // update the number of attributes
1428:                contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
1429:                contents[methodAttributeOffset] = (byte) attributeNumber;
1430:            }
1431:
1432:            /**
1433:             * INTERNAL USE-ONLY
1434:             * Generate the byte for a problem method info that correspond to a synthetic method that
1435:             * generate an write access to a private field.
1436:             *
1437:             * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
1438:             */
1439:            public void addSyntheticFieldWriteAccessMethod(
1440:                    SyntheticMethodBinding methodBinding) {
1441:                generateMethodInfoHeader(methodBinding);
1442:                int methodAttributeOffset = this .contentsOffset;
1443:                // this will add exception attribute, synthetic attribute, deprecated attribute,...
1444:                int attributeNumber = generateMethodInfoAttribute(methodBinding);
1445:                // Code attribute
1446:                int codeAttributeOffset = contentsOffset;
1447:                attributeNumber++; // add code attribute
1448:                generateCodeAttributeHeader();
1449:                codeStream.init(this );
1450:                codeStream
1451:                        .generateSyntheticBodyForFieldWriteAccess(methodBinding);
1452:                completeCodeAttributeForSyntheticMethod(
1453:                        methodBinding,
1454:                        codeAttributeOffset,
1455:                        ((SourceTypeBinding) methodBinding.declaringClass).scope
1456:                                .referenceCompilationUnit().compilationResult
1457:                                .getLineSeparatorPositions());
1458:                // update the number of attributes
1459:                contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
1460:                contents[methodAttributeOffset] = (byte) attributeNumber;
1461:            }
1462:
1463:            /**
1464:             * INTERNAL USE-ONLY
1465:             * Generate the bytes for a synthetic method that provides access to a private method.
1466:             *
1467:             * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
1468:             */
1469:            public void addSyntheticMethodAccessMethod(
1470:                    SyntheticMethodBinding methodBinding) {
1471:                generateMethodInfoHeader(methodBinding);
1472:                int methodAttributeOffset = this .contentsOffset;
1473:                // this will add exception attribute, synthetic attribute, deprecated attribute,...
1474:                int attributeNumber = generateMethodInfoAttribute(methodBinding);
1475:                // Code attribute
1476:                int codeAttributeOffset = contentsOffset;
1477:                attributeNumber++; // add code attribute
1478:                generateCodeAttributeHeader();
1479:                codeStream.init(this );
1480:                codeStream.generateSyntheticBodyForMethodAccess(methodBinding);
1481:                completeCodeAttributeForSyntheticMethod(
1482:                        methodBinding,
1483:                        codeAttributeOffset,
1484:                        ((SourceTypeBinding) methodBinding.declaringClass).scope
1485:                                .referenceCompilationUnit().compilationResult
1486:                                .getLineSeparatorPositions());
1487:                // update the number of attributes
1488:                contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
1489:                contents[methodAttributeOffset] = (byte) attributeNumber;
1490:            }
1491:
1492:            public void addSyntheticSwitchTable(
1493:                    SyntheticMethodBinding methodBinding) {
1494:                generateMethodInfoHeader(methodBinding);
1495:                int methodAttributeOffset = this .contentsOffset;
1496:                // this will add exception attribute, synthetic attribute, deprecated attribute,...
1497:                int attributeNumber = generateMethodInfoAttribute(methodBinding);
1498:                // Code attribute
1499:                int codeAttributeOffset = contentsOffset;
1500:                attributeNumber++; // add code attribute
1501:                generateCodeAttributeHeader();
1502:                codeStream.init(this );
1503:                codeStream.generateSyntheticBodyForSwitchTable(methodBinding);
1504:                completeCodeAttributeForSyntheticMethod(
1505:                        true,
1506:                        methodBinding,
1507:                        codeAttributeOffset,
1508:                        ((SourceTypeBinding) methodBinding.declaringClass).scope
1509:                                .referenceCompilationUnit().compilationResult
1510:                                .getLineSeparatorPositions());
1511:                // update the number of attributes
1512:                contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
1513:                contents[methodAttributeOffset] = (byte) attributeNumber;
1514:            }
1515:
1516:            /**
1517:             * INTERNAL USE-ONLY
1518:             * That method completes the creation of the code attribute by setting
1519:             * - the attribute_length
1520:             * - max_stack
1521:             * - max_locals
1522:             * - code_length
1523:             * - exception table
1524:             * - and debug attributes if necessary.
1525:             *
1526:             * @param codeAttributeOffset <CODE>int</CODE>
1527:             */
1528:            public void completeCodeAttribute(int codeAttributeOffset) {
1529:                // reinitialize the localContents with the byte modified by the code stream
1530:                this .contents = codeStream.bCodeStream;
1531:                int localContentsOffset = codeStream.classFileOffset;
1532:                // codeAttributeOffset is the position inside localContents byte array before we started to write
1533:                // any information about the codeAttribute
1534:                // That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
1535:                // to get the right position, 6 for the max_stack etc...
1536:                int code_length = codeStream.position;
1537:                if (code_length > 65535) {
1538:                    codeStream.methodDeclaration.scope.problemReporter()
1539:                            .bytecodeExceeds64KLimit(
1540:                                    codeStream.methodDeclaration);
1541:                }
1542:                if (localContentsOffset + 20 >= this .contents.length) {
1543:                    resizeContents(20);
1544:                }
1545:                int max_stack = codeStream.stackMax;
1546:                this .contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
1547:                this .contents[codeAttributeOffset + 7] = (byte) max_stack;
1548:                int max_locals = codeStream.maxLocals;
1549:                this .contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
1550:                this .contents[codeAttributeOffset + 9] = (byte) max_locals;
1551:                this .contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
1552:                this .contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
1553:                this .contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
1554:                this .contents[codeAttributeOffset + 13] = (byte) code_length;
1555:
1556:                boolean addStackMaps = (this .produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0;
1557:                // write the exception table
1558:                ExceptionLabel[] exceptionLabels = codeStream.exceptionLabels;
1559:                int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
1560:                for (int i = 0, length = codeStream.exceptionLabelsCounter; i < length; i++) {
1561:                    exceptionHandlersCount += codeStream.exceptionLabels[i].count / 2;
1562:                }
1563:                int exSize = exceptionHandlersCount * 8 + 2;
1564:                if (exSize + localContentsOffset >= this .contents.length) {
1565:                    resizeContents(exSize);
1566:                }
1567:                // there is no exception table, so we need to offset by 2 the current offset and move
1568:                // on the attribute generation
1569:                this .contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8);
1570:                this .contents[localContentsOffset++] = (byte) exceptionHandlersCount;
1571:                for (int i = 0, max = codeStream.exceptionLabelsCounter; i < max; i++) {
1572:                    ExceptionLabel exceptionLabel = exceptionLabels[i];
1573:                    if (exceptionLabel != null) {
1574:                        int iRange = 0, maxRange = exceptionLabel.count;
1575:                        if ((maxRange & 1) != 0) {
1576:                            codeStream.methodDeclaration.scope
1577:                                    .problemReporter()
1578:                                    .abortDueToInternalError(
1579:                                            Messages
1580:                                                    .bind(
1581:                                                            Messages.abort_invalidExceptionAttribute,
1582:                                                            new String(
1583:                                                                    codeStream.methodDeclaration.selector)),
1584:                                            codeStream.methodDeclaration);
1585:                        }
1586:                        while (iRange < maxRange) {
1587:                            int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions
1588:                            this .contents[localContentsOffset++] = (byte) (start >> 8);
1589:                            this .contents[localContentsOffset++] = (byte) start;
1590:                            int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions
1591:                            this .contents[localContentsOffset++] = (byte) (end >> 8);
1592:                            this .contents[localContentsOffset++] = (byte) end;
1593:                            int handlerPC = exceptionLabel.position;
1594:                            if (addStackMaps) {
1595:                                StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
1596:                                stackMapFrameCodeStream
1597:                                        .addFramePosition(handlerPC);
1598:                                //						stackMapFrameCodeStream.addExceptionMarker(handlerPC, exceptionLabel.exceptionType);
1599:                            }
1600:                            this .contents[localContentsOffset++] = (byte) (handlerPC >> 8);
1601:                            this .contents[localContentsOffset++] = (byte) handlerPC;
1602:                            if (exceptionLabel.exceptionType == null) {
1603:                                // any exception handler
1604:                                this .contents[localContentsOffset++] = 0;
1605:                                this .contents[localContentsOffset++] = 0;
1606:                            } else {
1607:                                int nameIndex;
1608:                                if (exceptionLabel.exceptionType == TypeBinding.NULL) {
1609:                                    /* represents ClassNotFoundException, see class literal access*/
1610:                                    nameIndex = constantPool
1611:                                            .literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
1612:                                } else {
1613:                                    nameIndex = constantPool
1614:                                            .literalIndexForType(exceptionLabel.exceptionType);
1615:                                }
1616:                                this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
1617:                                this .contents[localContentsOffset++] = (byte) nameIndex;
1618:                            }
1619:                        }
1620:                    }
1621:                }
1622:                // debug attributes
1623:                int codeAttributeAttributeOffset = localContentsOffset;
1624:                int attributeNumber = 0;
1625:                // leave two bytes for the attribute_length
1626:                localContentsOffset += 2;
1627:                if (localContentsOffset + 2 >= this .contents.length) {
1628:                    resizeContents(2);
1629:                }
1630:
1631:                // first we handle the linenumber attribute
1632:                if ((this .produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
1633:                    /* Create and add the line number attribute (used for debugging)
1634:                     * Build the pairs of:
1635:                     * 	(bytecodePC lineNumber)
1636:                     * according to the table of start line indexes and the pcToSourceMap table
1637:                     * contained into the codestream
1638:                     */
1639:                    int[] pcToSourceMapTable;
1640:                    if (((pcToSourceMapTable = codeStream.pcToSourceMap) != null)
1641:                            && (codeStream.pcToSourceMapSize != 0)) {
1642:                        int lineNumberNameIndex = constantPool
1643:                                .literalIndex(AttributeNamesConstants.LineNumberTableName);
1644:                        if (localContentsOffset + 8 >= this .contents.length) {
1645:                            resizeContents(8);
1646:                        }
1647:                        this .contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
1648:                        this .contents[localContentsOffset++] = (byte) lineNumberNameIndex;
1649:                        int lineNumberTableOffset = localContentsOffset;
1650:                        localContentsOffset += 6;
1651:                        // leave space for attribute_length and line_number_table_length
1652:                        int numberOfEntries = 0;
1653:                        int length = codeStream.pcToSourceMapSize;
1654:                        for (int i = 0; i < length;) {
1655:                            // write the entry
1656:                            if (localContentsOffset + 4 >= this .contents.length) {
1657:                                resizeContents(4);
1658:                            }
1659:                            int pc = pcToSourceMapTable[i++];
1660:                            this .contents[localContentsOffset++] = (byte) (pc >> 8);
1661:                            this .contents[localContentsOffset++] = (byte) pc;
1662:                            int lineNumber = pcToSourceMapTable[i++];
1663:                            this .contents[localContentsOffset++] = (byte) (lineNumber >> 8);
1664:                            this .contents[localContentsOffset++] = (byte) lineNumber;
1665:                            numberOfEntries++;
1666:                        }
1667:                        // now we change the size of the line number attribute
1668:                        int lineNumberAttr_length = numberOfEntries * 4 + 2;
1669:                        this .contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 24);
1670:                        this .contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 16);
1671:                        this .contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 8);
1672:                        this .contents[lineNumberTableOffset++] = (byte) lineNumberAttr_length;
1673:                        this .contents[lineNumberTableOffset++] = (byte) (numberOfEntries >> 8);
1674:                        this .contents[lineNumberTableOffset++] = (byte) numberOfEntries;
1675:                        attributeNumber++;
1676:                    }
1677:                }
1678:                // then we do the local variable attribute
1679:                if ((this .produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
1680:                    int numberOfEntries = 0;
1681:                    int localVariableNameIndex = constantPool
1682:                            .literalIndex(AttributeNamesConstants.LocalVariableTableName);
1683:                    final boolean methodDeclarationIsStatic = codeStream.methodDeclaration
1684:                            .isStatic();
1685:                    int maxOfEntries = 8 + 10 * (methodDeclarationIsStatic ? 0
1686:                            : 1);
1687:                    for (int i = 0; i < codeStream.allLocalsCounter; i++) {
1688:                        LocalVariableBinding localVariableBinding = codeStream.locals[i];
1689:                        maxOfEntries += 10 * localVariableBinding.initializationCount;
1690:                    }
1691:                    // reserve enough space
1692:                    if (localContentsOffset + maxOfEntries >= this .contents.length) {
1693:                        resizeContents(maxOfEntries);
1694:                    }
1695:                    this .contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
1696:                    this .contents[localContentsOffset++] = (byte) localVariableNameIndex;
1697:                    int localVariableTableOffset = localContentsOffset;
1698:                    // leave space for attribute_length and local_variable_table_length
1699:                    localContentsOffset += 6;
1700:                    int nameIndex;
1701:                    int descriptorIndex;
1702:                    SourceTypeBinding declaringClassBinding = null;
1703:                    if (!methodDeclarationIsStatic) {
1704:                        numberOfEntries++;
1705:                        this .contents[localContentsOffset++] = 0; // the startPC for this is always 0
1706:                        this .contents[localContentsOffset++] = 0;
1707:                        this .contents[localContentsOffset++] = (byte) (code_length >> 8);
1708:                        this .contents[localContentsOffset++] = (byte) code_length;
1709:                        nameIndex = constantPool
1710:                                .literalIndex(ConstantPool.This);
1711:                        this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
1712:                        this .contents[localContentsOffset++] = (byte) nameIndex;
1713:                        declaringClassBinding = (SourceTypeBinding) codeStream.methodDeclaration.binding.declaringClass;
1714:                        descriptorIndex = constantPool
1715:                                .literalIndex(declaringClassBinding.signature());
1716:                        this .contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
1717:                        this .contents[localContentsOffset++] = (byte) descriptorIndex;
1718:                        this .contents[localContentsOffset++] = 0;// the resolved position for this is always 0
1719:                        this .contents[localContentsOffset++] = 0;
1720:                    }
1721:                    // used to remember the local variable with a generic type
1722:                    int genericLocalVariablesCounter = 0;
1723:                    LocalVariableBinding[] genericLocalVariables = null;
1724:                    int numberOfGenericEntries = 0;
1725:
1726:                    for (int i = 0, max = codeStream.allLocalsCounter; i < max; i++) {
1727:                        LocalVariableBinding localVariable = codeStream.locals[i];
1728:                        if (localVariable.declaration == null)
1729:                            continue;
1730:                        final TypeBinding localVariableTypeBinding = localVariable.type;
1731:                        boolean isParameterizedType = localVariableTypeBinding
1732:                                .isParameterizedType()
1733:                                || localVariableTypeBinding.isTypeVariable();
1734:                        if (localVariable.initializationCount != 0
1735:                                && isParameterizedType) {
1736:                            if (genericLocalVariables == null) {
1737:                                // we cannot have more than max locals
1738:                                genericLocalVariables = new LocalVariableBinding[max];
1739:                            }
1740:                            genericLocalVariables[genericLocalVariablesCounter++] = localVariable;
1741:                        }
1742:                        for (int j = 0; j < localVariable.initializationCount; j++) {
1743:                            int startPC = localVariable.initializationPCs[j << 1];
1744:                            int endPC = localVariable.initializationPCs[(j << 1) + 1];
1745:                            if (startPC != endPC) { // only entries for non zero length
1746:                                if (endPC == -1) {
1747:                                    localVariable.declaringScope
1748:                                            .problemReporter()
1749:                                            .abortDueToInternalError(
1750:                                                    Messages
1751:                                                            .bind(
1752:                                                                    Messages.abort_invalidAttribute,
1753:                                                                    new String(
1754:                                                                            localVariable.name)),
1755:                                                    (ASTNode) localVariable.declaringScope
1756:                                                            .methodScope().referenceContext);
1757:                                }
1758:                                if (isParameterizedType) {
1759:                                    numberOfGenericEntries++;
1760:                                }
1761:                                // now we can safely add the local entry
1762:                                numberOfEntries++;
1763:                                this .contents[localContentsOffset++] = (byte) (startPC >> 8);
1764:                                this .contents[localContentsOffset++] = (byte) startPC;
1765:                                int length = endPC - startPC;
1766:                                this .contents[localContentsOffset++] = (byte) (length >> 8);
1767:                                this .contents[localContentsOffset++] = (byte) length;
1768:                                nameIndex = constantPool
1769:                                        .literalIndex(localVariable.name);
1770:                                this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
1771:                                this .contents[localContentsOffset++] = (byte) nameIndex;
1772:                                descriptorIndex = constantPool
1773:                                        .literalIndex(localVariableTypeBinding
1774:                                                .signature());
1775:                                this .contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
1776:                                this .contents[localContentsOffset++] = (byte) descriptorIndex;
1777:                                int resolvedPosition = localVariable.resolvedPosition;
1778:                                this .contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
1779:                                this .contents[localContentsOffset++] = (byte) resolvedPosition;
1780:                            }
1781:                        }
1782:                    }
1783:                    int value = numberOfEntries * 10 + 2;
1784:                    this .contents[localVariableTableOffset++] = (byte) (value >> 24);
1785:                    this .contents[localVariableTableOffset++] = (byte) (value >> 16);
1786:                    this .contents[localVariableTableOffset++] = (byte) (value >> 8);
1787:                    this .contents[localVariableTableOffset++] = (byte) value;
1788:                    this .contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
1789:                    this .contents[localVariableTableOffset] = (byte) numberOfEntries;
1790:                    attributeNumber++;
1791:
1792:                    final boolean currentInstanceIsGeneric = !methodDeclarationIsStatic
1793:                            && declaringClassBinding != null
1794:                            && declaringClassBinding.typeVariables != Binding.NO_TYPE_VARIABLES;
1795:                    if (genericLocalVariablesCounter != 0
1796:                            || currentInstanceIsGeneric) {
1797:                        // add the local variable type table attribute
1798:                        numberOfGenericEntries += (currentInstanceIsGeneric ? 1
1799:                                : 0);
1800:                        maxOfEntries = 8 + numberOfGenericEntries * 10;
1801:                        // reserve enough space
1802:                        if (localContentsOffset + maxOfEntries >= this .contents.length) {
1803:                            resizeContents(maxOfEntries);
1804:                        }
1805:                        int localVariableTypeNameIndex = constantPool
1806:                                .literalIndex(AttributeNamesConstants.LocalVariableTypeTableName);
1807:                        this .contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8);
1808:                        this .contents[localContentsOffset++] = (byte) localVariableTypeNameIndex;
1809:                        value = numberOfGenericEntries * 10 + 2;
1810:                        this .contents[localContentsOffset++] = (byte) (value >> 24);
1811:                        this .contents[localContentsOffset++] = (byte) (value >> 16);
1812:                        this .contents[localContentsOffset++] = (byte) (value >> 8);
1813:                        this .contents[localContentsOffset++] = (byte) value;
1814:                        this .contents[localContentsOffset++] = (byte) (numberOfGenericEntries >> 8);
1815:                        this .contents[localContentsOffset++] = (byte) numberOfGenericEntries;
1816:                        if (currentInstanceIsGeneric) {
1817:                            this .contents[localContentsOffset++] = 0; // the startPC for this is always 0
1818:                            this .contents[localContentsOffset++] = 0;
1819:                            this .contents[localContentsOffset++] = (byte) (code_length >> 8);
1820:                            this .contents[localContentsOffset++] = (byte) code_length;
1821:                            nameIndex = constantPool
1822:                                    .literalIndex(ConstantPool.This);
1823:                            this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
1824:                            this .contents[localContentsOffset++] = (byte) nameIndex;
1825:                            descriptorIndex = constantPool
1826:                                    .literalIndex(declaringClassBinding
1827:                                            .genericTypeSignature());
1828:                            this .contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
1829:                            this .contents[localContentsOffset++] = (byte) descriptorIndex;
1830:                            this .contents[localContentsOffset++] = 0;// the resolved position for this is always 0
1831:                            this .contents[localContentsOffset++] = 0;
1832:                        }
1833:
1834:                        for (int i = 0; i < genericLocalVariablesCounter; i++) {
1835:                            LocalVariableBinding localVariable = genericLocalVariables[i];
1836:                            for (int j = 0; j < localVariable.initializationCount; j++) {
1837:                                int startPC = localVariable.initializationPCs[j << 1];
1838:                                int endPC = localVariable.initializationPCs[(j << 1) + 1];
1839:                                if (startPC != endPC) {
1840:                                    // only entries for non zero length
1841:                                    // now we can safely add the local entry
1842:                                    this .contents[localContentsOffset++] = (byte) (startPC >> 8);
1843:                                    this .contents[localContentsOffset++] = (byte) startPC;
1844:                                    int length = endPC - startPC;
1845:                                    this .contents[localContentsOffset++] = (byte) (length >> 8);
1846:                                    this .contents[localContentsOffset++] = (byte) length;
1847:                                    nameIndex = constantPool
1848:                                            .literalIndex(localVariable.name);
1849:                                    this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
1850:                                    this .contents[localContentsOffset++] = (byte) nameIndex;
1851:                                    descriptorIndex = constantPool
1852:                                            .literalIndex(localVariable.type
1853:                                                    .genericTypeSignature());
1854:                                    this .contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
1855:                                    this .contents[localContentsOffset++] = (byte) descriptorIndex;
1856:                                    int resolvedPosition = localVariable.resolvedPosition;
1857:                                    this .contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
1858:                                    this .contents[localContentsOffset++] = (byte) resolvedPosition;
1859:                                }
1860:                            }
1861:                        }
1862:                        attributeNumber++;
1863:                    }
1864:                }
1865:
1866:                if (addStackMaps) {
1867:                    StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
1868:                    stackMapFrameCodeStream.removeFramePosition(code_length);
1869:                    if (stackMapFrameCodeStream.hasFramePositions()) {
1870:                        ArrayList frames = new ArrayList();
1871:                        traverse(this .codeStream.methodDeclaration.binding,
1872:                                max_locals, this .contents,
1873:                                codeAttributeOffset + 14, code_length, frames,
1874:                                false);
1875:                        int numberOfFrames = frames.size();
1876:                        if (numberOfFrames > 1) {
1877:                            int stackMapTableAttributeOffset = localContentsOffset;
1878:                            // add the stack map table attribute
1879:                            if (localContentsOffset + 8 >= this .contents.length) {
1880:                                resizeContents(8);
1881:                            }
1882:                            int stackMapTableAttributeNameIndex = constantPool
1883:                                    .literalIndex(AttributeNamesConstants.StackMapTableName);
1884:                            this .contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
1885:                            this .contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
1886:
1887:                            int stackMapTableAttributeLengthOffset = localContentsOffset;
1888:                            // generate the attribute
1889:                            localContentsOffset += 4;
1890:                            if (localContentsOffset + 4 >= this .contents.length) {
1891:                                resizeContents(4);
1892:                            }
1893:                            int numberOfFramesOffset = localContentsOffset;
1894:                            localContentsOffset += 2;
1895:                            if (localContentsOffset + 2 >= this .contents.length) {
1896:                                resizeContents(2);
1897:                            }
1898:                            StackMapFrame currentFrame = (StackMapFrame) frames
1899:                                    .get(0);
1900:                            StackMapFrame prevFrame = null;
1901:                            for (int j = 1; j < numberOfFrames; j++) {
1902:                                // select next frame
1903:                                prevFrame = currentFrame;
1904:                                currentFrame = (StackMapFrame) frames.get(j);
1905:                                // generate current frame
1906:                                // need to find differences between the current frame and the previous frame
1907:                                int offsetDelta = currentFrame
1908:                                        .getOffsetDelta(prevFrame);
1909:                                switch (currentFrame.getFrameType(prevFrame)) {
1910:                                case StackMapFrame.APPEND_FRAME:
1911:                                    if (localContentsOffset + 3 >= this .contents.length) {
1912:                                        resizeContents(3);
1913:                                    }
1914:                                    int numberOfDifferentLocals = currentFrame
1915:                                            .numberOfDifferentLocals(prevFrame);
1916:                                    this .contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
1917:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
1918:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
1919:                                    int index = currentFrame
1920:                                            .getIndexOfDifferentLocals(numberOfDifferentLocals);
1921:                                    int numberOfLocals = currentFrame
1922:                                            .getNumberOfLocals();
1923:                                    for (int i = index; i < currentFrame.locals.length
1924:                                            && numberOfDifferentLocals > 0; i++) {
1925:                                        if (localContentsOffset + 6 >= this .contents.length) {
1926:                                            resizeContents(6);
1927:                                        }
1928:                                        VerificationTypeInfo info = currentFrame.locals[i];
1929:                                        if (info == null) {
1930:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
1931:                                        } else {
1932:                                            switch (info.id()) {
1933:                                            case T_boolean:
1934:                                            case T_byte:
1935:                                            case T_char:
1936:                                            case T_int:
1937:                                            case T_short:
1938:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
1939:                                                break;
1940:                                            case T_float:
1941:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
1942:                                                break;
1943:                                            case T_long:
1944:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
1945:                                                i++;
1946:                                                break;
1947:                                            case T_double:
1948:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
1949:                                                i++;
1950:                                                break;
1951:                                            case T_null:
1952:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
1953:                                                break;
1954:                                            default:
1955:                                                this .contents[localContentsOffset++] = (byte) info.tag;
1956:                                                switch (info.tag) {
1957:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
1958:                                                    int offset = info.offset;
1959:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
1960:                                                    this .contents[localContentsOffset++] = (byte) offset;
1961:                                                    break;
1962:                                                case VerificationTypeInfo.ITEM_OBJECT:
1963:                                                    int indexForType = constantPool
1964:                                                            .literalIndexForType(info
1965:                                                                    .constantPoolName());
1966:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
1967:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
1968:                                                }
1969:                                            }
1970:                                            numberOfDifferentLocals--;
1971:                                        }
1972:                                    }
1973:                                    break;
1974:                                case StackMapFrame.SAME_FRAME:
1975:                                    if (localContentsOffset + 1 >= this .contents.length) {
1976:                                        resizeContents(1);
1977:                                    }
1978:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
1979:                                    break;
1980:                                case StackMapFrame.SAME_FRAME_EXTENDED:
1981:                                    if (localContentsOffset + 3 >= this .contents.length) {
1982:                                        resizeContents(3);
1983:                                    }
1984:                                    this .contents[localContentsOffset++] = (byte) 251;
1985:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
1986:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
1987:                                    break;
1988:                                case StackMapFrame.CHOP_FRAME:
1989:                                    if (localContentsOffset + 3 >= this .contents.length) {
1990:                                        resizeContents(3);
1991:                                    }
1992:                                    numberOfDifferentLocals = -currentFrame
1993:                                            .numberOfDifferentLocals(prevFrame);
1994:                                    this .contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
1995:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
1996:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
1997:                                    break;
1998:                                case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS:
1999:                                    if (localContentsOffset + 4 >= this .contents.length) {
2000:                                        resizeContents(4);
2001:                                    }
2002:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta + 64);
2003:                                    if (currentFrame.stackItems[0] == null) {
2004:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
2005:                                    } else {
2006:                                        switch (currentFrame.stackItems[0].id()) {
2007:                                        case T_boolean:
2008:                                        case T_byte:
2009:                                        case T_char:
2010:                                        case T_int:
2011:                                        case T_short:
2012:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
2013:                                            break;
2014:                                        case T_float:
2015:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
2016:                                            break;
2017:                                        case T_long:
2018:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
2019:                                            break;
2020:                                        case T_double:
2021:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
2022:                                            break;
2023:                                        case T_null:
2024:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
2025:                                            break;
2026:                                        default:
2027:                                            VerificationTypeInfo info = currentFrame.stackItems[0];
2028:                                            byte tag = (byte) info.tag;
2029:                                            this .contents[localContentsOffset++] = tag;
2030:                                            switch (tag) {
2031:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
2032:                                                int offset = info.offset;
2033:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
2034:                                                this .contents[localContentsOffset++] = (byte) offset;
2035:                                                break;
2036:                                            case VerificationTypeInfo.ITEM_OBJECT:
2037:                                                int indexForType = constantPool
2038:                                                        .literalIndexForType(info
2039:                                                                .constantPoolName());
2040:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
2041:                                                this .contents[localContentsOffset++] = (byte) indexForType;
2042:                                            }
2043:                                        }
2044:                                    }
2045:                                    break;
2046:                                case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED:
2047:                                    if (localContentsOffset + 6 >= this .contents.length) {
2048:                                        resizeContents(6);
2049:                                    }
2050:                                    this .contents[localContentsOffset++] = (byte) 247;
2051:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
2052:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
2053:                                    if (currentFrame.stackItems[0] == null) {
2054:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
2055:                                    } else {
2056:                                        switch (currentFrame.stackItems[0].id()) {
2057:                                        case T_boolean:
2058:                                        case T_byte:
2059:                                        case T_char:
2060:                                        case T_int:
2061:                                        case T_short:
2062:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
2063:                                            break;
2064:                                        case T_float:
2065:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
2066:                                            break;
2067:                                        case T_long:
2068:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
2069:                                            break;
2070:                                        case T_double:
2071:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
2072:                                            break;
2073:                                        case T_null:
2074:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
2075:                                            break;
2076:                                        default:
2077:                                            VerificationTypeInfo info = currentFrame.stackItems[0];
2078:                                            byte tag = (byte) info.tag;
2079:                                            this .contents[localContentsOffset++] = tag;
2080:                                            switch (tag) {
2081:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
2082:                                                int offset = info.offset;
2083:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
2084:                                                this .contents[localContentsOffset++] = (byte) offset;
2085:                                                break;
2086:                                            case VerificationTypeInfo.ITEM_OBJECT:
2087:                                                int indexForType = constantPool
2088:                                                        .literalIndexForType(info
2089:                                                                .constantPoolName());
2090:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
2091:                                                this .contents[localContentsOffset++] = (byte) indexForType;
2092:                                            }
2093:                                        }
2094:                                    }
2095:                                    break;
2096:                                default:
2097:                                    // FULL_FRAME
2098:                                    if (localContentsOffset + 5 >= this .contents.length) {
2099:                                        resizeContents(5);
2100:                                    }
2101:                                    this .contents[localContentsOffset++] = (byte) 255;
2102:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
2103:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
2104:                                    int numberOfLocalOffset = localContentsOffset;
2105:                                    localContentsOffset += 2; // leave two spots for number of locals
2106:                                    int numberOfLocalEntries = 0;
2107:                                    numberOfLocals = currentFrame
2108:                                            .getNumberOfLocals();
2109:                                    int numberOfEntries = 0;
2110:                                    int localsLength = currentFrame.locals == null ? 0
2111:                                            : currentFrame.locals.length;
2112:                                    for (int i = 0; i < localsLength
2113:                                            && numberOfLocalEntries < numberOfLocals; i++) {
2114:                                        if (localContentsOffset + 3 >= this .contents.length) {
2115:                                            resizeContents(3);
2116:                                        }
2117:                                        VerificationTypeInfo info = currentFrame.locals[i];
2118:                                        if (info == null) {
2119:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
2120:                                        } else {
2121:                                            switch (info.id()) {
2122:                                            case T_boolean:
2123:                                            case T_byte:
2124:                                            case T_char:
2125:                                            case T_int:
2126:                                            case T_short:
2127:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
2128:                                                break;
2129:                                            case T_float:
2130:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
2131:                                                break;
2132:                                            case T_long:
2133:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
2134:                                                i++;
2135:                                                break;
2136:                                            case T_double:
2137:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
2138:                                                i++;
2139:                                                break;
2140:                                            case T_null:
2141:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
2142:                                                break;
2143:                                            default:
2144:                                                this .contents[localContentsOffset++] = (byte) info.tag;
2145:                                                switch (info.tag) {
2146:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
2147:                                                    int offset = info.offset;
2148:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
2149:                                                    this .contents[localContentsOffset++] = (byte) offset;
2150:                                                    break;
2151:                                                case VerificationTypeInfo.ITEM_OBJECT:
2152:                                                    int indexForType = constantPool
2153:                                                            .literalIndexForType(info
2154:                                                                    .constantPoolName());
2155:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
2156:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
2157:                                                }
2158:                                            }
2159:                                            numberOfLocalEntries++;
2160:                                        }
2161:                                        numberOfEntries++;
2162:                                    }
2163:                                    if (localContentsOffset + 4 >= this .contents.length) {
2164:                                        resizeContents(4);
2165:                                    }
2166:                                    this .contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
2167:                                    this .contents[numberOfLocalOffset] = (byte) numberOfEntries;
2168:                                    int numberOfStackItems = currentFrame.numberOfStackItems;
2169:                                    this .contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
2170:                                    this .contents[localContentsOffset++] = (byte) numberOfStackItems;
2171:                                    for (int i = 0; i < numberOfStackItems; i++) {
2172:                                        if (localContentsOffset + 3 >= this .contents.length) {
2173:                                            resizeContents(3);
2174:                                        }
2175:                                        VerificationTypeInfo info = currentFrame.stackItems[i];
2176:                                        if (info == null) {
2177:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
2178:                                        } else {
2179:                                            switch (info.id()) {
2180:                                            case T_boolean:
2181:                                            case T_byte:
2182:                                            case T_char:
2183:                                            case T_int:
2184:                                            case T_short:
2185:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
2186:                                                break;
2187:                                            case T_float:
2188:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
2189:                                                break;
2190:                                            case T_long:
2191:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
2192:                                                break;
2193:                                            case T_double:
2194:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
2195:                                                break;
2196:                                            case T_null:
2197:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
2198:                                                break;
2199:                                            default:
2200:                                                this .contents[localContentsOffset++] = (byte) info.tag;
2201:                                                switch (info.tag) {
2202:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
2203:                                                    int offset = info.offset;
2204:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
2205:                                                    this .contents[localContentsOffset++] = (byte) offset;
2206:                                                    break;
2207:                                                case VerificationTypeInfo.ITEM_OBJECT:
2208:                                                    int indexForType = constantPool
2209:                                                            .literalIndexForType(info
2210:                                                                    .constantPoolName());
2211:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
2212:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
2213:                                                }
2214:                                            }
2215:                                        }
2216:                                    }
2217:                                }
2218:                            }
2219:
2220:                            numberOfFrames--;
2221:                            if (numberOfFrames != 0) {
2222:                                this .contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
2223:                                this .contents[numberOfFramesOffset] = (byte) numberOfFrames;
2224:
2225:                                int attributeLength = localContentsOffset
2226:                                        - stackMapTableAttributeLengthOffset
2227:                                        - 4;
2228:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
2229:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
2230:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
2231:                                this .contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
2232:                                attributeNumber++;
2233:                            } else {
2234:                                localContentsOffset = stackMapTableAttributeOffset;
2235:                            }
2236:                        }
2237:                    }
2238:                }
2239:
2240:                if ((this .produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
2241:                    StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
2242:                    stackMapFrameCodeStream.removeFramePosition(code_length);
2243:                    if (stackMapFrameCodeStream.hasFramePositions()) {
2244:                        ArrayList frames = new ArrayList();
2245:                        traverse(this .codeStream.methodDeclaration.binding,
2246:                                max_locals, this .contents,
2247:                                codeAttributeOffset + 14, code_length, frames,
2248:                                false);
2249:                        int numberOfFrames = frames.size();
2250:                        if (numberOfFrames > 1) {
2251:                            int stackMapTableAttributeOffset = localContentsOffset;
2252:                            // add the stack map table attribute
2253:                            if (localContentsOffset + 8 >= this .contents.length) {
2254:                                resizeContents(8);
2255:                            }
2256:                            int stackMapAttributeNameIndex = constantPool
2257:                                    .literalIndex(AttributeNamesConstants.StackMapName);
2258:                            this .contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
2259:                            this .contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
2260:
2261:                            int stackMapAttributeLengthOffset = localContentsOffset;
2262:                            // generate the attribute
2263:                            localContentsOffset += 4;
2264:                            if (localContentsOffset + 4 >= this .contents.length) {
2265:                                resizeContents(4);
2266:                            }
2267:                            int numberOfFramesOffset = localContentsOffset;
2268:                            localContentsOffset += 2;
2269:                            if (localContentsOffset + 2 >= this .contents.length) {
2270:                                resizeContents(2);
2271:                            }
2272:                            StackMapFrame currentFrame = (StackMapFrame) frames
2273:                                    .get(0);
2274:                            for (int j = 1; j < numberOfFrames; j++) {
2275:                                // select next frame
2276:                                currentFrame = (StackMapFrame) frames.get(j);
2277:                                // generate current frame
2278:                                // need to find differences between the current frame and the previous frame
2279:                                int frameOffset = currentFrame.pc;
2280:                                // FULL_FRAME
2281:                                if (localContentsOffset + 5 >= this .contents.length) {
2282:                                    resizeContents(5);
2283:                                }
2284:                                this .contents[localContentsOffset++] = (byte) (frameOffset >> 8);
2285:                                this .contents[localContentsOffset++] = (byte) frameOffset;
2286:                                int numberOfLocalOffset = localContentsOffset;
2287:                                localContentsOffset += 2; // leave two spots for number of locals
2288:                                int numberOfLocalEntries = 0;
2289:                                int numberOfLocals = currentFrame
2290:                                        .getNumberOfLocals();
2291:                                int numberOfEntries = 0;
2292:                                int localsLength = currentFrame.locals == null ? 0
2293:                                        : currentFrame.locals.length;
2294:                                for (int i = 0; i < localsLength
2295:                                        && numberOfLocalEntries < numberOfLocals; i++) {
2296:                                    if (localContentsOffset + 3 >= this .contents.length) {
2297:                                        resizeContents(3);
2298:                                    }
2299:                                    VerificationTypeInfo info = currentFrame.locals[i];
2300:                                    if (info == null) {
2301:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
2302:                                    } else {
2303:                                        switch (info.id()) {
2304:                                        case T_boolean:
2305:                                        case T_byte:
2306:                                        case T_char:
2307:                                        case T_int:
2308:                                        case T_short:
2309:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
2310:                                            break;
2311:                                        case T_float:
2312:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
2313:                                            break;
2314:                                        case T_long:
2315:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
2316:                                            i++;
2317:                                            break;
2318:                                        case T_double:
2319:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
2320:                                            i++;
2321:                                            break;
2322:                                        case T_null:
2323:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
2324:                                            break;
2325:                                        default:
2326:                                            this .contents[localContentsOffset++] = (byte) info.tag;
2327:                                            switch (info.tag) {
2328:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
2329:                                                int offset = info.offset;
2330:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
2331:                                                this .contents[localContentsOffset++] = (byte) offset;
2332:                                                break;
2333:                                            case VerificationTypeInfo.ITEM_OBJECT:
2334:                                                int indexForType = constantPool
2335:                                                        .literalIndexForType(info
2336:                                                                .constantPoolName());
2337:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
2338:                                                this .contents[localContentsOffset++] = (byte) indexForType;
2339:                                            }
2340:                                        }
2341:                                        numberOfLocalEntries++;
2342:                                    }
2343:                                    numberOfEntries++;
2344:                                }
2345:                                if (localContentsOffset + 4 >= this .contents.length) {
2346:                                    resizeContents(4);
2347:                                }
2348:                                this .contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
2349:                                this .contents[numberOfLocalOffset] = (byte) numberOfEntries;
2350:                                int numberOfStackItems = currentFrame.numberOfStackItems;
2351:                                this .contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
2352:                                this .contents[localContentsOffset++] = (byte) numberOfStackItems;
2353:                                for (int i = 0; i < numberOfStackItems; i++) {
2354:                                    if (localContentsOffset + 3 >= this .contents.length) {
2355:                                        resizeContents(3);
2356:                                    }
2357:                                    VerificationTypeInfo info = currentFrame.stackItems[i];
2358:                                    if (info == null) {
2359:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
2360:                                    } else {
2361:                                        switch (info.id()) {
2362:                                        case T_boolean:
2363:                                        case T_byte:
2364:                                        case T_char:
2365:                                        case T_int:
2366:                                        case T_short:
2367:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
2368:                                            break;
2369:                                        case T_float:
2370:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
2371:                                            break;
2372:                                        case T_long:
2373:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
2374:                                            break;
2375:                                        case T_double:
2376:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
2377:                                            break;
2378:                                        case T_null:
2379:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
2380:                                            break;
2381:                                        default:
2382:                                            this .contents[localContentsOffset++] = (byte) info.tag;
2383:                                            switch (info.tag) {
2384:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
2385:                                                int offset = info.offset;
2386:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
2387:                                                this .contents[localContentsOffset++] = (byte) offset;
2388:                                                break;
2389:                                            case VerificationTypeInfo.ITEM_OBJECT:
2390:                                                int indexForType = constantPool
2391:                                                        .literalIndexForType(info
2392:                                                                .constantPoolName());
2393:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
2394:                                                this .contents[localContentsOffset++] = (byte) indexForType;
2395:                                            }
2396:                                        }
2397:                                    }
2398:                                }
2399:                            }
2400:
2401:                            numberOfFrames--;
2402:                            if (numberOfFrames != 0) {
2403:                                this .contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
2404:                                this .contents[numberOfFramesOffset] = (byte) numberOfFrames;
2405:
2406:                                int attributeLength = localContentsOffset
2407:                                        - stackMapAttributeLengthOffset - 4;
2408:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
2409:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
2410:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
2411:                                this .contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
2412:                                attributeNumber++;
2413:                            } else {
2414:                                localContentsOffset = stackMapTableAttributeOffset;
2415:                            }
2416:                        }
2417:                    }
2418:                }
2419:
2420:                this .contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
2421:                this .contents[codeAttributeAttributeOffset] = (byte) attributeNumber;
2422:
2423:                // update the attribute length
2424:                int codeAttributeLength = localContentsOffset
2425:                        - (codeAttributeOffset + 6);
2426:                this .contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
2427:                this .contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
2428:                this .contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
2429:                this .contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
2430:                contentsOffset = localContentsOffset;
2431:            }
2432:
2433:            /**
2434:             * INTERNAL USE-ONLY
2435:             * That method completes the creation of the code attribute by setting
2436:             * - the attribute_length
2437:             * - max_stack
2438:             * - max_locals
2439:             * - code_length
2440:             * - exception table
2441:             * - and debug attributes if necessary.
2442:             *
2443:             * @param codeAttributeOffset <CODE>int</CODE>
2444:             */
2445:            public void completeCodeAttributeForClinit(int codeAttributeOffset) {
2446:                // reinitialize the contents with the byte modified by the code stream
2447:                this .contents = codeStream.bCodeStream;
2448:                int localContentsOffset = codeStream.classFileOffset;
2449:                // codeAttributeOffset is the position inside contents byte array before we started to write
2450:                // any information about the codeAttribute
2451:                // That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
2452:                // to get the right position, 6 for the max_stack etc...
2453:                int code_length = codeStream.position;
2454:                if (code_length > 65535) {
2455:                    codeStream.methodDeclaration.scope.problemReporter()
2456:                            .bytecodeExceeds64KLimit(
2457:                                    codeStream.methodDeclaration.scope
2458:                                            .referenceType());
2459:                }
2460:                if (localContentsOffset + 20 >= this .contents.length) {
2461:                    resizeContents(20);
2462:                }
2463:                int max_stack = codeStream.stackMax;
2464:                this .contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
2465:                this .contents[codeAttributeOffset + 7] = (byte) max_stack;
2466:                int max_locals = codeStream.maxLocals;
2467:                this .contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
2468:                this .contents[codeAttributeOffset + 9] = (byte) max_locals;
2469:                this .contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
2470:                this .contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
2471:                this .contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
2472:                this .contents[codeAttributeOffset + 13] = (byte) code_length;
2473:
2474:                boolean addStackMaps = (this .produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0;
2475:                // write the exception table
2476:                ExceptionLabel[] exceptionLabels = codeStream.exceptionLabels;
2477:                int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
2478:                for (int i = 0, length = codeStream.exceptionLabelsCounter; i < length; i++) {
2479:                    exceptionHandlersCount += codeStream.exceptionLabels[i].count / 2;
2480:                }
2481:                int exSize = exceptionHandlersCount * 8 + 2;
2482:                if (exSize + localContentsOffset >= this .contents.length) {
2483:                    resizeContents(exSize);
2484:                }
2485:                // there is no exception table, so we need to offset by 2 the current offset and move
2486:                // on the attribute generation
2487:                this .contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8);
2488:                this .contents[localContentsOffset++] = (byte) exceptionHandlersCount;
2489:                for (int i = 0, max = codeStream.exceptionLabelsCounter; i < max; i++) {
2490:                    ExceptionLabel exceptionLabel = exceptionLabels[i];
2491:                    if (exceptionLabel != null) {
2492:                        int iRange = 0, maxRange = exceptionLabel.count;
2493:                        if ((maxRange & 1) != 0) {
2494:                            codeStream.methodDeclaration.scope
2495:                                    .problemReporter()
2496:                                    .abortDueToInternalError(
2497:                                            Messages
2498:                                                    .bind(
2499:                                                            Messages.abort_invalidExceptionAttribute,
2500:                                                            new String(
2501:                                                                    codeStream.methodDeclaration.selector)),
2502:                                            codeStream.methodDeclaration);
2503:                        }
2504:                        while (iRange < maxRange) {
2505:                            int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions
2506:                            this .contents[localContentsOffset++] = (byte) (start >> 8);
2507:                            this .contents[localContentsOffset++] = (byte) start;
2508:                            int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions
2509:                            this .contents[localContentsOffset++] = (byte) (end >> 8);
2510:                            this .contents[localContentsOffset++] = (byte) end;
2511:                            int handlerPC = exceptionLabel.position;
2512:                            this .contents[localContentsOffset++] = (byte) (handlerPC >> 8);
2513:                            this .contents[localContentsOffset++] = (byte) handlerPC;
2514:                            if (addStackMaps) {
2515:                                StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
2516:                                stackMapFrameCodeStream
2517:                                        .addFramePosition(handlerPC);
2518:                                //						stackMapFrameCodeStream.addExceptionMarker(handlerPC, exceptionLabel.exceptionType);
2519:                            }
2520:                            if (exceptionLabel.exceptionType == null) {
2521:                                // any exception handler
2522:                                this .contents[localContentsOffset++] = 0;
2523:                                this .contents[localContentsOffset++] = 0;
2524:                            } else {
2525:                                int nameIndex;
2526:                                if (exceptionLabel.exceptionType == TypeBinding.NULL) {
2527:                                    /* represents denote ClassNotFoundException, see class literal access*/
2528:                                    nameIndex = constantPool
2529:                                            .literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
2530:                                } else {
2531:                                    nameIndex = constantPool
2532:                                            .literalIndexForType(exceptionLabel.exceptionType);
2533:                                }
2534:                                this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
2535:                                this .contents[localContentsOffset++] = (byte) nameIndex;
2536:                            }
2537:                        }
2538:                    }
2539:                }
2540:                // debug attributes
2541:                int codeAttributeAttributeOffset = localContentsOffset;
2542:                int attributeNumber = 0;
2543:                // leave two bytes for the attribute_length
2544:                localContentsOffset += 2;
2545:                if (localContentsOffset + 2 >= this .contents.length) {
2546:                    resizeContents(2);
2547:                }
2548:
2549:                // first we handle the linenumber attribute
2550:                if ((this .produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
2551:                    /* Create and add the line number attribute (used for debugging)
2552:                     * Build the pairs of:
2553:                     * 	(bytecodePC lineNumber)
2554:                     * according to the table of start line indexes and the pcToSourceMap table
2555:                     * contained into the codestream
2556:                     */
2557:                    int[] pcToSourceMapTable;
2558:                    if (((pcToSourceMapTable = codeStream.pcToSourceMap) != null)
2559:                            && (codeStream.pcToSourceMapSize != 0)) {
2560:                        int lineNumberNameIndex = constantPool
2561:                                .literalIndex(AttributeNamesConstants.LineNumberTableName);
2562:                        if (localContentsOffset + 8 >= this .contents.length) {
2563:                            resizeContents(8);
2564:                        }
2565:                        this .contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
2566:                        this .contents[localContentsOffset++] = (byte) lineNumberNameIndex;
2567:                        int lineNumberTableOffset = localContentsOffset;
2568:                        localContentsOffset += 6;
2569:                        // leave space for attribute_length and line_number_table_length
2570:                        int numberOfEntries = 0;
2571:                        int length = codeStream.pcToSourceMapSize;
2572:                        for (int i = 0; i < length;) {
2573:                            // write the entry
2574:                            if (localContentsOffset + 4 >= this .contents.length) {
2575:                                resizeContents(4);
2576:                            }
2577:                            int pc = pcToSourceMapTable[i++];
2578:                            this .contents[localContentsOffset++] = (byte) (pc >> 8);
2579:                            this .contents[localContentsOffset++] = (byte) pc;
2580:                            int lineNumber = pcToSourceMapTable[i++];
2581:                            this .contents[localContentsOffset++] = (byte) (lineNumber >> 8);
2582:                            this .contents[localContentsOffset++] = (byte) lineNumber;
2583:                            numberOfEntries++;
2584:                        }
2585:                        // now we change the size of the line number attribute
2586:                        int lineNumberAttr_length = numberOfEntries * 4 + 2;
2587:                        this .contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 24);
2588:                        this .contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 16);
2589:                        this .contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 8);
2590:                        this .contents[lineNumberTableOffset++] = (byte) lineNumberAttr_length;
2591:                        this .contents[lineNumberTableOffset++] = (byte) (numberOfEntries >> 8);
2592:                        this .contents[lineNumberTableOffset++] = (byte) numberOfEntries;
2593:                        attributeNumber++;
2594:                    }
2595:                }
2596:                // then we do the local variable attribute
2597:                if ((this .produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
2598:                    int numberOfEntries = 0;
2599:                    //		codeAttribute.addLocalVariableTableAttribute(this);
2600:                    if ((codeStream.pcToSourceMap != null)
2601:                            && (codeStream.pcToSourceMapSize != 0)) {
2602:                        int localVariableNameIndex = constantPool
2603:                                .literalIndex(AttributeNamesConstants.LocalVariableTableName);
2604:                        if (localContentsOffset + 8 >= this .contents.length) {
2605:                            resizeContents(8);
2606:                        }
2607:                        this .contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
2608:                        this .contents[localContentsOffset++] = (byte) localVariableNameIndex;
2609:                        int localVariableTableOffset = localContentsOffset;
2610:                        localContentsOffset += 6;
2611:
2612:                        // leave space for attribute_length and local_variable_table_length
2613:                        int nameIndex;
2614:                        int descriptorIndex;
2615:
2616:                        // used to remember the local variable with a generic type
2617:                        int genericLocalVariablesCounter = 0;
2618:                        LocalVariableBinding[] genericLocalVariables = null;
2619:                        int numberOfGenericEntries = 0;
2620:
2621:                        for (int i = 0, max = codeStream.allLocalsCounter; i < max; i++) {
2622:                            LocalVariableBinding localVariable = codeStream.locals[i];
2623:                            if (localVariable.declaration == null)
2624:                                continue;
2625:                            final TypeBinding localVariableTypeBinding = localVariable.type;
2626:                            boolean isParameterizedType = localVariableTypeBinding
2627:                                    .isParameterizedType()
2628:                                    || localVariableTypeBinding
2629:                                            .isTypeVariable();
2630:                            if (localVariable.initializationCount != 0
2631:                                    && isParameterizedType) {
2632:                                if (genericLocalVariables == null) {
2633:                                    // we cannot have more than max locals
2634:                                    genericLocalVariables = new LocalVariableBinding[max];
2635:                                }
2636:                                genericLocalVariables[genericLocalVariablesCounter++] = localVariable;
2637:                            }
2638:                            for (int j = 0; j < localVariable.initializationCount; j++) {
2639:                                int startPC = localVariable.initializationPCs[j << 1];
2640:                                int endPC = localVariable.initializationPCs[(j << 1) + 1];
2641:                                if (startPC != endPC) { // only entries for non zero length
2642:                                    if (endPC == -1) {
2643:                                        localVariable.declaringScope
2644:                                                .problemReporter()
2645:                                                .abortDueToInternalError(
2646:                                                        Messages
2647:                                                                .bind(
2648:                                                                        Messages.abort_invalidAttribute,
2649:                                                                        new String(
2650:                                                                                localVariable.name)),
2651:                                                        (ASTNode) localVariable.declaringScope
2652:                                                                .methodScope().referenceContext);
2653:                                    }
2654:                                    if (localContentsOffset + 10 >= this .contents.length) {
2655:                                        resizeContents(10);
2656:                                    }
2657:                                    // now we can safely add the local entry
2658:                                    numberOfEntries++;
2659:                                    if (isParameterizedType) {
2660:                                        numberOfGenericEntries++;
2661:                                    }
2662:                                    this .contents[localContentsOffset++] = (byte) (startPC >> 8);
2663:                                    this .contents[localContentsOffset++] = (byte) startPC;
2664:                                    int length = endPC - startPC;
2665:                                    this .contents[localContentsOffset++] = (byte) (length >> 8);
2666:                                    this .contents[localContentsOffset++] = (byte) length;
2667:                                    nameIndex = constantPool
2668:                                            .literalIndex(localVariable.name);
2669:                                    this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
2670:                                    this .contents[localContentsOffset++] = (byte) nameIndex;
2671:                                    descriptorIndex = constantPool
2672:                                            .literalIndex(localVariableTypeBinding
2673:                                                    .signature());
2674:                                    this .contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
2675:                                    this .contents[localContentsOffset++] = (byte) descriptorIndex;
2676:                                    int resolvedPosition = localVariable.resolvedPosition;
2677:                                    this .contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
2678:                                    this .contents[localContentsOffset++] = (byte) resolvedPosition;
2679:                                }
2680:                            }
2681:                        }
2682:                        int value = numberOfEntries * 10 + 2;
2683:                        this .contents[localVariableTableOffset++] = (byte) (value >> 24);
2684:                        this .contents[localVariableTableOffset++] = (byte) (value >> 16);
2685:                        this .contents[localVariableTableOffset++] = (byte) (value >> 8);
2686:                        this .contents[localVariableTableOffset++] = (byte) value;
2687:                        this .contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
2688:                        this .contents[localVariableTableOffset] = (byte) numberOfEntries;
2689:                        attributeNumber++;
2690:
2691:                        if (genericLocalVariablesCounter != 0) {
2692:                            // add the local variable type table attribute
2693:                            // reserve enough space
2694:                            int maxOfEntries = 8 + numberOfGenericEntries * 10;
2695:
2696:                            if (localContentsOffset + maxOfEntries >= this .contents.length) {
2697:                                resizeContents(maxOfEntries);
2698:                            }
2699:                            int localVariableTypeNameIndex = constantPool
2700:                                    .literalIndex(AttributeNamesConstants.LocalVariableTypeTableName);
2701:                            this .contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8);
2702:                            this .contents[localContentsOffset++] = (byte) localVariableTypeNameIndex;
2703:                            value = numberOfGenericEntries * 10 + 2;
2704:                            this .contents[localContentsOffset++] = (byte) (value >> 24);
2705:                            this .contents[localContentsOffset++] = (byte) (value >> 16);
2706:                            this .contents[localContentsOffset++] = (byte) (value >> 8);
2707:                            this .contents[localContentsOffset++] = (byte) value;
2708:                            this .contents[localContentsOffset++] = (byte) (numberOfGenericEntries >> 8);
2709:                            this .contents[localContentsOffset++] = (byte) numberOfGenericEntries;
2710:                            for (int i = 0; i < genericLocalVariablesCounter; i++) {
2711:                                LocalVariableBinding localVariable = genericLocalVariables[i];
2712:                                for (int j = 0; j < localVariable.initializationCount; j++) {
2713:                                    int startPC = localVariable.initializationPCs[j << 1];
2714:                                    int endPC = localVariable.initializationPCs[(j << 1) + 1];
2715:                                    if (startPC != endPC) { // only entries for non zero length
2716:                                        // now we can safely add the local entry
2717:                                        this .contents[localContentsOffset++] = (byte) (startPC >> 8);
2718:                                        this .contents[localContentsOffset++] = (byte) startPC;
2719:                                        int length = endPC - startPC;
2720:                                        this .contents[localContentsOffset++] = (byte) (length >> 8);
2721:                                        this .contents[localContentsOffset++] = (byte) length;
2722:                                        nameIndex = constantPool
2723:                                                .literalIndex(localVariable.name);
2724:                                        this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
2725:                                        this .contents[localContentsOffset++] = (byte) nameIndex;
2726:                                        descriptorIndex = constantPool
2727:                                                .literalIndex(localVariable.type
2728:                                                        .genericTypeSignature());
2729:                                        this .contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
2730:                                        this .contents[localContentsOffset++] = (byte) descriptorIndex;
2731:                                        int resolvedPosition = localVariable.resolvedPosition;
2732:                                        this .contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
2733:                                        this .contents[localContentsOffset++] = (byte) resolvedPosition;
2734:                                    }
2735:                                }
2736:                            }
2737:                            attributeNumber++;
2738:                        }
2739:                    }
2740:                }
2741:
2742:                if ((this .produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
2743:                    StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
2744:                    stackMapFrameCodeStream.removeFramePosition(code_length);
2745:                    if (stackMapFrameCodeStream.hasFramePositions()) {
2746:                        ArrayList frames = new ArrayList();
2747:                        traverse(null, max_locals, this .contents,
2748:                                codeAttributeOffset + 14, code_length, frames,
2749:                                true);
2750:                        int numberOfFrames = frames.size();
2751:                        if (numberOfFrames > 1) {
2752:                            int stackMapTableAttributeOffset = localContentsOffset;
2753:                            // add the stack map table attribute
2754:                            if (localContentsOffset + 8 >= this .contents.length) {
2755:                                resizeContents(8);
2756:                            }
2757:                            int stackMapTableAttributeNameIndex = constantPool
2758:                                    .literalIndex(AttributeNamesConstants.StackMapTableName);
2759:                            this .contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
2760:                            this .contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
2761:
2762:                            int stackMapTableAttributeLengthOffset = localContentsOffset;
2763:                            // generate the attribute
2764:                            localContentsOffset += 4;
2765:                            if (localContentsOffset + 4 >= this .contents.length) {
2766:                                resizeContents(4);
2767:                            }
2768:                            int numberOfFramesOffset = localContentsOffset;
2769:                            localContentsOffset += 2;
2770:                            if (localContentsOffset + 2 >= this .contents.length) {
2771:                                resizeContents(2);
2772:                            }
2773:                            StackMapFrame currentFrame = (StackMapFrame) frames
2774:                                    .get(0);
2775:                            StackMapFrame prevFrame = null;
2776:                            for (int j = 1; j < numberOfFrames; j++) {
2777:                                // select next frame
2778:                                prevFrame = currentFrame;
2779:                                currentFrame = (StackMapFrame) frames.get(j);
2780:                                // generate current frame
2781:                                // need to find differences between the current frame and the previous frame
2782:                                int offsetDelta = currentFrame
2783:                                        .getOffsetDelta(prevFrame);
2784:                                switch (currentFrame.getFrameType(prevFrame)) {
2785:                                case StackMapFrame.APPEND_FRAME:
2786:                                    if (localContentsOffset + 3 >= this .contents.length) {
2787:                                        resizeContents(3);
2788:                                    }
2789:                                    int numberOfDifferentLocals = currentFrame
2790:                                            .numberOfDifferentLocals(prevFrame);
2791:                                    this .contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
2792:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
2793:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
2794:                                    int index = currentFrame
2795:                                            .getIndexOfDifferentLocals(numberOfDifferentLocals);
2796:                                    int numberOfLocals = currentFrame
2797:                                            .getNumberOfLocals();
2798:                                    for (int i = index; i < currentFrame.locals.length
2799:                                            && numberOfDifferentLocals > 0; i++) {
2800:                                        if (localContentsOffset + 6 >= this .contents.length) {
2801:                                            resizeContents(6);
2802:                                        }
2803:                                        VerificationTypeInfo info = currentFrame.locals[i];
2804:                                        if (info == null) {
2805:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
2806:                                        } else {
2807:                                            switch (info.id()) {
2808:                                            case T_boolean:
2809:                                            case T_byte:
2810:                                            case T_char:
2811:                                            case T_int:
2812:                                            case T_short:
2813:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
2814:                                                break;
2815:                                            case T_float:
2816:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
2817:                                                break;
2818:                                            case T_long:
2819:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
2820:                                                i++;
2821:                                                break;
2822:                                            case T_double:
2823:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
2824:                                                i++;
2825:                                                break;
2826:                                            case T_null:
2827:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
2828:                                                break;
2829:                                            default:
2830:                                                this .contents[localContentsOffset++] = (byte) info.tag;
2831:                                                switch (info.tag) {
2832:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
2833:                                                    int offset = info.offset;
2834:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
2835:                                                    this .contents[localContentsOffset++] = (byte) offset;
2836:                                                    break;
2837:                                                case VerificationTypeInfo.ITEM_OBJECT:
2838:                                                    int indexForType = constantPool
2839:                                                            .literalIndexForType(info
2840:                                                                    .constantPoolName());
2841:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
2842:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
2843:                                                }
2844:                                            }
2845:                                            numberOfDifferentLocals--;
2846:                                        }
2847:                                    }
2848:                                    break;
2849:                                case StackMapFrame.SAME_FRAME:
2850:                                    if (localContentsOffset + 1 >= this .contents.length) {
2851:                                        resizeContents(1);
2852:                                    }
2853:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
2854:                                    break;
2855:                                case StackMapFrame.SAME_FRAME_EXTENDED:
2856:                                    if (localContentsOffset + 3 >= this .contents.length) {
2857:                                        resizeContents(3);
2858:                                    }
2859:                                    this .contents[localContentsOffset++] = (byte) 251;
2860:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
2861:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
2862:                                    break;
2863:                                case StackMapFrame.CHOP_FRAME:
2864:                                    if (localContentsOffset + 3 >= this .contents.length) {
2865:                                        resizeContents(3);
2866:                                    }
2867:                                    numberOfDifferentLocals = -currentFrame
2868:                                            .numberOfDifferentLocals(prevFrame);
2869:                                    this .contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
2870:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
2871:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
2872:                                    break;
2873:                                case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS:
2874:                                    if (localContentsOffset + 4 >= this .contents.length) {
2875:                                        resizeContents(4);
2876:                                    }
2877:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta + 64);
2878:                                    if (currentFrame.stackItems[0] == null) {
2879:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
2880:                                    } else {
2881:                                        switch (currentFrame.stackItems[0].id()) {
2882:                                        case T_boolean:
2883:                                        case T_byte:
2884:                                        case T_char:
2885:                                        case T_int:
2886:                                        case T_short:
2887:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
2888:                                            break;
2889:                                        case T_float:
2890:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
2891:                                            break;
2892:                                        case T_long:
2893:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
2894:                                            break;
2895:                                        case T_double:
2896:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
2897:                                            break;
2898:                                        case T_null:
2899:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
2900:                                            break;
2901:                                        default:
2902:                                            VerificationTypeInfo info = currentFrame.stackItems[0];
2903:                                            byte tag = (byte) info.tag;
2904:                                            this .contents[localContentsOffset++] = tag;
2905:                                            switch (tag) {
2906:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
2907:                                                int offset = info.offset;
2908:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
2909:                                                this .contents[localContentsOffset++] = (byte) offset;
2910:                                                break;
2911:                                            case VerificationTypeInfo.ITEM_OBJECT:
2912:                                                int indexForType = constantPool
2913:                                                        .literalIndexForType(info
2914:                                                                .constantPoolName());
2915:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
2916:                                                this .contents[localContentsOffset++] = (byte) indexForType;
2917:                                            }
2918:                                        }
2919:                                    }
2920:                                    break;
2921:                                case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED:
2922:                                    if (localContentsOffset + 6 >= this .contents.length) {
2923:                                        resizeContents(6);
2924:                                    }
2925:                                    this .contents[localContentsOffset++] = (byte) 247;
2926:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
2927:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
2928:                                    if (currentFrame.stackItems[0] == null) {
2929:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
2930:                                    } else {
2931:                                        switch (currentFrame.stackItems[0].id()) {
2932:                                        case T_boolean:
2933:                                        case T_byte:
2934:                                        case T_char:
2935:                                        case T_int:
2936:                                        case T_short:
2937:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
2938:                                            break;
2939:                                        case T_float:
2940:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
2941:                                            break;
2942:                                        case T_long:
2943:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
2944:                                            break;
2945:                                        case T_double:
2946:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
2947:                                            break;
2948:                                        case T_null:
2949:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
2950:                                            break;
2951:                                        default:
2952:                                            VerificationTypeInfo info = currentFrame.stackItems[0];
2953:                                            byte tag = (byte) info.tag;
2954:                                            this .contents[localContentsOffset++] = tag;
2955:                                            switch (tag) {
2956:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
2957:                                                int offset = info.offset;
2958:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
2959:                                                this .contents[localContentsOffset++] = (byte) offset;
2960:                                                break;
2961:                                            case VerificationTypeInfo.ITEM_OBJECT:
2962:                                                int indexForType = constantPool
2963:                                                        .literalIndexForType(info
2964:                                                                .constantPoolName());
2965:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
2966:                                                this .contents[localContentsOffset++] = (byte) indexForType;
2967:                                            }
2968:                                        }
2969:                                    }
2970:                                    break;
2971:                                default:
2972:                                    // FULL_FRAME
2973:                                    if (localContentsOffset + 5 >= this .contents.length) {
2974:                                        resizeContents(5);
2975:                                    }
2976:                                    this .contents[localContentsOffset++] = (byte) 255;
2977:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
2978:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
2979:                                    int numberOfLocalOffset = localContentsOffset;
2980:                                    localContentsOffset += 2; // leave two spots for number of locals
2981:                                    int numberOfLocalEntries = 0;
2982:                                    numberOfLocals = currentFrame
2983:                                            .getNumberOfLocals();
2984:                                    int numberOfEntries = 0;
2985:                                    int localsLength = currentFrame.locals == null ? 0
2986:                                            : currentFrame.locals.length;
2987:                                    for (int i = 0; i < localsLength
2988:                                            && numberOfLocalEntries < numberOfLocals; i++) {
2989:                                        if (localContentsOffset + 3 >= this .contents.length) {
2990:                                            resizeContents(3);
2991:                                        }
2992:                                        VerificationTypeInfo info = currentFrame.locals[i];
2993:                                        if (info == null) {
2994:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
2995:                                        } else {
2996:                                            switch (info.id()) {
2997:                                            case T_boolean:
2998:                                            case T_byte:
2999:                                            case T_char:
3000:                                            case T_int:
3001:                                            case T_short:
3002:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
3003:                                                break;
3004:                                            case T_float:
3005:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
3006:                                                break;
3007:                                            case T_long:
3008:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
3009:                                                i++;
3010:                                                break;
3011:                                            case T_double:
3012:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
3013:                                                i++;
3014:                                                break;
3015:                                            case T_null:
3016:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
3017:                                                break;
3018:                                            default:
3019:                                                this .contents[localContentsOffset++] = (byte) info.tag;
3020:                                                switch (info.tag) {
3021:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
3022:                                                    int offset = info.offset;
3023:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
3024:                                                    this .contents[localContentsOffset++] = (byte) offset;
3025:                                                    break;
3026:                                                case VerificationTypeInfo.ITEM_OBJECT:
3027:                                                    int indexForType = constantPool
3028:                                                            .literalIndexForType(info
3029:                                                                    .constantPoolName());
3030:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
3031:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
3032:                                                }
3033:                                            }
3034:                                            numberOfLocalEntries++;
3035:                                        }
3036:                                        numberOfEntries++;
3037:                                    }
3038:                                    if (localContentsOffset + 4 >= this .contents.length) {
3039:                                        resizeContents(4);
3040:                                    }
3041:                                    this .contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
3042:                                    this .contents[numberOfLocalOffset] = (byte) numberOfEntries;
3043:                                    int numberOfStackItems = currentFrame.numberOfStackItems;
3044:                                    this .contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
3045:                                    this .contents[localContentsOffset++] = (byte) numberOfStackItems;
3046:                                    for (int i = 0; i < numberOfStackItems; i++) {
3047:                                        if (localContentsOffset + 3 >= this .contents.length) {
3048:                                            resizeContents(3);
3049:                                        }
3050:                                        VerificationTypeInfo info = currentFrame.stackItems[i];
3051:                                        if (info == null) {
3052:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
3053:                                        } else {
3054:                                            switch (info.id()) {
3055:                                            case T_boolean:
3056:                                            case T_byte:
3057:                                            case T_char:
3058:                                            case T_int:
3059:                                            case T_short:
3060:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
3061:                                                break;
3062:                                            case T_float:
3063:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
3064:                                                break;
3065:                                            case T_long:
3066:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
3067:                                                break;
3068:                                            case T_double:
3069:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
3070:                                                break;
3071:                                            case T_null:
3072:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
3073:                                                break;
3074:                                            default:
3075:                                                this .contents[localContentsOffset++] = (byte) info.tag;
3076:                                                switch (info.tag) {
3077:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
3078:                                                    int offset = info.offset;
3079:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
3080:                                                    this .contents[localContentsOffset++] = (byte) offset;
3081:                                                    break;
3082:                                                case VerificationTypeInfo.ITEM_OBJECT:
3083:                                                    int indexForType = constantPool
3084:                                                            .literalIndexForType(info
3085:                                                                    .constantPoolName());
3086:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
3087:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
3088:                                                }
3089:                                            }
3090:                                        }
3091:                                    }
3092:                                }
3093:                            }
3094:
3095:                            numberOfFrames--;
3096:                            if (numberOfFrames != 0) {
3097:                                this .contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
3098:                                this .contents[numberOfFramesOffset] = (byte) numberOfFrames;
3099:
3100:                                int attributeLength = localContentsOffset
3101:                                        - stackMapTableAttributeLengthOffset
3102:                                        - 4;
3103:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
3104:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
3105:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
3106:                                this .contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
3107:                                attributeNumber++;
3108:                            } else {
3109:                                localContentsOffset = stackMapTableAttributeOffset;
3110:                            }
3111:                        }
3112:                    }
3113:                }
3114:
3115:                if ((this .produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
3116:                    StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
3117:                    stackMapFrameCodeStream.removeFramePosition(code_length);
3118:                    if (stackMapFrameCodeStream.hasFramePositions()) {
3119:                        ArrayList frames = new ArrayList();
3120:                        traverse(this .codeStream.methodDeclaration.binding,
3121:                                max_locals, this .contents,
3122:                                codeAttributeOffset + 14, code_length, frames,
3123:                                false);
3124:                        int numberOfFrames = frames.size();
3125:                        if (numberOfFrames > 1) {
3126:                            int stackMapTableAttributeOffset = localContentsOffset;
3127:                            // add the stack map table attribute
3128:                            if (localContentsOffset + 8 >= this .contents.length) {
3129:                                resizeContents(8);
3130:                            }
3131:                            int stackMapAttributeNameIndex = constantPool
3132:                                    .literalIndex(AttributeNamesConstants.StackMapName);
3133:                            this .contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
3134:                            this .contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
3135:
3136:                            int stackMapAttributeLengthOffset = localContentsOffset;
3137:                            // generate the attribute
3138:                            localContentsOffset += 4;
3139:                            if (localContentsOffset + 4 >= this .contents.length) {
3140:                                resizeContents(4);
3141:                            }
3142:                            int numberOfFramesOffset = localContentsOffset;
3143:                            localContentsOffset += 2;
3144:                            if (localContentsOffset + 2 >= this .contents.length) {
3145:                                resizeContents(2);
3146:                            }
3147:                            StackMapFrame currentFrame = (StackMapFrame) frames
3148:                                    .get(0);
3149:                            for (int j = 1; j < numberOfFrames; j++) {
3150:                                // select next frame
3151:                                currentFrame = (StackMapFrame) frames.get(j);
3152:                                // generate current frame
3153:                                // need to find differences between the current frame and the previous frame
3154:                                int frameOffset = currentFrame.pc;
3155:                                // FULL_FRAME
3156:                                if (localContentsOffset + 5 >= this .contents.length) {
3157:                                    resizeContents(5);
3158:                                }
3159:                                this .contents[localContentsOffset++] = (byte) (frameOffset >> 8);
3160:                                this .contents[localContentsOffset++] = (byte) frameOffset;
3161:                                int numberOfLocalOffset = localContentsOffset;
3162:                                localContentsOffset += 2; // leave two spots for number of locals
3163:                                int numberOfLocalEntries = 0;
3164:                                int numberOfLocals = currentFrame
3165:                                        .getNumberOfLocals();
3166:                                int numberOfEntries = 0;
3167:                                int localsLength = currentFrame.locals == null ? 0
3168:                                        : currentFrame.locals.length;
3169:                                for (int i = 0; i < localsLength
3170:                                        && numberOfLocalEntries < numberOfLocals; i++) {
3171:                                    if (localContentsOffset + 3 >= this .contents.length) {
3172:                                        resizeContents(3);
3173:                                    }
3174:                                    VerificationTypeInfo info = currentFrame.locals[i];
3175:                                    if (info == null) {
3176:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
3177:                                    } else {
3178:                                        switch (info.id()) {
3179:                                        case T_boolean:
3180:                                        case T_byte:
3181:                                        case T_char:
3182:                                        case T_int:
3183:                                        case T_short:
3184:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
3185:                                            break;
3186:                                        case T_float:
3187:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
3188:                                            break;
3189:                                        case T_long:
3190:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
3191:                                            i++;
3192:                                            break;
3193:                                        case T_double:
3194:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
3195:                                            i++;
3196:                                            break;
3197:                                        case T_null:
3198:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
3199:                                            break;
3200:                                        default:
3201:                                            this .contents[localContentsOffset++] = (byte) info.tag;
3202:                                            switch (info.tag) {
3203:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
3204:                                                int offset = info.offset;
3205:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
3206:                                                this .contents[localContentsOffset++] = (byte) offset;
3207:                                                break;
3208:                                            case VerificationTypeInfo.ITEM_OBJECT:
3209:                                                int indexForType = constantPool
3210:                                                        .literalIndexForType(info
3211:                                                                .constantPoolName());
3212:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
3213:                                                this .contents[localContentsOffset++] = (byte) indexForType;
3214:                                            }
3215:                                        }
3216:                                        numberOfLocalEntries++;
3217:                                    }
3218:                                    numberOfEntries++;
3219:                                }
3220:                                if (localContentsOffset + 4 >= this .contents.length) {
3221:                                    resizeContents(4);
3222:                                }
3223:                                this .contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
3224:                                this .contents[numberOfLocalOffset] = (byte) numberOfEntries;
3225:                                int numberOfStackItems = currentFrame.numberOfStackItems;
3226:                                this .contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
3227:                                this .contents[localContentsOffset++] = (byte) numberOfStackItems;
3228:                                for (int i = 0; i < numberOfStackItems; i++) {
3229:                                    if (localContentsOffset + 3 >= this .contents.length) {
3230:                                        resizeContents(3);
3231:                                    }
3232:                                    VerificationTypeInfo info = currentFrame.stackItems[i];
3233:                                    if (info == null) {
3234:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
3235:                                    } else {
3236:                                        switch (info.id()) {
3237:                                        case T_boolean:
3238:                                        case T_byte:
3239:                                        case T_char:
3240:                                        case T_int:
3241:                                        case T_short:
3242:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
3243:                                            break;
3244:                                        case T_float:
3245:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
3246:                                            break;
3247:                                        case T_long:
3248:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
3249:                                            break;
3250:                                        case T_double:
3251:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
3252:                                            break;
3253:                                        case T_null:
3254:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
3255:                                            break;
3256:                                        default:
3257:                                            this .contents[localContentsOffset++] = (byte) info.tag;
3258:                                            switch (info.tag) {
3259:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
3260:                                                int offset = info.offset;
3261:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
3262:                                                this .contents[localContentsOffset++] = (byte) offset;
3263:                                                break;
3264:                                            case VerificationTypeInfo.ITEM_OBJECT:
3265:                                                int indexForType = constantPool
3266:                                                        .literalIndexForType(info
3267:                                                                .constantPoolName());
3268:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
3269:                                                this .contents[localContentsOffset++] = (byte) indexForType;
3270:                                            }
3271:                                        }
3272:                                    }
3273:                                }
3274:                            }
3275:
3276:                            numberOfFrames--;
3277:                            if (numberOfFrames != 0) {
3278:                                this .contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
3279:                                this .contents[numberOfFramesOffset] = (byte) numberOfFrames;
3280:
3281:                                int attributeLength = localContentsOffset
3282:                                        - stackMapAttributeLengthOffset - 4;
3283:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
3284:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
3285:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
3286:                                this .contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
3287:                                attributeNumber++;
3288:                            } else {
3289:                                localContentsOffset = stackMapTableAttributeOffset;
3290:                            }
3291:                        }
3292:                    }
3293:                }
3294:
3295:                // update the number of attributes
3296:                // ensure first that there is enough space available inside the contents array
3297:                if (codeAttributeAttributeOffset + 2 >= this .contents.length) {
3298:                    resizeContents(2);
3299:                }
3300:                this .contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
3301:                this .contents[codeAttributeAttributeOffset] = (byte) attributeNumber;
3302:                // update the attribute length
3303:                int codeAttributeLength = localContentsOffset
3304:                        - (codeAttributeOffset + 6);
3305:                this .contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
3306:                this .contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
3307:                this .contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
3308:                this .contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
3309:                contentsOffset = localContentsOffset;
3310:            }
3311:
3312:            /**
3313:             * INTERNAL USE-ONLY
3314:             * That method completes the creation of the code attribute by setting
3315:             * - the attribute_length
3316:             * - max_stack
3317:             * - max_locals
3318:             * - code_length
3319:             * - exception table
3320:             * - and debug attributes if necessary.
3321:             */
3322:            public void completeCodeAttributeForClinit(int codeAttributeOffset,
3323:                    int problemLine) {
3324:                // reinitialize the contents with the byte modified by the code stream
3325:                this .contents = codeStream.bCodeStream;
3326:                int localContentsOffset = codeStream.classFileOffset;
3327:                // codeAttributeOffset is the position inside contents byte array before we started to write
3328:                // any information about the codeAttribute
3329:                // That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
3330:                // to get the right position, 6 for the max_stack etc...
3331:                int code_length = codeStream.position;
3332:                if (code_length > 65535) {
3333:                    codeStream.methodDeclaration.scope.problemReporter()
3334:                            .bytecodeExceeds64KLimit(
3335:                                    codeStream.methodDeclaration.scope
3336:                                            .referenceType());
3337:                }
3338:                if (localContentsOffset + 20 >= this .contents.length) {
3339:                    resizeContents(20);
3340:                }
3341:                int max_stack = codeStream.stackMax;
3342:                this .contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
3343:                this .contents[codeAttributeOffset + 7] = (byte) max_stack;
3344:                int max_locals = codeStream.maxLocals;
3345:                this .contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
3346:                this .contents[codeAttributeOffset + 9] = (byte) max_locals;
3347:                this .contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
3348:                this .contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
3349:                this .contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
3350:                this .contents[codeAttributeOffset + 13] = (byte) code_length;
3351:
3352:                // write the exception table
3353:                this .contents[localContentsOffset++] = 0;
3354:                this .contents[localContentsOffset++] = 0;
3355:
3356:                // debug attributes
3357:                int codeAttributeAttributeOffset = localContentsOffset;
3358:                int attributeNumber = 0; // leave two bytes for the attribute_length
3359:                localContentsOffset += 2; // first we handle the linenumber attribute
3360:                if (localContentsOffset + 2 >= this .contents.length) {
3361:                    resizeContents(2);
3362:                }
3363:
3364:                // first we handle the linenumber attribute
3365:                if ((this .produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
3366:                    if (localContentsOffset + 20 >= this .contents.length) {
3367:                        resizeContents(20);
3368:                    }
3369:                    /* Create and add the line number attribute (used for debugging)
3370:                     * Build the pairs of:
3371:                     * (bytecodePC lineNumber)
3372:                     * according to the table of start line indexes and the pcToSourceMap table
3373:                     * contained into the codestream
3374:                     */
3375:                    int lineNumberNameIndex = constantPool
3376:                            .literalIndex(AttributeNamesConstants.LineNumberTableName);
3377:                    this .contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
3378:                    this .contents[localContentsOffset++] = (byte) lineNumberNameIndex;
3379:                    this .contents[localContentsOffset++] = 0;
3380:                    this .contents[localContentsOffset++] = 0;
3381:                    this .contents[localContentsOffset++] = 0;
3382:                    this .contents[localContentsOffset++] = 6;
3383:                    this .contents[localContentsOffset++] = 0;
3384:                    this .contents[localContentsOffset++] = 1;
3385:                    // first entry at pc = 0
3386:                    this .contents[localContentsOffset++] = 0;
3387:                    this .contents[localContentsOffset++] = 0;
3388:                    this .contents[localContentsOffset++] = (byte) (problemLine >> 8);
3389:                    this .contents[localContentsOffset++] = (byte) problemLine;
3390:                    // now we change the size of the line number attribute
3391:                    attributeNumber++;
3392:                }
3393:                // then we do the local variable attribute
3394:                if ((this .produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
3395:                    int localVariableNameIndex = constantPool
3396:                            .literalIndex(AttributeNamesConstants.LocalVariableTableName);
3397:                    if (localContentsOffset + 8 >= this .contents.length) {
3398:                        resizeContents(8);
3399:                    }
3400:                    this .contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
3401:                    this .contents[localContentsOffset++] = (byte) localVariableNameIndex;
3402:                    this .contents[localContentsOffset++] = 0;
3403:                    this .contents[localContentsOffset++] = 0;
3404:                    this .contents[localContentsOffset++] = 0;
3405:                    this .contents[localContentsOffset++] = 2;
3406:                    this .contents[localContentsOffset++] = 0;
3407:                    this .contents[localContentsOffset++] = 0;
3408:                    attributeNumber++;
3409:                }
3410:
3411:                if ((this .produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
3412:                    StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
3413:                    stackMapFrameCodeStream.removeFramePosition(code_length);
3414:                    if (stackMapFrameCodeStream.hasFramePositions()) {
3415:                        ArrayList frames = new ArrayList();
3416:                        traverse(null, max_locals, this .contents,
3417:                                codeAttributeOffset + 14, code_length, frames,
3418:                                true);
3419:                        int numberOfFrames = frames.size();
3420:                        if (numberOfFrames > 1) {
3421:                            int stackMapTableAttributeOffset = localContentsOffset;
3422:                            // add the stack map table attribute
3423:                            if (localContentsOffset + 8 >= this .contents.length) {
3424:                                resizeContents(8);
3425:                            }
3426:                            int stackMapTableAttributeNameIndex = constantPool
3427:                                    .literalIndex(AttributeNamesConstants.StackMapTableName);
3428:                            this .contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
3429:                            this .contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
3430:
3431:                            int stackMapTableAttributeLengthOffset = localContentsOffset;
3432:                            // generate the attribute
3433:                            localContentsOffset += 4;
3434:                            if (localContentsOffset + 4 >= this .contents.length) {
3435:                                resizeContents(4);
3436:                            }
3437:                            numberOfFrames = 0;
3438:                            int numberOfFramesOffset = localContentsOffset;
3439:                            localContentsOffset += 2;
3440:                            if (localContentsOffset + 2 >= this .contents.length) {
3441:                                resizeContents(2);
3442:                            }
3443:                            StackMapFrame currentFrame = (StackMapFrame) frames
3444:                                    .get(0);
3445:                            StackMapFrame prevFrame = null;
3446:                            for (int j = 1; j < numberOfFrames; j++) {
3447:                                // select next frame
3448:                                prevFrame = currentFrame;
3449:                                currentFrame = (StackMapFrame) frames.get(j);
3450:                                // generate current frame
3451:                                // need to find differences between the current frame and the previous frame
3452:                                numberOfFrames++;
3453:                                int offsetDelta = currentFrame
3454:                                        .getOffsetDelta(prevFrame);
3455:                                switch (currentFrame.getFrameType(prevFrame)) {
3456:                                case StackMapFrame.APPEND_FRAME:
3457:                                    if (localContentsOffset + 3 >= this .contents.length) {
3458:                                        resizeContents(3);
3459:                                    }
3460:                                    int numberOfDifferentLocals = currentFrame
3461:                                            .numberOfDifferentLocals(prevFrame);
3462:                                    this .contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
3463:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
3464:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
3465:                                    int index = currentFrame
3466:                                            .getIndexOfDifferentLocals(numberOfDifferentLocals);
3467:                                    int numberOfLocals = currentFrame
3468:                                            .getNumberOfLocals();
3469:                                    for (int i = index; i < currentFrame.locals.length
3470:                                            && numberOfDifferentLocals > 0; i++) {
3471:                                        if (localContentsOffset + 6 >= this .contents.length) {
3472:                                            resizeContents(6);
3473:                                        }
3474:                                        VerificationTypeInfo info = currentFrame.locals[i];
3475:                                        if (info == null) {
3476:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
3477:                                        } else {
3478:                                            switch (info.id()) {
3479:                                            case T_boolean:
3480:                                            case T_byte:
3481:                                            case T_char:
3482:                                            case T_int:
3483:                                            case T_short:
3484:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
3485:                                                break;
3486:                                            case T_float:
3487:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
3488:                                                break;
3489:                                            case T_long:
3490:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
3491:                                                i++;
3492:                                                break;
3493:                                            case T_double:
3494:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
3495:                                                i++;
3496:                                                break;
3497:                                            case T_null:
3498:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
3499:                                                break;
3500:                                            default:
3501:                                                this .contents[localContentsOffset++] = (byte) info.tag;
3502:                                                switch (info.tag) {
3503:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
3504:                                                    int offset = info.offset;
3505:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
3506:                                                    this .contents[localContentsOffset++] = (byte) offset;
3507:                                                    break;
3508:                                                case VerificationTypeInfo.ITEM_OBJECT:
3509:                                                    int indexForType = constantPool
3510:                                                            .literalIndexForType(info
3511:                                                                    .constantPoolName());
3512:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
3513:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
3514:                                                }
3515:                                            }
3516:                                            numberOfDifferentLocals--;
3517:                                        }
3518:                                    }
3519:                                    break;
3520:                                case StackMapFrame.SAME_FRAME:
3521:                                    if (localContentsOffset + 1 >= this .contents.length) {
3522:                                        resizeContents(1);
3523:                                    }
3524:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
3525:                                    break;
3526:                                case StackMapFrame.SAME_FRAME_EXTENDED:
3527:                                    if (localContentsOffset + 3 >= this .contents.length) {
3528:                                        resizeContents(3);
3529:                                    }
3530:                                    this .contents[localContentsOffset++] = (byte) 251;
3531:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
3532:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
3533:                                    break;
3534:                                case StackMapFrame.CHOP_FRAME:
3535:                                    if (localContentsOffset + 3 >= this .contents.length) {
3536:                                        resizeContents(3);
3537:                                    }
3538:                                    numberOfDifferentLocals = -currentFrame
3539:                                            .numberOfDifferentLocals(prevFrame);
3540:                                    this .contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
3541:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
3542:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
3543:                                    break;
3544:                                case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS:
3545:                                    if (localContentsOffset + 4 >= this .contents.length) {
3546:                                        resizeContents(4);
3547:                                    }
3548:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta + 64);
3549:                                    if (currentFrame.stackItems[0] == null) {
3550:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
3551:                                    } else {
3552:                                        switch (currentFrame.stackItems[0].id()) {
3553:                                        case T_boolean:
3554:                                        case T_byte:
3555:                                        case T_char:
3556:                                        case T_int:
3557:                                        case T_short:
3558:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
3559:                                            break;
3560:                                        case T_float:
3561:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
3562:                                            break;
3563:                                        case T_long:
3564:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
3565:                                            break;
3566:                                        case T_double:
3567:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
3568:                                            break;
3569:                                        case T_null:
3570:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
3571:                                            break;
3572:                                        default:
3573:                                            VerificationTypeInfo info = currentFrame.stackItems[0];
3574:                                            byte tag = (byte) info.tag;
3575:                                            this .contents[localContentsOffset++] = tag;
3576:                                            switch (tag) {
3577:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
3578:                                                int offset = info.offset;
3579:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
3580:                                                this .contents[localContentsOffset++] = (byte) offset;
3581:                                                break;
3582:                                            case VerificationTypeInfo.ITEM_OBJECT:
3583:                                                int indexForType = constantPool
3584:                                                        .literalIndexForType(info
3585:                                                                .constantPoolName());
3586:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
3587:                                                this .contents[localContentsOffset++] = (byte) indexForType;
3588:                                            }
3589:                                        }
3590:                                    }
3591:                                    break;
3592:                                case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED:
3593:                                    if (localContentsOffset + 6 >= this .contents.length) {
3594:                                        resizeContents(6);
3595:                                    }
3596:                                    this .contents[localContentsOffset++] = (byte) 247;
3597:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
3598:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
3599:                                    if (currentFrame.stackItems[0] == null) {
3600:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
3601:                                    } else {
3602:                                        switch (currentFrame.stackItems[0].id()) {
3603:                                        case T_boolean:
3604:                                        case T_byte:
3605:                                        case T_char:
3606:                                        case T_int:
3607:                                        case T_short:
3608:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
3609:                                            break;
3610:                                        case T_float:
3611:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
3612:                                            break;
3613:                                        case T_long:
3614:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
3615:                                            break;
3616:                                        case T_double:
3617:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
3618:                                            break;
3619:                                        case T_null:
3620:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
3621:                                            break;
3622:                                        default:
3623:                                            VerificationTypeInfo info = currentFrame.stackItems[0];
3624:                                            byte tag = (byte) info.tag;
3625:                                            this .contents[localContentsOffset++] = tag;
3626:                                            switch (tag) {
3627:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
3628:                                                int offset = info.offset;
3629:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
3630:                                                this .contents[localContentsOffset++] = (byte) offset;
3631:                                                break;
3632:                                            case VerificationTypeInfo.ITEM_OBJECT:
3633:                                                int indexForType = constantPool
3634:                                                        .literalIndexForType(info
3635:                                                                .constantPoolName());
3636:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
3637:                                                this .contents[localContentsOffset++] = (byte) indexForType;
3638:                                            }
3639:                                        }
3640:                                    }
3641:                                    break;
3642:                                default:
3643:                                    // FULL_FRAME
3644:                                    if (localContentsOffset + 5 >= this .contents.length) {
3645:                                        resizeContents(5);
3646:                                    }
3647:                                    this .contents[localContentsOffset++] = (byte) 255;
3648:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
3649:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
3650:                                    int numberOfLocalOffset = localContentsOffset;
3651:                                    localContentsOffset += 2; // leave two spots for number of locals
3652:                                    int numberOfLocalEntries = 0;
3653:                                    numberOfLocals = currentFrame
3654:                                            .getNumberOfLocals();
3655:                                    int numberOfEntries = 0;
3656:                                    int localsLength = currentFrame.locals == null ? 0
3657:                                            : currentFrame.locals.length;
3658:                                    for (int i = 0; i < localsLength
3659:                                            && numberOfLocalEntries < numberOfLocals; i++) {
3660:                                        if (localContentsOffset + 3 >= this .contents.length) {
3661:                                            resizeContents(3);
3662:                                        }
3663:                                        VerificationTypeInfo info = currentFrame.locals[i];
3664:                                        if (info == null) {
3665:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
3666:                                        } else {
3667:                                            switch (info.id()) {
3668:                                            case T_boolean:
3669:                                            case T_byte:
3670:                                            case T_char:
3671:                                            case T_int:
3672:                                            case T_short:
3673:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
3674:                                                break;
3675:                                            case T_float:
3676:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
3677:                                                break;
3678:                                            case T_long:
3679:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
3680:                                                i++;
3681:                                                break;
3682:                                            case T_double:
3683:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
3684:                                                i++;
3685:                                                break;
3686:                                            case T_null:
3687:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
3688:                                                break;
3689:                                            default:
3690:                                                this .contents[localContentsOffset++] = (byte) info.tag;
3691:                                                switch (info.tag) {
3692:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
3693:                                                    int offset = info.offset;
3694:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
3695:                                                    this .contents[localContentsOffset++] = (byte) offset;
3696:                                                    break;
3697:                                                case VerificationTypeInfo.ITEM_OBJECT:
3698:                                                    int indexForType = constantPool
3699:                                                            .literalIndexForType(info
3700:                                                                    .constantPoolName());
3701:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
3702:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
3703:                                                }
3704:                                            }
3705:                                            numberOfLocalEntries++;
3706:                                        }
3707:                                        numberOfEntries++;
3708:                                    }
3709:                                    if (localContentsOffset + 4 >= this .contents.length) {
3710:                                        resizeContents(4);
3711:                                    }
3712:                                    this .contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
3713:                                    this .contents[numberOfLocalOffset] = (byte) numberOfEntries;
3714:                                    int numberOfStackItems = currentFrame.numberOfStackItems;
3715:                                    this .contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
3716:                                    this .contents[localContentsOffset++] = (byte) numberOfStackItems;
3717:                                    for (int i = 0; i < numberOfStackItems; i++) {
3718:                                        if (localContentsOffset + 3 >= this .contents.length) {
3719:                                            resizeContents(3);
3720:                                        }
3721:                                        VerificationTypeInfo info = currentFrame.stackItems[i];
3722:                                        if (info == null) {
3723:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
3724:                                        } else {
3725:                                            switch (info.id()) {
3726:                                            case T_boolean:
3727:                                            case T_byte:
3728:                                            case T_char:
3729:                                            case T_int:
3730:                                            case T_short:
3731:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
3732:                                                break;
3733:                                            case T_float:
3734:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
3735:                                                break;
3736:                                            case T_long:
3737:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
3738:                                                break;
3739:                                            case T_double:
3740:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
3741:                                                break;
3742:                                            case T_null:
3743:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
3744:                                                break;
3745:                                            default:
3746:                                                this .contents[localContentsOffset++] = (byte) info.tag;
3747:                                                switch (info.tag) {
3748:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
3749:                                                    int offset = info.offset;
3750:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
3751:                                                    this .contents[localContentsOffset++] = (byte) offset;
3752:                                                    break;
3753:                                                case VerificationTypeInfo.ITEM_OBJECT:
3754:                                                    int indexForType = constantPool
3755:                                                            .literalIndexForType(info
3756:                                                                    .constantPoolName());
3757:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
3758:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
3759:                                                }
3760:                                            }
3761:                                        }
3762:                                    }
3763:                                }
3764:                            }
3765:
3766:                            if (numberOfFrames != 0) {
3767:                                this .contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
3768:                                this .contents[numberOfFramesOffset] = (byte) numberOfFrames;
3769:
3770:                                int attributeLength = localContentsOffset
3771:                                        - stackMapTableAttributeLengthOffset
3772:                                        - 4;
3773:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
3774:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
3775:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
3776:                                this .contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
3777:                                attributeNumber++;
3778:                            } else {
3779:                                localContentsOffset = stackMapTableAttributeOffset;
3780:                            }
3781:                        }
3782:                    }
3783:                }
3784:
3785:                if ((this .produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
3786:                    StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
3787:                    stackMapFrameCodeStream.removeFramePosition(code_length);
3788:                    if (stackMapFrameCodeStream.hasFramePositions()) {
3789:                        ArrayList frames = new ArrayList();
3790:                        traverse(this .codeStream.methodDeclaration.binding,
3791:                                max_locals, this .contents,
3792:                                codeAttributeOffset + 14, code_length, frames,
3793:                                false);
3794:                        int numberOfFrames = frames.size();
3795:                        if (numberOfFrames > 1) {
3796:                            int stackMapTableAttributeOffset = localContentsOffset;
3797:                            // add the stack map table attribute
3798:                            if (localContentsOffset + 8 >= this .contents.length) {
3799:                                resizeContents(8);
3800:                            }
3801:                            int stackMapAttributeNameIndex = constantPool
3802:                                    .literalIndex(AttributeNamesConstants.StackMapName);
3803:                            this .contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
3804:                            this .contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
3805:
3806:                            int stackMapAttributeLengthOffset = localContentsOffset;
3807:                            // generate the attribute
3808:                            localContentsOffset += 4;
3809:                            if (localContentsOffset + 4 >= this .contents.length) {
3810:                                resizeContents(4);
3811:                            }
3812:                            int numberOfFramesOffset = localContentsOffset;
3813:                            localContentsOffset += 2;
3814:                            if (localContentsOffset + 2 >= this .contents.length) {
3815:                                resizeContents(2);
3816:                            }
3817:                            StackMapFrame currentFrame = (StackMapFrame) frames
3818:                                    .get(0);
3819:                            for (int j = 1; j < numberOfFrames; j++) {
3820:                                // select next frame
3821:                                currentFrame = (StackMapFrame) frames.get(j);
3822:                                // generate current frame
3823:                                // need to find differences between the current frame and the previous frame
3824:                                int frameOffset = currentFrame.pc;
3825:                                // FULL_FRAME
3826:                                if (localContentsOffset + 5 >= this .contents.length) {
3827:                                    resizeContents(5);
3828:                                }
3829:                                this .contents[localContentsOffset++] = (byte) (frameOffset >> 8);
3830:                                this .contents[localContentsOffset++] = (byte) frameOffset;
3831:                                int numberOfLocalOffset = localContentsOffset;
3832:                                localContentsOffset += 2; // leave two spots for number of locals
3833:                                int numberOfLocalEntries = 0;
3834:                                int numberOfLocals = currentFrame
3835:                                        .getNumberOfLocals();
3836:                                int numberOfEntries = 0;
3837:                                int localsLength = currentFrame.locals == null ? 0
3838:                                        : currentFrame.locals.length;
3839:                                for (int i = 0; i < localsLength
3840:                                        && numberOfLocalEntries < numberOfLocals; i++) {
3841:                                    if (localContentsOffset + 3 >= this .contents.length) {
3842:                                        resizeContents(3);
3843:                                    }
3844:                                    VerificationTypeInfo info = currentFrame.locals[i];
3845:                                    if (info == null) {
3846:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
3847:                                    } else {
3848:                                        switch (info.id()) {
3849:                                        case T_boolean:
3850:                                        case T_byte:
3851:                                        case T_char:
3852:                                        case T_int:
3853:                                        case T_short:
3854:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
3855:                                            break;
3856:                                        case T_float:
3857:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
3858:                                            break;
3859:                                        case T_long:
3860:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
3861:                                            i++;
3862:                                            break;
3863:                                        case T_double:
3864:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
3865:                                            i++;
3866:                                            break;
3867:                                        case T_null:
3868:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
3869:                                            break;
3870:                                        default:
3871:                                            this .contents[localContentsOffset++] = (byte) info.tag;
3872:                                            switch (info.tag) {
3873:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
3874:                                                int offset = info.offset;
3875:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
3876:                                                this .contents[localContentsOffset++] = (byte) offset;
3877:                                                break;
3878:                                            case VerificationTypeInfo.ITEM_OBJECT:
3879:                                                int indexForType = constantPool
3880:                                                        .literalIndexForType(info
3881:                                                                .constantPoolName());
3882:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
3883:                                                this .contents[localContentsOffset++] = (byte) indexForType;
3884:                                            }
3885:                                        }
3886:                                        numberOfLocalEntries++;
3887:                                    }
3888:                                    numberOfEntries++;
3889:                                }
3890:                                if (localContentsOffset + 4 >= this .contents.length) {
3891:                                    resizeContents(4);
3892:                                }
3893:                                this .contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
3894:                                this .contents[numberOfLocalOffset] = (byte) numberOfEntries;
3895:                                int numberOfStackItems = currentFrame.numberOfStackItems;
3896:                                this .contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
3897:                                this .contents[localContentsOffset++] = (byte) numberOfStackItems;
3898:                                for (int i = 0; i < numberOfStackItems; i++) {
3899:                                    if (localContentsOffset + 3 >= this .contents.length) {
3900:                                        resizeContents(3);
3901:                                    }
3902:                                    VerificationTypeInfo info = currentFrame.stackItems[i];
3903:                                    if (info == null) {
3904:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
3905:                                    } else {
3906:                                        switch (info.id()) {
3907:                                        case T_boolean:
3908:                                        case T_byte:
3909:                                        case T_char:
3910:                                        case T_int:
3911:                                        case T_short:
3912:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
3913:                                            break;
3914:                                        case T_float:
3915:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
3916:                                            break;
3917:                                        case T_long:
3918:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
3919:                                            break;
3920:                                        case T_double:
3921:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
3922:                                            break;
3923:                                        case T_null:
3924:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
3925:                                            break;
3926:                                        default:
3927:                                            this .contents[localContentsOffset++] = (byte) info.tag;
3928:                                            switch (info.tag) {
3929:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
3930:                                                int offset = info.offset;
3931:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
3932:                                                this .contents[localContentsOffset++] = (byte) offset;
3933:                                                break;
3934:                                            case VerificationTypeInfo.ITEM_OBJECT:
3935:                                                int indexForType = constantPool
3936:                                                        .literalIndexForType(info
3937:                                                                .constantPoolName());
3938:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
3939:                                                this .contents[localContentsOffset++] = (byte) indexForType;
3940:                                            }
3941:                                        }
3942:                                    }
3943:                                }
3944:                            }
3945:
3946:                            numberOfFrames--;
3947:                            if (numberOfFrames != 0) {
3948:                                this .contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
3949:                                this .contents[numberOfFramesOffset] = (byte) numberOfFrames;
3950:
3951:                                int attributeLength = localContentsOffset
3952:                                        - stackMapAttributeLengthOffset - 4;
3953:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
3954:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
3955:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
3956:                                this .contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
3957:                                attributeNumber++;
3958:                            } else {
3959:                                localContentsOffset = stackMapTableAttributeOffset;
3960:                            }
3961:                        }
3962:                    }
3963:                }
3964:
3965:                // update the number of attributes
3966:                // ensure first that there is enough space available inside the contents array
3967:                if (codeAttributeAttributeOffset + 2 >= this .contents.length) {
3968:                    resizeContents(2);
3969:                }
3970:                this .contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
3971:                this .contents[codeAttributeAttributeOffset] = (byte) attributeNumber;
3972:                // update the attribute length
3973:                int codeAttributeLength = localContentsOffset
3974:                        - (codeAttributeOffset + 6);
3975:                this .contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
3976:                this .contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
3977:                this .contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
3978:                this .contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
3979:                contentsOffset = localContentsOffset;
3980:            }
3981:
3982:            /**
3983:             *
3984:             */
3985:            public void completeCodeAttributeForMissingAbstractProblemMethod(
3986:                    MethodBinding binding, int codeAttributeOffset,
3987:                    int[] startLineIndexes, int problemLine) {
3988:                // reinitialize the localContents with the byte modified by the code stream
3989:                this .contents = codeStream.bCodeStream;
3990:                int localContentsOffset = codeStream.classFileOffset;
3991:                // codeAttributeOffset is the position inside localContents byte array before we started to write// any information about the codeAttribute// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset// to get the right position, 6 for the max_stack etc...
3992:                int max_stack = codeStream.stackMax;
3993:                this .contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
3994:                this .contents[codeAttributeOffset + 7] = (byte) max_stack;
3995:                int max_locals = codeStream.maxLocals;
3996:                this .contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
3997:                this .contents[codeAttributeOffset + 9] = (byte) max_locals;
3998:                int code_length = codeStream.position;
3999:                this .contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
4000:                this .contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
4001:                this .contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
4002:                this .contents[codeAttributeOffset + 13] = (byte) code_length;
4003:                // write the exception table
4004:                if (localContentsOffset + 50 >= this .contents.length) {
4005:                    resizeContents(50);
4006:                }
4007:                this .contents[localContentsOffset++] = 0;
4008:                this .contents[localContentsOffset++] = 0;
4009:                // debug attributes
4010:                int codeAttributeAttributeOffset = localContentsOffset;
4011:                int attributeNumber = 0; // leave two bytes for the attribute_length
4012:                localContentsOffset += 2; // first we handle the linenumber attribute
4013:                if (localContentsOffset + 2 >= this .contents.length) {
4014:                    resizeContents(2);
4015:                }
4016:
4017:                if ((this .produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
4018:                    if (localContentsOffset + 12 >= this .contents.length) {
4019:                        resizeContents(12);
4020:                    }
4021:                    /* Create and add the line number attribute (used for debugging)
4022:                     * Build the pairs of:
4023:                     * (bytecodePC lineNumber)
4024:                     * according to the table of start line indexes and the pcToSourceMap table
4025:                     * contained into the codestream
4026:                     */
4027:                    int lineNumberNameIndex = constantPool
4028:                            .literalIndex(AttributeNamesConstants.LineNumberTableName);
4029:                    this .contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
4030:                    this .contents[localContentsOffset++] = (byte) lineNumberNameIndex;
4031:                    this .contents[localContentsOffset++] = 0;
4032:                    this .contents[localContentsOffset++] = 0;
4033:                    this .contents[localContentsOffset++] = 0;
4034:                    this .contents[localContentsOffset++] = 6;
4035:                    this .contents[localContentsOffset++] = 0;
4036:                    this .contents[localContentsOffset++] = 1;
4037:                    if (problemLine == 0) {
4038:                        problemLine = Util.getLineNumber(binding.sourceStart(),
4039:                                startLineIndexes, 0,
4040:                                startLineIndexes.length - 1);
4041:                    }
4042:                    // first entry at pc = 0
4043:                    this .contents[localContentsOffset++] = 0;
4044:                    this .contents[localContentsOffset++] = 0;
4045:                    this .contents[localContentsOffset++] = (byte) (problemLine >> 8);
4046:                    this .contents[localContentsOffset++] = (byte) problemLine;
4047:                    // now we change the size of the line number attribute
4048:                    attributeNumber++;
4049:                }
4050:
4051:                if ((this .produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
4052:                    StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
4053:                    stackMapFrameCodeStream.removeFramePosition(code_length);
4054:                    if (stackMapFrameCodeStream.hasFramePositions()) {
4055:                        ArrayList frames = new ArrayList();
4056:                        traverse(binding, max_locals, this .contents,
4057:                                codeAttributeOffset + 14, code_length, frames,
4058:                                false);
4059:                        int numberOfFrames = frames.size();
4060:                        if (numberOfFrames > 1) {
4061:                            int stackMapTableAttributeOffset = localContentsOffset;
4062:                            // add the stack map table attribute
4063:                            if (localContentsOffset + 8 >= this .contents.length) {
4064:                                resizeContents(8);
4065:                            }
4066:                            int stackMapTableAttributeNameIndex = constantPool
4067:                                    .literalIndex(AttributeNamesConstants.StackMapTableName);
4068:                            this .contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
4069:                            this .contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
4070:
4071:                            int stackMapTableAttributeLengthOffset = localContentsOffset;
4072:                            // generate the attribute
4073:                            localContentsOffset += 4;
4074:                            if (localContentsOffset + 4 >= this .contents.length) {
4075:                                resizeContents(4);
4076:                            }
4077:                            numberOfFrames = 0;
4078:                            int numberOfFramesOffset = localContentsOffset;
4079:                            localContentsOffset += 2;
4080:                            if (localContentsOffset + 2 >= this .contents.length) {
4081:                                resizeContents(2);
4082:                            }
4083:                            StackMapFrame currentFrame = (StackMapFrame) frames
4084:                                    .get(0);
4085:                            StackMapFrame prevFrame = null;
4086:                            for (int j = 1; j < numberOfFrames; j++) {
4087:                                // select next frame
4088:                                prevFrame = currentFrame;
4089:                                currentFrame = (StackMapFrame) frames.get(j);
4090:                                // generate current frame
4091:                                // need to find differences between the current frame and the previous frame
4092:                                numberOfFrames++;
4093:                                int offsetDelta = currentFrame
4094:                                        .getOffsetDelta(prevFrame);
4095:                                switch (currentFrame.getFrameType(prevFrame)) {
4096:                                case StackMapFrame.APPEND_FRAME:
4097:                                    if (localContentsOffset + 3 >= this .contents.length) {
4098:                                        resizeContents(3);
4099:                                    }
4100:                                    int numberOfDifferentLocals = currentFrame
4101:                                            .numberOfDifferentLocals(prevFrame);
4102:                                    this .contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
4103:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
4104:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
4105:                                    int index = currentFrame
4106:                                            .getIndexOfDifferentLocals(numberOfDifferentLocals);
4107:                                    int numberOfLocals = currentFrame
4108:                                            .getNumberOfLocals();
4109:                                    for (int i = index; i < currentFrame.locals.length
4110:                                            && numberOfDifferentLocals > 0; i++) {
4111:                                        if (localContentsOffset + 6 >= this .contents.length) {
4112:                                            resizeContents(6);
4113:                                        }
4114:                                        VerificationTypeInfo info = currentFrame.locals[i];
4115:                                        if (info == null) {
4116:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
4117:                                        } else {
4118:                                            switch (info.id()) {
4119:                                            case T_boolean:
4120:                                            case T_byte:
4121:                                            case T_char:
4122:                                            case T_int:
4123:                                            case T_short:
4124:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
4125:                                                break;
4126:                                            case T_float:
4127:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
4128:                                                break;
4129:                                            case T_long:
4130:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
4131:                                                i++;
4132:                                                break;
4133:                                            case T_double:
4134:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
4135:                                                i++;
4136:                                                break;
4137:                                            case T_null:
4138:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
4139:                                                break;
4140:                                            default:
4141:                                                this .contents[localContentsOffset++] = (byte) info.tag;
4142:                                                switch (info.tag) {
4143:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
4144:                                                    int offset = info.offset;
4145:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
4146:                                                    this .contents[localContentsOffset++] = (byte) offset;
4147:                                                    break;
4148:                                                case VerificationTypeInfo.ITEM_OBJECT:
4149:                                                    int indexForType = constantPool
4150:                                                            .literalIndexForType(info
4151:                                                                    .constantPoolName());
4152:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
4153:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
4154:                                                }
4155:                                            }
4156:                                            numberOfDifferentLocals--;
4157:                                        }
4158:                                    }
4159:                                    break;
4160:                                case StackMapFrame.SAME_FRAME:
4161:                                    if (localContentsOffset + 1 >= this .contents.length) {
4162:                                        resizeContents(1);
4163:                                    }
4164:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
4165:                                    break;
4166:                                case StackMapFrame.SAME_FRAME_EXTENDED:
4167:                                    if (localContentsOffset + 3 >= this .contents.length) {
4168:                                        resizeContents(3);
4169:                                    }
4170:                                    this .contents[localContentsOffset++] = (byte) 251;
4171:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
4172:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
4173:                                    break;
4174:                                case StackMapFrame.CHOP_FRAME:
4175:                                    if (localContentsOffset + 3 >= this .contents.length) {
4176:                                        resizeContents(3);
4177:                                    }
4178:                                    numberOfDifferentLocals = -currentFrame
4179:                                            .numberOfDifferentLocals(prevFrame);
4180:                                    this .contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
4181:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
4182:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
4183:                                    break;
4184:                                case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS:
4185:                                    if (localContentsOffset + 4 >= this .contents.length) {
4186:                                        resizeContents(4);
4187:                                    }
4188:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta + 64);
4189:                                    if (currentFrame.stackItems[0] == null) {
4190:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
4191:                                    } else {
4192:                                        switch (currentFrame.stackItems[0].id()) {
4193:                                        case T_boolean:
4194:                                        case T_byte:
4195:                                        case T_char:
4196:                                        case T_int:
4197:                                        case T_short:
4198:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
4199:                                            break;
4200:                                        case T_float:
4201:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
4202:                                            break;
4203:                                        case T_long:
4204:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
4205:                                            break;
4206:                                        case T_double:
4207:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
4208:                                            break;
4209:                                        case T_null:
4210:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
4211:                                            break;
4212:                                        default:
4213:                                            VerificationTypeInfo info = currentFrame.stackItems[0];
4214:                                            byte tag = (byte) info.tag;
4215:                                            this .contents[localContentsOffset++] = tag;
4216:                                            switch (tag) {
4217:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
4218:                                                int offset = info.offset;
4219:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
4220:                                                this .contents[localContentsOffset++] = (byte) offset;
4221:                                                break;
4222:                                            case VerificationTypeInfo.ITEM_OBJECT:
4223:                                                int indexForType = constantPool
4224:                                                        .literalIndexForType(info
4225:                                                                .constantPoolName());
4226:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
4227:                                                this .contents[localContentsOffset++] = (byte) indexForType;
4228:                                            }
4229:                                        }
4230:                                    }
4231:                                    break;
4232:                                case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED:
4233:                                    if (localContentsOffset + 6 >= this .contents.length) {
4234:                                        resizeContents(6);
4235:                                    }
4236:                                    this .contents[localContentsOffset++] = (byte) 247;
4237:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
4238:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
4239:                                    if (currentFrame.stackItems[0] == null) {
4240:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
4241:                                    } else {
4242:                                        switch (currentFrame.stackItems[0].id()) {
4243:                                        case T_boolean:
4244:                                        case T_byte:
4245:                                        case T_char:
4246:                                        case T_int:
4247:                                        case T_short:
4248:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
4249:                                            break;
4250:                                        case T_float:
4251:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
4252:                                            break;
4253:                                        case T_long:
4254:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
4255:                                            break;
4256:                                        case T_double:
4257:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
4258:                                            break;
4259:                                        case T_null:
4260:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
4261:                                            break;
4262:                                        default:
4263:                                            VerificationTypeInfo info = currentFrame.stackItems[0];
4264:                                            byte tag = (byte) info.tag;
4265:                                            this .contents[localContentsOffset++] = tag;
4266:                                            switch (tag) {
4267:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
4268:                                                int offset = info.offset;
4269:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
4270:                                                this .contents[localContentsOffset++] = (byte) offset;
4271:                                                break;
4272:                                            case VerificationTypeInfo.ITEM_OBJECT:
4273:                                                int indexForType = constantPool
4274:                                                        .literalIndexForType(info
4275:                                                                .constantPoolName());
4276:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
4277:                                                this .contents[localContentsOffset++] = (byte) indexForType;
4278:                                            }
4279:                                        }
4280:                                    }
4281:                                    break;
4282:                                default:
4283:                                    // FULL_FRAME
4284:                                    if (localContentsOffset + 5 >= this .contents.length) {
4285:                                        resizeContents(5);
4286:                                    }
4287:                                    this .contents[localContentsOffset++] = (byte) 255;
4288:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
4289:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
4290:                                    int numberOfLocalOffset = localContentsOffset;
4291:                                    localContentsOffset += 2; // leave two spots for number of locals
4292:                                    int numberOfLocalEntries = 0;
4293:                                    numberOfLocals = currentFrame
4294:                                            .getNumberOfLocals();
4295:                                    int numberOfEntries = 0;
4296:                                    int localsLength = currentFrame.locals == null ? 0
4297:                                            : currentFrame.locals.length;
4298:                                    for (int i = 0; i < localsLength
4299:                                            && numberOfLocalEntries < numberOfLocals; i++) {
4300:                                        if (localContentsOffset + 3 >= this .contents.length) {
4301:                                            resizeContents(3);
4302:                                        }
4303:                                        VerificationTypeInfo info = currentFrame.locals[i];
4304:                                        if (info == null) {
4305:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
4306:                                        } else {
4307:                                            switch (info.id()) {
4308:                                            case T_boolean:
4309:                                            case T_byte:
4310:                                            case T_char:
4311:                                            case T_int:
4312:                                            case T_short:
4313:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
4314:                                                break;
4315:                                            case T_float:
4316:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
4317:                                                break;
4318:                                            case T_long:
4319:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
4320:                                                i++;
4321:                                                break;
4322:                                            case T_double:
4323:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
4324:                                                i++;
4325:                                                break;
4326:                                            case T_null:
4327:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
4328:                                                break;
4329:                                            default:
4330:                                                this .contents[localContentsOffset++] = (byte) info.tag;
4331:                                                switch (info.tag) {
4332:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
4333:                                                    int offset = info.offset;
4334:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
4335:                                                    this .contents[localContentsOffset++] = (byte) offset;
4336:                                                    break;
4337:                                                case VerificationTypeInfo.ITEM_OBJECT:
4338:                                                    int indexForType = constantPool
4339:                                                            .literalIndexForType(info
4340:                                                                    .constantPoolName());
4341:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
4342:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
4343:                                                }
4344:                                            }
4345:                                            numberOfLocalEntries++;
4346:                                        }
4347:                                        numberOfEntries++;
4348:                                    }
4349:                                    if (localContentsOffset + 4 >= this .contents.length) {
4350:                                        resizeContents(4);
4351:                                    }
4352:                                    this .contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
4353:                                    this .contents[numberOfLocalOffset] = (byte) numberOfEntries;
4354:                                    int numberOfStackItems = currentFrame.numberOfStackItems;
4355:                                    this .contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
4356:                                    this .contents[localContentsOffset++] = (byte) numberOfStackItems;
4357:                                    for (int i = 0; i < numberOfStackItems; i++) {
4358:                                        if (localContentsOffset + 3 >= this .contents.length) {
4359:                                            resizeContents(3);
4360:                                        }
4361:                                        VerificationTypeInfo info = currentFrame.stackItems[i];
4362:                                        if (info == null) {
4363:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
4364:                                        } else {
4365:                                            switch (info.id()) {
4366:                                            case T_boolean:
4367:                                            case T_byte:
4368:                                            case T_char:
4369:                                            case T_int:
4370:                                            case T_short:
4371:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
4372:                                                break;
4373:                                            case T_float:
4374:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
4375:                                                break;
4376:                                            case T_long:
4377:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
4378:                                                break;
4379:                                            case T_double:
4380:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
4381:                                                break;
4382:                                            case T_null:
4383:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
4384:                                                break;
4385:                                            default:
4386:                                                this .contents[localContentsOffset++] = (byte) info.tag;
4387:                                                switch (info.tag) {
4388:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
4389:                                                    int offset = info.offset;
4390:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
4391:                                                    this .contents[localContentsOffset++] = (byte) offset;
4392:                                                    break;
4393:                                                case VerificationTypeInfo.ITEM_OBJECT:
4394:                                                    int indexForType = constantPool
4395:                                                            .literalIndexForType(info
4396:                                                                    .constantPoolName());
4397:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
4398:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
4399:                                                }
4400:                                            }
4401:                                        }
4402:                                    }
4403:                                }
4404:                            }
4405:
4406:                            if (numberOfFrames != 0) {
4407:                                this .contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
4408:                                this .contents[numberOfFramesOffset] = (byte) numberOfFrames;
4409:
4410:                                int attributeLength = localContentsOffset
4411:                                        - stackMapTableAttributeLengthOffset
4412:                                        - 4;
4413:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
4414:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
4415:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
4416:                                this .contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
4417:                                attributeNumber++;
4418:                            } else {
4419:                                localContentsOffset = stackMapTableAttributeOffset;
4420:                            }
4421:                        }
4422:                    }
4423:                }
4424:
4425:                if ((this .produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
4426:                    StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
4427:                    stackMapFrameCodeStream.removeFramePosition(code_length);
4428:                    if (stackMapFrameCodeStream.hasFramePositions()) {
4429:                        ArrayList frames = new ArrayList();
4430:                        traverse(this .codeStream.methodDeclaration.binding,
4431:                                max_locals, this .contents,
4432:                                codeAttributeOffset + 14, code_length, frames,
4433:                                false);
4434:                        int numberOfFrames = frames.size();
4435:                        if (numberOfFrames > 1) {
4436:                            int stackMapTableAttributeOffset = localContentsOffset;
4437:                            // add the stack map table attribute
4438:                            if (localContentsOffset + 8 >= this .contents.length) {
4439:                                resizeContents(8);
4440:                            }
4441:                            int stackMapAttributeNameIndex = constantPool
4442:                                    .literalIndex(AttributeNamesConstants.StackMapName);
4443:                            this .contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
4444:                            this .contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
4445:
4446:                            int stackMapAttributeLengthOffset = localContentsOffset;
4447:                            // generate the attribute
4448:                            localContentsOffset += 4;
4449:                            if (localContentsOffset + 4 >= this .contents.length) {
4450:                                resizeContents(4);
4451:                            }
4452:                            int numberOfFramesOffset = localContentsOffset;
4453:                            localContentsOffset += 2;
4454:                            if (localContentsOffset + 2 >= this .contents.length) {
4455:                                resizeContents(2);
4456:                            }
4457:                            StackMapFrame currentFrame = (StackMapFrame) frames
4458:                                    .get(0);
4459:                            for (int j = 1; j < numberOfFrames; j++) {
4460:                                // select next frame
4461:                                currentFrame = (StackMapFrame) frames.get(j);
4462:                                // generate current frame
4463:                                // need to find differences between the current frame and the previous frame
4464:                                int frameOffset = currentFrame.pc;
4465:                                // FULL_FRAME
4466:                                if (localContentsOffset + 5 >= this .contents.length) {
4467:                                    resizeContents(5);
4468:                                }
4469:                                this .contents[localContentsOffset++] = (byte) (frameOffset >> 8);
4470:                                this .contents[localContentsOffset++] = (byte) frameOffset;
4471:                                int numberOfLocalOffset = localContentsOffset;
4472:                                localContentsOffset += 2; // leave two spots for number of locals
4473:                                int numberOfLocalEntries = 0;
4474:                                int numberOfLocals = currentFrame
4475:                                        .getNumberOfLocals();
4476:                                int numberOfEntries = 0;
4477:                                int localsLength = currentFrame.locals == null ? 0
4478:                                        : currentFrame.locals.length;
4479:                                for (int i = 0; i < localsLength
4480:                                        && numberOfLocalEntries < numberOfLocals; i++) {
4481:                                    if (localContentsOffset + 3 >= this .contents.length) {
4482:                                        resizeContents(3);
4483:                                    }
4484:                                    VerificationTypeInfo info = currentFrame.locals[i];
4485:                                    if (info == null) {
4486:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
4487:                                    } else {
4488:                                        switch (info.id()) {
4489:                                        case T_boolean:
4490:                                        case T_byte:
4491:                                        case T_char:
4492:                                        case T_int:
4493:                                        case T_short:
4494:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
4495:                                            break;
4496:                                        case T_float:
4497:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
4498:                                            break;
4499:                                        case T_long:
4500:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
4501:                                            i++;
4502:                                            break;
4503:                                        case T_double:
4504:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
4505:                                            i++;
4506:                                            break;
4507:                                        case T_null:
4508:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
4509:                                            break;
4510:                                        default:
4511:                                            this .contents[localContentsOffset++] = (byte) info.tag;
4512:                                            switch (info.tag) {
4513:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
4514:                                                int offset = info.offset;
4515:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
4516:                                                this .contents[localContentsOffset++] = (byte) offset;
4517:                                                break;
4518:                                            case VerificationTypeInfo.ITEM_OBJECT:
4519:                                                int indexForType = constantPool
4520:                                                        .literalIndexForType(info
4521:                                                                .constantPoolName());
4522:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
4523:                                                this .contents[localContentsOffset++] = (byte) indexForType;
4524:                                            }
4525:                                        }
4526:                                        numberOfLocalEntries++;
4527:                                    }
4528:                                    numberOfEntries++;
4529:                                }
4530:                                if (localContentsOffset + 4 >= this .contents.length) {
4531:                                    resizeContents(4);
4532:                                }
4533:                                this .contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
4534:                                this .contents[numberOfLocalOffset] = (byte) numberOfEntries;
4535:                                int numberOfStackItems = currentFrame.numberOfStackItems;
4536:                                this .contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
4537:                                this .contents[localContentsOffset++] = (byte) numberOfStackItems;
4538:                                for (int i = 0; i < numberOfStackItems; i++) {
4539:                                    if (localContentsOffset + 3 >= this .contents.length) {
4540:                                        resizeContents(3);
4541:                                    }
4542:                                    VerificationTypeInfo info = currentFrame.stackItems[i];
4543:                                    if (info == null) {
4544:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
4545:                                    } else {
4546:                                        switch (info.id()) {
4547:                                        case T_boolean:
4548:                                        case T_byte:
4549:                                        case T_char:
4550:                                        case T_int:
4551:                                        case T_short:
4552:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
4553:                                            break;
4554:                                        case T_float:
4555:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
4556:                                            break;
4557:                                        case T_long:
4558:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
4559:                                            break;
4560:                                        case T_double:
4561:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
4562:                                            break;
4563:                                        case T_null:
4564:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
4565:                                            break;
4566:                                        default:
4567:                                            this .contents[localContentsOffset++] = (byte) info.tag;
4568:                                            switch (info.tag) {
4569:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
4570:                                                int offset = info.offset;
4571:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
4572:                                                this .contents[localContentsOffset++] = (byte) offset;
4573:                                                break;
4574:                                            case VerificationTypeInfo.ITEM_OBJECT:
4575:                                                int indexForType = constantPool
4576:                                                        .literalIndexForType(info
4577:                                                                .constantPoolName());
4578:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
4579:                                                this .contents[localContentsOffset++] = (byte) indexForType;
4580:                                            }
4581:                                        }
4582:                                    }
4583:                                }
4584:                            }
4585:
4586:                            numberOfFrames--;
4587:                            if (numberOfFrames != 0) {
4588:                                this .contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
4589:                                this .contents[numberOfFramesOffset] = (byte) numberOfFrames;
4590:
4591:                                int attributeLength = localContentsOffset
4592:                                        - stackMapAttributeLengthOffset - 4;
4593:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
4594:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
4595:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
4596:                                this .contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
4597:                                attributeNumber++;
4598:                            } else {
4599:                                localContentsOffset = stackMapTableAttributeOffset;
4600:                            }
4601:                        }
4602:                    }
4603:                }
4604:
4605:                // then we do the local variable attribute
4606:                // update the number of attributes// ensure first that there is enough space available inside the localContents array
4607:                if (codeAttributeAttributeOffset + 2 >= this .contents.length) {
4608:                    resizeContents(2);
4609:                }
4610:                this .contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
4611:                this .contents[codeAttributeAttributeOffset] = (byte) attributeNumber;
4612:                // update the attribute length
4613:                int codeAttributeLength = localContentsOffset
4614:                        - (codeAttributeOffset + 6);
4615:                this .contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
4616:                this .contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
4617:                this .contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
4618:                this .contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
4619:                contentsOffset = localContentsOffset;
4620:            }
4621:
4622:            /**
4623:             * INTERNAL USE-ONLY
4624:             * That method completes the creation of the code attribute by setting
4625:             * - the attribute_length
4626:             * - max_stack
4627:             * - max_locals
4628:             * - code_length
4629:             * - exception table
4630:             * - and debug attributes if necessary.
4631:             *
4632:             * @param codeAttributeOffset <CODE>int</CODE>
4633:             */
4634:            public void completeCodeAttributeForProblemMethod(
4635:                    AbstractMethodDeclaration method, MethodBinding binding,
4636:                    int codeAttributeOffset, int[] startLineIndexes,
4637:                    int problemLine) {
4638:                // reinitialize the localContents with the byte modified by the code stream
4639:                this .contents = codeStream.bCodeStream;
4640:                int localContentsOffset = codeStream.classFileOffset;
4641:                // codeAttributeOffset is the position inside localContents byte array before we started to write// any information about the codeAttribute// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset// to get the right position, 6 for the max_stack etc...
4642:                int max_stack = codeStream.stackMax;
4643:                this .contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
4644:                this .contents[codeAttributeOffset + 7] = (byte) max_stack;
4645:                int max_locals = codeStream.maxLocals;
4646:                this .contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
4647:                this .contents[codeAttributeOffset + 9] = (byte) max_locals;
4648:                int code_length = codeStream.position;
4649:                this .contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
4650:                this .contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
4651:                this .contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
4652:                this .contents[codeAttributeOffset + 13] = (byte) code_length;
4653:                // write the exception table
4654:                if (localContentsOffset + 50 >= this .contents.length) {
4655:                    resizeContents(50);
4656:                }
4657:
4658:                // write the exception table
4659:                this .contents[localContentsOffset++] = 0;
4660:                this .contents[localContentsOffset++] = 0;
4661:                // debug attributes
4662:                int codeAttributeAttributeOffset = localContentsOffset;
4663:                int attributeNumber = 0; // leave two bytes for the attribute_length
4664:                localContentsOffset += 2; // first we handle the linenumber attribute
4665:                if (localContentsOffset + 2 >= this .contents.length) {
4666:                    resizeContents(2);
4667:                }
4668:
4669:                if ((this .produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
4670:                    if (localContentsOffset + 20 >= this .contents.length) {
4671:                        resizeContents(20);
4672:                    }
4673:                    /* Create and add the line number attribute (used for debugging)
4674:                     * Build the pairs of:
4675:                     * (bytecodePC lineNumber)
4676:                     * according to the table of start line indexes and the pcToSourceMap table
4677:                     * contained into the codestream
4678:                     */
4679:                    int lineNumberNameIndex = constantPool
4680:                            .literalIndex(AttributeNamesConstants.LineNumberTableName);
4681:                    this .contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
4682:                    this .contents[localContentsOffset++] = (byte) lineNumberNameIndex;
4683:                    this .contents[localContentsOffset++] = 0;
4684:                    this .contents[localContentsOffset++] = 0;
4685:                    this .contents[localContentsOffset++] = 0;
4686:                    this .contents[localContentsOffset++] = 6;
4687:                    this .contents[localContentsOffset++] = 0;
4688:                    this .contents[localContentsOffset++] = 1;
4689:                    if (problemLine == 0) {
4690:                        problemLine = Util.getLineNumber(binding.sourceStart(),
4691:                                startLineIndexes, 0,
4692:                                startLineIndexes.length - 1);
4693:                    }
4694:                    // first entry at pc = 0
4695:                    this .contents[localContentsOffset++] = 0;
4696:                    this .contents[localContentsOffset++] = 0;
4697:                    this .contents[localContentsOffset++] = (byte) (problemLine >> 8);
4698:                    this .contents[localContentsOffset++] = (byte) problemLine;
4699:                    // now we change the size of the line number attribute
4700:                    attributeNumber++;
4701:                }
4702:                // then we do the local variable attribute
4703:                if ((this .produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
4704:                    // compute the resolved position for the arguments of the method
4705:                    int argSize;
4706:                    int numberOfEntries = 0;
4707:                    //		codeAttribute.addLocalVariableTableAttribute(this);
4708:                    int localVariableNameIndex = constantPool
4709:                            .literalIndex(AttributeNamesConstants.LocalVariableTableName);
4710:                    if (localContentsOffset + 8 >= this .contents.length) {
4711:                        resizeContents(8);
4712:                    }
4713:                    this .contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
4714:                    this .contents[localContentsOffset++] = (byte) localVariableNameIndex;
4715:                    int localVariableTableOffset = localContentsOffset;
4716:                    localContentsOffset += 6;
4717:                    // leave space for attribute_length and local_variable_table_length
4718:                    int descriptorIndex;
4719:                    int nameIndex;
4720:                    SourceTypeBinding declaringClassBinding = null;
4721:                    final boolean methodDeclarationIsStatic = codeStream.methodDeclaration
4722:                            .isStatic();
4723:                    if (!methodDeclarationIsStatic) {
4724:                        numberOfEntries++;
4725:                        if (localContentsOffset + 10 >= this .contents.length) {
4726:                            resizeContents(10);
4727:                        }
4728:                        this .contents[localContentsOffset++] = 0;
4729:                        this .contents[localContentsOffset++] = 0;
4730:                        this .contents[localContentsOffset++] = (byte) (code_length >> 8);
4731:                        this .contents[localContentsOffset++] = (byte) code_length;
4732:                        nameIndex = constantPool
4733:                                .literalIndex(ConstantPool.This);
4734:                        this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
4735:                        this .contents[localContentsOffset++] = (byte) nameIndex;
4736:                        declaringClassBinding = (SourceTypeBinding) codeStream.methodDeclaration.binding.declaringClass;
4737:                        descriptorIndex = constantPool
4738:                                .literalIndex(declaringClassBinding.signature());
4739:                        this .contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
4740:                        this .contents[localContentsOffset++] = (byte) descriptorIndex;
4741:                        // the resolved position for this is always 0
4742:                        this .contents[localContentsOffset++] = 0;
4743:                        this .contents[localContentsOffset++] = 0;
4744:                    }
4745:                    // used to remember the local variable with a generic type
4746:                    int genericLocalVariablesCounter = 0;
4747:                    LocalVariableBinding[] genericLocalVariables = null;
4748:                    int numberOfGenericEntries = 0;
4749:
4750:                    if (binding.isConstructor()) {
4751:                        ReferenceBinding declaringClass = binding.declaringClass;
4752:                        if (declaringClass.isNestedType()) {
4753:                            NestedTypeBinding methodDeclaringClass = (NestedTypeBinding) declaringClass;
4754:                            argSize = methodDeclaringClass.enclosingInstancesSlotSize;
4755:                            SyntheticArgumentBinding[] syntheticArguments;
4756:                            if ((syntheticArguments = methodDeclaringClass
4757:                                    .syntheticEnclosingInstances()) != null) {
4758:                                for (int i = 0, max = syntheticArguments.length; i < max; i++) {
4759:                                    LocalVariableBinding localVariable = syntheticArguments[i];
4760:                                    final TypeBinding localVariableTypeBinding = localVariable.type;
4761:                                    if (localVariableTypeBinding
4762:                                            .isParameterizedType()
4763:                                            || localVariableTypeBinding
4764:                                                    .isTypeVariable()) {
4765:                                        if (genericLocalVariables == null) {
4766:                                            // we cannot have more than max locals
4767:                                            genericLocalVariables = new LocalVariableBinding[max];
4768:                                        }
4769:                                        genericLocalVariables[genericLocalVariablesCounter++] = localVariable;
4770:                                        numberOfGenericEntries++;
4771:                                    }
4772:                                    if (localContentsOffset + 10 >= this .contents.length) {
4773:                                        resizeContents(10);
4774:                                    }
4775:                                    // now we can safely add the local entry
4776:                                    numberOfEntries++;
4777:                                    this .contents[localContentsOffset++] = 0;
4778:                                    this .contents[localContentsOffset++] = 0;
4779:                                    this .contents[localContentsOffset++] = (byte) (code_length >> 8);
4780:                                    this .contents[localContentsOffset++] = (byte) code_length;
4781:                                    nameIndex = constantPool
4782:                                            .literalIndex(localVariable.name);
4783:                                    this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
4784:                                    this .contents[localContentsOffset++] = (byte) nameIndex;
4785:                                    descriptorIndex = constantPool
4786:                                            .literalIndex(localVariableTypeBinding
4787:                                                    .signature());
4788:                                    this .contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
4789:                                    this .contents[localContentsOffset++] = (byte) descriptorIndex;
4790:                                    int resolvedPosition = localVariable.resolvedPosition;
4791:                                    this .contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
4792:                                    this .contents[localContentsOffset++] = (byte) resolvedPosition;
4793:                                }
4794:                            }
4795:                        } else {
4796:                            argSize = 1;
4797:                        }
4798:                    } else {
4799:                        argSize = binding.isStatic() ? 0 : 1;
4800:                    }
4801:
4802:                    int genericArgumentsCounter = 0;
4803:                    int[] genericArgumentsNameIndexes = null;
4804:                    int[] genericArgumentsResolvedPositions = null;
4805:                    TypeBinding[] genericArgumentsTypeBindings = null;
4806:
4807:                    if (method.binding != null) {
4808:                        TypeBinding[] parameters = method.binding.parameters;
4809:                        Argument[] arguments = method.arguments;
4810:                        if ((parameters != null) && (arguments != null)) {
4811:                            for (int i = 0, max = parameters.length; i < max; i++) {
4812:                                TypeBinding argumentBinding = parameters[i];
4813:                                if (localContentsOffset + 10 >= this .contents.length) {
4814:                                    resizeContents(10);
4815:                                }
4816:                                // now we can safely add the local entry
4817:                                numberOfEntries++;
4818:                                this .contents[localContentsOffset++] = 0;
4819:                                this .contents[localContentsOffset++] = 0;
4820:                                this .contents[localContentsOffset++] = (byte) (code_length >> 8);
4821:                                this .contents[localContentsOffset++] = (byte) code_length;
4822:                                nameIndex = constantPool
4823:                                        .literalIndex(arguments[i].name);
4824:                                this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
4825:                                this .contents[localContentsOffset++] = (byte) nameIndex;
4826:                                int resolvedPosition = argSize;
4827:                                if (argumentBinding.isParameterizedType()
4828:                                        || argumentBinding.isTypeVariable()) {
4829:                                    if (genericArgumentsCounter == 0) {
4830:                                        // we cannot have more than max locals
4831:                                        genericArgumentsNameIndexes = new int[max];
4832:                                        genericArgumentsResolvedPositions = new int[max];
4833:                                        genericArgumentsTypeBindings = new TypeBinding[max];
4834:                                    }
4835:                                    genericArgumentsNameIndexes[genericArgumentsCounter] = nameIndex;
4836:                                    genericArgumentsResolvedPositions[genericArgumentsCounter] = resolvedPosition;
4837:                                    genericArgumentsTypeBindings[genericArgumentsCounter++] = argumentBinding;
4838:                                }
4839:                                descriptorIndex = constantPool
4840:                                        .literalIndex(argumentBinding
4841:                                                .signature());
4842:                                this .contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
4843:                                this .contents[localContentsOffset++] = (byte) descriptorIndex;
4844:                                if ((argumentBinding == TypeBinding.LONG)
4845:                                        || (argumentBinding == TypeBinding.DOUBLE))
4846:                                    argSize += 2;
4847:                                else
4848:                                    argSize++;
4849:                                this .contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
4850:                                this .contents[localContentsOffset++] = (byte) resolvedPosition;
4851:                            }
4852:                        }
4853:                    }
4854:                    int value = numberOfEntries * 10 + 2;
4855:                    this .contents[localVariableTableOffset++] = (byte) (value >> 24);
4856:                    this .contents[localVariableTableOffset++] = (byte) (value >> 16);
4857:                    this .contents[localVariableTableOffset++] = (byte) (value >> 8);
4858:                    this .contents[localVariableTableOffset++] = (byte) value;
4859:                    this .contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
4860:                    this .contents[localVariableTableOffset] = (byte) numberOfEntries;
4861:                    attributeNumber++;
4862:
4863:                    final boolean currentInstanceIsGeneric = !methodDeclarationIsStatic
4864:                            && declaringClassBinding != null
4865:                            && declaringClassBinding.typeVariables != Binding.NO_TYPE_VARIABLES;
4866:                    if (genericLocalVariablesCounter != 0
4867:                            || genericArgumentsCounter != 0
4868:                            || currentInstanceIsGeneric) {
4869:                        // add the local variable type table attribute
4870:                        numberOfEntries = numberOfGenericEntries
4871:                                + genericArgumentsCounter
4872:                                + (currentInstanceIsGeneric ? 1 : 0);
4873:                        // reserve enough space
4874:                        int maxOfEntries = 8 + numberOfEntries * 10;
4875:                        if (localContentsOffset + maxOfEntries >= this .contents.length) {
4876:                            resizeContents(maxOfEntries);
4877:                        }
4878:                        int localVariableTypeNameIndex = constantPool
4879:                                .literalIndex(AttributeNamesConstants.LocalVariableTypeTableName);
4880:                        this .contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8);
4881:                        this .contents[localContentsOffset++] = (byte) localVariableTypeNameIndex;
4882:                        value = numberOfEntries * 10 + 2;
4883:                        this .contents[localContentsOffset++] = (byte) (value >> 24);
4884:                        this .contents[localContentsOffset++] = (byte) (value >> 16);
4885:                        this .contents[localContentsOffset++] = (byte) (value >> 8);
4886:                        this .contents[localContentsOffset++] = (byte) value;
4887:                        this .contents[localContentsOffset++] = (byte) (numberOfEntries >> 8);
4888:                        this .contents[localContentsOffset++] = (byte) numberOfEntries;
4889:                        if (currentInstanceIsGeneric) {
4890:                            numberOfEntries++;
4891:                            this .contents[localContentsOffset++] = 0; // the startPC for this is always 0
4892:                            this .contents[localContentsOffset++] = 0;
4893:                            this .contents[localContentsOffset++] = (byte) (code_length >> 8);
4894:                            this .contents[localContentsOffset++] = (byte) code_length;
4895:                            nameIndex = constantPool
4896:                                    .literalIndex(ConstantPool.This);
4897:                            this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
4898:                            this .contents[localContentsOffset++] = (byte) nameIndex;
4899:                            descriptorIndex = constantPool
4900:                                    .literalIndex(declaringClassBinding
4901:                                            .genericTypeSignature());
4902:                            this .contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
4903:                            this .contents[localContentsOffset++] = (byte) descriptorIndex;
4904:                            this .contents[localContentsOffset++] = 0;// the resolved position for this is always 0
4905:                            this .contents[localContentsOffset++] = 0;
4906:                        }
4907:
4908:                        for (int i = 0; i < genericLocalVariablesCounter; i++) {
4909:                            LocalVariableBinding localVariable = genericLocalVariables[i];
4910:                            this .contents[localContentsOffset++] = 0;
4911:                            this .contents[localContentsOffset++] = 0;
4912:                            this .contents[localContentsOffset++] = (byte) (code_length >> 8);
4913:                            this .contents[localContentsOffset++] = (byte) code_length;
4914:                            nameIndex = constantPool
4915:                                    .literalIndex(localVariable.name);
4916:                            this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
4917:                            this .contents[localContentsOffset++] = (byte) nameIndex;
4918:                            descriptorIndex = constantPool
4919:                                    .literalIndex(localVariable.type
4920:                                            .genericTypeSignature());
4921:                            this .contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
4922:                            this .contents[localContentsOffset++] = (byte) descriptorIndex;
4923:                            int resolvedPosition = localVariable.resolvedPosition;
4924:                            this .contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
4925:                            this .contents[localContentsOffset++] = (byte) resolvedPosition;
4926:                        }
4927:                        for (int i = 0; i < genericArgumentsCounter; i++) {
4928:                            this .contents[localContentsOffset++] = 0;
4929:                            this .contents[localContentsOffset++] = 0;
4930:                            this .contents[localContentsOffset++] = (byte) (code_length >> 8);
4931:                            this .contents[localContentsOffset++] = (byte) code_length;
4932:                            nameIndex = genericArgumentsNameIndexes[i];
4933:                            this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
4934:                            this .contents[localContentsOffset++] = (byte) nameIndex;
4935:                            descriptorIndex = constantPool
4936:                                    .literalIndex(genericArgumentsTypeBindings[i]
4937:                                            .genericTypeSignature());
4938:                            this .contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
4939:                            this .contents[localContentsOffset++] = (byte) descriptorIndex;
4940:                            int resolvedPosition = genericArgumentsResolvedPositions[i];
4941:                            this .contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
4942:                            this .contents[localContentsOffset++] = (byte) resolvedPosition;
4943:                        }
4944:                        attributeNumber++;
4945:                    }
4946:                }
4947:
4948:                if ((this .produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
4949:                    StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
4950:                    stackMapFrameCodeStream.removeFramePosition(code_length);
4951:                    if (stackMapFrameCodeStream.hasFramePositions()) {
4952:                        ArrayList frames = new ArrayList();
4953:                        traverse(binding, max_locals, this .contents,
4954:                                codeAttributeOffset + 14, code_length, frames,
4955:                                false);
4956:                        int numberOfFrames = frames.size();
4957:                        if (numberOfFrames > 1) {
4958:                            int stackMapTableAttributeOffset = localContentsOffset;
4959:                            // add the stack map table attribute
4960:                            if (localContentsOffset + 8 >= this .contents.length) {
4961:                                resizeContents(8);
4962:                            }
4963:                            int stackMapTableAttributeNameIndex = constantPool
4964:                                    .literalIndex(AttributeNamesConstants.StackMapTableName);
4965:                            this .contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
4966:                            this .contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
4967:
4968:                            int stackMapTableAttributeLengthOffset = localContentsOffset;
4969:                            // generate the attribute
4970:                            localContentsOffset += 4;
4971:                            if (localContentsOffset + 4 >= this .contents.length) {
4972:                                resizeContents(4);
4973:                            }
4974:                            numberOfFrames = 0;
4975:                            int numberOfFramesOffset = localContentsOffset;
4976:                            localContentsOffset += 2;
4977:                            if (localContentsOffset + 2 >= this .contents.length) {
4978:                                resizeContents(2);
4979:                            }
4980:                            StackMapFrame currentFrame = (StackMapFrame) frames
4981:                                    .get(0);
4982:                            StackMapFrame prevFrame = null;
4983:                            for (int j = 1; j < numberOfFrames; j++) {
4984:                                // select next frame
4985:                                prevFrame = currentFrame;
4986:                                currentFrame = (StackMapFrame) frames.get(j);
4987:                                // generate current frame
4988:                                // need to find differences between the current frame and the previous frame
4989:                                numberOfFrames++;
4990:                                int offsetDelta = currentFrame
4991:                                        .getOffsetDelta(prevFrame);
4992:                                switch (currentFrame.getFrameType(prevFrame)) {
4993:                                case StackMapFrame.APPEND_FRAME:
4994:                                    if (localContentsOffset + 3 >= this .contents.length) {
4995:                                        resizeContents(3);
4996:                                    }
4997:                                    int numberOfDifferentLocals = currentFrame
4998:                                            .numberOfDifferentLocals(prevFrame);
4999:                                    this .contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
5000:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
5001:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
5002:                                    int index = currentFrame
5003:                                            .getIndexOfDifferentLocals(numberOfDifferentLocals);
5004:                                    int numberOfLocals = currentFrame
5005:                                            .getNumberOfLocals();
5006:                                    for (int i = index; i < currentFrame.locals.length
5007:                                            && numberOfDifferentLocals > 0; i++) {
5008:                                        if (localContentsOffset + 6 >= this .contents.length) {
5009:                                            resizeContents(6);
5010:                                        }
5011:                                        VerificationTypeInfo info = currentFrame.locals[i];
5012:                                        if (info == null) {
5013:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
5014:                                        } else {
5015:                                            switch (info.id()) {
5016:                                            case T_boolean:
5017:                                            case T_byte:
5018:                                            case T_char:
5019:                                            case T_int:
5020:                                            case T_short:
5021:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
5022:                                                break;
5023:                                            case T_float:
5024:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
5025:                                                break;
5026:                                            case T_long:
5027:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
5028:                                                i++;
5029:                                                break;
5030:                                            case T_double:
5031:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
5032:                                                i++;
5033:                                                break;
5034:                                            case T_null:
5035:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
5036:                                                break;
5037:                                            default:
5038:                                                this .contents[localContentsOffset++] = (byte) info.tag;
5039:                                                switch (info.tag) {
5040:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
5041:                                                    int offset = info.offset;
5042:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
5043:                                                    this .contents[localContentsOffset++] = (byte) offset;
5044:                                                    break;
5045:                                                case VerificationTypeInfo.ITEM_OBJECT:
5046:                                                    int indexForType = constantPool
5047:                                                            .literalIndexForType(info
5048:                                                                    .constantPoolName());
5049:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
5050:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
5051:                                                }
5052:                                            }
5053:                                            numberOfDifferentLocals--;
5054:                                        }
5055:                                    }
5056:                                    break;
5057:                                case StackMapFrame.SAME_FRAME:
5058:                                    if (localContentsOffset + 1 >= this .contents.length) {
5059:                                        resizeContents(1);
5060:                                    }
5061:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
5062:                                    break;
5063:                                case StackMapFrame.SAME_FRAME_EXTENDED:
5064:                                    if (localContentsOffset + 3 >= this .contents.length) {
5065:                                        resizeContents(3);
5066:                                    }
5067:                                    this .contents[localContentsOffset++] = (byte) 251;
5068:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
5069:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
5070:                                    break;
5071:                                case StackMapFrame.CHOP_FRAME:
5072:                                    if (localContentsOffset + 3 >= this .contents.length) {
5073:                                        resizeContents(3);
5074:                                    }
5075:                                    numberOfDifferentLocals = -currentFrame
5076:                                            .numberOfDifferentLocals(prevFrame);
5077:                                    this .contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
5078:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
5079:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
5080:                                    break;
5081:                                case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS:
5082:                                    if (localContentsOffset + 4 >= this .contents.length) {
5083:                                        resizeContents(4);
5084:                                    }
5085:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta + 64);
5086:                                    if (currentFrame.stackItems[0] == null) {
5087:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
5088:                                    } else {
5089:                                        switch (currentFrame.stackItems[0].id()) {
5090:                                        case T_boolean:
5091:                                        case T_byte:
5092:                                        case T_char:
5093:                                        case T_int:
5094:                                        case T_short:
5095:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
5096:                                            break;
5097:                                        case T_float:
5098:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
5099:                                            break;
5100:                                        case T_long:
5101:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
5102:                                            break;
5103:                                        case T_double:
5104:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
5105:                                            break;
5106:                                        case T_null:
5107:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
5108:                                            break;
5109:                                        default:
5110:                                            VerificationTypeInfo info = currentFrame.stackItems[0];
5111:                                            byte tag = (byte) info.tag;
5112:                                            this .contents[localContentsOffset++] = tag;
5113:                                            switch (tag) {
5114:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
5115:                                                int offset = info.offset;
5116:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
5117:                                                this .contents[localContentsOffset++] = (byte) offset;
5118:                                                break;
5119:                                            case VerificationTypeInfo.ITEM_OBJECT:
5120:                                                int indexForType = constantPool
5121:                                                        .literalIndexForType(info
5122:                                                                .constantPoolName());
5123:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
5124:                                                this .contents[localContentsOffset++] = (byte) indexForType;
5125:                                            }
5126:                                        }
5127:                                    }
5128:                                    break;
5129:                                case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED:
5130:                                    if (localContentsOffset + 6 >= this .contents.length) {
5131:                                        resizeContents(6);
5132:                                    }
5133:                                    this .contents[localContentsOffset++] = (byte) 247;
5134:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
5135:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
5136:                                    if (currentFrame.stackItems[0] == null) {
5137:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
5138:                                    } else {
5139:                                        switch (currentFrame.stackItems[0].id()) {
5140:                                        case T_boolean:
5141:                                        case T_byte:
5142:                                        case T_char:
5143:                                        case T_int:
5144:                                        case T_short:
5145:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
5146:                                            break;
5147:                                        case T_float:
5148:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
5149:                                            break;
5150:                                        case T_long:
5151:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
5152:                                            break;
5153:                                        case T_double:
5154:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
5155:                                            break;
5156:                                        case T_null:
5157:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
5158:                                            break;
5159:                                        default:
5160:                                            VerificationTypeInfo info = currentFrame.stackItems[0];
5161:                                            byte tag = (byte) info.tag;
5162:                                            this .contents[localContentsOffset++] = tag;
5163:                                            switch (tag) {
5164:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
5165:                                                int offset = info.offset;
5166:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
5167:                                                this .contents[localContentsOffset++] = (byte) offset;
5168:                                                break;
5169:                                            case VerificationTypeInfo.ITEM_OBJECT:
5170:                                                int indexForType = constantPool
5171:                                                        .literalIndexForType(info
5172:                                                                .constantPoolName());
5173:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
5174:                                                this .contents[localContentsOffset++] = (byte) indexForType;
5175:                                            }
5176:                                        }
5177:                                    }
5178:                                    break;
5179:                                default:
5180:                                    // FULL_FRAME
5181:                                    if (localContentsOffset + 5 >= this .contents.length) {
5182:                                        resizeContents(5);
5183:                                    }
5184:                                    this .contents[localContentsOffset++] = (byte) 255;
5185:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
5186:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
5187:                                    int numberOfLocalOffset = localContentsOffset;
5188:                                    localContentsOffset += 2; // leave two spots for number of locals
5189:                                    int numberOfLocalEntries = 0;
5190:                                    numberOfLocals = currentFrame
5191:                                            .getNumberOfLocals();
5192:                                    int numberOfEntries = 0;
5193:                                    int localsLength = currentFrame.locals == null ? 0
5194:                                            : currentFrame.locals.length;
5195:                                    for (int i = 0; i < localsLength
5196:                                            && numberOfLocalEntries < numberOfLocals; i++) {
5197:                                        if (localContentsOffset + 3 >= this .contents.length) {
5198:                                            resizeContents(3);
5199:                                        }
5200:                                        VerificationTypeInfo info = currentFrame.locals[i];
5201:                                        if (info == null) {
5202:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
5203:                                        } else {
5204:                                            switch (info.id()) {
5205:                                            case T_boolean:
5206:                                            case T_byte:
5207:                                            case T_char:
5208:                                            case T_int:
5209:                                            case T_short:
5210:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
5211:                                                break;
5212:                                            case T_float:
5213:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
5214:                                                break;
5215:                                            case T_long:
5216:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
5217:                                                i++;
5218:                                                break;
5219:                                            case T_double:
5220:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
5221:                                                i++;
5222:                                                break;
5223:                                            case T_null:
5224:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
5225:                                                break;
5226:                                            default:
5227:                                                this .contents[localContentsOffset++] = (byte) info.tag;
5228:                                                switch (info.tag) {
5229:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
5230:                                                    int offset = info.offset;
5231:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
5232:                                                    this .contents[localContentsOffset++] = (byte) offset;
5233:                                                    break;
5234:                                                case VerificationTypeInfo.ITEM_OBJECT:
5235:                                                    int indexForType = constantPool
5236:                                                            .literalIndexForType(info
5237:                                                                    .constantPoolName());
5238:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
5239:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
5240:                                                }
5241:                                            }
5242:                                            numberOfLocalEntries++;
5243:                                        }
5244:                                        numberOfEntries++;
5245:                                    }
5246:                                    if (localContentsOffset + 4 >= this .contents.length) {
5247:                                        resizeContents(4);
5248:                                    }
5249:                                    this .contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
5250:                                    this .contents[numberOfLocalOffset] = (byte) numberOfEntries;
5251:                                    int numberOfStackItems = currentFrame.numberOfStackItems;
5252:                                    this .contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
5253:                                    this .contents[localContentsOffset++] = (byte) numberOfStackItems;
5254:                                    for (int i = 0; i < numberOfStackItems; i++) {
5255:                                        if (localContentsOffset + 3 >= this .contents.length) {
5256:                                            resizeContents(3);
5257:                                        }
5258:                                        VerificationTypeInfo info = currentFrame.stackItems[i];
5259:                                        if (info == null) {
5260:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
5261:                                        } else {
5262:                                            switch (info.id()) {
5263:                                            case T_boolean:
5264:                                            case T_byte:
5265:                                            case T_char:
5266:                                            case T_int:
5267:                                            case T_short:
5268:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
5269:                                                break;
5270:                                            case T_float:
5271:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
5272:                                                break;
5273:                                            case T_long:
5274:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
5275:                                                break;
5276:                                            case T_double:
5277:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
5278:                                                break;
5279:                                            case T_null:
5280:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
5281:                                                break;
5282:                                            default:
5283:                                                this .contents[localContentsOffset++] = (byte) info.tag;
5284:                                                switch (info.tag) {
5285:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
5286:                                                    int offset = info.offset;
5287:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
5288:                                                    this .contents[localContentsOffset++] = (byte) offset;
5289:                                                    break;
5290:                                                case VerificationTypeInfo.ITEM_OBJECT:
5291:                                                    int indexForType = constantPool
5292:                                                            .literalIndexForType(info
5293:                                                                    .constantPoolName());
5294:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
5295:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
5296:                                                }
5297:                                            }
5298:                                        }
5299:                                    }
5300:                                }
5301:                            }
5302:
5303:                            if (numberOfFrames != 0) {
5304:                                this .contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
5305:                                this .contents[numberOfFramesOffset] = (byte) numberOfFrames;
5306:
5307:                                int attributeLength = localContentsOffset
5308:                                        - stackMapTableAttributeLengthOffset
5309:                                        - 4;
5310:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
5311:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
5312:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
5313:                                this .contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
5314:                                attributeNumber++;
5315:                            } else {
5316:                                localContentsOffset = stackMapTableAttributeOffset;
5317:                            }
5318:                        }
5319:                    }
5320:                }
5321:
5322:                if ((this .produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
5323:                    StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
5324:                    stackMapFrameCodeStream.removeFramePosition(code_length);
5325:                    if (stackMapFrameCodeStream.hasFramePositions()) {
5326:                        ArrayList frames = new ArrayList();
5327:                        traverse(this .codeStream.methodDeclaration.binding,
5328:                                max_locals, this .contents,
5329:                                codeAttributeOffset + 14, code_length, frames,
5330:                                false);
5331:                        int numberOfFrames = frames.size();
5332:                        if (numberOfFrames > 1) {
5333:                            int stackMapTableAttributeOffset = localContentsOffset;
5334:                            // add the stack map table attribute
5335:                            if (localContentsOffset + 8 >= this .contents.length) {
5336:                                resizeContents(8);
5337:                            }
5338:                            int stackMapAttributeNameIndex = constantPool
5339:                                    .literalIndex(AttributeNamesConstants.StackMapName);
5340:                            this .contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
5341:                            this .contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
5342:
5343:                            int stackMapAttributeLengthOffset = localContentsOffset;
5344:                            // generate the attribute
5345:                            localContentsOffset += 4;
5346:                            if (localContentsOffset + 4 >= this .contents.length) {
5347:                                resizeContents(4);
5348:                            }
5349:                            int numberOfFramesOffset = localContentsOffset;
5350:                            localContentsOffset += 2;
5351:                            if (localContentsOffset + 2 >= this .contents.length) {
5352:                                resizeContents(2);
5353:                            }
5354:                            StackMapFrame currentFrame = (StackMapFrame) frames
5355:                                    .get(0);
5356:                            for (int j = 1; j < numberOfFrames; j++) {
5357:                                // select next frame
5358:                                currentFrame = (StackMapFrame) frames.get(j);
5359:                                // generate current frame
5360:                                // need to find differences between the current frame and the previous frame
5361:                                int frameOffset = currentFrame.pc;
5362:                                // FULL_FRAME
5363:                                if (localContentsOffset + 5 >= this .contents.length) {
5364:                                    resizeContents(5);
5365:                                }
5366:                                this .contents[localContentsOffset++] = (byte) (frameOffset >> 8);
5367:                                this .contents[localContentsOffset++] = (byte) frameOffset;
5368:                                int numberOfLocalOffset = localContentsOffset;
5369:                                localContentsOffset += 2; // leave two spots for number of locals
5370:                                int numberOfLocalEntries = 0;
5371:                                int numberOfLocals = currentFrame
5372:                                        .getNumberOfLocals();
5373:                                int numberOfEntries = 0;
5374:                                int localsLength = currentFrame.locals == null ? 0
5375:                                        : currentFrame.locals.length;
5376:                                for (int i = 0; i < localsLength
5377:                                        && numberOfLocalEntries < numberOfLocals; i++) {
5378:                                    if (localContentsOffset + 3 >= this .contents.length) {
5379:                                        resizeContents(3);
5380:                                    }
5381:                                    VerificationTypeInfo info = currentFrame.locals[i];
5382:                                    if (info == null) {
5383:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
5384:                                    } else {
5385:                                        switch (info.id()) {
5386:                                        case T_boolean:
5387:                                        case T_byte:
5388:                                        case T_char:
5389:                                        case T_int:
5390:                                        case T_short:
5391:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
5392:                                            break;
5393:                                        case T_float:
5394:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
5395:                                            break;
5396:                                        case T_long:
5397:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
5398:                                            i++;
5399:                                            break;
5400:                                        case T_double:
5401:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
5402:                                            i++;
5403:                                            break;
5404:                                        case T_null:
5405:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
5406:                                            break;
5407:                                        default:
5408:                                            this .contents[localContentsOffset++] = (byte) info.tag;
5409:                                            switch (info.tag) {
5410:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
5411:                                                int offset = info.offset;
5412:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
5413:                                                this .contents[localContentsOffset++] = (byte) offset;
5414:                                                break;
5415:                                            case VerificationTypeInfo.ITEM_OBJECT:
5416:                                                int indexForType = constantPool
5417:                                                        .literalIndexForType(info
5418:                                                                .constantPoolName());
5419:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
5420:                                                this .contents[localContentsOffset++] = (byte) indexForType;
5421:                                            }
5422:                                        }
5423:                                        numberOfLocalEntries++;
5424:                                    }
5425:                                    numberOfEntries++;
5426:                                }
5427:                                if (localContentsOffset + 4 >= this .contents.length) {
5428:                                    resizeContents(4);
5429:                                }
5430:                                this .contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
5431:                                this .contents[numberOfLocalOffset] = (byte) numberOfEntries;
5432:                                int numberOfStackItems = currentFrame.numberOfStackItems;
5433:                                this .contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
5434:                                this .contents[localContentsOffset++] = (byte) numberOfStackItems;
5435:                                for (int i = 0; i < numberOfStackItems; i++) {
5436:                                    if (localContentsOffset + 3 >= this .contents.length) {
5437:                                        resizeContents(3);
5438:                                    }
5439:                                    VerificationTypeInfo info = currentFrame.stackItems[i];
5440:                                    if (info == null) {
5441:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
5442:                                    } else {
5443:                                        switch (info.id()) {
5444:                                        case T_boolean:
5445:                                        case T_byte:
5446:                                        case T_char:
5447:                                        case T_int:
5448:                                        case T_short:
5449:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
5450:                                            break;
5451:                                        case T_float:
5452:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
5453:                                            break;
5454:                                        case T_long:
5455:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
5456:                                            break;
5457:                                        case T_double:
5458:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
5459:                                            break;
5460:                                        case T_null:
5461:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
5462:                                            break;
5463:                                        default:
5464:                                            this .contents[localContentsOffset++] = (byte) info.tag;
5465:                                            switch (info.tag) {
5466:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
5467:                                                int offset = info.offset;
5468:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
5469:                                                this .contents[localContentsOffset++] = (byte) offset;
5470:                                                break;
5471:                                            case VerificationTypeInfo.ITEM_OBJECT:
5472:                                                int indexForType = constantPool
5473:                                                        .literalIndexForType(info
5474:                                                                .constantPoolName());
5475:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
5476:                                                this .contents[localContentsOffset++] = (byte) indexForType;
5477:                                            }
5478:                                        }
5479:                                    }
5480:                                }
5481:                            }
5482:
5483:                            numberOfFrames--;
5484:                            if (numberOfFrames != 0) {
5485:                                this .contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
5486:                                this .contents[numberOfFramesOffset] = (byte) numberOfFrames;
5487:
5488:                                int attributeLength = localContentsOffset
5489:                                        - stackMapAttributeLengthOffset - 4;
5490:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
5491:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
5492:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
5493:                                this .contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
5494:                                attributeNumber++;
5495:                            } else {
5496:                                localContentsOffset = stackMapTableAttributeOffset;
5497:                            }
5498:                        }
5499:                    }
5500:                }
5501:
5502:                // update the number of attributes// ensure first that there is enough space available inside the localContents array
5503:                if (codeAttributeAttributeOffset + 2 >= this .contents.length) {
5504:                    resizeContents(2);
5505:                }
5506:                this .contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
5507:                this .contents[codeAttributeAttributeOffset] = (byte) attributeNumber;
5508:                // update the attribute length
5509:                int codeAttributeLength = localContentsOffset
5510:                        - (codeAttributeOffset + 6);
5511:                this .contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
5512:                this .contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
5513:                this .contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
5514:                this .contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
5515:                contentsOffset = localContentsOffset;
5516:            }
5517:
5518:            /**
5519:             * INTERNAL USE-ONLY
5520:             * That method completes the creation of the code attribute by setting
5521:             * - the attribute_length
5522:             * - max_stack
5523:             * - max_locals
5524:             * - code_length
5525:             * - exception table
5526:             * - and debug attributes if necessary.
5527:             *
5528:             * @param binding org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
5529:             * @param codeAttributeOffset <CODE>int</CODE>
5530:             */
5531:            public void completeCodeAttributeForSyntheticMethod(
5532:                    boolean hasExceptionHandlers,
5533:                    SyntheticMethodBinding binding, int codeAttributeOffset,
5534:                    int[] startLineIndexes) {
5535:                // reinitialize the contents with the byte modified by the code stream
5536:                this .contents = codeStream.bCodeStream;
5537:                int localContentsOffset = codeStream.classFileOffset;
5538:                // codeAttributeOffset is the position inside contents byte array before we started to write
5539:                // any information about the codeAttribute
5540:                // That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
5541:                // to get the right position, 6 for the max_stack etc...
5542:                int max_stack = codeStream.stackMax;
5543:                contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
5544:                contents[codeAttributeOffset + 7] = (byte) max_stack;
5545:                int max_locals = codeStream.maxLocals;
5546:                contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
5547:                contents[codeAttributeOffset + 9] = (byte) max_locals;
5548:                int code_length = codeStream.position;
5549:                contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
5550:                contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
5551:                contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
5552:                contents[codeAttributeOffset + 13] = (byte) code_length;
5553:                if ((localContentsOffset + 40) >= this .contents.length) {
5554:                    resizeContents(40);
5555:                }
5556:
5557:                boolean addStackMaps = (this .produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0;
5558:                if (hasExceptionHandlers) {
5559:                    // write the exception table
5560:                    ExceptionLabel[] exceptionLabels = codeStream.exceptionLabels;
5561:                    int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
5562:                    for (int i = 0, length = codeStream.exceptionLabelsCounter; i < length; i++) {
5563:                        exceptionHandlersCount += codeStream.exceptionLabels[i].count / 2;
5564:                    }
5565:                    int exSize = exceptionHandlersCount * 8 + 2;
5566:                    if (exSize + localContentsOffset >= this .contents.length) {
5567:                        resizeContents(exSize);
5568:                    }
5569:                    // there is no exception table, so we need to offset by 2 the current offset and move
5570:                    // on the attribute generation
5571:                    this .contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8);
5572:                    this .contents[localContentsOffset++] = (byte) exceptionHandlersCount;
5573:                    for (int i = 0, max = codeStream.exceptionLabelsCounter; i < max; i++) {
5574:                        ExceptionLabel exceptionLabel = exceptionLabels[i];
5575:                        if (exceptionLabel != null) {
5576:                            int iRange = 0, maxRange = exceptionLabel.count;
5577:                            if ((maxRange & 1) != 0) {
5578:                                referenceBinding.scope
5579:                                        .problemReporter()
5580:                                        .abortDueToInternalError(
5581:                                                Messages
5582:                                                        .bind(
5583:                                                                Messages.abort_invalidExceptionAttribute,
5584:                                                                new String(
5585:                                                                        binding.selector),
5586:                                                                referenceBinding.scope
5587:                                                                        .problemReporter().referenceContext));
5588:                            }
5589:                            while (iRange < maxRange) {
5590:                                int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions
5591:                                this .contents[localContentsOffset++] = (byte) (start >> 8);
5592:                                this .contents[localContentsOffset++] = (byte) start;
5593:                                int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions
5594:                                this .contents[localContentsOffset++] = (byte) (end >> 8);
5595:                                this .contents[localContentsOffset++] = (byte) end;
5596:                                int handlerPC = exceptionLabel.position;
5597:                                if (addStackMaps) {
5598:                                    StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
5599:                                    stackMapFrameCodeStream
5600:                                            .addFramePosition(handlerPC);
5601:                                    //							stackMapFrameCodeStream.addExceptionMarker(handlerPC, exceptionLabel.exceptionType);
5602:                                }
5603:                                this .contents[localContentsOffset++] = (byte) (handlerPC >> 8);
5604:                                this .contents[localContentsOffset++] = (byte) handlerPC;
5605:                                if (exceptionLabel.exceptionType == null) {
5606:                                    // any exception handler
5607:                                    this .contents[localContentsOffset++] = 0;
5608:                                    this .contents[localContentsOffset++] = 0;
5609:                                } else {
5610:                                    int nameIndex;
5611:                                    switch (exceptionLabel.exceptionType.id) {
5612:                                    case T_null:
5613:                                        /* represents ClassNotFoundException, see class literal access*/
5614:                                        nameIndex = constantPool
5615:                                                .literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
5616:                                        break;
5617:                                    case T_long:
5618:                                        /* represents NoSuchFieldError, see switch table generation*/
5619:                                        nameIndex = constantPool
5620:                                                .literalIndexForType(ConstantPool.JavaLangNoSuchFieldErrorConstantPoolName);
5621:                                        break;
5622:                                    default:
5623:                                        nameIndex = constantPool
5624:                                                .literalIndexForType(exceptionLabel.exceptionType);
5625:                                    }
5626:                                    this .contents[localContentsOffset++] = (byte) (nameIndex >> 8);
5627:                                    this .contents[localContentsOffset++] = (byte) nameIndex;
5628:                                }
5629:                            }
5630:                        }
5631:                    }
5632:                } else {
5633:                    // there is no exception table, so we need to offset by 2 the current offset and move
5634:                    // on the attribute generation
5635:                    contents[localContentsOffset++] = 0;
5636:                    contents[localContentsOffset++] = 0;
5637:                }
5638:                // debug attributes
5639:                int codeAttributeAttributeOffset = localContentsOffset;
5640:                int attributeNumber = 0;
5641:                // leave two bytes for the attribute_length
5642:                localContentsOffset += 2;
5643:                if (localContentsOffset + 2 >= this .contents.length) {
5644:                    resizeContents(2);
5645:                }
5646:
5647:                // first we handle the linenumber attribute
5648:                if ((this .produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
5649:                    if (localContentsOffset + 12 >= this .contents.length) {
5650:                        resizeContents(12);
5651:                    }
5652:                    int index = 0;
5653:                    int lineNumberNameIndex = constantPool
5654:                            .literalIndex(AttributeNamesConstants.LineNumberTableName);
5655:                    contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
5656:                    contents[localContentsOffset++] = (byte) lineNumberNameIndex;
5657:                    int lineNumberTableOffset = localContentsOffset;
5658:                    localContentsOffset += 6;
5659:                    // leave space for attribute_length and line_number_table_length
5660:                    // Seems like do would be better, but this preserves the existing behavior.
5661:                    index = Util.getLineNumber(binding.sourceStart,
5662:                            startLineIndexes, 0, startLineIndexes.length - 1);
5663:                    contents[localContentsOffset++] = 0;
5664:                    contents[localContentsOffset++] = 0;
5665:                    contents[localContentsOffset++] = (byte) (index >> 8);
5666:                    contents[localContentsOffset++] = (byte) index;
5667:                    // now we change the size of the line number attribute
5668:                    contents[lineNumberTableOffset++] = 0;
5669:                    contents[lineNumberTableOffset++] = 0;
5670:                    contents[lineNumberTableOffset++] = 0;
5671:                    contents[lineNumberTableOffset++] = 6;
5672:                    contents[lineNumberTableOffset++] = 0;
5673:                    contents[lineNumberTableOffset++] = 1;
5674:                    attributeNumber++;
5675:                }
5676:                // then we do the local variable attribute
5677:                if ((this .produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
5678:                    int numberOfEntries = 0;
5679:                    int localVariableNameIndex = constantPool
5680:                            .literalIndex(AttributeNamesConstants.LocalVariableTableName);
5681:                    if (localContentsOffset + 8 > this .contents.length) {
5682:                        resizeContents(8);
5683:                    }
5684:                    contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
5685:                    contents[localContentsOffset++] = (byte) localVariableNameIndex;
5686:                    int localVariableTableOffset = localContentsOffset;
5687:                    localContentsOffset += 6;
5688:                    // leave space for attribute_length and local_variable_table_length
5689:                    int nameIndex;
5690:                    int descriptorIndex;
5691:
5692:                    // used to remember the local variable with a generic type
5693:                    int genericLocalVariablesCounter = 0;
5694:                    LocalVariableBinding[] genericLocalVariables = null;
5695:                    int numberOfGenericEntries = 0;
5696:
5697:                    for (int i = 0, max = codeStream.allLocalsCounter; i < max; i++) {
5698:                        LocalVariableBinding localVariable = codeStream.locals[i];
5699:                        if (localVariable.declaration == null)
5700:                            continue;
5701:                        final TypeBinding localVariableTypeBinding = localVariable.type;
5702:                        boolean isParameterizedType = localVariableTypeBinding
5703:                                .isParameterizedType()
5704:                                || localVariableTypeBinding.isTypeVariable();
5705:                        if (localVariable.initializationCount != 0
5706:                                && isParameterizedType) {
5707:                            if (genericLocalVariables == null) {
5708:                                // we cannot have more than max locals
5709:                                genericLocalVariables = new LocalVariableBinding[max];
5710:                            }
5711:                            genericLocalVariables[genericLocalVariablesCounter++] = localVariable;
5712:                        }
5713:                        for (int j = 0; j < localVariable.initializationCount; j++) {
5714:                            int startPC = localVariable.initializationPCs[j << 1];
5715:                            int endPC = localVariable.initializationPCs[(j << 1) + 1];
5716:                            if (startPC != endPC) { // only entries for non zero length
5717:                                if (endPC == -1) {
5718:                                    localVariable.declaringScope
5719:                                            .problemReporter()
5720:                                            .abortDueToInternalError(
5721:                                                    Messages
5722:                                                            .bind(
5723:                                                                    Messages.abort_invalidAttribute,
5724:                                                                    new String(
5725:                                                                            localVariable.name)),
5726:                                                    (ASTNode) localVariable.declaringScope
5727:                                                            .methodScope().referenceContext);
5728:                                }
5729:                                if (localContentsOffset + 10 > this .contents.length) {
5730:                                    resizeContents(10);
5731:                                }
5732:                                // now we can safely add the local entry
5733:                                numberOfEntries++;
5734:                                if (isParameterizedType) {
5735:                                    numberOfGenericEntries++;
5736:                                }
5737:                                contents[localContentsOffset++] = (byte) (startPC >> 8);
5738:                                contents[localContentsOffset++] = (byte) startPC;
5739:                                int length = endPC - startPC;
5740:                                contents[localContentsOffset++] = (byte) (length >> 8);
5741:                                contents[localContentsOffset++] = (byte) length;
5742:                                nameIndex = constantPool
5743:                                        .literalIndex(localVariable.name);
5744:                                contents[localContentsOffset++] = (byte) (nameIndex >> 8);
5745:                                contents[localContentsOffset++] = (byte) nameIndex;
5746:                                descriptorIndex = constantPool
5747:                                        .literalIndex(localVariableTypeBinding
5748:                                                .signature());
5749:                                contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
5750:                                contents[localContentsOffset++] = (byte) descriptorIndex;
5751:                                int resolvedPosition = localVariable.resolvedPosition;
5752:                                contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
5753:                                contents[localContentsOffset++] = (byte) resolvedPosition;
5754:                            }
5755:                        }
5756:                    }
5757:                    int value = numberOfEntries * 10 + 2;
5758:                    contents[localVariableTableOffset++] = (byte) (value >> 24);
5759:                    contents[localVariableTableOffset++] = (byte) (value >> 16);
5760:                    contents[localVariableTableOffset++] = (byte) (value >> 8);
5761:                    contents[localVariableTableOffset++] = (byte) value;
5762:                    contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
5763:                    contents[localVariableTableOffset] = (byte) numberOfEntries;
5764:                    attributeNumber++;
5765:
5766:                    if (genericLocalVariablesCounter != 0) {
5767:                        // add the local variable type table attribute
5768:                        int maxOfEntries = 8 + numberOfGenericEntries * 10;
5769:                        // reserve enough space
5770:                        if (localContentsOffset + maxOfEntries >= this .contents.length) {
5771:                            resizeContents(maxOfEntries);
5772:                        }
5773:                        int localVariableTypeNameIndex = constantPool
5774:                                .literalIndex(AttributeNamesConstants.LocalVariableTypeTableName);
5775:                        contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8);
5776:                        contents[localContentsOffset++] = (byte) localVariableTypeNameIndex;
5777:                        value = numberOfGenericEntries * 10 + 2;
5778:                        contents[localContentsOffset++] = (byte) (value >> 24);
5779:                        contents[localContentsOffset++] = (byte) (value >> 16);
5780:                        contents[localContentsOffset++] = (byte) (value >> 8);
5781:                        contents[localContentsOffset++] = (byte) value;
5782:                        contents[localContentsOffset++] = (byte) (numberOfGenericEntries >> 8);
5783:                        contents[localContentsOffset++] = (byte) numberOfGenericEntries;
5784:
5785:                        for (int i = 0; i < genericLocalVariablesCounter; i++) {
5786:                            LocalVariableBinding localVariable = genericLocalVariables[i];
5787:                            for (int j = 0; j < localVariable.initializationCount; j++) {
5788:                                int startPC = localVariable.initializationPCs[j << 1];
5789:                                int endPC = localVariable.initializationPCs[(j << 1) + 1];
5790:                                if (startPC != endPC) { // only entries for non zero length
5791:                                    // now we can safely add the local entry
5792:                                    contents[localContentsOffset++] = (byte) (startPC >> 8);
5793:                                    contents[localContentsOffset++] = (byte) startPC;
5794:                                    int length = endPC - startPC;
5795:                                    contents[localContentsOffset++] = (byte) (length >> 8);
5796:                                    contents[localContentsOffset++] = (byte) length;
5797:                                    nameIndex = constantPool
5798:                                            .literalIndex(localVariable.name);
5799:                                    contents[localContentsOffset++] = (byte) (nameIndex >> 8);
5800:                                    contents[localContentsOffset++] = (byte) nameIndex;
5801:                                    descriptorIndex = constantPool
5802:                                            .literalIndex(localVariable.type
5803:                                                    .genericTypeSignature());
5804:                                    contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
5805:                                    contents[localContentsOffset++] = (byte) descriptorIndex;
5806:                                    int resolvedPosition = localVariable.resolvedPosition;
5807:                                    contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
5808:                                    contents[localContentsOffset++] = (byte) resolvedPosition;
5809:                                }
5810:                            }
5811:                        }
5812:                        attributeNumber++;
5813:                    }
5814:                }
5815:
5816:                if (addStackMaps) {
5817:                    StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
5818:                    stackMapFrameCodeStream.removeFramePosition(code_length);
5819:                    if (stackMapFrameCodeStream.hasFramePositions()) {
5820:                        ArrayList frames = new ArrayList();
5821:                        traverse(binding, max_locals, this .contents,
5822:                                codeAttributeOffset + 14, code_length, frames,
5823:                                false);
5824:                        int numberOfFrames = frames.size();
5825:                        if (numberOfFrames > 1) {
5826:                            int stackMapTableAttributeOffset = localContentsOffset;
5827:                            // add the stack map table attribute
5828:                            if (localContentsOffset + 8 >= this .contents.length) {
5829:                                resizeContents(8);
5830:                            }
5831:                            int stackMapTableAttributeNameIndex = constantPool
5832:                                    .literalIndex(AttributeNamesConstants.StackMapTableName);
5833:                            this .contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
5834:                            this .contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
5835:
5836:                            int stackMapTableAttributeLengthOffset = localContentsOffset;
5837:                            // generate the attribute
5838:                            localContentsOffset += 4;
5839:                            if (localContentsOffset + 4 >= this .contents.length) {
5840:                                resizeContents(4);
5841:                            }
5842:                            int numberOfFramesOffset = localContentsOffset;
5843:                            localContentsOffset += 2;
5844:                            if (localContentsOffset + 2 >= this .contents.length) {
5845:                                resizeContents(2);
5846:                            }
5847:                            StackMapFrame currentFrame = (StackMapFrame) frames
5848:                                    .get(0);
5849:                            StackMapFrame prevFrame = null;
5850:                            for (int j = 1; j < numberOfFrames; j++) {
5851:                                // select next frame
5852:                                prevFrame = currentFrame;
5853:                                currentFrame = (StackMapFrame) frames.get(j);
5854:                                // generate current frame
5855:                                // need to find differences between the current frame and the previous frame
5856:                                int offsetDelta = currentFrame
5857:                                        .getOffsetDelta(prevFrame);
5858:                                switch (currentFrame.getFrameType(prevFrame)) {
5859:                                case StackMapFrame.APPEND_FRAME:
5860:                                    if (localContentsOffset + 3 >= this .contents.length) {
5861:                                        resizeContents(3);
5862:                                    }
5863:                                    int numberOfDifferentLocals = currentFrame
5864:                                            .numberOfDifferentLocals(prevFrame);
5865:                                    this .contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
5866:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
5867:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
5868:                                    int index = currentFrame
5869:                                            .getIndexOfDifferentLocals(numberOfDifferentLocals);
5870:                                    int numberOfLocals = currentFrame
5871:                                            .getNumberOfLocals();
5872:                                    for (int i = index; i < currentFrame.locals.length
5873:                                            && numberOfDifferentLocals > 0; i++) {
5874:                                        if (localContentsOffset + 6 >= this .contents.length) {
5875:                                            resizeContents(6);
5876:                                        }
5877:                                        VerificationTypeInfo info = currentFrame.locals[i];
5878:                                        if (info == null) {
5879:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
5880:                                        } else {
5881:                                            switch (info.id()) {
5882:                                            case T_boolean:
5883:                                            case T_byte:
5884:                                            case T_char:
5885:                                            case T_int:
5886:                                            case T_short:
5887:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
5888:                                                break;
5889:                                            case T_float:
5890:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
5891:                                                break;
5892:                                            case T_long:
5893:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
5894:                                                i++;
5895:                                                break;
5896:                                            case T_double:
5897:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
5898:                                                i++;
5899:                                                break;
5900:                                            case T_null:
5901:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
5902:                                                break;
5903:                                            default:
5904:                                                this .contents[localContentsOffset++] = (byte) info.tag;
5905:                                                switch (info.tag) {
5906:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
5907:                                                    int offset = info.offset;
5908:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
5909:                                                    this .contents[localContentsOffset++] = (byte) offset;
5910:                                                    break;
5911:                                                case VerificationTypeInfo.ITEM_OBJECT:
5912:                                                    int indexForType = constantPool
5913:                                                            .literalIndexForType(info
5914:                                                                    .constantPoolName());
5915:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
5916:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
5917:                                                }
5918:                                            }
5919:                                            numberOfDifferentLocals--;
5920:                                        }
5921:                                    }
5922:                                    break;
5923:                                case StackMapFrame.SAME_FRAME:
5924:                                    if (localContentsOffset + 1 >= this .contents.length) {
5925:                                        resizeContents(1);
5926:                                    }
5927:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
5928:                                    break;
5929:                                case StackMapFrame.SAME_FRAME_EXTENDED:
5930:                                    if (localContentsOffset + 3 >= this .contents.length) {
5931:                                        resizeContents(3);
5932:                                    }
5933:                                    this .contents[localContentsOffset++] = (byte) 251;
5934:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
5935:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
5936:                                    break;
5937:                                case StackMapFrame.CHOP_FRAME:
5938:                                    if (localContentsOffset + 3 >= this .contents.length) {
5939:                                        resizeContents(3);
5940:                                    }
5941:                                    numberOfDifferentLocals = -currentFrame
5942:                                            .numberOfDifferentLocals(prevFrame);
5943:                                    this .contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
5944:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
5945:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
5946:                                    break;
5947:                                case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS:
5948:                                    if (localContentsOffset + 4 >= this .contents.length) {
5949:                                        resizeContents(4);
5950:                                    }
5951:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta + 64);
5952:                                    if (currentFrame.stackItems[0] == null) {
5953:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
5954:                                    } else {
5955:                                        switch (currentFrame.stackItems[0].id()) {
5956:                                        case T_boolean:
5957:                                        case T_byte:
5958:                                        case T_char:
5959:                                        case T_int:
5960:                                        case T_short:
5961:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
5962:                                            break;
5963:                                        case T_float:
5964:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
5965:                                            break;
5966:                                        case T_long:
5967:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
5968:                                            break;
5969:                                        case T_double:
5970:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
5971:                                            break;
5972:                                        case T_null:
5973:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
5974:                                            break;
5975:                                        default:
5976:                                            VerificationTypeInfo info = currentFrame.stackItems[0];
5977:                                            byte tag = (byte) info.tag;
5978:                                            this .contents[localContentsOffset++] = tag;
5979:                                            switch (tag) {
5980:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
5981:                                                int offset = info.offset;
5982:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
5983:                                                this .contents[localContentsOffset++] = (byte) offset;
5984:                                                break;
5985:                                            case VerificationTypeInfo.ITEM_OBJECT:
5986:                                                int indexForType = constantPool
5987:                                                        .literalIndexForType(info
5988:                                                                .constantPoolName());
5989:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
5990:                                                this .contents[localContentsOffset++] = (byte) indexForType;
5991:                                            }
5992:                                        }
5993:                                    }
5994:                                    break;
5995:                                case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED:
5996:                                    if (localContentsOffset + 6 >= this .contents.length) {
5997:                                        resizeContents(6);
5998:                                    }
5999:                                    this .contents[localContentsOffset++] = (byte) 247;
6000:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
6001:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
6002:                                    if (currentFrame.stackItems[0] == null) {
6003:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
6004:                                    } else {
6005:                                        switch (currentFrame.stackItems[0].id()) {
6006:                                        case T_boolean:
6007:                                        case T_byte:
6008:                                        case T_char:
6009:                                        case T_int:
6010:                                        case T_short:
6011:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
6012:                                            break;
6013:                                        case T_float:
6014:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
6015:                                            break;
6016:                                        case T_long:
6017:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
6018:                                            break;
6019:                                        case T_double:
6020:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
6021:                                            break;
6022:                                        case T_null:
6023:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
6024:                                            break;
6025:                                        default:
6026:                                            VerificationTypeInfo info = currentFrame.stackItems[0];
6027:                                            byte tag = (byte) info.tag;
6028:                                            this .contents[localContentsOffset++] = tag;
6029:                                            switch (tag) {
6030:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
6031:                                                int offset = info.offset;
6032:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
6033:                                                this .contents[localContentsOffset++] = (byte) offset;
6034:                                                break;
6035:                                            case VerificationTypeInfo.ITEM_OBJECT:
6036:                                                int indexForType = constantPool
6037:                                                        .literalIndexForType(info
6038:                                                                .constantPoolName());
6039:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
6040:                                                this .contents[localContentsOffset++] = (byte) indexForType;
6041:                                            }
6042:                                        }
6043:                                    }
6044:                                    break;
6045:                                default:
6046:                                    // FULL_FRAME
6047:                                    if (localContentsOffset + 5 >= this .contents.length) {
6048:                                        resizeContents(5);
6049:                                    }
6050:                                    this .contents[localContentsOffset++] = (byte) 255;
6051:                                    this .contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
6052:                                    this .contents[localContentsOffset++] = (byte) offsetDelta;
6053:                                    int numberOfLocalOffset = localContentsOffset;
6054:                                    localContentsOffset += 2; // leave two spots for number of locals
6055:                                    int numberOfLocalEntries = 0;
6056:                                    numberOfLocals = currentFrame
6057:                                            .getNumberOfLocals();
6058:                                    int numberOfEntries = 0;
6059:                                    int localsLength = currentFrame.locals == null ? 0
6060:                                            : currentFrame.locals.length;
6061:                                    for (int i = 0; i < localsLength
6062:                                            && numberOfLocalEntries < numberOfLocals; i++) {
6063:                                        if (localContentsOffset + 3 >= this .contents.length) {
6064:                                            resizeContents(3);
6065:                                        }
6066:                                        VerificationTypeInfo info = currentFrame.locals[i];
6067:                                        if (info == null) {
6068:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
6069:                                        } else {
6070:                                            switch (info.id()) {
6071:                                            case T_boolean:
6072:                                            case T_byte:
6073:                                            case T_char:
6074:                                            case T_int:
6075:                                            case T_short:
6076:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
6077:                                                break;
6078:                                            case T_float:
6079:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
6080:                                                break;
6081:                                            case T_long:
6082:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
6083:                                                i++;
6084:                                                break;
6085:                                            case T_double:
6086:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
6087:                                                i++;
6088:                                                break;
6089:                                            case T_null:
6090:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
6091:                                                break;
6092:                                            default:
6093:                                                this .contents[localContentsOffset++] = (byte) info.tag;
6094:                                                switch (info.tag) {
6095:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
6096:                                                    int offset = info.offset;
6097:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
6098:                                                    this .contents[localContentsOffset++] = (byte) offset;
6099:                                                    break;
6100:                                                case VerificationTypeInfo.ITEM_OBJECT:
6101:                                                    int indexForType = constantPool
6102:                                                            .literalIndexForType(info
6103:                                                                    .constantPoolName());
6104:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
6105:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
6106:                                                }
6107:                                            }
6108:                                            numberOfLocalEntries++;
6109:                                        }
6110:                                        numberOfEntries++;
6111:                                    }
6112:                                    if (localContentsOffset + 4 >= this .contents.length) {
6113:                                        resizeContents(4);
6114:                                    }
6115:                                    this .contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
6116:                                    this .contents[numberOfLocalOffset] = (byte) numberOfEntries;
6117:                                    int numberOfStackItems = currentFrame.numberOfStackItems;
6118:                                    this .contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
6119:                                    this .contents[localContentsOffset++] = (byte) numberOfStackItems;
6120:                                    for (int i = 0; i < numberOfStackItems; i++) {
6121:                                        if (localContentsOffset + 3 >= this .contents.length) {
6122:                                            resizeContents(3);
6123:                                        }
6124:                                        VerificationTypeInfo info = currentFrame.stackItems[i];
6125:                                        if (info == null) {
6126:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
6127:                                        } else {
6128:                                            switch (info.id()) {
6129:                                            case T_boolean:
6130:                                            case T_byte:
6131:                                            case T_char:
6132:                                            case T_int:
6133:                                            case T_short:
6134:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
6135:                                                break;
6136:                                            case T_float:
6137:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
6138:                                                break;
6139:                                            case T_long:
6140:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
6141:                                                break;
6142:                                            case T_double:
6143:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
6144:                                                break;
6145:                                            case T_null:
6146:                                                this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
6147:                                                break;
6148:                                            default:
6149:                                                this .contents[localContentsOffset++] = (byte) info.tag;
6150:                                                switch (info.tag) {
6151:                                                case VerificationTypeInfo.ITEM_UNINITIALIZED:
6152:                                                    int offset = info.offset;
6153:                                                    this .contents[localContentsOffset++] = (byte) (offset >> 8);
6154:                                                    this .contents[localContentsOffset++] = (byte) offset;
6155:                                                    break;
6156:                                                case VerificationTypeInfo.ITEM_OBJECT:
6157:                                                    int indexForType = constantPool
6158:                                                            .literalIndexForType(info
6159:                                                                    .constantPoolName());
6160:                                                    this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
6161:                                                    this .contents[localContentsOffset++] = (byte) indexForType;
6162:                                                }
6163:                                            }
6164:                                        }
6165:                                    }
6166:                                }
6167:                            }
6168:
6169:                            numberOfFrames--;
6170:                            if (numberOfFrames != 0) {
6171:                                this .contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
6172:                                this .contents[numberOfFramesOffset] = (byte) numberOfFrames;
6173:
6174:                                int attributeLength = localContentsOffset
6175:                                        - stackMapTableAttributeLengthOffset
6176:                                        - 4;
6177:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
6178:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
6179:                                this .contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
6180:                                this .contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
6181:                                attributeNumber++;
6182:                            } else {
6183:                                localContentsOffset = stackMapTableAttributeOffset;
6184:                            }
6185:                        }
6186:                    }
6187:                }
6188:
6189:                if ((this .produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
6190:                    StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
6191:                    stackMapFrameCodeStream.removeFramePosition(code_length);
6192:                    if (stackMapFrameCodeStream.hasFramePositions()) {
6193:                        ArrayList frames = new ArrayList();
6194:                        traverse(this .codeStream.methodDeclaration.binding,
6195:                                max_locals, this .contents,
6196:                                codeAttributeOffset + 14, code_length, frames,
6197:                                false);
6198:                        int numberOfFrames = frames.size();
6199:                        if (numberOfFrames > 1) {
6200:                            int stackMapTableAttributeOffset = localContentsOffset;
6201:                            // add the stack map table attribute
6202:                            if (localContentsOffset + 8 >= this .contents.length) {
6203:                                resizeContents(8);
6204:                            }
6205:                            int stackMapAttributeNameIndex = constantPool
6206:                                    .literalIndex(AttributeNamesConstants.StackMapName);
6207:                            this .contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
6208:                            this .contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
6209:
6210:                            int stackMapAttributeLengthOffset = localContentsOffset;
6211:                            // generate the attribute
6212:                            localContentsOffset += 4;
6213:                            if (localContentsOffset + 4 >= this .contents.length) {
6214:                                resizeContents(4);
6215:                            }
6216:                            int numberOfFramesOffset = localContentsOffset;
6217:                            localContentsOffset += 2;
6218:                            if (localContentsOffset + 2 >= this .contents.length) {
6219:                                resizeContents(2);
6220:                            }
6221:                            StackMapFrame currentFrame = (StackMapFrame) frames
6222:                                    .get(0);
6223:                            for (int j = 1; j < numberOfFrames; j++) {
6224:                                // select next frame
6225:                                currentFrame = (StackMapFrame) frames.get(j);
6226:                                // generate current frame
6227:                                // need to find differences between the current frame and the previous frame
6228:                                int frameOffset = currentFrame.pc;
6229:                                // FULL_FRAME
6230:                                if (localContentsOffset + 5 >= this .contents.length) {
6231:                                    resizeContents(5);
6232:                                }
6233:                                this .contents[localContentsOffset++] = (byte) (frameOffset >> 8);
6234:                                this .contents[localContentsOffset++] = (byte) frameOffset;
6235:                                int numberOfLocalOffset = localContentsOffset;
6236:                                localContentsOffset += 2; // leave two spots for number of locals
6237:                                int numberOfLocalEntries = 0;
6238:                                int numberOfLocals = currentFrame
6239:                                        .getNumberOfLocals();
6240:                                int numberOfEntries = 0;
6241:                                int localsLength = currentFrame.locals == null ? 0
6242:                                        : currentFrame.locals.length;
6243:                                for (int i = 0; i < localsLength
6244:                                        && numberOfLocalEntries < numberOfLocals; i++) {
6245:                                    if (localContentsOffset + 3 >= this .contents.length) {
6246:                                        resizeContents(3);
6247:                                    }
6248:                                    VerificationTypeInfo info = currentFrame.locals[i];
6249:                                    if (info == null) {
6250:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
6251:                                    } else {
6252:                                        switch (info.id()) {
6253:                                        case T_boolean:
6254:                                        case T_byte:
6255:                                        case T_char:
6256:                                        case T_int:
6257:                                        case T_short:
6258:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
6259:                                            break;
6260:                                        case T_float:
6261:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
6262:                                            break;
6263:                                        case T_long:
6264:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
6265:                                            i++;
6266:                                            break;
6267:                                        case T_double:
6268:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
6269:                                            i++;
6270:                                            break;
6271:                                        case T_null:
6272:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
6273:                                            break;
6274:                                        default:
6275:                                            this .contents[localContentsOffset++] = (byte) info.tag;
6276:                                            switch (info.tag) {
6277:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
6278:                                                int offset = info.offset;
6279:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
6280:                                                this .contents[localContentsOffset++] = (byte) offset;
6281:                                                break;
6282:                                            case VerificationTypeInfo.ITEM_OBJECT:
6283:                                                int indexForType = constantPool
6284:                                                        .literalIndexForType(info
6285:                                                                .constantPoolName());
6286:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
6287:                                                this .contents[localContentsOffset++] = (byte) indexForType;
6288:                                            }
6289:                                        }
6290:                                        numberOfLocalEntries++;
6291:                                    }
6292:                                    numberOfEntries++;
6293:                                }
6294:                                if (localContentsOffset + 4 >= this .contents.length) {
6295:                                    resizeContents(4);
6296:                                }
6297:                                this .contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
6298:                                this .contents[numberOfLocalOffset] = (byte) numberOfEntries;
6299:                                int numberOfStackItems = currentFrame.numberOfStackItems;
6300:                                this .contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
6301:                                this .contents[localContentsOffset++] = (byte) numberOfStackItems;
6302:                                for (int i = 0; i < numberOfStackItems; i++) {
6303:                                    if (localContentsOffset + 3 >= this .contents.length) {
6304:                                        resizeContents(3);
6305:                                    }
6306:                                    VerificationTypeInfo info = currentFrame.stackItems[i];
6307:                                    if (info == null) {
6308:                                        this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
6309:                                    } else {
6310:                                        switch (info.id()) {
6311:                                        case T_boolean:
6312:                                        case T_byte:
6313:                                        case T_char:
6314:                                        case T_int:
6315:                                        case T_short:
6316:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
6317:                                            break;
6318:                                        case T_float:
6319:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
6320:                                            break;
6321:                                        case T_long:
6322:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
6323:                                            break;
6324:                                        case T_double:
6325:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
6326:                                            break;
6327:                                        case T_null:
6328:                                            this .contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
6329:                                            break;
6330:                                        default:
6331:                                            this .contents[localContentsOffset++] = (byte) info.tag;
6332:                                            switch (info.tag) {
6333:                                            case VerificationTypeInfo.ITEM_UNINITIALIZED:
6334:                                                int offset = info.offset;
6335:                                                this .contents[localContentsOffset++] = (byte) (offset >> 8);
6336:                                                this .contents[localContentsOffset++] = (byte) offset;
6337:                                                break;
6338:                                            case VerificationTypeInfo.ITEM_OBJECT:
6339:                                                int indexForType = constantPool
6340:                                                        .literalIndexForType(info
6341:                                                                .constantPoolName());
6342:                                                this .contents[localContentsOffset++] = (byte) (indexForType >> 8);
6343:                                                this .contents[localContentsOffset++] = (byte) indexForType;
6344:                                            }
6345:                                        }
6346:                                    }
6347:                                }
6348:                            }
6349:
6350:                            numberOfFrames--;
6351:                            if (numberOfFrames != 0) {
6352:                                this .contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
6353:                                this .contents[numberOfFramesOffset] = (byte) numberOfFrames;
6354:
6355:                                int attributeLength = localContentsOffset
6356:                                        - stackMapAttributeLengthOffset - 4;
6357:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
6358:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
6359:                                this .contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
6360:                                this .contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
6361:                                attributeNumber++;
6362:                            } else {
6363:                                localContentsOffset = stackMapTableAttributeOffset;
6364:                            }
6365:                        }
6366:                    }
6367:                }
6368:
6369:                // update the number of attributes
6370:                // ensure first that there is enough space available inside the contents array
6371:                if (codeAttributeAttributeOffset + 2 >= this .contents.length) {
6372:                    resizeContents(2);
6373:                }
6374:                contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
6375:                contents[codeAttributeAttributeOffset] = (byte) attributeNumber;
6376:
6377:                // update the attribute length
6378:                int codeAttributeLength = localContentsOffset
6379:                        - (codeAttributeOffset + 6);
6380:                contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
6381:                contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
6382:                contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
6383:                contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
6384:                contentsOffset = localContentsOffset;
6385:            }
6386:
6387:            /**
6388:             * INTERNAL USE-ONLY
6389:             * That method completes the creation of the code attribute by setting
6390:             * - the attribute_length
6391:             * - max_stack
6392:             * - max_locals
6393:             * - code_length
6394:             * - exception table
6395:             * - and debug attributes if necessary.
6396:             *
6397:             * @param binding org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
6398:             * @param codeAttributeOffset <CODE>int</CODE>
6399:             */
6400:            public void completeCodeAttributeForSyntheticMethod(
6401:                    SyntheticMethodBinding binding, int codeAttributeOffset,
6402:                    int[] startLineIndexes) {
6403:
6404:                this .completeCodeAttributeForSyntheticMethod(false, binding,
6405:                        codeAttributeOffset, startLineIndexes);
6406:            }
6407:
6408:            /**
6409:             * INTERNAL USE-ONLY
6410:             * Complete the creation of a method info by setting up the number of attributes at the right offset.
6411:             *
6412:             * @param methodAttributeOffset <CODE>int</CODE>
6413:             * @param attributeNumber <CODE>int</CODE>
6414:             */
6415:            public void completeMethodInfo(int methodAttributeOffset,
6416:                    int attributeNumber) {
6417:                // update the number of attributes
6418:                contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
6419:                contents[methodAttributeOffset] = (byte) attributeNumber;
6420:            }
6421:
6422:            /**
6423:             * INTERNAL USE-ONLY
6424:             * This methods returns a char[] representing the file name of the receiver
6425:             *
6426:             * @return char[]
6427:             */
6428:            public char[] fileName() {
6429:                return constantPool.UTF8Cache.returnKeyFor(2);
6430:            }
6431:
6432:            private void generateAnnotation(Annotation annotation,
6433:                    int attributeOffset) {
6434:                if (contentsOffset + 4 >= this .contents.length) {
6435:                    resizeContents(4);
6436:                }
6437:                TypeBinding annotationTypeBinding = annotation.resolvedType;
6438:                if (annotationTypeBinding == null) {
6439:                    this .contentsOffset = attributeOffset;
6440:                    return;
6441:                }
6442:                final int typeIndex = constantPool
6443:                        .literalIndex(annotationTypeBinding.signature());
6444:                contents[contentsOffset++] = (byte) (typeIndex >> 8);
6445:                contents[contentsOffset++] = (byte) typeIndex;
6446:                if (annotation instanceof  NormalAnnotation) {
6447:                    NormalAnnotation normalAnnotation = (NormalAnnotation) annotation;
6448:                    MemberValuePair[] memberValuePairs = normalAnnotation.memberValuePairs;
6449:                    if (memberValuePairs != null) {
6450:                        final int memberValuePairsLength = memberValuePairs.length;
6451:                        contents[contentsOffset++] = (byte) (memberValuePairsLength >> 8);
6452:                        contents[contentsOffset++] = (byte) memberValuePairsLength;
6453:                        for (int i = 0; i < memberValuePairsLength; i++) {
6454:                            MemberValuePair memberValuePair = memberValuePairs[i];
6455:                            if (contentsOffset + 2 >= this .contents.length) {
6456:                                resizeContents(2);
6457:                            }
6458:                            final int elementNameIndex = constantPool
6459:                                    .literalIndex(memberValuePair.name);
6460:                            contents[contentsOffset++] = (byte) (elementNameIndex >> 8);
6461:                            contents[contentsOffset++] = (byte) elementNameIndex;
6462:                            MethodBinding methodBinding = memberValuePair.binding;
6463:                            if (methodBinding == null) {
6464:                                contentsOffset = attributeOffset;
6465:                            } else {
6466:                                generateElementValue(memberValuePair.value,
6467:                                        methodBinding.returnType,
6468:                                        attributeOffset);
6469:                            }
6470:                        }
6471:                    } else {
6472:                        contents[contentsOffset++] = 0;
6473:                        contents[contentsOffset++] = 0;
6474:                    }
6475:                } else if (annotation instanceof  SingleMemberAnnotation) {
6476:                    SingleMemberAnnotation singleMemberAnnotation = (SingleMemberAnnotation) annotation;
6477:                    // this is a single member annotation (one member value)
6478:                    contents[contentsOffset++] = 0;
6479:                    contents[contentsOffset++] = 1;
6480:                    if (contentsOffset + 2 >= this .contents.length) {
6481:                        resizeContents(2);
6482:                    }
6483:                    final int elementNameIndex = constantPool
6484:                            .literalIndex(VALUE);
6485:                    contents[contentsOffset++] = (byte) (elementNameIndex >> 8);
6486:                    contents[contentsOffset++] = (byte) elementNameIndex;
6487:                    MethodBinding methodBinding = singleMemberAnnotation
6488:                            .memberValuePairs()[0].binding;
6489:                    if (methodBinding == null) {
6490:                        contentsOffset = attributeOffset;
6491:                    } else {
6492:                        generateElementValue(
6493:                                singleMemberAnnotation.memberValue,
6494:                                methodBinding.returnType, attributeOffset);
6495:                    }
6496:                } else {
6497:                    // this is a marker annotation (no member value pairs)
6498:                    contents[contentsOffset++] = 0;
6499:                    contents[contentsOffset++] = 0;
6500:                }
6501:            }
6502:
6503:            /**
6504:             * INTERNAL USE-ONLY
6505:             * That method generates the header of a code attribute.
6506:             * - the index inside the constant pool for the attribute name ("Code")
6507:             * - leave some space for attribute_length(4), max_stack(2), max_locals(2), code_length(4).
6508:             */
6509:            public void generateCodeAttributeHeader() {
6510:                if (contentsOffset + 20 >= this .contents.length) {
6511:                    resizeContents(20);
6512:                }
6513:                int constantValueNameIndex = constantPool
6514:                        .literalIndex(AttributeNamesConstants.CodeName);
6515:                contents[contentsOffset++] = (byte) (constantValueNameIndex >> 8);
6516:                contents[contentsOffset++] = (byte) constantValueNameIndex;
6517:                // leave space for attribute_length(4), max_stack(2), max_locals(2), code_length(4)
6518:                contentsOffset += 12;
6519:            }
6520:
6521:            private void generateElementValue(Expression defaultValue,
6522:                    TypeBinding memberValuePairReturnType, int attributeOffset) {
6523:                Constant constant = defaultValue.constant;
6524:                TypeBinding defaultValueBinding = defaultValue.resolvedType;
6525:                if (defaultValueBinding == null) {
6526:                    contentsOffset = attributeOffset;
6527:                } else {
6528:                    if (memberValuePairReturnType.isArrayType()
6529:                            && !defaultValueBinding.isArrayType()) {
6530:                        // automatic wrapping
6531:                        if (contentsOffset + 3 >= this .contents.length) {
6532:                            resizeContents(3);
6533:                        }
6534:                        contents[contentsOffset++] = (byte) '[';
6535:                        contents[contentsOffset++] = (byte) 0;
6536:                        contents[contentsOffset++] = (byte) 1;
6537:                    }
6538:                    if (constant != null && constant != Constant.NotAConstant) {
6539:                        generateElementValue(attributeOffset, defaultValue,
6540:                                constant, memberValuePairReturnType
6541:                                        .leafComponentType());
6542:                    } else {
6543:                        generateElementValueForNonConstantExpression(
6544:                                defaultValue, attributeOffset,
6545:                                defaultValueBinding);
6546:                    }
6547:                }
6548:            }
6549:
6550:            /**
6551:             * @param attributeOffset
6552:             */
6553:            private void generateElementValue(int attributeOffset,
6554:                    Expression defaultValue, Constant constant,
6555:                    TypeBinding binding) {
6556:                if (contentsOffset + 3 >= this .contents.length) {
6557:                    resizeContents(3);
6558:                }
6559:                switch (binding.id) {
6560:                case T_boolean:
6561:                    contents[contentsOffset++] = (byte) 'Z';
6562:                    int booleanValueIndex = constantPool.literalIndex(constant
6563:                            .booleanValue() ? 1 : 0);
6564:                    contents[contentsOffset++] = (byte) (booleanValueIndex >> 8);
6565:                    contents[contentsOffset++] = (byte) booleanValueIndex;
6566:                    break;
6567:                case T_byte:
6568:                    contents[contentsOffset++] = (byte) 'B';
6569:                    int integerValueIndex = constantPool.literalIndex(constant
6570:                            .intValue());
6571:                    contents[contentsOffset++] = (byte) (integerValueIndex >> 8);
6572:                    contents[contentsOffset++] = (byte) integerValueIndex;
6573:                    break;
6574:                case T_char:
6575:                    contents[contentsOffset++] = (byte) 'C';
6576:                    integerValueIndex = constantPool.literalIndex(constant
6577:                            .intValue());
6578:                    contents[contentsOffset++] = (byte) (integerValueIndex >> 8);
6579:                    contents[contentsOffset++] = (byte) integerValueIndex;
6580:                    break;
6581:                case T_int:
6582:                    contents[contentsOffset++] = (byte) 'I';
6583:                    integerValueIndex = constantPool.literalIndex(constant
6584:                            .intValue());
6585:                    contents[contentsOffset++] = (byte) (integerValueIndex >> 8);
6586:                    contents[contentsOffset++] = (byte) integerValueIndex;
6587:                    break;
6588:                case T_short:
6589:                    contents[contentsOffset++] = (byte) 'S';
6590:                    integerValueIndex = constantPool.literalIndex(constant
6591:                            .intValue());
6592:                    contents[contentsOffset++] = (byte) (integerValueIndex >> 8);
6593:                    contents[contentsOffset++] = (byte) integerValueIndex;
6594:                    break;
6595:                case T_float:
6596:                    contents[contentsOffset++] = (byte) 'F';
6597:                    int floatValueIndex = constantPool.literalIndex(constant
6598:                            .floatValue());
6599:                    contents[contentsOffset++] = (byte) (floatValueIndex >> 8);
6600:                    contents[contentsOffset++] = (byte) floatValueIndex;
6601:                    break;
6602:                case T_double:
6603:                    contents[contentsOffset++] = (byte) 'D';
6604:                    int doubleValueIndex = constantPool.literalIndex(constant
6605:                            .doubleValue());
6606:                    contents[contentsOffset++] = (byte) (doubleValueIndex >> 8);
6607:                    contents[contentsOffset++] = (byte) doubleValueIndex;
6608:                    break;
6609:                case T_long:
6610:                    contents[contentsOffset++] = (byte) 'J';
6611:                    int longValueIndex = constantPool.literalIndex(constant
6612:                            .longValue());
6613:                    contents[contentsOffset++] = (byte) (longValueIndex >> 8);
6614:                    contents[contentsOffset++] = (byte) longValueIndex;
6615:                    break;
6616:                case T_JavaLangString:
6617:                    contents[contentsOffset++] = (byte) 's';
6618:                    int stringValueIndex = constantPool
6619:                            .literalIndex(((StringConstant) constant)
6620:                                    .stringValue().toCharArray());
6621:                    if (stringValueIndex == -1) {
6622:                        if (!creatingProblemType) {
6623:                            // report an error and abort: will lead to a problem type classfile creation
6624:                            TypeDeclaration typeDeclaration = referenceBinding.scope.referenceContext;
6625:                            typeDeclaration.scope.problemReporter()
6626:                                    .stringConstantIsExceedingUtf8Limit(
6627:                                            defaultValue);
6628:                        } else {
6629:                            // already inside a problem type creation : no attribute
6630:                            contentsOffset = attributeOffset;
6631:                        }
6632:                    } else {
6633:                        contents[contentsOffset++] = (byte) (stringValueIndex >> 8);
6634:                        contents[contentsOffset++] = (byte) stringValueIndex;
6635:                    }
6636:                }
6637:            }
6638:
6639:            private void generateElementValueForNonConstantExpression(
6640:                    Expression defaultValue, int attributeOffset,
6641:                    TypeBinding defaultValueBinding) {
6642:                if (defaultValueBinding != null) {
6643:                    if (defaultValueBinding.isEnum()) {
6644:                        if (contentsOffset + 5 >= this .contents.length) {
6645:                            resizeContents(5);
6646:                        }
6647:                        contents[contentsOffset++] = (byte) 'e';
6648:                        FieldBinding fieldBinding = null;
6649:                        if (defaultValue instanceof  QualifiedNameReference) {
6650:                            QualifiedNameReference nameReference = (QualifiedNameReference) defaultValue;
6651:                            fieldBinding = (FieldBinding) nameReference.binding;
6652:                        } else if (defaultValue instanceof  SingleNameReference) {
6653:                            SingleNameReference nameReference = (SingleNameReference) defaultValue;
6654:                            fieldBinding = (FieldBinding) nameReference.binding;
6655:                        } else {
6656:                            contentsOffset = attributeOffset;
6657:                        }
6658:                        if (fieldBinding != null) {
6659:                            final int enumConstantTypeNameIndex = constantPool
6660:                                    .literalIndex(fieldBinding.type.signature());
6661:                            final int enumConstantNameIndex = constantPool
6662:                                    .literalIndex(fieldBinding.name);
6663:                            contents[contentsOffset++] = (byte) (enumConstantTypeNameIndex >> 8);
6664:                            contents[contentsOffset++] = (byte) enumConstantTypeNameIndex;
6665:                            contents[contentsOffset++] = (byte) (enumConstantNameIndex >> 8);
6666:                            contents[contentsOffset++] = (byte) enumConstantNameIndex;
6667:                        }
6668:                    } else if (defaultValueBinding.isAnnotationType()) {
6669:                        if (contentsOffset + 1 >= this .contents.length) {
6670:                            resizeContents(1);
6671:                        }
6672:                        contents[contentsOffset++] = (byte) '@';
6673:                        generateAnnotation((Annotation) defaultValue,
6674:                                attributeOffset);
6675:                    } else if (defaultValueBinding.isArrayType()) {
6676:                        // array type
6677:                        if (contentsOffset + 3 >= this .contents.length) {
6678:                            resizeContents(3);
6679:                        }
6680:                        contents[contentsOffset++] = (byte) '[';
6681:                        if (defaultValue instanceof  ArrayInitializer) {
6682:                            ArrayInitializer arrayInitializer = (ArrayInitializer) defaultValue;
6683:                            int arrayLength = arrayInitializer.expressions != null ? arrayInitializer.expressions.length
6684:                                    : 0;
6685:                            contents[contentsOffset++] = (byte) (arrayLength >> 8);
6686:                            contents[contentsOffset++] = (byte) arrayLength;
6687:                            for (int i = 0; i < arrayLength; i++) {
6688:                                generateElementValue(
6689:                                        arrayInitializer.expressions[i],
6690:                                        defaultValueBinding.leafComponentType(),
6691:                                        attributeOffset);
6692:                            }
6693:                        } else {
6694:                            contentsOffset = attributeOffset;
6695:                        }
6696:                    } else {
6697:                        // class type
6698:                        if (contentsOffset + 3 >= this .contents.length) {
6699:                            resizeContents(3);
6700:                        }
6701:                        contents[contentsOffset++] = (byte) 'c';
6702:                        if (defaultValue instanceof  ClassLiteralAccess) {
6703:                            ClassLiteralAccess classLiteralAccess = (ClassLiteralAccess) defaultValue;
6704:                            final int classInfoIndex = constantPool
6705:                                    .literalIndex(classLiteralAccess.targetType
6706:                                            .signature());
6707:                            contents[contentsOffset++] = (byte) (classInfoIndex >> 8);
6708:                            contents[contentsOffset++] = (byte) classInfoIndex;
6709:                        } else {
6710:                            contentsOffset = attributeOffset;
6711:                        }
6712:                    }
6713:                } else {
6714:                    contentsOffset = attributeOffset;
6715:                }
6716:            }
6717:
6718:            public int generateMethodInfoAttribute(MethodBinding methodBinding) {
6719:                return generateMethodInfoAttribute(methodBinding, false);
6720:            }
6721:
6722:            public int generateMethodInfoAttribute(MethodBinding methodBinding,
6723:                    AnnotationMethodDeclaration declaration) {
6724:                int attributesNumber = generateMethodInfoAttribute(methodBinding);
6725:                int attributeOffset = contentsOffset;
6726:                if ((declaration.modifiers & ClassFileConstants.AccAnnotationDefault) != 0) {
6727:                    // add an annotation default attribute
6728:                    int annotationDefaultNameIndex = constantPool
6729:                            .literalIndex(AttributeNamesConstants.AnnotationDefaultName);
6730:                    contents[contentsOffset++] = (byte) (annotationDefaultNameIndex >> 8);
6731:                    contents[contentsOffset++] = (byte) annotationDefaultNameIndex;
6732:                    int attributeLengthOffset = contentsOffset;
6733:                    contentsOffset += 4;
6734:                    if (contentsOffset + 4 >= this .contents.length) {
6735:                        resizeContents(4);
6736:                    }
6737:                    generateElementValue(declaration.defaultValue,
6738:                            declaration.binding.returnType, attributeOffset);
6739:                    if (contentsOffset != attributeOffset) {
6740:                        int attributeLength = contentsOffset
6741:                                - attributeLengthOffset - 4;
6742:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
6743:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
6744:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
6745:                        contents[attributeLengthOffset++] = (byte) attributeLength;
6746:                        attributesNumber++;
6747:                    }
6748:                }
6749:                return attributesNumber;
6750:            }
6751:
6752:            /**
6753:             * INTERNAL USE-ONLY
6754:             * That method generates the attributes of a code attribute.
6755:             * They could be:
6756:             * - an exception attribute for each try/catch found inside the method
6757:             * - a deprecated attribute
6758:             * - a synthetic attribute for synthetic access methods
6759:             *
6760:             * It returns the number of attributes created for the code attribute.
6761:             *
6762:             * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
6763:             * @return <CODE>int</CODE>
6764:             */
6765:            public int generateMethodInfoAttribute(MethodBinding methodBinding,
6766:                    boolean createProblemMethod) {
6767:                // leave two bytes for the attribute_number
6768:                contentsOffset += 2;
6769:                if (contentsOffset + 2 >= this .contents.length) {
6770:                    resizeContents(2);
6771:                }
6772:                // now we can handle all the attribute for that method info:
6773:                // it could be:
6774:                // - a CodeAttribute
6775:                // - a ExceptionAttribute
6776:                // - a DeprecatedAttribute
6777:                // - a SyntheticAttribute
6778:
6779:                // Exception attribute
6780:                ReferenceBinding[] thrownsExceptions;
6781:                int attributeNumber = 0;
6782:                if ((thrownsExceptions = methodBinding.thrownExceptions) != Binding.NO_EXCEPTIONS) {
6783:                    // The method has a throw clause. So we need to add an exception attribute
6784:                    // check that there is enough space to write all the bytes for the exception attribute
6785:                    int length = thrownsExceptions.length;
6786:                    int exSize = 8 + length * 2;
6787:                    if (exSize + contentsOffset >= this .contents.length) {
6788:                        resizeContents(exSize);
6789:                    }
6790:                    int exceptionNameIndex = constantPool
6791:                            .literalIndex(AttributeNamesConstants.ExceptionsName);
6792:                    contents[contentsOffset++] = (byte) (exceptionNameIndex >> 8);
6793:                    contents[contentsOffset++] = (byte) exceptionNameIndex;
6794:                    // The attribute length = length * 2 + 2 in case of a exception attribute
6795:                    int attributeLength = length * 2 + 2;
6796:                    contents[contentsOffset++] = (byte) (attributeLength >> 24);
6797:                    contents[contentsOffset++] = (byte) (attributeLength >> 16);
6798:                    contents[contentsOffset++] = (byte) (attributeLength >> 8);
6799:                    contents[contentsOffset++] = (byte) attributeLength;
6800:                    contents[contentsOffset++] = (byte) (length >> 8);
6801:                    contents[contentsOffset++] = (byte) length;
6802:                    for (int i = 0; i < length; i++) {
6803:                        int exceptionIndex = constantPool
6804:                                .literalIndexForType(thrownsExceptions[i]);
6805:                        contents[contentsOffset++] = (byte) (exceptionIndex >> 8);
6806:                        contents[contentsOffset++] = (byte) exceptionIndex;
6807:                    }
6808:                    attributeNumber++;
6809:                }
6810:                if (methodBinding.isDeprecated()) {
6811:                    // Deprecated attribute
6812:                    // Check that there is enough space to write the deprecated attribute
6813:                    if (contentsOffset + 6 >= this .contents.length) {
6814:                        resizeContents(6);
6815:                    }
6816:                    int deprecatedAttributeNameIndex = constantPool
6817:                            .literalIndex(AttributeNamesConstants.DeprecatedName);
6818:                    contents[contentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8);
6819:                    contents[contentsOffset++] = (byte) deprecatedAttributeNameIndex;
6820:                    // the length of a deprecated attribute is equals to 0
6821:                    contents[contentsOffset++] = 0;
6822:                    contents[contentsOffset++] = 0;
6823:                    contents[contentsOffset++] = 0;
6824:                    contents[contentsOffset++] = 0;
6825:
6826:                    attributeNumber++;
6827:                }
6828:                if (this .targetJDK < ClassFileConstants.JDK1_5) {
6829:                    if (methodBinding.isSynthetic()) {
6830:                        // Synthetic attribute
6831:                        // Check that there is enough space to write the deprecated attribute
6832:                        if (contentsOffset + 6 >= this .contents.length) {
6833:                            resizeContents(6);
6834:                        }
6835:                        int syntheticAttributeNameIndex = constantPool
6836:                                .literalIndex(AttributeNamesConstants.SyntheticName);
6837:                        contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
6838:                        contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
6839:                        // the length of a synthetic attribute is equals to 0
6840:                        contents[contentsOffset++] = 0;
6841:                        contents[contentsOffset++] = 0;
6842:                        contents[contentsOffset++] = 0;
6843:                        contents[contentsOffset++] = 0;
6844:
6845:                        attributeNumber++;
6846:                    }
6847:                    if (methodBinding.isVarargs()) {
6848:                        /*
6849:                         * handle of the target jsr14 for varargs in the source
6850:                         * Varargs attribute
6851:                         * Check that there is enough space to write the deprecated attribute
6852:                         */
6853:                        if (contentsOffset + 6 >= this .contents.length) {
6854:                            resizeContents(6);
6855:                        }
6856:                        int varargsAttributeNameIndex = constantPool
6857:                                .literalIndex(AttributeNamesConstants.VarargsName);
6858:                        contents[contentsOffset++] = (byte) (varargsAttributeNameIndex >> 8);
6859:                        contents[contentsOffset++] = (byte) varargsAttributeNameIndex;
6860:                        // the length of a varargs attribute is equals to 0
6861:                        contents[contentsOffset++] = 0;
6862:                        contents[contentsOffset++] = 0;
6863:                        contents[contentsOffset++] = 0;
6864:                        contents[contentsOffset++] = 0;
6865:
6866:                        attributeNumber++;
6867:                    }
6868:                }
6869:                // add signature attribute
6870:                char[] genericSignature = methodBinding.genericSignature();
6871:                if (genericSignature != null) {
6872:                    // check that there is enough space to write all the bytes for the field info corresponding
6873:                    // to the @fieldBinding
6874:                    if (contentsOffset + 8 >= this .contents.length) {
6875:                        resizeContents(8);
6876:                    }
6877:                    int signatureAttributeNameIndex = constantPool
6878:                            .literalIndex(AttributeNamesConstants.SignatureName);
6879:                    contents[contentsOffset++] = (byte) (signatureAttributeNameIndex >> 8);
6880:                    contents[contentsOffset++] = (byte) signatureAttributeNameIndex;
6881:                    // the length of a signature attribute is equals to 2
6882:                    contents[contentsOffset++] = 0;
6883:                    contents[contentsOffset++] = 0;
6884:                    contents[contentsOffset++] = 0;
6885:                    contents[contentsOffset++] = 2;
6886:                    int signatureIndex = constantPool
6887:                            .literalIndex(genericSignature);
6888:                    contents[contentsOffset++] = (byte) (signatureIndex >> 8);
6889:                    contents[contentsOffset++] = (byte) signatureIndex;
6890:                    attributeNumber++;
6891:                }
6892:                if (this .targetJDK >= ClassFileConstants.JDK1_5
6893:                        && !this .creatingProblemType && !createProblemMethod) {
6894:                    AbstractMethodDeclaration methodDeclaration = methodBinding
6895:                            .sourceMethod();
6896:                    if (methodDeclaration != null) {
6897:                        Annotation[] annotations = methodDeclaration.annotations;
6898:                        if (annotations != null) {
6899:                            attributeNumber += generateRuntimeAnnotations(annotations);
6900:                        }
6901:                        if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) {
6902:                            Argument[] arguments = methodDeclaration.arguments;
6903:                            if (arguments != null) {
6904:                                attributeNumber += generateRuntimeAnnotationsForParameters(arguments);
6905:                            }
6906:                        }
6907:                    }
6908:                }
6909:                return attributeNumber;
6910:            }
6911:
6912:            /**
6913:             * INTERNAL USE-ONLY
6914:             * That method generates the header of a method info:
6915:             * The header consists in:
6916:             * - the access flags
6917:             * - the name index of the method name inside the constant pool
6918:             * - the descriptor index of the signature of the method inside the constant pool.
6919:             *
6920:             * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
6921:             */
6922:            public void generateMethodInfoHeader(MethodBinding methodBinding) {
6923:                generateMethodInfoHeader(methodBinding, methodBinding.modifiers);
6924:            }
6925:
6926:            /**
6927:             * INTERNAL USE-ONLY
6928:             * That method generates the header of a method info:
6929:             * The header consists in:
6930:             * - the access flags
6931:             * - the name index of the method name inside the constant pool
6932:             * - the descriptor index of the signature of the method inside the constant pool.
6933:             *
6934:             * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
6935:             * @param accessFlags the access flags
6936:             */
6937:            public void generateMethodInfoHeader(MethodBinding methodBinding,
6938:                    int accessFlags) {
6939:                // check that there is enough space to write all the bytes for the method info corresponding
6940:                // to the @methodBinding
6941:                methodCount++; // add one more method
6942:                if (contentsOffset + 10 >= this .contents.length) {
6943:                    resizeContents(10);
6944:                }
6945:                if (targetJDK < ClassFileConstants.JDK1_5) {
6946:                    // pre 1.5, synthetic is an attribute, not a modifier
6947:                    // pre 1.5, varargs is an attribute, not a modifier (-target jsr14 mode)
6948:                    accessFlags &= ~(ClassFileConstants.AccSynthetic | ClassFileConstants.AccVarargs);
6949:                }
6950:                if ((methodBinding.tagBits & TagBits.ClearPrivateModifier) != 0) {
6951:                    accessFlags &= ~ClassFileConstants.AccPrivate;
6952:                }
6953:                contents[contentsOffset++] = (byte) (accessFlags >> 8);
6954:                contents[contentsOffset++] = (byte) accessFlags;
6955:                int nameIndex = constantPool
6956:                        .literalIndex(methodBinding.selector);
6957:                contents[contentsOffset++] = (byte) (nameIndex >> 8);
6958:                contents[contentsOffset++] = (byte) nameIndex;
6959:                int descriptorIndex = constantPool.literalIndex(methodBinding
6960:                        .signature(this ));
6961:                contents[contentsOffset++] = (byte) (descriptorIndex >> 8);
6962:                contents[contentsOffset++] = (byte) descriptorIndex;
6963:            }
6964:
6965:            /**
6966:             * INTERNAL USE-ONLY
6967:             * That method generates the method info header of a clinit:
6968:             * The header consists in:
6969:             * - the access flags (always default access + static)
6970:             * - the name index of the method name (always <clinit>) inside the constant pool
6971:             * - the descriptor index of the signature (always ()V) of the method inside the constant pool.
6972:             */
6973:            public void generateMethodInfoHeaderForClinit() {
6974:                // check that there is enough space to write all the bytes for the method info corresponding
6975:                // to the @methodBinding
6976:                methodCount++; // add one more method
6977:                if (contentsOffset + 10 >= this .contents.length) {
6978:                    resizeContents(10);
6979:                }
6980:                contents[contentsOffset++] = (byte) ((ClassFileConstants.AccDefault | ClassFileConstants.AccStatic) >> 8);
6981:                contents[contentsOffset++] = (byte) (ClassFileConstants.AccDefault | ClassFileConstants.AccStatic);
6982:                int nameIndex = constantPool.literalIndex(ConstantPool.Clinit);
6983:                contents[contentsOffset++] = (byte) (nameIndex >> 8);
6984:                contents[contentsOffset++] = (byte) nameIndex;
6985:                int descriptorIndex = constantPool
6986:                        .literalIndex(ConstantPool.ClinitSignature);
6987:                contents[contentsOffset++] = (byte) (descriptorIndex >> 8);
6988:                contents[contentsOffset++] = (byte) descriptorIndex;
6989:                // We know that we won't get more than 1 attribute: the code attribute
6990:                contents[contentsOffset++] = 0;
6991:                contents[contentsOffset++] = 1;
6992:            }
6993:
6994:            /**
6995:             * INTERNAL USE-ONLY
6996:             * Generate the byte for problem method infos that correspond to missing abstract methods.
6997:             * http://dev.eclipse.org/bugs/show_bug.cgi?id=3179
6998:             *
6999:             * @param methodDeclarations Array of all missing abstract methods
7000:             */
7001:            public void generateMissingAbstractMethods(
7002:                    MethodDeclaration[] methodDeclarations,
7003:                    CompilationResult compilationResult) {
7004:                if (methodDeclarations != null) {
7005:                    TypeDeclaration currentDeclaration = this .referenceBinding.scope.referenceContext;
7006:                    int typeDeclarationSourceStart = currentDeclaration
7007:                            .sourceStart();
7008:                    int typeDeclarationSourceEnd = currentDeclaration
7009:                            .sourceEnd();
7010:                    for (int i = 0, max = methodDeclarations.length; i < max; i++) {
7011:                        MethodDeclaration methodDeclaration = methodDeclarations[i];
7012:                        MethodBinding methodBinding = methodDeclaration.binding;
7013:                        String readableName = new String(methodBinding
7014:                                .readableName());
7015:                        CategorizedProblem[] problems = compilationResult.problems;
7016:                        int problemsCount = compilationResult.problemCount;
7017:                        for (int j = 0; j < problemsCount; j++) {
7018:                            CategorizedProblem problem = problems[j];
7019:                            if (problem != null
7020:                                    && problem.getID() == IProblem.AbstractMethodMustBeImplemented
7021:                                    && problem.getMessage().indexOf(
7022:                                            readableName) != -1
7023:                                    && problem.getSourceStart() >= typeDeclarationSourceStart
7024:                                    && problem.getSourceEnd() <= typeDeclarationSourceEnd) {
7025:                                // we found a match
7026:                                addMissingAbstractProblemMethod(
7027:                                        methodDeclaration, methodBinding,
7028:                                        problem, compilationResult);
7029:                            }
7030:                        }
7031:                    }
7032:                }
7033:            }
7034:
7035:            /**
7036:             * @param annotations
7037:             * @return the number of attributes created while dumping the annotations in the .class file
7038:             */
7039:            private int generateRuntimeAnnotations(
7040:                    final Annotation[] annotations) {
7041:                int attributesNumber = 0;
7042:                final int length = annotations.length;
7043:                int visibleAnnotationsCounter = 0;
7044:                int invisibleAnnotationsCounter = 0;
7045:
7046:                for (int i = 0; i < length; i++) {
7047:                    Annotation annotation = annotations[i];
7048:                    if (isRuntimeInvisible(annotation)) {
7049:                        invisibleAnnotationsCounter++;
7050:                    } else if (isRuntimeVisible(annotation)) {
7051:                        visibleAnnotationsCounter++;
7052:                    }
7053:                }
7054:
7055:                if (invisibleAnnotationsCounter != 0) {
7056:                    int annotationAttributeOffset = contentsOffset;
7057:                    if (contentsOffset + 10 >= contents.length) {
7058:                        resizeContents(10);
7059:                    }
7060:                    int runtimeInvisibleAnnotationsAttributeNameIndex = constantPool
7061:                            .literalIndex(AttributeNamesConstants.RuntimeInvisibleAnnotationsName);
7062:                    contents[contentsOffset++] = (byte) (runtimeInvisibleAnnotationsAttributeNameIndex >> 8);
7063:                    contents[contentsOffset++] = (byte) runtimeInvisibleAnnotationsAttributeNameIndex;
7064:                    int attributeLengthOffset = contentsOffset;
7065:                    contentsOffset += 4; // leave space for the attribute length
7066:
7067:                    int annotationsLengthOffset = contentsOffset;
7068:                    contentsOffset += 2; // leave space for the annotations length
7069:
7070:                    contents[annotationsLengthOffset++] = (byte) (invisibleAnnotationsCounter >> 8);
7071:                    contents[annotationsLengthOffset++] = (byte) invisibleAnnotationsCounter;
7072:
7073:                    loop: for (int i = 0; i < length; i++) {
7074:                        if (invisibleAnnotationsCounter == 0)
7075:                            break loop;
7076:                        Annotation annotation = annotations[i];
7077:                        if (isRuntimeInvisible(annotation)) {
7078:                            generateAnnotation(annotation,
7079:                                    annotationAttributeOffset);
7080:                            invisibleAnnotationsCounter--;
7081:                            if (this .contentsOffset == annotationAttributeOffset) {
7082:                                break loop;
7083:                            }
7084:                        }
7085:                    }
7086:                    if (contentsOffset != annotationAttributeOffset) {
7087:                        int attributeLength = contentsOffset
7088:                                - attributeLengthOffset - 4;
7089:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
7090:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
7091:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
7092:                        contents[attributeLengthOffset++] = (byte) attributeLength;
7093:                        attributesNumber++;
7094:                    } else {
7095:                        contentsOffset = annotationAttributeOffset;
7096:                    }
7097:                }
7098:
7099:                if (visibleAnnotationsCounter != 0) {
7100:                    int annotationAttributeOffset = contentsOffset;
7101:                    if (contentsOffset + 10 >= contents.length) {
7102:                        resizeContents(10);
7103:                    }
7104:                    int runtimeVisibleAnnotationsAttributeNameIndex = constantPool
7105:                            .literalIndex(AttributeNamesConstants.RuntimeVisibleAnnotationsName);
7106:                    contents[contentsOffset++] = (byte) (runtimeVisibleAnnotationsAttributeNameIndex >> 8);
7107:                    contents[contentsOffset++] = (byte) runtimeVisibleAnnotationsAttributeNameIndex;
7108:                    int attributeLengthOffset = contentsOffset;
7109:                    contentsOffset += 4; // leave space for the attribute length
7110:
7111:                    int annotationsLengthOffset = contentsOffset;
7112:                    contentsOffset += 2; // leave space for the annotations length
7113:
7114:                    contents[annotationsLengthOffset++] = (byte) (visibleAnnotationsCounter >> 8);
7115:                    contents[annotationsLengthOffset++] = (byte) visibleAnnotationsCounter;
7116:
7117:                    loop: for (int i = 0; i < length; i++) {
7118:                        if (visibleAnnotationsCounter == 0)
7119:                            break loop;
7120:                        Annotation annotation = annotations[i];
7121:                        if (isRuntimeVisible(annotation)) {
7122:                            visibleAnnotationsCounter--;
7123:                            generateAnnotation(annotation,
7124:                                    annotationAttributeOffset);
7125:                            if (this .contentsOffset == annotationAttributeOffset) {
7126:                                break loop;
7127:                            }
7128:                        }
7129:                    }
7130:                    if (contentsOffset != annotationAttributeOffset) {
7131:                        int attributeLength = contentsOffset
7132:                                - attributeLengthOffset - 4;
7133:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
7134:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
7135:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
7136:                        contents[attributeLengthOffset++] = (byte) attributeLength;
7137:                        attributesNumber++;
7138:                    } else {
7139:                        contentsOffset = annotationAttributeOffset;
7140:                    }
7141:                }
7142:                return attributesNumber;
7143:            }
7144:
7145:            private int generateRuntimeAnnotationsForParameters(
7146:                    Argument[] arguments) {
7147:                final int argumentsLength = arguments.length;
7148:                final int VISIBLE_INDEX = 0;
7149:                final int INVISIBLE_INDEX = 1;
7150:                int invisibleParametersAnnotationsCounter = 0;
7151:                int visibleParametersAnnotationsCounter = 0;
7152:                int[][] annotationsCounters = new int[argumentsLength][2];
7153:                for (int i = 0; i < argumentsLength; i++) {
7154:                    Argument argument = arguments[i];
7155:                    Annotation[] annotations = argument.annotations;
7156:                    if (annotations != null) {
7157:                        for (int j = 0, max2 = annotations.length; j < max2; j++) {
7158:                            Annotation annotation = annotations[j];
7159:                            if (isRuntimeInvisible(annotation)) {
7160:                                annotationsCounters[i][INVISIBLE_INDEX]++;
7161:                                invisibleParametersAnnotationsCounter++;
7162:                            } else if (isRuntimeVisible(annotation)) {
7163:                                annotationsCounters[i][VISIBLE_INDEX]++;
7164:                                visibleParametersAnnotationsCounter++;
7165:                            }
7166:                        }
7167:                    }
7168:                }
7169:                int attributesNumber = 0;
7170:                int annotationAttributeOffset = contentsOffset;
7171:                if (invisibleParametersAnnotationsCounter != 0) {
7172:                    if (contentsOffset + 7 >= contents.length) {
7173:                        resizeContents(7);
7174:                    }
7175:                    int attributeNameIndex = constantPool
7176:                            .literalIndex(AttributeNamesConstants.RuntimeInvisibleParameterAnnotationsName);
7177:                    contents[contentsOffset++] = (byte) (attributeNameIndex >> 8);
7178:                    contents[contentsOffset++] = (byte) attributeNameIndex;
7179:                    int attributeLengthOffset = contentsOffset;
7180:                    contentsOffset += 4; // leave space for the attribute length
7181:
7182:                    contents[contentsOffset++] = (byte) argumentsLength;
7183:                    invisibleLoop: for (int i = 0; i < argumentsLength; i++) {
7184:                        if (contentsOffset + 2 >= contents.length) {
7185:                            resizeContents(2);
7186:                        }
7187:                        if (invisibleParametersAnnotationsCounter == 0) {
7188:                            contents[contentsOffset++] = (byte) 0;
7189:                            contents[contentsOffset++] = (byte) 0;
7190:                        } else {
7191:                            final int numberOfInvisibleAnnotations = annotationsCounters[i][INVISIBLE_INDEX];
7192:                            contents[contentsOffset++] = (byte) (numberOfInvisibleAnnotations >> 8);
7193:                            contents[contentsOffset++] = (byte) numberOfInvisibleAnnotations;
7194:                            if (numberOfInvisibleAnnotations != 0) {
7195:                                Argument argument = arguments[i];
7196:                                Annotation[] annotations = argument.annotations;
7197:                                for (int j = 0, max = annotations.length; j < max; j++) {
7198:                                    Annotation annotation = annotations[j];
7199:                                    if (isRuntimeInvisible(annotation)) {
7200:                                        generateAnnotation(annotation,
7201:                                                annotationAttributeOffset);
7202:                                        if (contentsOffset == annotationAttributeOffset) {
7203:                                            break invisibleLoop;
7204:                                        }
7205:                                        invisibleParametersAnnotationsCounter--;
7206:                                    }
7207:                                }
7208:                            }
7209:                        }
7210:                    }
7211:                    if (contentsOffset != annotationAttributeOffset) {
7212:                        int attributeLength = contentsOffset
7213:                                - attributeLengthOffset - 4;
7214:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
7215:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
7216:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
7217:                        contents[attributeLengthOffset++] = (byte) attributeLength;
7218:                        attributesNumber++;
7219:                    } else {
7220:                        contentsOffset = annotationAttributeOffset;
7221:                    }
7222:                }
7223:                if (visibleParametersAnnotationsCounter != 0) {
7224:                    if (contentsOffset + 7 >= contents.length) {
7225:                        resizeContents(7);
7226:                    }
7227:                    int attributeNameIndex = constantPool
7228:                            .literalIndex(AttributeNamesConstants.RuntimeVisibleParameterAnnotationsName);
7229:                    contents[contentsOffset++] = (byte) (attributeNameIndex >> 8);
7230:                    contents[contentsOffset++] = (byte) attributeNameIndex;
7231:                    int attributeLengthOffset = contentsOffset;
7232:                    contentsOffset += 4; // leave space for the attribute length
7233:
7234:                    contents[contentsOffset++] = (byte) argumentsLength;
7235:                    visibleLoop: for (int i = 0; i < argumentsLength; i++) {
7236:                        if (contentsOffset + 2 >= contents.length) {
7237:                            resizeContents(2);
7238:                        }
7239:                        if (visibleParametersAnnotationsCounter == 0) {
7240:                            contents[contentsOffset++] = (byte) 0;
7241:                            contents[contentsOffset++] = (byte) 0;
7242:                        } else {
7243:                            final int numberOfVisibleAnnotations = annotationsCounters[i][VISIBLE_INDEX];
7244:                            contents[contentsOffset++] = (byte) (numberOfVisibleAnnotations >> 8);
7245:                            contents[contentsOffset++] = (byte) numberOfVisibleAnnotations;
7246:                            if (numberOfVisibleAnnotations != 0) {
7247:                                Argument argument = arguments[i];
7248:                                Annotation[] annotations = argument.annotations;
7249:                                for (int j = 0, max = annotations.length; j < max; j++) {
7250:                                    Annotation annotation = annotations[j];
7251:                                    if (isRuntimeVisible(annotation)) {
7252:                                        generateAnnotation(annotation,
7253:                                                annotationAttributeOffset);
7254:                                        if (contentsOffset == annotationAttributeOffset) {
7255:                                            break visibleLoop;
7256:                                        }
7257:                                        visibleParametersAnnotationsCounter--;
7258:                                    }
7259:                                }
7260:                            }
7261:                        }
7262:                    }
7263:                    if (contentsOffset != annotationAttributeOffset) {
7264:                        int attributeLength = contentsOffset
7265:                                - attributeLengthOffset - 4;
7266:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
7267:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
7268:                        contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
7269:                        contents[attributeLengthOffset++] = (byte) attributeLength;
7270:                        attributesNumber++;
7271:                    } else {
7272:                        contentsOffset = annotationAttributeOffset;
7273:                    }
7274:                }
7275:                return attributesNumber;
7276:            }
7277:
7278:            /**
7279:             * EXTERNAL API
7280:             * Answer the actual bytes of the class file
7281:             *
7282:             * This method encodes the receiver structure into a byte array which is the content of the classfile.
7283:             * Returns the byte array that represents the encoded structure of the receiver.
7284:             *
7285:             * @return byte[]
7286:             */
7287:            public byte[] getBytes() {
7288:                if (this .bytes == null) {
7289:                    this .bytes = new byte[this .headerOffset
7290:                            + this .contentsOffset];
7291:                    System.arraycopy(this .header, 0, this .bytes, 0,
7292:                            this .headerOffset);
7293:                    System.arraycopy(this .contents, 0, this .bytes,
7294:                            this .headerOffset, this .contentsOffset);
7295:                }
7296:                return this .bytes;
7297:            }
7298:
7299:            /**
7300:             * EXTERNAL API
7301:             * Answer the compound name of the class file.
7302:             * @return char[][]
7303:             * e.g. {{java}, {util}, {Hashtable}}.
7304:             */
7305:            public char[][] getCompoundName() {
7306:                return CharOperation.splitOn('/', fileName());
7307:            }
7308:
7309:            protected void initByteArrays() {
7310:                int members = referenceBinding.methods().length
7311:                        + referenceBinding.fields().length;
7312:                this .header = new byte[INITIAL_HEADER_SIZE];
7313:                this .contents = new byte[members < 15 ? INITIAL_CONTENTS_SIZE
7314:                        : INITIAL_HEADER_SIZE];
7315:            }
7316:
7317:            public void initialize(SourceTypeBinding aType,
7318:                    ClassFile parentClassFile, boolean createProblemType) {
7319:                // generate the magic numbers inside the header
7320:                header[headerOffset++] = (byte) (0xCAFEBABEL >> 24);
7321:                header[headerOffset++] = (byte) (0xCAFEBABEL >> 16);
7322:                header[headerOffset++] = (byte) (0xCAFEBABEL >> 8);
7323:                header[headerOffset++] = (byte) (0xCAFEBABEL >> 0);
7324:
7325:                header[headerOffset++] = (byte) (this .targetJDK >> 8); // minor high
7326:                header[headerOffset++] = (byte) (this .targetJDK >> 0); // minor low
7327:                header[headerOffset++] = (byte) (this .targetJDK >> 24); // major high
7328:                header[headerOffset++] = (byte) (this .targetJDK >> 16); // major low
7329:
7330:                constantPoolOffset = headerOffset;
7331:                headerOffset += 2;
7332:                this .constantPool.initialize(this );
7333:
7334:                // Modifier manipulations for classfile
7335:                int accessFlags = aType.getAccessFlags();
7336:                if (aType.isPrivate()) { // rewrite private to non-public
7337:                    accessFlags &= ~ClassFileConstants.AccPublic;
7338:                }
7339:                if (aType.isProtected()) { // rewrite protected into public
7340:                    accessFlags |= ClassFileConstants.AccPublic;
7341:                }
7342:                // clear all bits that are illegal for a class or an interface
7343:                accessFlags &= ~(ClassFileConstants.AccStrictfp
7344:                        | ClassFileConstants.AccProtected
7345:                        | ClassFileConstants.AccPrivate
7346:                        | ClassFileConstants.AccStatic
7347:                        | ClassFileConstants.AccSynchronized | ClassFileConstants.AccNative);
7348:
7349:                // set the AccSuper flag (has to be done after clearing AccSynchronized - since same value)
7350:                if (!aType.isInterface()) { // class or enum
7351:                    accessFlags |= ClassFileConstants.AccSuper;
7352:                }
7353:
7354:                this .enclosingClassFile = parentClassFile;
7355:                // innerclasses get their names computed at code gen time
7356:
7357:                // now we continue to generate the bytes inside the contents array
7358:                contents[contentsOffset++] = (byte) (accessFlags >> 8);
7359:                contents[contentsOffset++] = (byte) accessFlags;
7360:                int classNameIndex = constantPool.literalIndexForType(aType);
7361:                contents[contentsOffset++] = (byte) (classNameIndex >> 8);
7362:                contents[contentsOffset++] = (byte) classNameIndex;
7363:                int super classNameIndex;
7364:                if (aType.isInterface()) {
7365:                    super classNameIndex = constantPool
7366:                            .literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName);
7367:                } else {
7368:                    super classNameIndex = (aType.super class == null ? 0
7369:                            : constantPool
7370:                                    .literalIndexForType(aType.super class));
7371:                }
7372:                contents[contentsOffset++] = (byte) (super classNameIndex >> 8);
7373:                contents[contentsOffset++] = (byte) super classNameIndex;
7374:                ReferenceBinding[] super InterfacesBinding = aType
7375:                        .super Interfaces();
7376:                int interfacesCount = super InterfacesBinding.length;
7377:                contents[contentsOffset++] = (byte) (interfacesCount >> 8);
7378:                contents[contentsOffset++] = (byte) interfacesCount;
7379:                for (int i = 0; i < interfacesCount; i++) {
7380:                    int interfaceIndex = constantPool
7381:                            .literalIndexForType(super InterfacesBinding[i]);
7382:                    contents[contentsOffset++] = (byte) (interfaceIndex >> 8);
7383:                    contents[contentsOffset++] = (byte) interfaceIndex;
7384:                }
7385:                this .creatingProblemType = createProblemType;
7386:
7387:                // retrieve the enclosing one guaranteed to be the one matching the propagated flow info
7388:                // 1FF9ZBU: LFCOM:ALL - Local variable attributes busted (Sanity check)
7389:                if (this .enclosingClassFile == null) {
7390:                    this .codeStream.maxFieldCount = aType.scope.referenceType().maxFieldCount;
7391:                } else {
7392:                    ClassFile outermostClassFile = this 
7393:                            .outerMostEnclosingClassFile();
7394:                    this .codeStream.maxFieldCount = outermostClassFile.codeStream.maxFieldCount;
7395:                }
7396:            }
7397:
7398:            private boolean isRuntimeInvisible(Annotation annotation) {
7399:                final TypeBinding annotationBinding = annotation.resolvedType;
7400:                if (annotationBinding == null) {
7401:                    return false;
7402:                }
7403:                long metaTagBits = annotationBinding.getAnnotationTagBits(); // could be forward reference
7404:                if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
7405:                    return true; // by default the retention is CLASS
7406:
7407:                return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationClassRetention;
7408:            }
7409:
7410:            private boolean isRuntimeVisible(Annotation annotation) {
7411:                final TypeBinding annotationBinding = annotation.resolvedType;
7412:                if (annotationBinding == null) {
7413:                    return false;
7414:                }
7415:                long metaTagBits = annotationBinding.getAnnotationTagBits();
7416:                if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
7417:                    return false; // by default the retention is CLASS
7418:
7419:                return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationRuntimeRetention;
7420:            }
7421:
7422:            /**
7423:             * INTERNAL USE-ONLY
7424:             * Returns the most enclosing classfile of the receiver. This is used know to store the constant pool name
7425:             * for all inner types of the receiver.
7426:             * @return org.eclipse.jdt.internal.compiler.codegen.ClassFile
7427:             */
7428:            public ClassFile outerMostEnclosingClassFile() {
7429:                ClassFile current = this ;
7430:                while (current.enclosingClassFile != null)
7431:                    current = current.enclosingClassFile;
7432:                return current;
7433:            }
7434:
7435:            public void recordInnerClasses(TypeBinding binding) {
7436:                if (this .innerClassesBindings == null) {
7437:                    this .innerClassesBindings = new HashSet(INNER_CLASSES_SIZE);
7438:                }
7439:                ReferenceBinding innerClass = (ReferenceBinding) binding;
7440:                this .innerClassesBindings.add(innerClass.erasure());
7441:                ReferenceBinding enclosingType = innerClass.enclosingType();
7442:                while (enclosingType != null && enclosingType.isNestedType()) {
7443:                    this .innerClassesBindings.add(enclosingType.erasure());
7444:                    enclosingType = enclosingType.enclosingType();
7445:                }
7446:            }
7447:
7448:            public void reset(SourceTypeBinding typeBinding) {
7449:                // the code stream is reinitialized for each method
7450:                final CompilerOptions options = typeBinding.scope
7451:                        .compilerOptions();
7452:                this .referenceBinding = typeBinding;
7453:                this .targetJDK = options.targetJDK;
7454:                this .produceAttributes = options.produceDebugAttributes;
7455:                if (this .targetJDK >= ClassFileConstants.JDK1_6) {
7456:                    this .produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE;
7457:                } else if (this .targetJDK == ClassFileConstants.CLDC_1_1) {
7458:                    this .targetJDK = ClassFileConstants.JDK1_1; // put back 45.3
7459:                    this .produceAttributes |= ClassFileConstants.ATTR_STACK_MAP;
7460:                }
7461:                this .bytes = null;
7462:                this .constantPool.reset();
7463:                this .codeStream.reset(this );
7464:                this .constantPoolOffset = 0;
7465:                this .contentsOffset = 0;
7466:                this .creatingProblemType = false;
7467:                this .enclosingClassFile = null;
7468:                this .headerOffset = 0;
7469:                this .methodCount = 0;
7470:                this .methodCountOffset = 0;
7471:                if (this .innerClassesBindings != null) {
7472:                    this .innerClassesBindings.clear();
7473:                }
7474:            }
7475:
7476:            /**
7477:             * Resize the pool contents
7478:             */
7479:            private final void resizeContents(int minimalSize) {
7480:                int length = this .contents.length;
7481:                int toAdd = length;
7482:                if (toAdd < minimalSize)
7483:                    toAdd = minimalSize;
7484:                System.arraycopy(this .contents, 0,
7485:                        this .contents = new byte[length + toAdd], 0, length);
7486:            }
7487:
7488:            /**
7489:             * INTERNAL USE-ONLY
7490:             * This methods leaves the space for method counts recording.
7491:             */
7492:            public void setForMethodInfos() {
7493:                // leave some space for the methodCount
7494:                methodCountOffset = contentsOffset;
7495:                contentsOffset += 2;
7496:            }
7497:
7498:            public void traverse(MethodBinding methodBinding, int maxLocals,
7499:                    byte[] bytecodes, int codeOffset, int codeLength,
7500:                    ArrayList frames, boolean isClinit) {
7501:                StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this .codeStream;
7502:                int[] framePositions = stackMapFrameCodeStream
7503:                        .getFramePositions();
7504:                int pc = codeOffset;
7505:                int index;
7506:                int[] constantPoolOffsets = this .constantPool.offsets;
7507:                byte[] poolContents = this .constantPool.poolContent;
7508:
7509:                // set initial values for frame positions
7510:                int indexInFramePositions = 0;
7511:                int framePositionsLength = framePositions.length;
7512:                int currentFramePosition = framePositions[0];
7513:
7514:                // set initial values for stack markers
7515:                int indexInStackMarkers = 0;
7516:                ArrayList stackMarkers = stackMapFrameCodeStream.stackMarkers;
7517:                boolean hasStackMarkers = stackMarkers != null
7518:                        && stackMarkers.size() != 0;
7519:                StackMarker[] markers = null;
7520:                int markersLength = 0;
7521:                StackMarker marker = null;
7522:                if (hasStackMarkers) {
7523:                    markersLength = stackMarkers.size();
7524:                    stackMarkers
7525:                            .toArray(markers = new StackMarker[markersLength]);
7526:                    marker = markers[0];
7527:                }
7528:
7529:                // set initial values for exception markers
7530:                int indexInExceptionMarkers = 0;
7531:                ExceptionMarker[] exceptionMarkers = stackMapFrameCodeStream
7532:                        .getExceptionMarkers();
7533:                boolean hasExceptionMarkers = exceptionMarkers != null
7534:                        && exceptionMarkers.length != 0;
7535:                int exceptionsMarkersLength = 0;
7536:                ExceptionMarker exceptionMarker = null;
7537:                if (hasExceptionMarkers) {
7538:                    exceptionsMarkersLength = exceptionMarkers.length;
7539:                    exceptionMarker = exceptionMarkers[0];
7540:                }
7541:
7542:                StackMapFrame frame = new StackMapFrame(maxLocals);
7543:                if (!isClinit) {
7544:                    initializeDefaultLocals(frame, methodBinding, maxLocals,
7545:                            codeLength);
7546:                }
7547:                frame.pc = -1;
7548:                frames.add(frame.duplicate());
7549:                while (true) {
7550:                    int currentPC = pc - codeOffset;
7551:                    if (hasStackMarkers && marker.pc == currentPC) {
7552:                        TypeBinding typeBinding = marker.typeBinding;
7553:                        if (typeBinding != null) {
7554:                            if (marker.delta > 0) {
7555:                                frame.addStackItem(new VerificationTypeInfo(
7556:                                        typeBinding));
7557:                            } else {
7558:                                frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
7559:                                        typeBinding);
7560:                            }
7561:                        } else {
7562:                            frame.numberOfStackItems--;
7563:                        }
7564:                        indexInStackMarkers++;
7565:                        if (indexInStackMarkers < markersLength) {
7566:                            marker = markers[indexInStackMarkers];
7567:                        } else {
7568:                            hasStackMarkers = false;
7569:                        }
7570:                    }
7571:                    if (hasExceptionMarkers && exceptionMarker.pc == currentPC) {
7572:                        frame.addStackItem(new VerificationTypeInfo(0,
7573:                                VerificationTypeInfo.ITEM_OBJECT,
7574:                                exceptionMarker.constantPoolName));
7575:                        indexInExceptionMarkers++;
7576:                        if (indexInExceptionMarkers < exceptionsMarkersLength) {
7577:                            exceptionMarker = exceptionMarkers[indexInExceptionMarkers];
7578:                        } else {
7579:                            hasExceptionMarkers = false;
7580:                        }
7581:                    }
7582:                    if (currentFramePosition < currentPC) {
7583:                        do {
7584:                            indexInFramePositions++;
7585:                            if (indexInFramePositions < framePositionsLength) {
7586:                                currentFramePosition = framePositions[indexInFramePositions];
7587:                            } else {
7588:                                // no more frame to generate
7589:                                return;
7590:                            }
7591:                        } while (currentFramePosition < currentPC);
7592:                    }
7593:                    if (currentFramePosition == currentPC) {
7594:                        // need to build a new frame and create a stack map attribute entry
7595:                        StackMapFrame currentFrame = frame.duplicate();
7596:                        currentFrame.pc = currentPC;
7597:                        // initialize locals
7598:                        initializeLocals(isClinit ? true : methodBinding
7599:                                .isStatic(), currentPC, currentFrame);
7600:                        // insert a new frame
7601:                        frames.add(currentFrame);
7602:                        indexInFramePositions++;
7603:                        if (indexInFramePositions < framePositionsLength) {
7604:                            currentFramePosition = framePositions[indexInFramePositions];
7605:                        } else {
7606:                            // no more frame to generate
7607:                            return;
7608:                        }
7609:                    }
7610:                    byte opcode = (byte) u1At(bytecodes, 0, pc);
7611:                    switch (opcode) {
7612:                    case Opcodes.OPC_nop:
7613:                        pc++;
7614:                        break;
7615:                    case Opcodes.OPC_aconst_null:
7616:                        frame.addStackItem(TypeBinding.NULL);
7617:                        pc++;
7618:                        break;
7619:                    case Opcodes.OPC_iconst_m1:
7620:                    case Opcodes.OPC_iconst_0:
7621:                    case Opcodes.OPC_iconst_1:
7622:                    case Opcodes.OPC_iconst_2:
7623:                    case Opcodes.OPC_iconst_3:
7624:                    case Opcodes.OPC_iconst_4:
7625:                    case Opcodes.OPC_iconst_5:
7626:                        frame.addStackItem(TypeBinding.INT);
7627:                        pc++;
7628:                        break;
7629:                    case Opcodes.OPC_lconst_0:
7630:                    case Opcodes.OPC_lconst_1:
7631:                        frame.addStackItem(TypeBinding.LONG);
7632:                        pc++;
7633:                        break;
7634:                    case Opcodes.OPC_fconst_0:
7635:                    case Opcodes.OPC_fconst_1:
7636:                    case Opcodes.OPC_fconst_2:
7637:                        frame.addStackItem(TypeBinding.FLOAT);
7638:                        pc++;
7639:                        break;
7640:                    case Opcodes.OPC_dconst_0:
7641:                    case Opcodes.OPC_dconst_1:
7642:                        frame.addStackItem(TypeBinding.DOUBLE);
7643:                        pc++;
7644:                        break;
7645:                    case Opcodes.OPC_bipush:
7646:                        frame.addStackItem(TypeBinding.BYTE);
7647:                        pc += 2;
7648:                        break;
7649:                    case Opcodes.OPC_sipush:
7650:                        frame.addStackItem(TypeBinding.SHORT);
7651:                        pc += 3;
7652:                        break;
7653:                    case Opcodes.OPC_ldc:
7654:                        index = u1At(bytecodes, 1, pc);
7655:                        switch (u1At(poolContents, 0,
7656:                                constantPoolOffsets[index])) {
7657:                        case ClassFileConstants.StringTag:
7658:                            frame
7659:                                    .addStackItem(new VerificationTypeInfo(
7660:                                            TypeIds.T_JavaLangString,
7661:                                            ConstantPool.JavaLangStringConstantPoolName));
7662:                            break;
7663:                        case ClassFileConstants.IntegerTag:
7664:                            frame.addStackItem(TypeBinding.INT);
7665:                            break;
7666:                        case ClassFileConstants.FloatTag:
7667:                            frame.addStackItem(TypeBinding.FLOAT);
7668:                            break;
7669:                        case ClassFileConstants.ClassTag:
7670:                            int utf8index = u2At(poolContents, 1,
7671:                                    constantPoolOffsets[index]);
7672:                            char[] classSignature = utf8At(poolContents,
7673:                                    constantPoolOffsets[utf8index] + 3, u2At(
7674:                                            poolContents, 1,
7675:                                            constantPoolOffsets[utf8index]));
7676:                            frame.addStackItem(new VerificationTypeInfo(0,
7677:                                    classSignature));
7678:                        }
7679:                        pc += 2;
7680:                        break;
7681:                    case Opcodes.OPC_ldc_w:
7682:                        index = u2At(bytecodes, 1, pc);
7683:                        switch (u1At(poolContents, 0,
7684:                                constantPoolOffsets[index])) {
7685:                        case ClassFileConstants.StringTag:
7686:                            frame
7687:                                    .addStackItem(new VerificationTypeInfo(
7688:                                            TypeIds.T_JavaLangString,
7689:                                            ConstantPool.JavaLangStringConstantPoolName));
7690:                            break;
7691:                        case ClassFileConstants.IntegerTag:
7692:                            frame.addStackItem(TypeBinding.INT);
7693:                            break;
7694:                        case ClassFileConstants.FloatTag:
7695:                            frame.addStackItem(TypeBinding.FLOAT);
7696:                            break;
7697:                        case ClassFileConstants.ClassTag:
7698:                            int utf8index = u2At(poolContents, 1,
7699:                                    constantPoolOffsets[index]);
7700:                            char[] classSignature = utf8At(poolContents,
7701:                                    constantPoolOffsets[utf8index] + 3, u2At(
7702:                                            poolContents, 1,
7703:                                            constantPoolOffsets[utf8index]));
7704:                            frame.addStackItem(new VerificationTypeInfo(0,
7705:                                    classSignature));
7706:                        }
7707:                        pc += 3;
7708:                        break;
7709:                    case Opcodes.OPC_ldc2_w:
7710:                        index = u2At(bytecodes, 1, pc);
7711:                        switch (u1At(poolContents, 0,
7712:                                constantPoolOffsets[index])) {
7713:                        case ClassFileConstants.DoubleTag:
7714:                            frame.addStackItem(TypeBinding.DOUBLE);
7715:                            break;
7716:                        case ClassFileConstants.LongTag:
7717:                            frame.addStackItem(TypeBinding.LONG);
7718:                            break;
7719:                        }
7720:                        pc += 3;
7721:                        break;
7722:                    case Opcodes.OPC_iload:
7723:                        frame.addStackItem(TypeBinding.INT);
7724:                        pc += 2;
7725:                        break;
7726:                    case Opcodes.OPC_lload:
7727:                        frame.addStackItem(TypeBinding.LONG);
7728:                        pc += 2;
7729:                        break;
7730:                    case Opcodes.OPC_fload:
7731:                        frame.addStackItem(TypeBinding.FLOAT);
7732:                        pc += 2;
7733:                        break;
7734:                    case Opcodes.OPC_dload:
7735:                        frame.addStackItem(TypeBinding.DOUBLE);
7736:                        pc += 2;
7737:                        break;
7738:                    case Opcodes.OPC_aload:
7739:                        index = u1At(bytecodes, 1, pc);
7740:                        VerificationTypeInfo localsN = frame.locals[index];
7741:                        if (localsN == null) {
7742:                            localsN = retrieveLocal(currentPC, index);
7743:                        }
7744:                        frame.addStackItem(localsN);
7745:                        pc += 2;
7746:                        break;
7747:                    case Opcodes.OPC_iload_0:
7748:                    case Opcodes.OPC_iload_1:
7749:                    case Opcodes.OPC_iload_2:
7750:                    case Opcodes.OPC_iload_3:
7751:                        frame.addStackItem(TypeBinding.INT);
7752:                        pc++;
7753:                        break;
7754:                    case Opcodes.OPC_lload_0:
7755:                    case Opcodes.OPC_lload_1:
7756:                    case Opcodes.OPC_lload_2:
7757:                    case Opcodes.OPC_lload_3:
7758:                        frame.addStackItem(TypeBinding.LONG);
7759:                        pc++;
7760:                        break;
7761:                    case Opcodes.OPC_fload_0:
7762:                    case Opcodes.OPC_fload_1:
7763:                    case Opcodes.OPC_fload_2:
7764:                    case Opcodes.OPC_fload_3:
7765:                        frame.addStackItem(TypeBinding.FLOAT);
7766:                        pc++;
7767:                        break;
7768:                    case Opcodes.OPC_dload_0:
7769:                    case Opcodes.OPC_dload_1:
7770:                    case Opcodes.OPC_dload_2:
7771:                    case Opcodes.OPC_dload_3:
7772:                        frame.addStackItem(TypeBinding.DOUBLE);
7773:                        pc++;
7774:                        break;
7775:                    case Opcodes.OPC_aload_0:
7776:                        VerificationTypeInfo locals0 = frame.locals[0];
7777:                        // special case to handle uninitialized object
7778:                        if (locals0 == null) {
7779:                            locals0 = retrieveLocal(currentPC, 0);
7780:                        }
7781:                        frame.addStackItem(locals0);
7782:                        pc++;
7783:                        break;
7784:                    case Opcodes.OPC_aload_1:
7785:                        VerificationTypeInfo locals1 = retrieveLocal(currentPC,
7786:                                1);
7787:                        frame.addStackItem(locals1);
7788:                        pc++;
7789:                        break;
7790:                    case Opcodes.OPC_aload_2:
7791:                        VerificationTypeInfo locals2 = retrieveLocal(currentPC,
7792:                                2);
7793:                        frame.addStackItem(locals2);
7794:                        pc++;
7795:                        break;
7796:                    case Opcodes.OPC_aload_3:
7797:                        VerificationTypeInfo locals3 = retrieveLocal(currentPC,
7798:                                3);
7799:                        frame.addStackItem(locals3);
7800:                        pc++;
7801:                        break;
7802:                    case Opcodes.OPC_iaload:
7803:                        frame.numberOfStackItems -= 2;
7804:                        frame.addStackItem(TypeBinding.INT);
7805:                        pc++;
7806:                        break;
7807:                    case Opcodes.OPC_laload:
7808:                        frame.numberOfStackItems -= 2;
7809:                        frame.addStackItem(TypeBinding.LONG);
7810:                        pc++;
7811:                        break;
7812:                    case Opcodes.OPC_faload:
7813:                        frame.numberOfStackItems -= 2;
7814:                        frame.addStackItem(TypeBinding.FLOAT);
7815:                        pc++;
7816:                        break;
7817:                    case Opcodes.OPC_daload:
7818:                        frame.numberOfStackItems -= 2;
7819:                        frame.addStackItem(TypeBinding.DOUBLE);
7820:                        pc++;
7821:                        break;
7822:                    case Opcodes.OPC_aaload:
7823:                        frame.numberOfStackItems--;
7824:                        frame.replaceWithElementType();
7825:                        pc++;
7826:                        break;
7827:                    case Opcodes.OPC_baload:
7828:                        frame.numberOfStackItems -= 2;
7829:                        frame.addStackItem(TypeBinding.BYTE);
7830:                        pc++;
7831:                        break;
7832:                    case Opcodes.OPC_caload:
7833:                        frame.numberOfStackItems -= 2;
7834:                        frame.addStackItem(TypeBinding.CHAR);
7835:                        pc++;
7836:                        break;
7837:                    case Opcodes.OPC_saload:
7838:                        frame.numberOfStackItems -= 2;
7839:                        frame.addStackItem(TypeBinding.SHORT);
7840:                        pc++;
7841:                        break;
7842:                    case Opcodes.OPC_istore:
7843:                    case Opcodes.OPC_lstore:
7844:                    case Opcodes.OPC_fstore:
7845:                    case Opcodes.OPC_dstore:
7846:                        frame.numberOfStackItems--;
7847:                        pc += 2;
7848:                        break;
7849:                    case Opcodes.OPC_astore:
7850:                        index = u1At(bytecodes, 1, pc);
7851:                        frame.numberOfStackItems--;
7852:                        pc += 2;
7853:                        break;
7854:                    case Opcodes.OPC_astore_0:
7855:                        frame.locals[0] = frame.stackItems[frame.numberOfStackItems - 1];
7856:                        frame.numberOfStackItems--;
7857:                        pc++;
7858:                        break;
7859:                    case Opcodes.OPC_astore_1:
7860:                    case Opcodes.OPC_astore_2:
7861:                    case Opcodes.OPC_astore_3:
7862:                    case Opcodes.OPC_istore_0:
7863:                    case Opcodes.OPC_istore_1:
7864:                    case Opcodes.OPC_istore_2:
7865:                    case Opcodes.OPC_istore_3:
7866:                    case Opcodes.OPC_lstore_0:
7867:                    case Opcodes.OPC_lstore_1:
7868:                    case Opcodes.OPC_lstore_2:
7869:                    case Opcodes.OPC_lstore_3:
7870:                    case Opcodes.OPC_fstore_0:
7871:                    case Opcodes.OPC_fstore_1:
7872:                    case Opcodes.OPC_fstore_2:
7873:                    case Opcodes.OPC_fstore_3:
7874:                    case Opcodes.OPC_dstore_0:
7875:                    case Opcodes.OPC_dstore_1:
7876:                    case Opcodes.OPC_dstore_2:
7877:                    case Opcodes.OPC_dstore_3:
7878:                        frame.numberOfStackItems--;
7879:                        pc++;
7880:                        break;
7881:                    case Opcodes.OPC_iastore:
7882:                    case Opcodes.OPC_lastore:
7883:                    case Opcodes.OPC_fastore:
7884:                    case Opcodes.OPC_dastore:
7885:                    case Opcodes.OPC_aastore:
7886:                    case Opcodes.OPC_bastore:
7887:                    case Opcodes.OPC_castore:
7888:                    case Opcodes.OPC_sastore:
7889:                        frame.numberOfStackItems -= 3;
7890:                        pc++;
7891:                        break;
7892:                    case Opcodes.OPC_pop:
7893:                        frame.numberOfStackItems--;
7894:                        pc++;
7895:                        break;
7896:                    case Opcodes.OPC_pop2:
7897:                        int numberOfStackItems = frame.numberOfStackItems;
7898:                        switch (frame.stackItems[numberOfStackItems - 1].id()) {
7899:                        case TypeIds.T_long:
7900:                        case TypeIds.T_double:
7901:                            frame.numberOfStackItems--;
7902:                            break;
7903:                        default:
7904:                            frame.numberOfStackItems -= 2;
7905:                        }
7906:                        pc++;
7907:                        break;
7908:                    case Opcodes.OPC_dup:
7909:                        frame
7910:                                .addStackItem(frame.stackItems[frame.numberOfStackItems - 1]);
7911:                        pc++;
7912:                        break;
7913:                    case Opcodes.OPC_dup_x1:
7914:                        VerificationTypeInfo info = frame.stackItems[frame.numberOfStackItems - 1];
7915:                        frame.numberOfStackItems--;
7916:                        VerificationTypeInfo info2 = frame.stackItems[frame.numberOfStackItems - 1];
7917:                        frame.numberOfStackItems--;
7918:                        frame.addStackItem(info);
7919:                        frame.addStackItem(info2);
7920:                        frame.addStackItem(info);
7921:                        pc++;
7922:                        break;
7923:                    case Opcodes.OPC_dup_x2:
7924:                        info = frame.stackItems[frame.numberOfStackItems - 1];
7925:                        frame.numberOfStackItems--;
7926:                        info2 = frame.stackItems[frame.numberOfStackItems - 1];
7927:                        frame.numberOfStackItems--;
7928:                        switch (info2.id()) {
7929:                        case TypeIds.T_long:
7930:                        case TypeIds.T_double:
7931:                            frame.addStackItem(info);
7932:                            frame.addStackItem(info2);
7933:                            frame.addStackItem(info);
7934:                            break;
7935:                        default:
7936:                            numberOfStackItems = frame.numberOfStackItems;
7937:                            VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
7938:                            frame.numberOfStackItems--;
7939:                            frame.addStackItem(info);
7940:                            frame.addStackItem(info3);
7941:                            frame.addStackItem(info2);
7942:                            frame.addStackItem(info);
7943:                        }
7944:                        pc++;
7945:                        break;
7946:                    case Opcodes.OPC_dup2:
7947:                        info = frame.stackItems[frame.numberOfStackItems - 1];
7948:                        frame.numberOfStackItems--;
7949:                        switch (info.id()) {
7950:                        case TypeIds.T_double:
7951:                        case TypeIds.T_long:
7952:                            frame.addStackItem(info);
7953:                            frame.addStackItem(info);
7954:                            break;
7955:                        default:
7956:                            info2 = frame.stackItems[frame.numberOfStackItems - 1];
7957:                            frame.numberOfStackItems--;
7958:                            frame.addStackItem(info2);
7959:                            frame.addStackItem(info);
7960:                            frame.addStackItem(info2);
7961:                            frame.addStackItem(info);
7962:                        }
7963:                        pc++;
7964:                        break;
7965:                    case Opcodes.OPC_dup2_x1:
7966:                        info = frame.stackItems[frame.numberOfStackItems - 1];
7967:                        frame.numberOfStackItems--;
7968:                        info2 = frame.stackItems[frame.numberOfStackItems - 1];
7969:                        frame.numberOfStackItems--;
7970:                        switch (info.id()) {
7971:                        case TypeIds.T_double:
7972:                        case TypeIds.T_long:
7973:                            frame.addStackItem(info);
7974:                            frame.addStackItem(info2);
7975:                            frame.addStackItem(info);
7976:                            break;
7977:                        default:
7978:                            VerificationTypeInfo info3 = frame.stackItems[frame.numberOfStackItems - 1];
7979:                            frame.numberOfStackItems--;
7980:                            frame.addStackItem(info2);
7981:                            frame.addStackItem(info);
7982:                            frame.addStackItem(info3);
7983:                            frame.addStackItem(info2);
7984:                            frame.addStackItem(info);
7985:                        }
7986:                        pc++;
7987:                        break;
7988:                    case Opcodes.OPC_dup2_x2:
7989:                        numberOfStackItems = frame.numberOfStackItems;
7990:                        info = frame.stackItems[numberOfStackItems - 1];
7991:                        frame.numberOfStackItems--;
7992:                        info2 = frame.stackItems[frame.numberOfStackItems - 1];
7993:                        frame.numberOfStackItems--;
7994:                        switch (info.id()) {
7995:                        case TypeIds.T_long:
7996:                        case TypeIds.T_double:
7997:                            switch (info2.id()) {
7998:                            case TypeIds.T_long:
7999:                            case TypeIds.T_double:
8000:                                // form 4
8001:                                frame.addStackItem(info);
8002:                                frame.addStackItem(info2);
8003:                                frame.addStackItem(info);
8004:                                break;
8005:                            default:
8006:                                // form 2
8007:                                numberOfStackItems = frame.numberOfStackItems;
8008:                                VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
8009:                                frame.numberOfStackItems--;
8010:                                frame.addStackItem(info);
8011:                                frame.addStackItem(info3);
8012:                                frame.addStackItem(info2);
8013:                                frame.addStackItem(info);
8014:                            }
8015:                            break;
8016:                        default:
8017:                            numberOfStackItems = frame.numberOfStackItems;
8018:                            VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
8019:                            frame.numberOfStackItems--;
8020:                            switch (info3.id()) {
8021:                            case TypeIds.T_long:
8022:                            case TypeIds.T_double:
8023:                                // form 3
8024:                                frame.addStackItem(info2);
8025:                                frame.addStackItem(info);
8026:                                frame.addStackItem(info3);
8027:                                frame.addStackItem(info2);
8028:                                frame.addStackItem(info);
8029:                                break;
8030:                            default:
8031:                                // form 1
8032:                                numberOfStackItems = frame.numberOfStackItems;
8033:                                VerificationTypeInfo info4 = frame.stackItems[numberOfStackItems - 1];
8034:                                frame.numberOfStackItems--;
8035:                                frame.addStackItem(info2);
8036:                                frame.addStackItem(info);
8037:                                frame.addStackItem(info4);
8038:                                frame.addStackItem(info3);
8039:                                frame.addStackItem(info2);
8040:                                frame.addStackItem(info);
8041:                            }
8042:                        }
8043:                        pc++;
8044:                        break;
8045:                    case Opcodes.OPC_swap:
8046:                        numberOfStackItems = frame.numberOfStackItems;
8047:                        info = frame.stackItems[numberOfStackItems - 1];
8048:                        info2 = frame.stackItems[numberOfStackItems - 2];
8049:                        frame.stackItems[numberOfStackItems - 1] = info2;
8050:                        frame.stackItems[numberOfStackItems - 2] = info;
8051:                        pc++;
8052:                        break;
8053:                    case Opcodes.OPC_iadd:
8054:                    case Opcodes.OPC_ladd:
8055:                    case Opcodes.OPC_fadd:
8056:                    case Opcodes.OPC_dadd:
8057:                    case Opcodes.OPC_isub:
8058:                    case Opcodes.OPC_lsub:
8059:                    case Opcodes.OPC_fsub:
8060:                    case Opcodes.OPC_dsub:
8061:                    case Opcodes.OPC_imul:
8062:                    case Opcodes.OPC_lmul:
8063:                    case Opcodes.OPC_fmul:
8064:                    case Opcodes.OPC_dmul:
8065:                    case Opcodes.OPC_idiv:
8066:                    case Opcodes.OPC_ldiv:
8067:                    case Opcodes.OPC_fdiv:
8068:                    case Opcodes.OPC_ddiv:
8069:                    case Opcodes.OPC_irem:
8070:                    case Opcodes.OPC_lrem:
8071:                    case Opcodes.OPC_frem:
8072:                    case Opcodes.OPC_drem:
8073:                    case Opcodes.OPC_ishl:
8074:                    case Opcodes.OPC_lshl:
8075:                    case Opcodes.OPC_ishr:
8076:                    case Opcodes.OPC_lshr:
8077:                    case Opcodes.OPC_iushr:
8078:                    case Opcodes.OPC_lushr:
8079:                    case Opcodes.OPC_iand:
8080:                    case Opcodes.OPC_land:
8081:                    case Opcodes.OPC_ior:
8082:                    case Opcodes.OPC_lor:
8083:                    case Opcodes.OPC_ixor:
8084:                    case Opcodes.OPC_lxor:
8085:                        frame.numberOfStackItems--;
8086:                        pc++;
8087:                        break;
8088:                    case Opcodes.OPC_ineg:
8089:                    case Opcodes.OPC_lneg:
8090:                    case Opcodes.OPC_fneg:
8091:                    case Opcodes.OPC_dneg:
8092:                        pc++;
8093:                        break;
8094:                    case Opcodes.OPC_iinc:
8095:                        pc += 3;
8096:                        break;
8097:                    case Opcodes.OPC_i2l:
8098:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8099:                                TypeBinding.LONG);
8100:                        pc++;
8101:                        break;
8102:                    case Opcodes.OPC_i2f:
8103:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8104:                                TypeBinding.FLOAT);
8105:                        pc++;
8106:                        break;
8107:                    case Opcodes.OPC_i2d:
8108:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8109:                                TypeBinding.DOUBLE);
8110:                        pc++;
8111:                        break;
8112:                    case Opcodes.OPC_l2i:
8113:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8114:                                TypeBinding.INT);
8115:                        pc++;
8116:                        break;
8117:                    case Opcodes.OPC_l2f:
8118:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8119:                                TypeBinding.FLOAT);
8120:                        pc++;
8121:                        break;
8122:                    case Opcodes.OPC_l2d:
8123:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8124:                                TypeBinding.DOUBLE);
8125:                        pc++;
8126:                        break;
8127:                    case Opcodes.OPC_f2i:
8128:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8129:                                TypeBinding.INT);
8130:                        pc++;
8131:                        break;
8132:                    case Opcodes.OPC_f2l:
8133:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8134:                                TypeBinding.LONG);
8135:                        pc++;
8136:                        break;
8137:                    case Opcodes.OPC_f2d:
8138:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8139:                                TypeBinding.DOUBLE);
8140:                        pc++;
8141:                        break;
8142:                    case Opcodes.OPC_d2i:
8143:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8144:                                TypeBinding.INT);
8145:                        pc++;
8146:                        break;
8147:                    case Opcodes.OPC_d2l:
8148:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8149:                                TypeBinding.LONG);
8150:                        pc++;
8151:                        break;
8152:                    case Opcodes.OPC_d2f:
8153:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8154:                                TypeBinding.FLOAT);
8155:                        pc++;
8156:                        break;
8157:                    case Opcodes.OPC_i2b:
8158:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8159:                                TypeBinding.BYTE);
8160:                        pc++;
8161:                        break;
8162:                    case Opcodes.OPC_i2c:
8163:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8164:                                TypeBinding.CHAR);
8165:                        pc++;
8166:                        break;
8167:                    case Opcodes.OPC_i2s:
8168:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8169:                                TypeBinding.SHORT);
8170:                        pc++;
8171:                        break;
8172:                    case Opcodes.OPC_lcmp:
8173:                    case Opcodes.OPC_fcmpl:
8174:                    case Opcodes.OPC_fcmpg:
8175:                    case Opcodes.OPC_dcmpl:
8176:                    case Opcodes.OPC_dcmpg:
8177:                        frame.numberOfStackItems -= 2;
8178:                        frame.addStackItem(TypeBinding.INT);
8179:                        pc++;
8180:                        break;
8181:                    case Opcodes.OPC_ifeq:
8182:                    case Opcodes.OPC_ifne:
8183:                    case Opcodes.OPC_iflt:
8184:                    case Opcodes.OPC_ifge:
8185:                    case Opcodes.OPC_ifgt:
8186:                    case Opcodes.OPC_ifle:
8187:                        frame.numberOfStackItems--;
8188:                        pc += 3;
8189:                        break;
8190:                    case Opcodes.OPC_if_icmpeq:
8191:                    case Opcodes.OPC_if_icmpne:
8192:                    case Opcodes.OPC_if_icmplt:
8193:                    case Opcodes.OPC_if_icmpge:
8194:                    case Opcodes.OPC_if_icmpgt:
8195:                    case Opcodes.OPC_if_icmple:
8196:                    case Opcodes.OPC_if_acmpeq:
8197:                    case Opcodes.OPC_if_acmpne:
8198:                        frame.numberOfStackItems -= 2;
8199:                        pc += 3;
8200:                        break;
8201:                    case Opcodes.OPC_goto:
8202:                        pc += 3;
8203:                        break;
8204:                    case Opcodes.OPC_tableswitch:
8205:                        pc++;
8206:                        while (((pc - codeOffset) & 0x03) != 0) {
8207:                            pc++;
8208:                        }
8209:                        pc += 4; // default
8210:                        int low = i4At(bytecodes, 0, pc);
8211:                        pc += 4;
8212:                        int high = i4At(bytecodes, 0, pc);
8213:                        pc += 4;
8214:                        int length = high - low + 1;
8215:                        pc += (length * 4);
8216:                        frame.numberOfStackItems--;
8217:                        break;
8218:                    case Opcodes.OPC_lookupswitch:
8219:                        pc++;
8220:                        while (((pc - codeOffset) & 0x03) != 0) {
8221:                            pc++;
8222:                        }
8223:                        pc += 4; // default
8224:                        int npairs = (int) u4At(bytecodes, 0, pc);
8225:                        pc += (4 + npairs * 8);
8226:                        frame.numberOfStackItems--;
8227:                        break;
8228:                    case Opcodes.OPC_ireturn:
8229:                    case Opcodes.OPC_lreturn:
8230:                    case Opcodes.OPC_freturn:
8231:                    case Opcodes.OPC_dreturn:
8232:                    case Opcodes.OPC_areturn:
8233:                        frame.numberOfStackItems--;
8234:                        pc++;
8235:                        break;
8236:                    case Opcodes.OPC_return:
8237:                        pc++;
8238:                        break;
8239:                    case Opcodes.OPC_getstatic:
8240:                        index = u2At(bytecodes, 1, pc);
8241:                        int nameAndTypeIndex = u2At(poolContents, 3,
8242:                                constantPoolOffsets[index]);
8243:                        int utf8index = u2At(poolContents, 3,
8244:                                constantPoolOffsets[nameAndTypeIndex]);
8245:                        char[] descriptor = utf8At(poolContents,
8246:                                constantPoolOffsets[utf8index] + 3, u2At(
8247:                                        poolContents, 1,
8248:                                        constantPoolOffsets[utf8index]));
8249:                        if (descriptor.length == 1) {
8250:                            // base type
8251:                            switch (descriptor[0]) {
8252:                            case 'Z':
8253:                                frame.addStackItem(TypeBinding.BOOLEAN);
8254:                                break;
8255:                            case 'B':
8256:                                frame.addStackItem(TypeBinding.BYTE);
8257:                                break;
8258:                            case 'C':
8259:                                frame.addStackItem(TypeBinding.CHAR);
8260:                                break;
8261:                            case 'D':
8262:                                frame.addStackItem(TypeBinding.DOUBLE);
8263:                                break;
8264:                            case 'F':
8265:                                frame.addStackItem(TypeBinding.FLOAT);
8266:                                break;
8267:                            case 'I':
8268:                                frame.addStackItem(TypeBinding.INT);
8269:                                break;
8270:                            case 'J':
8271:                                frame.addStackItem(TypeBinding.LONG);
8272:                                break;
8273:                            case 'S':
8274:                                frame.addStackItem(TypeBinding.SHORT);
8275:                                break;
8276:                            }
8277:                        } else if (descriptor[0] == '[') {
8278:                            frame.addStackItem(new VerificationTypeInfo(0,
8279:                                    descriptor));
8280:                        } else {
8281:                            frame.addStackItem(new VerificationTypeInfo(0,
8282:                                    CharOperation.subarray(descriptor, 1,
8283:                                            descriptor.length - 1)));
8284:                        }
8285:                        pc += 3;
8286:                        break;
8287:                    case Opcodes.OPC_putstatic:
8288:                        frame.numberOfStackItems--;
8289:                        pc += 3;
8290:                        break;
8291:                    case Opcodes.OPC_getfield:
8292:                        index = u2At(bytecodes, 1, pc);
8293:                        nameAndTypeIndex = u2At(poolContents, 3,
8294:                                constantPoolOffsets[index]);
8295:                        utf8index = u2At(poolContents, 3,
8296:                                constantPoolOffsets[nameAndTypeIndex]);
8297:                        descriptor = utf8At(poolContents,
8298:                                constantPoolOffsets[utf8index] + 3, u2At(
8299:                                        poolContents, 1,
8300:                                        constantPoolOffsets[utf8index]));
8301:                        frame.numberOfStackItems--;
8302:                        if (descriptor.length == 1) {
8303:                            // base type
8304:                            switch (descriptor[0]) {
8305:                            case 'Z':
8306:                                frame.addStackItem(TypeBinding.BOOLEAN);
8307:                                break;
8308:                            case 'B':
8309:                                frame.addStackItem(TypeBinding.BYTE);
8310:                                break;
8311:                            case 'C':
8312:                                frame.addStackItem(TypeBinding.CHAR);
8313:                                break;
8314:                            case 'D':
8315:                                frame.addStackItem(TypeBinding.DOUBLE);
8316:                                break;
8317:                            case 'F':
8318:                                frame.addStackItem(TypeBinding.FLOAT);
8319:                                break;
8320:                            case 'I':
8321:                                frame.addStackItem(TypeBinding.INT);
8322:                                break;
8323:                            case 'J':
8324:                                frame.addStackItem(TypeBinding.LONG);
8325:                                break;
8326:                            case 'S':
8327:                                frame.addStackItem(TypeBinding.SHORT);
8328:                                break;
8329:                            }
8330:                        } else if (descriptor[0] == '[') {
8331:                            frame.addStackItem(new VerificationTypeInfo(0,
8332:                                    descriptor));
8333:                        } else {
8334:                            frame.addStackItem(new VerificationTypeInfo(0,
8335:                                    CharOperation.subarray(descriptor, 1,
8336:                                            descriptor.length - 1)));
8337:                        }
8338:                        pc += 3;
8339:                        break;
8340:                    case Opcodes.OPC_putfield:
8341:                        frame.numberOfStackItems -= 2;
8342:                        pc += 3;
8343:                        break;
8344:                    case Opcodes.OPC_invokevirtual:
8345:                        index = u2At(bytecodes, 1, pc);
8346:                        nameAndTypeIndex = u2At(poolContents, 3,
8347:                                constantPoolOffsets[index]);
8348:                        utf8index = u2At(poolContents, 3,
8349:                                constantPoolOffsets[nameAndTypeIndex]);
8350:                        descriptor = utf8At(poolContents,
8351:                                constantPoolOffsets[utf8index] + 3, u2At(
8352:                                        poolContents, 1,
8353:                                        constantPoolOffsets[utf8index]));
8354:                        utf8index = u2At(poolContents, 1,
8355:                                constantPoolOffsets[nameAndTypeIndex]);
8356:                        char[] name = utf8At(poolContents,
8357:                                constantPoolOffsets[utf8index] + 3, u2At(
8358:                                        poolContents, 1,
8359:                                        constantPoolOffsets[utf8index]));
8360:                        frame.numberOfStackItems -= (getParametersCount(descriptor) + 1);
8361:                        char[] returnType = getReturnType(descriptor);
8362:                        if (returnType.length == 1) {
8363:                            // base type
8364:                            switch (returnType[0]) {
8365:                            case 'Z':
8366:                                frame.addStackItem(TypeBinding.BOOLEAN);
8367:                                break;
8368:                            case 'B':
8369:                                frame.addStackItem(TypeBinding.BYTE);
8370:                                break;
8371:                            case 'C':
8372:                                frame.addStackItem(TypeBinding.CHAR);
8373:                                break;
8374:                            case 'D':
8375:                                frame.addStackItem(TypeBinding.DOUBLE);
8376:                                break;
8377:                            case 'F':
8378:                                frame.addStackItem(TypeBinding.FLOAT);
8379:                                break;
8380:                            case 'I':
8381:                                frame.addStackItem(TypeBinding.INT);
8382:                                break;
8383:                            case 'J':
8384:                                frame.addStackItem(TypeBinding.LONG);
8385:                                break;
8386:                            case 'S':
8387:                                frame.addStackItem(TypeBinding.SHORT);
8388:                                break;
8389:                            }
8390:                        } else {
8391:                            if (returnType[0] == '[') {
8392:                                frame.addStackItem(new VerificationTypeInfo(0,
8393:                                        returnType));
8394:                            } else {
8395:                                frame.addStackItem(new VerificationTypeInfo(0,
8396:                                        CharOperation.subarray(returnType, 1,
8397:                                                returnType.length - 1)));
8398:                            }
8399:                        }
8400:                        pc += 3;
8401:                        break;
8402:                    case Opcodes.OPC_invokespecial:
8403:                        index = u2At(bytecodes, 1, pc);
8404:                        nameAndTypeIndex = u2At(poolContents, 3,
8405:                                constantPoolOffsets[index]);
8406:                        utf8index = u2At(poolContents, 3,
8407:                                constantPoolOffsets[nameAndTypeIndex]);
8408:                        descriptor = utf8At(poolContents,
8409:                                constantPoolOffsets[utf8index] + 3, u2At(
8410:                                        poolContents, 1,
8411:                                        constantPoolOffsets[utf8index]));
8412:                        utf8index = u2At(poolContents, 1,
8413:                                constantPoolOffsets[nameAndTypeIndex]);
8414:                        name = utf8At(poolContents,
8415:                                constantPoolOffsets[utf8index] + 3, u2At(
8416:                                        poolContents, 1,
8417:                                        constantPoolOffsets[utf8index]));
8418:                        frame.numberOfStackItems -= getParametersCount(descriptor);
8419:                        if (CharOperation.equals(ConstantPool.Init, name)) {
8420:                            // constructor
8421:                            frame.stackItems[frame.numberOfStackItems - 1].tag = VerificationTypeInfo.ITEM_OBJECT;
8422:                        }
8423:                        frame.numberOfStackItems--;
8424:                        returnType = getReturnType(descriptor);
8425:                        if (returnType.length == 1) {
8426:                            // base type
8427:                            switch (returnType[0]) {
8428:                            case 'Z':
8429:                                frame.addStackItem(TypeBinding.BOOLEAN);
8430:                                break;
8431:                            case 'B':
8432:                                frame.addStackItem(TypeBinding.BYTE);
8433:                                break;
8434:                            case 'C':
8435:                                frame.addStackItem(TypeBinding.CHAR);
8436:                                break;
8437:                            case 'D':
8438:                                frame.addStackItem(TypeBinding.DOUBLE);
8439:                                break;
8440:                            case 'F':
8441:                                frame.addStackItem(TypeBinding.FLOAT);
8442:                                break;
8443:                            case 'I':
8444:                                frame.addStackItem(TypeBinding.INT);
8445:                                break;
8446:                            case 'J':
8447:                                frame.addStackItem(TypeBinding.LONG);
8448:                                break;
8449:                            case 'S':
8450:                                frame.addStackItem(TypeBinding.SHORT);
8451:                                break;
8452:                            }
8453:                        } else {
8454:                            if (returnType[0] == '[') {
8455:                                frame.addStackItem(new VerificationTypeInfo(0,
8456:                                        returnType));
8457:                            } else {
8458:                                frame.addStackItem(new VerificationTypeInfo(0,
8459:                                        CharOperation.subarray(returnType, 1,
8460:                                                returnType.length - 1)));
8461:                            }
8462:                        }
8463:                        pc += 3;
8464:                        break;
8465:                    case Opcodes.OPC_invokestatic:
8466:                        index = u2At(bytecodes, 1, pc);
8467:                        nameAndTypeIndex = u2At(poolContents, 3,
8468:                                constantPoolOffsets[index]);
8469:                        utf8index = u2At(poolContents, 3,
8470:                                constantPoolOffsets[nameAndTypeIndex]);
8471:                        descriptor = utf8At(poolContents,
8472:                                constantPoolOffsets[utf8index] + 3, u2At(
8473:                                        poolContents, 1,
8474:                                        constantPoolOffsets[utf8index]));
8475:                        utf8index = u2At(poolContents, 1,
8476:                                constantPoolOffsets[nameAndTypeIndex]);
8477:                        name = utf8At(poolContents,
8478:                                constantPoolOffsets[utf8index] + 3, u2At(
8479:                                        poolContents, 1,
8480:                                        constantPoolOffsets[utf8index]));
8481:                        frame.numberOfStackItems -= getParametersCount(descriptor);
8482:                        returnType = getReturnType(descriptor);
8483:                        if (returnType.length == 1) {
8484:                            // base type
8485:                            switch (returnType[0]) {
8486:                            case 'Z':
8487:                                frame.addStackItem(TypeBinding.BOOLEAN);
8488:                                break;
8489:                            case 'B':
8490:                                frame.addStackItem(TypeBinding.BYTE);
8491:                                break;
8492:                            case 'C':
8493:                                frame.addStackItem(TypeBinding.CHAR);
8494:                                break;
8495:                            case 'D':
8496:                                frame.addStackItem(TypeBinding.DOUBLE);
8497:                                break;
8498:                            case 'F':
8499:                                frame.addStackItem(TypeBinding.FLOAT);
8500:                                break;
8501:                            case 'I':
8502:                                frame.addStackItem(TypeBinding.INT);
8503:                                break;
8504:                            case 'J':
8505:                                frame.addStackItem(TypeBinding.LONG);
8506:                                break;
8507:                            case 'S':
8508:                                frame.addStackItem(TypeBinding.SHORT);
8509:                                break;
8510:                            }
8511:                        } else {
8512:                            if (returnType[0] == '[') {
8513:                                frame.addStackItem(new VerificationTypeInfo(0,
8514:                                        returnType));
8515:                            } else {
8516:                                frame.addStackItem(new VerificationTypeInfo(0,
8517:                                        CharOperation.subarray(returnType, 1,
8518:                                                returnType.length - 1)));
8519:                            }
8520:                        }
8521:                        pc += 3;
8522:                        break;
8523:                    case Opcodes.OPC_invokeinterface:
8524:                        index = u2At(bytecodes, 1, pc);
8525:                        nameAndTypeIndex = u2At(poolContents, 3,
8526:                                constantPoolOffsets[index]);
8527:                        utf8index = u2At(poolContents, 3,
8528:                                constantPoolOffsets[nameAndTypeIndex]);
8529:                        descriptor = utf8At(poolContents,
8530:                                constantPoolOffsets[utf8index] + 3, u2At(
8531:                                        poolContents, 1,
8532:                                        constantPoolOffsets[utf8index]));
8533:                        utf8index = u2At(poolContents, 1,
8534:                                constantPoolOffsets[nameAndTypeIndex]);
8535:                        name = utf8At(poolContents,
8536:                                constantPoolOffsets[utf8index] + 3, u2At(
8537:                                        poolContents, 1,
8538:                                        constantPoolOffsets[utf8index]));
8539:                        // we don't need count and args
8540:                        // u1At(bytecodes, 3, pc); // count
8541:                        // u1At(bytecodes, 4, pc); // extra args
8542:                        frame.numberOfStackItems -= (getParametersCount(descriptor) + 1);
8543:                        returnType = getReturnType(descriptor);
8544:                        if (returnType.length == 1) {
8545:                            // base type
8546:                            switch (returnType[0]) {
8547:                            case 'Z':
8548:                                frame.addStackItem(TypeBinding.BOOLEAN);
8549:                                break;
8550:                            case 'B':
8551:                                frame.addStackItem(TypeBinding.BYTE);
8552:                                break;
8553:                            case 'C':
8554:                                frame.addStackItem(TypeBinding.CHAR);
8555:                                break;
8556:                            case 'D':
8557:                                frame.addStackItem(TypeBinding.DOUBLE);
8558:                                break;
8559:                            case 'F':
8560:                                frame.addStackItem(TypeBinding.FLOAT);
8561:                                break;
8562:                            case 'I':
8563:                                frame.addStackItem(TypeBinding.INT);
8564:                                break;
8565:                            case 'J':
8566:                                frame.addStackItem(TypeBinding.LONG);
8567:                                break;
8568:                            case 'S':
8569:                                frame.addStackItem(TypeBinding.SHORT);
8570:                                break;
8571:                            }
8572:                        } else {
8573:                            if (returnType[0] == '[') {
8574:                                frame.addStackItem(new VerificationTypeInfo(0,
8575:                                        returnType));
8576:                            } else {
8577:                                frame.addStackItem(new VerificationTypeInfo(0,
8578:                                        CharOperation.subarray(returnType, 1,
8579:                                                returnType.length - 1)));
8580:                            }
8581:                        }
8582:                        pc += 5;
8583:                        break;
8584:                    case Opcodes.OPC_new:
8585:                        index = u2At(bytecodes, 1, pc);
8586:                        utf8index = u2At(poolContents, 1,
8587:                                constantPoolOffsets[index]);
8588:                        char[] className = utf8At(poolContents,
8589:                                constantPoolOffsets[utf8index] + 3, u2At(
8590:                                        poolContents, 1,
8591:                                        constantPoolOffsets[utf8index]));
8592:                        VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(
8593:                                0, VerificationTypeInfo.ITEM_UNINITIALIZED,
8594:                                className);
8595:                        verificationTypeInfo.offset = currentPC;
8596:                        frame.addStackItem(verificationTypeInfo);
8597:                        pc += 3;
8598:                        break;
8599:                    case Opcodes.OPC_newarray:
8600:                        char[] constantPoolName = null;
8601:                        switch (u1At(bytecodes, 1, pc)) {
8602:                        case ClassFileConstants.INT_ARRAY:
8603:                            constantPoolName = new char[] { '[', 'I' };
8604:                            break;
8605:                        case ClassFileConstants.BYTE_ARRAY:
8606:                            constantPoolName = new char[] { '[', 'B' };
8607:                            break;
8608:                        case ClassFileConstants.BOOLEAN_ARRAY:
8609:                            constantPoolName = new char[] { '[', 'Z' };
8610:                            break;
8611:                        case ClassFileConstants.SHORT_ARRAY:
8612:                            constantPoolName = new char[] { '[', 'S' };
8613:                            break;
8614:                        case ClassFileConstants.CHAR_ARRAY:
8615:                            constantPoolName = new char[] { '[', 'C' };
8616:                            break;
8617:                        case ClassFileConstants.LONG_ARRAY:
8618:                            constantPoolName = new char[] { '[', 'J' };
8619:                            break;
8620:                        case ClassFileConstants.FLOAT_ARRAY:
8621:                            constantPoolName = new char[] { '[', 'F' };
8622:                            break;
8623:                        case ClassFileConstants.DOUBLE_ARRAY:
8624:                            constantPoolName = new char[] { '[', 'D' };
8625:                            break;
8626:                        }
8627:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8628:                                TypeIds.T_JavaLangObject, constantPoolName);
8629:                        pc += 2;
8630:                        break;
8631:                    case Opcodes.OPC_anewarray:
8632:                        index = u2At(bytecodes, 1, pc);
8633:                        utf8index = u2At(poolContents, 1,
8634:                                constantPoolOffsets[index]);
8635:                        className = utf8At(poolContents,
8636:                                constantPoolOffsets[utf8index] + 3, u2At(
8637:                                        poolContents, 1,
8638:                                        constantPoolOffsets[utf8index]));
8639:                        int classNameLength = className.length;
8640:                        System
8641:                                .arraycopy(
8642:                                        className,
8643:                                        0,
8644:                                        (constantPoolName = new char[classNameLength + 3]),
8645:                                        2, classNameLength);
8646:                        constantPoolName[0] = '[';
8647:                        constantPoolName[1] = 'L';
8648:                        constantPoolName[classNameLength + 2] = ';';
8649:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8650:                                0, constantPoolName);
8651:                        pc += 3;
8652:                        break;
8653:                    case Opcodes.OPC_arraylength:
8654:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8655:                                TypeBinding.INT);
8656:                        pc++;
8657:                        break;
8658:                    case Opcodes.OPC_athrow:
8659:                        frame.numberOfStackItems--;
8660:                        pc++;
8661:                        break;
8662:                    case Opcodes.OPC_checkcast:
8663:                        index = u2At(bytecodes, 1, pc);
8664:                        utf8index = u2At(poolContents, 1,
8665:                                constantPoolOffsets[index]);
8666:                        className = utf8At(poolContents,
8667:                                constantPoolOffsets[utf8index] + 3, u2At(
8668:                                        poolContents, 1,
8669:                                        constantPoolOffsets[utf8index]));
8670:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8671:                                0, className);
8672:                        pc += 3;
8673:                        break;
8674:                    case Opcodes.OPC_instanceof :
8675:                        // no need to know the class index = u2At(bytecodes, 1, pc);
8676:                        frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(
8677:                                TypeBinding.INT);
8678:                        pc += 3;
8679:                        break;
8680:                    case Opcodes.OPC_monitorenter:
8681:                    case Opcodes.OPC_monitorexit:
8682:                        frame.numberOfStackItems--;
8683:                        pc++;
8684:                        break;
8685:                    case Opcodes.OPC_wide:
8686:                        opcode = (byte) u1At(bytecodes, 1, pc);
8687:                        if (opcode == Opcodes.OPC_iinc) {
8688:                            // index = u2At(bytecodes, 2, pc);
8689:                            // i2At(bytecodes, 4, pc); // const
8690:                            // we don't need the index and the const value
8691:                            pc += 6;
8692:                        } else {
8693:                            index = u2At(bytecodes, 2, pc);
8694:                            // need to handle iload, fload, aload, lload, dload, istore, fstore, astore, lstore or dstore
8695:                            switch (opcode) {
8696:                            case Opcodes.OPC_iload:
8697:                                frame.addStackItem(TypeBinding.INT);
8698:                                break;
8699:                            case Opcodes.OPC_fload:
8700:                                frame.addStackItem(TypeBinding.FLOAT);
8701:                                break;
8702:                            case Opcodes.OPC_aload:
8703:                                localsN = frame.locals[index];
8704:                                if (localsN == null) {
8705:                                    localsN = retrieveLocal(currentPC, index);
8706:                                }
8707:                                frame.addStackItem(localsN);
8708:                                break;
8709:                            case Opcodes.OPC_lload:
8710:                                frame.addStackItem(TypeBinding.LONG);
8711:                                break;
8712:                            case Opcodes.OPC_dload:
8713:                                frame.addStackItem(TypeBinding.DOUBLE);
8714:                                break;
8715:                            case Opcodes.OPC_istore:
8716:                                frame.numberOfStackItems--;
8717:                                break;
8718:                            case Opcodes.OPC_fstore:
8719:                                frame.numberOfStackItems--;
8720:                                break;
8721:                            case Opcodes.OPC_astore:
8722:                                frame.locals[index] = frame.stackItems[frame.numberOfStackItems - 1];
8723:                                frame.numberOfStackItems--;
8724:                                break;
8725:                            case Opcodes.OPC_lstore:
8726:                                frame.numberOfStackItems--;
8727:                                break;
8728:                            case Opcodes.OPC_dstore:
8729:                                frame.numberOfStackItems--;
8730:                                break;
8731:                            }
8732:                            pc += 4;
8733:                        }
8734:                        break;
8735:                    case Opcodes.OPC_multianewarray:
8736:                        index = u2At(bytecodes, 1, pc);
8737:                        utf8index = u2At(poolContents, 1,
8738:                                constantPoolOffsets[index]);
8739:                        className = utf8At(poolContents,
8740:                                constantPoolOffsets[utf8index] + 3, u2At(
8741:                                        poolContents, 1,
8742:                                        constantPoolOffsets[utf8index]));
8743:                        int dimensions = u1At(bytecodes, 3, pc); // dimensions
8744:                        frame.numberOfStackItems -= dimensions;
8745:                        classNameLength = className.length;
8746:                        constantPoolName = new char[classNameLength
8747:                                + dimensions];
8748:                        for (int i = 0; i < dimensions; i++) {
8749:                            constantPoolName[i] = '[';
8750:                        }
8751:                        System.arraycopy(className, 0, constantPoolName,
8752:                                dimensions, classNameLength);
8753:                        frame.addStackItem(new VerificationTypeInfo(0,
8754:                                constantPoolName));
8755:                        pc += 4;
8756:                        break;
8757:                    case Opcodes.OPC_ifnull:
8758:                    case Opcodes.OPC_ifnonnull:
8759:                        frame.numberOfStackItems--;
8760:                        pc += 3;
8761:                        break;
8762:                    case Opcodes.OPC_goto_w:
8763:                        pc += 5;
8764:                        break;
8765:                    default: // should not occur
8766:                        codeStream.methodDeclaration.scope
8767:                                .problemReporter()
8768:                                .abortDueToInternalError(
8769:                                        Messages
8770:                                                .bind(
8771:                                                        Messages.abort_invalidOpcode,
8772:                                                        new Object[] {
8773:                                                                new Byte(opcode),
8774:                                                                new Integer(pc),
8775:                                                                new String(
8776:                                                                        methodBinding
8777:                                                                                .shortReadableName()), }),
8778:                                        codeStream.methodDeclaration);
8779:                        break;
8780:                    }
8781:                    if (pc >= (codeLength + codeOffset)) {
8782:                        break;
8783:                    }
8784:                }
8785:            }
8786:
8787:            private void initializeDefaultLocals(StackMapFrame frame,
8788:                    MethodBinding methodBinding, int maxLocals, int codeLength) {
8789:                if (maxLocals != 0) {
8790:                    int resolvedPosition = 0;
8791:                    // take into account enum constructor synthetic name+ordinal
8792:                    final boolean isConstructor = methodBinding.isConstructor();
8793:                    if (isConstructor) {
8794:                        LocalVariableBinding localVariableBinding = new LocalVariableBinding(
8795:                                "this".toCharArray(), methodBinding.declaringClass, 0, false); //$NON-NLS-1$
8796:                        localVariableBinding.resolvedPosition = 0;
8797:                        codeStream.record(localVariableBinding);
8798:                        localVariableBinding.recordInitializationStartPC(0);
8799:                        localVariableBinding
8800:                                .recordInitializationEndPC(codeLength);
8801:                        frame
8802:                                .putLocal(
8803:                                        resolvedPosition,
8804:                                        new VerificationTypeInfo(
8805:                                                VerificationTypeInfo.ITEM_UNINITIALIZED_THIS,
8806:                                                methodBinding.declaringClass));
8807:                        resolvedPosition++;
8808:                    } else if (!methodBinding.isStatic()) {
8809:                        LocalVariableBinding localVariableBinding = new LocalVariableBinding(
8810:                                "this".toCharArray(), methodBinding.declaringClass, 0, false); //$NON-NLS-1$
8811:                        localVariableBinding.resolvedPosition = 0;
8812:                        codeStream.record(localVariableBinding);
8813:                        localVariableBinding.recordInitializationStartPC(0);
8814:                        localVariableBinding
8815:                                .recordInitializationEndPC(codeLength);
8816:                        frame.putLocal(resolvedPosition,
8817:                                new VerificationTypeInfo(
8818:                                        VerificationTypeInfo.ITEM_OBJECT,
8819:                                        methodBinding.declaringClass));
8820:                        resolvedPosition++;
8821:                    }
8822:
8823:                    if (isConstructor) {
8824:                        if (methodBinding.declaringClass.isEnum()) {
8825:                            LocalVariableBinding localVariableBinding = new LocalVariableBinding(
8826:                                    " name".toCharArray(), this .referenceBinding.scope.getJavaLangString(), 0, false); //$NON-NLS-1$
8827:                            localVariableBinding.resolvedPosition = resolvedPosition;
8828:                            codeStream.record(localVariableBinding);
8829:                            localVariableBinding.recordInitializationStartPC(0);
8830:                            localVariableBinding
8831:                                    .recordInitializationEndPC(codeLength);
8832:
8833:                            frame
8834:                                    .putLocal(
8835:                                            resolvedPosition,
8836:                                            new VerificationTypeInfo(
8837:                                                    TypeIds.T_JavaLangString,
8838:                                                    ConstantPool.JavaLangStringConstantPoolName));
8839:                            resolvedPosition++;
8840:
8841:                            localVariableBinding = new LocalVariableBinding(
8842:                                    " ordinal".toCharArray(), TypeBinding.INT, 0, false); //$NON-NLS-1$
8843:                            localVariableBinding.resolvedPosition = resolvedPosition;
8844:                            codeStream.record(localVariableBinding);
8845:                            localVariableBinding.recordInitializationStartPC(0);
8846:                            localVariableBinding
8847:                                    .recordInitializationEndPC(codeLength);
8848:                            frame.putLocal(resolvedPosition,
8849:                                    new VerificationTypeInfo(TypeBinding.INT));
8850:                            resolvedPosition++;
8851:                        }
8852:
8853:                        // take into account the synthetic parameters
8854:                        if (methodBinding.declaringClass.isNestedType()) {
8855:                            ReferenceBinding enclosingInstanceTypes[];
8856:                            if ((enclosingInstanceTypes = methodBinding.declaringClass
8857:                                    .syntheticEnclosingInstanceTypes()) != null) {
8858:                                for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
8859:                                    // an enclosingInstanceType can only be a reference
8860:                                    // binding. It cannot be
8861:                                    // LongBinding or DoubleBinding
8862:                                    LocalVariableBinding localVariableBinding = new LocalVariableBinding(
8863:                                            (" enclosingType" + i).toCharArray(), enclosingInstanceTypes[i], 0, false); //$NON-NLS-1$
8864:                                    localVariableBinding.resolvedPosition = resolvedPosition;
8865:                                    codeStream.record(localVariableBinding);
8866:                                    localVariableBinding
8867:                                            .recordInitializationStartPC(0);
8868:                                    localVariableBinding
8869:                                            .recordInitializationEndPC(codeLength);
8870:
8871:                                    frame.putLocal(resolvedPosition,
8872:                                            new VerificationTypeInfo(
8873:                                                    enclosingInstanceTypes[i]));
8874:                                    resolvedPosition++;
8875:                                }
8876:                            }
8877:
8878:                            TypeBinding[] arguments;
8879:                            if ((arguments = methodBinding.parameters) != null) {
8880:                                for (int i = 0, max = arguments.length; i < max; i++) {
8881:                                    final TypeBinding typeBinding = arguments[i];
8882:                                    frame.putLocal(resolvedPosition,
8883:                                            new VerificationTypeInfo(
8884:                                                    typeBinding));
8885:                                    switch (typeBinding.id) {
8886:                                    case TypeIds.T_double:
8887:                                    case TypeIds.T_long:
8888:                                        resolvedPosition += 2;
8889:                                        break;
8890:                                    default:
8891:                                        resolvedPosition++;
8892:                                    }
8893:                                }
8894:                            }
8895:
8896:                            SyntheticArgumentBinding syntheticArguments[];
8897:                            if ((syntheticArguments = methodBinding.declaringClass
8898:                                    .syntheticOuterLocalVariables()) != null) {
8899:                                for (int i = 0, max = syntheticArguments.length; i < max; i++) {
8900:                                    final TypeBinding typeBinding = syntheticArguments[i].type;
8901:                                    LocalVariableBinding localVariableBinding = new LocalVariableBinding(
8902:                                            (" synthetic" + i).toCharArray(), typeBinding, 0, false); //$NON-NLS-1$
8903:                                    localVariableBinding.resolvedPosition = resolvedPosition;
8904:                                    codeStream.record(localVariableBinding);
8905:                                    localVariableBinding
8906:                                            .recordInitializationStartPC(0);
8907:                                    localVariableBinding
8908:                                            .recordInitializationEndPC(codeLength);
8909:
8910:                                    frame.putLocal(resolvedPosition,
8911:                                            new VerificationTypeInfo(
8912:                                                    typeBinding));
8913:                                    switch (typeBinding.id) {
8914:                                    case TypeIds.T_double:
8915:                                    case TypeIds.T_long:
8916:                                        resolvedPosition += 2;
8917:                                        break;
8918:                                    default:
8919:                                        resolvedPosition++;
8920:                                    }
8921:                                }
8922:                            }
8923:                        } else {
8924:                            TypeBinding[] arguments;
8925:                            if ((arguments = methodBinding.parameters) != null) {
8926:                                for (int i = 0, max = arguments.length; i < max; i++) {
8927:                                    final TypeBinding typeBinding = arguments[i];
8928:                                    frame.putLocal(resolvedPosition,
8929:                                            new VerificationTypeInfo(
8930:                                                    typeBinding));
8931:                                    switch (typeBinding.id) {
8932:                                    case TypeIds.T_double:
8933:                                    case TypeIds.T_long:
8934:                                        resolvedPosition += 2;
8935:                                        break;
8936:                                    default:
8937:                                        resolvedPosition++;
8938:                                    }
8939:                                }
8940:                            }
8941:                        }
8942:                    } else {
8943:                        TypeBinding[] arguments;
8944:                        if ((arguments = methodBinding.parameters) != null) {
8945:                            for (int i = 0, max = arguments.length; i < max; i++) {
8946:                                final TypeBinding typeBinding = arguments[i];
8947:                                frame.putLocal(resolvedPosition,
8948:                                        new VerificationTypeInfo(typeBinding));
8949:                                switch (typeBinding.id) {
8950:                                case TypeIds.T_double:
8951:                                case TypeIds.T_long:
8952:                                    resolvedPosition += 2;
8953:                                    break;
8954:                                default:
8955:                                    resolvedPosition++;
8956:                                }
8957:                            }
8958:                        }
8959:                    }
8960:                }
8961:            }
8962:
8963:            private void initializeLocals(boolean isStatic, int currentPC,
8964:                    StackMapFrame currentFrame) {
8965:                VerificationTypeInfo[] locals = currentFrame.locals;
8966:                int localsLength = locals.length;
8967:                int i = 0;
8968:                if (!isStatic) {
8969:                    // we don't want to reset the first local if the method is not static
8970:                    i = 1;
8971:                }
8972:                for (; i < localsLength; i++) {
8973:                    locals[i] = null;
8974:                }
8975:                i = 0;
8976:                locals: for (int max = codeStream.allLocalsCounter; i < max; i++) {
8977:                    LocalVariableBinding localVariable = codeStream.locals[i];
8978:                    if (localVariable == null)
8979:                        continue;
8980:                    int resolvedPosition = localVariable.resolvedPosition;
8981:                    final TypeBinding localVariableTypeBinding = localVariable.type;
8982:                    inits: for (int j = 0; j < localVariable.initializationCount; j++) {
8983:                        int startPC = localVariable.initializationPCs[j << 1];
8984:                        int endPC = localVariable.initializationPCs[(j << 1) + 1];
8985:                        if (currentPC < startPC) {
8986:                            continue inits;
8987:                        } else if (currentPC < endPC) {
8988:                            // the current local is an active local
8989:                            if (currentFrame.locals[resolvedPosition] == null) {
8990:                                currentFrame.locals[resolvedPosition] = new VerificationTypeInfo(
8991:                                        localVariableTypeBinding);
8992:                            }
8993:                            continue locals;
8994:                        }
8995:                    }
8996:                }
8997:            }
8998:
8999:            private VerificationTypeInfo retrieveLocal(int currentPC,
9000:                    int resolvedPosition) {
9001:                for (int i = 0, max = codeStream.allLocalsCounter; i < max; i++) {
9002:                    LocalVariableBinding localVariable = codeStream.locals[i];
9003:                    if (localVariable == null)
9004:                        continue;
9005:                    if (resolvedPosition == localVariable.resolvedPosition) {
9006:                        inits: for (int j = 0; j < localVariable.initializationCount; j++) {
9007:                            int startPC = localVariable.initializationPCs[j << 1];
9008:                            int endPC = localVariable.initializationPCs[(j << 1) + 1];
9009:                            if (currentPC < startPC) {
9010:                                continue inits;
9011:                            } else if (currentPC < endPC) {
9012:                                // the current local is an active local
9013:                                return new VerificationTypeInfo(
9014:                                        localVariable.type);
9015:                            }
9016:                        }
9017:                    }
9018:                }
9019:                return null;
9020:            }
9021:
9022:            private final int u1At(byte[] reference, int relativeOffset,
9023:                    int structOffset) {
9024:                return (reference[relativeOffset + structOffset] & 0xFF);
9025:            }
9026:
9027:            private final int i4At(byte[] reference, int relativeOffset,
9028:                    int structOffset) {
9029:                int position = relativeOffset + structOffset;
9030:                return ((reference[position++] & 0xFF) << 24)
9031:                        + ((reference[position++] & 0xFF) << 16)
9032:                        + ((reference[position++] & 0xFF) << 8)
9033:                        + (reference[position] & 0xFF);
9034:            }
9035:
9036:            private final int u2At(byte[] reference, int relativeOffset,
9037:                    int structOffset) {
9038:                int position = relativeOffset + structOffset;
9039:                return ((reference[position++] & 0xFF) << 8)
9040:                        + (reference[position] & 0xFF);
9041:            }
9042:
9043:            private final long u4At(byte[] reference, int relativeOffset,
9044:                    int structOffset) {
9045:                int position = relativeOffset + structOffset;
9046:                return (((reference[position++] & 0xFFL) << 24)
9047:                        + ((reference[position++] & 0xFF) << 16)
9048:                        + ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF));
9049:            }
9050:
9051:            public char[] utf8At(byte[] reference, int absoluteOffset,
9052:                    int bytesAvailable) {
9053:                int length = bytesAvailable;
9054:                char outputBuf[] = new char[bytesAvailable];
9055:                int outputPos = 0;
9056:                int readOffset = absoluteOffset;
9057:
9058:                while (length != 0) {
9059:                    int x = reference[readOffset++] & 0xFF;
9060:                    length--;
9061:                    if ((0x80 & x) != 0) {
9062:                        if ((x & 0x20) != 0) {
9063:                            length -= 2;
9064:                            x = ((x & 0xF) << 12)
9065:                                    | ((reference[readOffset++] & 0x3F) << 6)
9066:                                    | (reference[readOffset++] & 0x3F);
9067:                        } else {
9068:                            length--;
9069:                            x = ((x & 0x1F) << 6)
9070:                                    | (reference[readOffset++] & 0x3F);
9071:                        }
9072:                    }
9073:                    outputBuf[outputPos++] = (char) x;
9074:                }
9075:
9076:                if (outputPos != bytesAvailable) {
9077:                    System.arraycopy(outputBuf, 0,
9078:                            (outputBuf = new char[outputPos]), 0, outputPos);
9079:                }
9080:                return outputBuf;
9081:            }
9082:
9083:            private char[] getReturnType(char[] methodSignature) {
9084:                // skip type parameters
9085:                int paren = CharOperation.lastIndexOf(')', methodSignature);
9086:                // there could be thrown exceptions behind, thus scan one type exactly
9087:                return CharOperation.subarray(methodSignature, paren + 1,
9088:                        methodSignature.length);
9089:            }
9090:
9091:            private int getParametersCount(char[] methodSignature) {
9092:                int i = CharOperation.indexOf('(', methodSignature);
9093:                i++;
9094:                char currentCharacter = methodSignature[i];
9095:                if (currentCharacter == ')') {
9096:                    return 0;
9097:                }
9098:                int result = 0;
9099:                while (true) {
9100:                    currentCharacter = methodSignature[i];
9101:                    if (currentCharacter == ')') {
9102:                        return result;
9103:                    }
9104:                    switch (currentCharacter) {
9105:                    case '[':
9106:                        // array type
9107:                        int scanType = scanType(methodSignature, i + 1);
9108:                        result++;
9109:                        i = scanType + 1;
9110:                        break;
9111:                    case 'L':
9112:                        scanType = CharOperation.indexOf(';', methodSignature,
9113:                                i + 1);
9114:                        result++;
9115:                        i = scanType + 1;
9116:                        break;
9117:                    case 'Z':
9118:                    case 'B':
9119:                    case 'C':
9120:                    case 'D':
9121:                    case 'F':
9122:                    case 'I':
9123:                    case 'J':
9124:                    case 'S':
9125:                        result++;
9126:                        i++;
9127:                        break;
9128:                    default:
9129:                        throw new IllegalArgumentException();
9130:                    }
9131:                }
9132:            }
9133:
9134:            private int scanType(char[] methodSignature, int index) {
9135:                switch (methodSignature[index]) {
9136:                case '[':
9137:                    // array type
9138:                    return scanType(methodSignature, index + 1);
9139:                case 'L':
9140:                    return CharOperation.indexOf(';', methodSignature,
9141:                            index + 1);
9142:                case 'Z':
9143:                case 'B':
9144:                case 'C':
9145:                case 'D':
9146:                case 'F':
9147:                case 'I':
9148:                case 'J':
9149:                case 'S':
9150:                    return index;
9151:                default:
9152:                    throw new IllegalArgumentException();
9153:                }
9154:            }
9155:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.