Source Code Cross Referenced for JSRInlinerAdapterUnitTest.java in  » Byte-Code » asm » org » objectweb » asm » commons » 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 » Byte Code » asm » org.objectweb.asm.commons 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /***
0002:         * ASM tests
0003:         * Copyright (c) 2002-2005 France Telecom
0004:         * All rights reserved.
0005:         *
0006:         * Redistribution and use in source and binary forms, with or without
0007:         * modification, are permitted provided that the following conditions
0008:         * are met:
0009:         * 1. Redistributions of source code must retain the above copyright
0010:         *    notice, this list of conditions and the following disclaimer.
0011:         * 2. Redistributions in binary form must reproduce the above copyright
0012:         *    notice, this list of conditions and the following disclaimer in the
0013:         *    documentation and/or other materials provided with the distribution.
0014:         * 3. Neither the name of the copyright holders nor the names of its
0015:         *    contributors may be used to endorse or promote products derived from
0016:         *    this software without specific prior written permission.
0017:         *
0018:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021:         * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0022:         * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023:         * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024:         * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025:         * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026:         * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027:         * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
0028:         * THE POSSIBILITY OF SUCH DAMAGE.
0029:         */package org.objectweb.asm.commons;
0030:
0031:        import junit.framework.TestCase;
0032:
0033:        import org.objectweb.asm.ClassWriter;
0034:        import org.objectweb.asm.Label;
0035:        import org.objectweb.asm.MethodVisitor;
0036:        import org.objectweb.asm.Opcodes;
0037:        import org.objectweb.asm.tree.MethodNode;
0038:        import org.objectweb.asm.util.TraceMethodVisitor;
0039:
0040:        /**
0041:         * JsrInlinerTest
0042:         * 
0043:         * @author Eugene Kuleshov, Niko Matsakis, Eric Bruneton
0044:         */
0045:        public class JSRInlinerAdapterUnitTest extends TestCase {
0046:
0047:            private JSRInlinerAdapter jsr;
0048:            private MethodNode exp;
0049:            private MethodVisitor current;
0050:
0051:            protected void setUp() throws Exception {
0052:                super .setUp();
0053:                jsr = new JSRInlinerAdapter(null, 0, "m", "()V", null, null) {
0054:                    public void visitEnd() {
0055:                        System.err.println("started w/ method:" + name);
0056:                        TraceMethodVisitor mv = new TraceMethodVisitor();
0057:                        for (int i = 0; i < instructions.size(); ++i) {
0058:                            instructions.get(i).accept(mv);
0059:                            System.err.print(Integer.toString(i + 100000)
0060:                                    .substring(1));
0061:                            System.err.print(" : " + mv.text.get(i));
0062:                        }
0063:                        super .visitEnd();
0064:                        System.err.println("finished w/ method:" + name);
0065:                    }
0066:                };
0067:                exp = new MethodNode(0, "m", "()V", null, null);
0068:            }
0069:
0070:            private void setCurrent(final MethodVisitor cv) {
0071:                this .current = cv;
0072:            }
0073:
0074:            private void ICONST_0() {
0075:                this .current.visitInsn(Opcodes.ICONST_0);
0076:            }
0077:
0078:            private void ISTORE(final int var) {
0079:                this .current.visitVarInsn(Opcodes.ISTORE, var);
0080:            }
0081:
0082:            private void ALOAD(final int var) {
0083:                this .current.visitVarInsn(Opcodes.ALOAD, var);
0084:            }
0085:
0086:            private void ILOAD(final int var) {
0087:                this .current.visitVarInsn(Opcodes.ILOAD, var);
0088:            }
0089:
0090:            private void ASTORE(final int var) {
0091:                this .current.visitVarInsn(Opcodes.ASTORE, var);
0092:            }
0093:
0094:            private void RET(final int var) {
0095:                this .current.visitVarInsn(Opcodes.RET, var);
0096:            }
0097:
0098:            private void ATHROW() {
0099:                this .current.visitInsn(Opcodes.ATHROW);
0100:            }
0101:
0102:            private void ACONST_NULL() {
0103:                this .current.visitInsn(Opcodes.ACONST_NULL);
0104:            }
0105:
0106:            private void RETURN() {
0107:                this .current.visitInsn(Opcodes.RETURN);
0108:            }
0109:
0110:            private void LABEL(final Label l) {
0111:                this .current.visitLabel(l);
0112:            }
0113:
0114:            private void IINC(final int var, final int amnt) {
0115:                this .current.visitIincInsn(var, amnt);
0116:            }
0117:
0118:            private void GOTO(final Label l) {
0119:                this .current.visitJumpInsn(Opcodes.GOTO, l);
0120:            }
0121:
0122:            private void JSR(final Label l) {
0123:                this .current.visitJumpInsn(Opcodes.JSR, l);
0124:            }
0125:
0126:            private void IFNONNULL(final Label l) {
0127:                this .current.visitJumpInsn(Opcodes.IFNONNULL, l);
0128:            }
0129:
0130:            private void IFNE(final Label l) {
0131:                this .current.visitJumpInsn(Opcodes.IFNE, l);
0132:            }
0133:
0134:            private void TRYCATCH(final Label start, final Label end,
0135:                    final Label handler) {
0136:                this .current.visitTryCatchBlock(start, end, handler, null);
0137:            }
0138:
0139:            private void LINE(final int line, final Label start) {
0140:                this .current.visitLineNumber(line, start);
0141:            }
0142:
0143:            private void LOCALVAR(final String name, final String desc,
0144:                    final int index, final Label start, final Label end) {
0145:                this .current.visitLocalVariable(name, desc, null, start, end,
0146:                        index);
0147:            }
0148:
0149:            private void END(final int maxStack, final int maxLocals) {
0150:                this .current.visitMaxs(maxStack, maxLocals);
0151:                this .current.visitEnd();
0152:                ClassWriter cw = new ClassWriter(0);
0153:                cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "C", null,
0154:                        "java/lang/Object", null);
0155:                MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
0156:                        "()V", null, null);
0157:                mv.visitCode();
0158:                mv.visitVarInsn(Opcodes.ALOAD, 0);
0159:                mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object",
0160:                        "<init>", "()V");
0161:                mv.visitInsn(Opcodes.RETURN);
0162:                mv.visitMaxs(1, 1);
0163:                mv.visitEnd();
0164:                ((MethodNode) this .current).accept(cw);
0165:                cw.visitEnd();
0166:                byte[] b = cw.toByteArray();
0167:                try {
0168:                    TestClassLoader loader = new TestClassLoader();
0169:                    Class c = loader.defineClass("C", b);
0170:                    c.newInstance();
0171:                } catch (Throwable t) {
0172:                    fail(t.getMessage());
0173:                }
0174:                this .current = null;
0175:            }
0176:
0177:            static class TestClassLoader extends ClassLoader {
0178:
0179:                public Class defineClass(final String name, final byte[] b) {
0180:                    return defineClass(name, b, 0, b.length);
0181:                }
0182:            }
0183:
0184:            /**
0185:             * Tests a method which has the most basic <code>try{}finally</code> form
0186:             * imaginable:
0187:             * 
0188:             * <pre>
0189:             *   public void a() {
0190:             *     int a = 0;
0191:             *     try {
0192:             *       a++;
0193:             *     } finally {
0194:             *       a--;
0195:             *     }
0196:             *   }
0197:             * </pre>
0198:             */
0199:            public void testBasic() {
0200:                {
0201:                    Label L0 = new Label();
0202:                    Label L1 = new Label();
0203:                    Label L2 = new Label();
0204:                    Label L3 = new Label();
0205:                    Label L4 = new Label();
0206:
0207:                    setCurrent(jsr);
0208:                    ICONST_0();
0209:                    ISTORE(1);
0210:
0211:                    /* L0: body of try block */
0212:                    LABEL(L0);
0213:                    IINC(1, 1);
0214:                    GOTO(L1);
0215:
0216:                    /* L2: exception handler */
0217:                    LABEL(L2);
0218:                    ASTORE(3);
0219:                    JSR(L3);
0220:                    ALOAD(3);
0221:                    ATHROW();
0222:
0223:                    /* L3: subroutine */
0224:                    LABEL(L3);
0225:                    ASTORE(2);
0226:                    IINC(1, -1);
0227:                    RET(2);
0228:
0229:                    /* L1: non-exceptional exit from try block */
0230:                    LABEL(L1);
0231:                    JSR(L3);
0232:                    LABEL(L4); // L4
0233:                    RETURN();
0234:
0235:                    TRYCATCH(L0, L2, L2);
0236:                    TRYCATCH(L1, L4, L2);
0237:
0238:                    END(1, 4);
0239:                }
0240:
0241:                {
0242:                    Label L0 = new Label();
0243:                    Label L1 = new Label();
0244:                    Label L2 = new Label();
0245:                    Label L3_1a = new Label();
0246:                    Label L3_1b = new Label();
0247:                    Label L3_2a = new Label();
0248:                    Label L3_2b = new Label();
0249:                    Label L4 = new Label();
0250:
0251:                    setCurrent(exp);
0252:                    ICONST_0();
0253:                    ISTORE(1);
0254:                    // L0: try/catch block
0255:                    LABEL(L0);
0256:                    IINC(1, 1);
0257:                    GOTO(L1);
0258:
0259:                    // L2: Exception handler:
0260:                    LABEL(L2);
0261:                    ASTORE(3);
0262:                    ACONST_NULL();
0263:                    GOTO(L3_1a);
0264:                    LABEL(L3_1b); // L3_1b;
0265:                    ALOAD(3);
0266:                    ATHROW();
0267:
0268:                    // L1: On non-exceptional exit, try block leads here:
0269:                    LABEL(L1);
0270:                    ACONST_NULL();
0271:                    GOTO(L3_2a);
0272:                    LABEL(L3_2b); // L3_2b
0273:                    LABEL(L4); // L4
0274:                    RETURN();
0275:
0276:                    // L3_1a: First instantiation of subroutine:
0277:                    LABEL(L3_1a);
0278:                    ASTORE(2);
0279:                    IINC(1, -1);
0280:                    GOTO(L3_1b);
0281:                    LABEL(new Label()); // extra label emitted due to impl quirks
0282:
0283:                    // L3_2a: Second instantiation of subroutine:
0284:                    LABEL(L3_2a);
0285:                    ASTORE(2);
0286:                    IINC(1, -1);
0287:                    GOTO(L3_2b);
0288:                    LABEL(new Label()); // extra label emitted due to impl quirks
0289:
0290:                    TRYCATCH(L0, L2, L2);
0291:                    TRYCATCH(L1, L4, L2);
0292:
0293:                    END(1, 4);
0294:                }
0295:
0296:                assertEquals(exp, jsr);
0297:            }
0298:
0299:            /**
0300:             * Tests a method which has an if/else-if w/in the finally clause:
0301:             * 
0302:             * <pre>
0303:             *   public void a() {
0304:             *     int a = 0;
0305:             *     try {
0306:             *       a++;
0307:             *     } finally {
0308:             *       if (a == 0)
0309:             *         a+=2;
0310:             *       else
0311:             *         a+=3;
0312:             *     }
0313:             *   }
0314:             * </pre>
0315:             */
0316:            public void testIfElseInFinally() {
0317:                {
0318:                    Label L0 = new Label();
0319:                    Label L1 = new Label();
0320:                    Label L2 = new Label();
0321:                    Label L3 = new Label();
0322:                    Label L4 = new Label();
0323:                    Label L5 = new Label();
0324:                    Label L6 = new Label();
0325:
0326:                    setCurrent(jsr);
0327:                    ICONST_0();
0328:                    ISTORE(1);
0329:
0330:                    /* L0: body of try block */
0331:                    LABEL(L0);
0332:                    IINC(1, 1);
0333:                    GOTO(L1);
0334:
0335:                    /* L2: exception handler */
0336:                    LABEL(L2);
0337:                    ASTORE(3);
0338:                    JSR(L3);
0339:                    ALOAD(3);
0340:                    ATHROW();
0341:
0342:                    /* L3: subroutine */
0343:                    LABEL(L3);
0344:                    ASTORE(2);
0345:                    ILOAD(1);
0346:                    IFNE(L4);
0347:                    IINC(1, 2);
0348:                    GOTO(L5);
0349:                    LABEL(L4); // L4: a != 0
0350:                    IINC(1, 3);
0351:                    LABEL(L5); // L5: common exit
0352:                    RET(2);
0353:
0354:                    /* L1: non-exceptional exit from try block */
0355:                    LABEL(L1);
0356:                    JSR(L3);
0357:                    LABEL(L6); // L6 is used in the TRYCATCH below
0358:                    RETURN();
0359:
0360:                    TRYCATCH(L0, L2, L2);
0361:                    TRYCATCH(L1, L6, L2);
0362:
0363:                    END(1, 4);
0364:                }
0365:
0366:                {
0367:                    Label L0 = new Label();
0368:                    Label L1 = new Label();
0369:                    Label L2 = new Label();
0370:                    Label L3_1a = new Label();
0371:                    Label L3_1b = new Label();
0372:                    Label L3_2a = new Label();
0373:                    Label L3_2b = new Label();
0374:                    Label L4_1 = new Label();
0375:                    Label L4_2 = new Label();
0376:                    Label L5_1 = new Label();
0377:                    Label L5_2 = new Label();
0378:                    Label L6 = new Label();
0379:
0380:                    setCurrent(exp);
0381:                    ICONST_0();
0382:                    ISTORE(1);
0383:                    // L0: try/catch block
0384:                    LABEL(L0);
0385:                    IINC(1, 1);
0386:                    GOTO(L1);
0387:
0388:                    // L2: Exception handler:
0389:                    LABEL(L2);
0390:                    ASTORE(3);
0391:                    ACONST_NULL();
0392:                    GOTO(L3_1a);
0393:                    LABEL(L3_1b); // L3_1b;
0394:                    ALOAD(3);
0395:                    ATHROW();
0396:
0397:                    // L1: On non-exceptional exit, try block leads here:
0398:                    LABEL(L1);
0399:                    ACONST_NULL();
0400:                    GOTO(L3_2a);
0401:                    LABEL(L3_2b); // L3_2b
0402:                    LABEL(L6); // L6
0403:                    RETURN();
0404:
0405:                    // L3_1a: First instantiation of subroutine:
0406:                    LABEL(L3_1a);
0407:                    ASTORE(2);
0408:                    ILOAD(1);
0409:                    IFNE(L4_1);
0410:                    IINC(1, 2);
0411:                    GOTO(L5_1);
0412:                    LABEL(L4_1); // L4_1: a != 0
0413:                    IINC(1, 3);
0414:                    LABEL(L5_1); // L5_1: common exit
0415:                    GOTO(L3_1b);
0416:                    LABEL(new Label()); // extra label emitted due to impl quirks
0417:
0418:                    // L3_2a: First instantiation of subroutine:
0419:                    LABEL(L3_2a);
0420:                    ASTORE(2);
0421:                    ILOAD(1);
0422:                    IFNE(L4_2);
0423:                    IINC(1, 2);
0424:                    GOTO(L5_2);
0425:                    LABEL(L4_2); // L4_2: a != 0
0426:                    IINC(1, 3);
0427:                    LABEL(L5_2); // L5_2: common exit
0428:                    GOTO(L3_2b);
0429:                    LABEL(new Label()); // extra label emitted due to impl quirks
0430:
0431:                    TRYCATCH(L0, L2, L2);
0432:                    TRYCATCH(L1, L6, L2);
0433:
0434:                    END(1, 4);
0435:                }
0436:
0437:                assertEquals(exp, jsr);
0438:            }
0439:
0440:            /**
0441:             * Tests a simple nested finally:
0442:             * 
0443:             * <pre>
0444:             * public void a1() {
0445:             *   int a = 0;
0446:             *   try {
0447:             *     a += 1;
0448:             *   } finally {
0449:             *     try {
0450:             *       a += 2;
0451:             *     } finally {
0452:             *       a += 3;
0453:             *     }
0454:             *   }
0455:             * }
0456:             * </pre>
0457:             */
0458:            public void testSimpleNestedFinally() {
0459:                {
0460:                    Label L0 = new Label();
0461:                    Label L1 = new Label();
0462:                    Label L2 = new Label();
0463:                    Label L3 = new Label();
0464:                    Label L4 = new Label();
0465:                    Label L5 = new Label();
0466:
0467:                    setCurrent(jsr);
0468:
0469:                    ICONST_0();
0470:                    ISTORE(1);
0471:
0472:                    // L0: Body of try block:
0473:                    LABEL(L0);
0474:                    IINC(1, 1);
0475:                    JSR(L3);
0476:                    GOTO(L1);
0477:
0478:                    // L2: First exception handler:
0479:                    LABEL(L2);
0480:                    JSR(L3);
0481:                    ATHROW();
0482:
0483:                    // L3: First subroutine:
0484:                    LABEL(L3);
0485:                    ASTORE(2);
0486:                    IINC(1, 2);
0487:                    JSR(L4);
0488:                    RET(2);
0489:
0490:                    // L5: Second exception handler:
0491:                    LABEL(L5);
0492:                    JSR(L4);
0493:                    ATHROW();
0494:
0495:                    // L4: Second subroutine:
0496:                    LABEL(L4);
0497:                    ASTORE(3);
0498:                    IINC(1, 3);
0499:                    RET(3);
0500:
0501:                    // L1: On normal exit, try block jumps here:
0502:                    LABEL(L1);
0503:                    RETURN();
0504:
0505:                    TRYCATCH(L0, L2, L2);
0506:                    TRYCATCH(L3, L5, L5);
0507:
0508:                    END(2, 6);
0509:                }
0510:
0511:                {
0512:                    Label L0 = new Label();
0513:                    Label L1 = new Label();
0514:                    Label L2 = new Label();
0515:                    Label L3_1a = new Label();
0516:                    Label L3_1b = new Label();
0517:                    Label L3_2a = new Label();
0518:                    Label L3_2b = new Label();
0519:                    Label L4_1a = new Label();
0520:                    Label L4_1b = new Label();
0521:                    Label L4_2a = new Label();
0522:                    Label L4_2b = new Label();
0523:                    Label L4_3a = new Label();
0524:                    Label L4_3b = new Label();
0525:                    Label L4_4a = new Label();
0526:                    Label L4_4b = new Label();
0527:                    Label L5_1 = new Label();
0528:                    Label L5_2 = new Label();
0529:
0530:                    setCurrent(exp);
0531:
0532:                    ICONST_0();
0533:                    ISTORE(1);
0534:
0535:                    // L0: Body of try block:
0536:                    LABEL(L0);
0537:                    IINC(1, 1);
0538:                    ACONST_NULL();
0539:                    GOTO(L3_1a);
0540:                    LABEL(L3_1b); // L3_1b
0541:                    GOTO(L1);
0542:
0543:                    // L2: First exception handler:
0544:                    LABEL(L2);
0545:                    ACONST_NULL();
0546:                    GOTO(L3_2a);
0547:                    LABEL(L3_2b); // L3_2b
0548:                    ATHROW();
0549:
0550:                    // L1: On normal exit, try block jumps here:
0551:                    LABEL(L1);
0552:                    RETURN();
0553:
0554:                    // L3_1a: First instantiation of first subroutine:
0555:                    LABEL(L3_1a);
0556:                    ASTORE(2);
0557:                    IINC(1, 2);
0558:                    ACONST_NULL();
0559:                    GOTO(L4_1a);
0560:                    LABEL(L4_1b); // L4_1b
0561:                    GOTO(L3_1b);
0562:                    LABEL(L5_1); // L5_1
0563:                    ACONST_NULL();
0564:                    GOTO(L4_2a);
0565:                    LABEL(L4_2b); // L4_2b
0566:                    ATHROW();
0567:                    LABEL(new Label()); // extra label emitted due to impl quirks
0568:
0569:                    // L3_2a: Second instantiation of first subroutine:
0570:                    LABEL(L3_2a);
0571:                    ASTORE(2);
0572:                    IINC(1, 2);
0573:                    ACONST_NULL();
0574:                    GOTO(L4_3a);
0575:                    LABEL(L4_3b); // L4_3b
0576:                    GOTO(L3_2b);
0577:                    LABEL(L5_2); // L5_2
0578:                    ACONST_NULL();
0579:                    GOTO(L4_4a);
0580:                    LABEL(L4_4b); // L4_4b
0581:                    ATHROW();
0582:                    LABEL(new Label()); // extra label emitted due to impl quirks
0583:
0584:                    // L4_1a: First instantiation of second subroutine:
0585:                    LABEL(L4_1a);
0586:                    ASTORE(3);
0587:                    IINC(1, 3);
0588:                    GOTO(L4_1b);
0589:                    LABEL(new Label()); // extra label emitted due to impl quirks
0590:
0591:                    // L4_2a: Second instantiation of second subroutine:
0592:                    LABEL(L4_2a);
0593:                    ASTORE(3);
0594:                    IINC(1, 3);
0595:                    GOTO(L4_2b);
0596:                    LABEL(new Label()); // extra label emitted due to impl quirks
0597:
0598:                    // L4_3a: Third instantiation of second subroutine:
0599:                    LABEL(L4_3a);
0600:                    ASTORE(3);
0601:                    IINC(1, 3);
0602:                    GOTO(L4_3b);
0603:                    LABEL(new Label()); // extra label emitted due to impl quirks
0604:
0605:                    // L4_4a: Fourth instantiation of second subroutine:
0606:                    LABEL(L4_4a);
0607:                    ASTORE(3);
0608:                    IINC(1, 3);
0609:                    GOTO(L4_4b);
0610:                    LABEL(new Label()); // extra label emitted due to impl quirks
0611:
0612:                    TRYCATCH(L0, L2, L2);
0613:                    TRYCATCH(L3_1a, L5_1, L5_1);
0614:                    TRYCATCH(L3_2a, L5_2, L5_2);
0615:
0616:                    END(2, 6);
0617:                }
0618:
0619:                assertEquals(exp, jsr);
0620:            }
0621:
0622:            /**
0623:             * This tests a subroutine which has no ret statement, but ends in a
0624:             * "return" instead.
0625:             * 
0626:             * We structure this as a try/finally with a break in the finally. Because
0627:             * the while loop is infinite, it's clear from the byte code that the only
0628:             * path which reaches the RETURN instruction is through the subroutine.
0629:             * 
0630:             * <pre>
0631:             * public void a1() {
0632:             *   int a = 0;
0633:             *   while (true) {
0634:             *     try {
0635:             *       a += 1;
0636:             *     } finally {
0637:             *       a += 2;
0638:             *       break;
0639:             *     }
0640:             *   }
0641:             * }
0642:             * </pre>
0643:             */
0644:            public void testSubroutineWithNoRet() {
0645:                {
0646:                    Label L0 = new Label();
0647:                    Label L1 = new Label();
0648:                    Label L2 = new Label();
0649:                    Label L3 = new Label();
0650:                    Label L4 = new Label();
0651:
0652:                    setCurrent(jsr);
0653:                    ICONST_0();
0654:                    ISTORE(1);
0655:
0656:                    // L0: while loop header/try block
0657:                    LABEL(L0);
0658:                    IINC(1, 1);
0659:                    JSR(L1);
0660:                    GOTO(L2);
0661:
0662:                    // L3: implicit catch block
0663:                    LABEL(L3);
0664:                    ASTORE(2);
0665:                    JSR(L1);
0666:                    ALOAD(2);
0667:                    ATHROW();
0668:
0669:                    // L1: subroutine ...
0670:                    LABEL(L1);
0671:                    ASTORE(3);
0672:                    IINC(1, 2);
0673:                    GOTO(L4); // ...not that it does not return!
0674:
0675:                    // L2: end of the loop... goes back to the top!
0676:                    LABEL(L2);
0677:                    GOTO(L0);
0678:
0679:                    // L4:
0680:                    LABEL(L4);
0681:                    RETURN();
0682:
0683:                    TRYCATCH(L0, L3, L3);
0684:
0685:                    END(1, 4);
0686:                }
0687:
0688:                {
0689:                    Label L0 = new Label();
0690:                    Label L1_1a = new Label();
0691:                    Label L1_1b = new Label();
0692:                    Label L1_2a = new Label();
0693:                    Label L1_2b = new Label();
0694:                    Label L2 = new Label();
0695:                    Label L3 = new Label();
0696:                    Label L4_1 = new Label();
0697:                    Label L4_2 = new Label();
0698:
0699:                    setCurrent(exp);
0700:                    ICONST_0();
0701:                    ISTORE(1);
0702:
0703:                    // L0: while loop header/try block
0704:                    LABEL(L0);
0705:                    IINC(1, 1);
0706:                    ACONST_NULL();
0707:                    GOTO(L1_1a);
0708:                    LABEL(L1_1b); // L1_1b
0709:                    GOTO(L2);
0710:
0711:                    // L3: implicit catch block
0712:                    LABEL(L3);
0713:                    ASTORE(2);
0714:                    ACONST_NULL();
0715:                    GOTO(L1_2a);
0716:                    LABEL(L1_2b); // L1_2b
0717:                    ALOAD(2);
0718:                    ATHROW();
0719:
0720:                    // L2: end of the loop... goes back to the top!
0721:                    LABEL(L2);
0722:                    GOTO(L0);
0723:                    LABEL(new Label()); // extra label emitted due to impl quirks
0724:
0725:                    // L1_1a: first instantiation of subroutine ...
0726:                    LABEL(L1_1a);
0727:                    ASTORE(3);
0728:                    IINC(1, 2);
0729:                    GOTO(L4_1); // ...not that it does not return!
0730:                    LABEL(L4_1);
0731:                    RETURN();
0732:
0733:                    // L1_2a: second instantiation of subroutine ...
0734:                    LABEL(L1_2a);
0735:                    ASTORE(3);
0736:                    IINC(1, 2);
0737:                    GOTO(L4_2); // ...not that it does not return!
0738:                    LABEL(L4_2);
0739:                    RETURN();
0740:
0741:                    TRYCATCH(L0, L3, L3);
0742:
0743:                    END(1, 4);
0744:                }
0745:
0746:                assertEquals(exp, jsr);
0747:            }
0748:
0749:            /**
0750:             * This tests a subroutine which has no ret statement, but ends in a
0751:             * "return" instead.
0752:             * 
0753:             * <pre>
0754:             *   JSR L0
0755:             * L0:
0756:             *   ASTORE 0 
0757:             *   RETURN 
0758:             * </pre>
0759:             */
0760:            public void testSubroutineWithNoRet2() {
0761:                {
0762:                    Label L0 = new Label();
0763:
0764:                    setCurrent(jsr);
0765:                    JSR(L0);
0766:                    LABEL(L0);
0767:                    ASTORE(0);
0768:                    RETURN();
0769:                    END(1, 1);
0770:                }
0771:
0772:                {
0773:                    Label L0_1a = new Label();
0774:                    Label L0_1b = new Label();
0775:
0776:                    setCurrent(exp);
0777:
0778:                    ACONST_NULL();
0779:                    GOTO(L0_1a);
0780:                    LABEL(L0_1b);
0781:
0782:                    // L0_1a: First instantiation of subroutine:
0783:                    LABEL(L0_1a);
0784:                    ASTORE(0);
0785:                    RETURN();
0786:                    LABEL(new Label()); // extra label emitted due to impl quirks
0787:
0788:                    END(1, 1);
0789:                }
0790:
0791:                assertEquals(exp, jsr);
0792:            }
0793:
0794:            /**
0795:             * This tests a subroutine which has no ret statement, but instead exits
0796:             * implicitely by branching to code which is not part of the subroutine.
0797:             * (Sadly, this is legal)
0798:             * 
0799:             * We structure this as a try/finally in a loop with a break in the finally.
0800:             * The loop is not trivially infinite, so the RETURN statement is reachable
0801:             * both from the JSR subroutine and from the main entry point.
0802:             * 
0803:             * <pre>
0804:             * public void a1() {
0805:             *   int a = 0;
0806:             *   while (null == null) {
0807:             *     try {
0808:             *       a += 1;
0809:             *     } finally {
0810:             *       a += 2;
0811:             *       break;
0812:             *     }
0813:             *   }
0814:             * }
0815:             * </pre>
0816:             */
0817:            public void testImplicitExit() {
0818:                {
0819:                    Label L0 = new Label();
0820:                    Label L1 = new Label();
0821:                    Label L2 = new Label();
0822:                    Label L3 = new Label();
0823:                    Label L4 = new Label();
0824:                    Label L5 = new Label();
0825:
0826:                    setCurrent(jsr);
0827:                    ICONST_0();
0828:                    ISTORE(1);
0829:
0830:                    // L5: while loop header
0831:                    LABEL(L5);
0832:                    ACONST_NULL();
0833:                    IFNONNULL(L4);
0834:
0835:                    // L0: try block
0836:                    LABEL(L0);
0837:                    IINC(1, 1);
0838:                    JSR(L1);
0839:                    GOTO(L2);
0840:
0841:                    // L3: implicit catch block
0842:                    LABEL(L3);
0843:                    ASTORE(2);
0844:                    JSR(L1);
0845:                    ALOAD(2);
0846:                    ATHROW();
0847:
0848:                    // L1: subroutine ...
0849:                    LABEL(L1);
0850:                    ASTORE(3);
0851:                    IINC(1, 2);
0852:                    GOTO(L4); // ...not that it does not return!
0853:
0854:                    // L2: end of the loop... goes back to the top!
0855:                    LABEL(L2);
0856:                    GOTO(L0);
0857:
0858:                    // L4:
0859:                    LABEL(L4);
0860:                    RETURN();
0861:
0862:                    TRYCATCH(L0, L3, L3);
0863:
0864:                    END(1, 4);
0865:                }
0866:
0867:                {
0868:                    Label L0 = new Label();
0869:                    Label L1_1a = new Label();
0870:                    Label L1_1b = new Label();
0871:                    Label L1_2a = new Label();
0872:                    Label L1_2b = new Label();
0873:                    Label L2 = new Label();
0874:                    Label L3 = new Label();
0875:                    Label L4 = new Label();
0876:                    Label L5 = new Label();
0877:
0878:                    setCurrent(exp);
0879:                    ICONST_0();
0880:                    ISTORE(1);
0881:
0882:                    // L5: while loop header
0883:                    LABEL(L5);
0884:                    ACONST_NULL();
0885:                    IFNONNULL(L4);
0886:
0887:                    // L0: while loop header/try block
0888:                    LABEL(L0);
0889:                    IINC(1, 1);
0890:                    ACONST_NULL();
0891:                    GOTO(L1_1a);
0892:                    LABEL(L1_1b); // L1_1b
0893:                    GOTO(L2);
0894:
0895:                    // L3: implicit catch block
0896:                    LABEL(L3);
0897:                    ASTORE(2);
0898:                    ACONST_NULL();
0899:                    GOTO(L1_2a);
0900:                    LABEL(L1_2b); // L1_2b
0901:                    ALOAD(2);
0902:                    ATHROW();
0903:
0904:                    // L2: end of the loop... goes back to the top!
0905:                    LABEL(L2);
0906:                    GOTO(L0);
0907:
0908:                    // L4: exit, not part of subroutine
0909:                    // Note that the two subroutine instantiations branch here
0910:                    LABEL(L4);
0911:                    RETURN();
0912:
0913:                    // L1_1a: first instantiation of subroutine ...
0914:                    LABEL(L1_1a);
0915:                    ASTORE(3);
0916:                    IINC(1, 2);
0917:                    GOTO(L4); // ...note that it does not return!
0918:                    LABEL(new Label()); // extra label emitted due to impl quirks
0919:
0920:                    // L1_2a: second instantiation of subroutine ...
0921:                    LABEL(L1_2a);
0922:                    ASTORE(3);
0923:                    IINC(1, 2);
0924:                    GOTO(L4); // ...note that it does not return!
0925:                    LABEL(new Label()); // extra label emitted due to impl quirks
0926:
0927:                    TRYCATCH(L0, L3, L3);
0928:
0929:                    END(1, 4);
0930:                }
0931:
0932:                assertEquals(exp, jsr);
0933:            }
0934:
0935:            /**
0936:             * Tests a nested try/finally with implicit exit from one subroutine to the
0937:             * other subroutine. Equivalent to the following java code:
0938:             * 
0939:             * <pre>
0940:             * void m(boolean b) {
0941:             *   try {
0942:             *     return;
0943:             *   } finally {
0944:             *     while (b) {
0945:             *       try {
0946:             *         return;
0947:             *       } finally {
0948:             *         // NOTE --- this break avoids the second return above (weird)
0949:             *         if (b) break;
0950:             *       }
0951:             *     }
0952:             *   }
0953:             * }
0954:             * </pre>
0955:             * 
0956:             * This example is from the paper, "Subroutine Inlining and Bytecode
0957:             * Abstraction to Simplify Static and Dynamic Analysis" by Cyrille Artho and
0958:             * Armin Biere.
0959:             */
0960:            public void testImplicitExitToAnotherSubroutine() {
0961:                {
0962:                    Label T1 = new Label();
0963:                    Label C1 = new Label();
0964:                    Label S1 = new Label();
0965:                    Label L = new Label();
0966:                    Label C2 = new Label();
0967:                    Label S2 = new Label();
0968:                    Label W = new Label();
0969:                    Label X = new Label();
0970:
0971:                    // variable numbers:
0972:                    int b = 1;
0973:                    int e1 = 2;
0974:                    int e2 = 3;
0975:                    int r1 = 4;
0976:                    int r2 = 5;
0977:
0978:                    setCurrent(jsr);
0979:
0980:                    ICONST_0();
0981:                    ISTORE(1);
0982:
0983:                    // T1: first try:
0984:                    LABEL(T1);
0985:                    JSR(S1);
0986:                    RETURN();
0987:
0988:                    // C1: exception handler for first try
0989:                    LABEL(C1);
0990:                    ASTORE(e1);
0991:                    JSR(S1);
0992:                    ALOAD(e1);
0993:                    ATHROW();
0994:
0995:                    // S1: first finally handler
0996:                    LABEL(S1);
0997:                    ASTORE(r1);
0998:                    GOTO(W);
0999:
1000:                    // L: body of while loop, also second try
1001:                    LABEL(L);
1002:                    JSR(S2);
1003:                    RETURN();
1004:
1005:                    // C2: exception handler for second try
1006:                    LABEL(C2);
1007:                    ASTORE(e2);
1008:                    JSR(S2);
1009:                    ALOAD(e2);
1010:                    ATHROW();
1011:
1012:                    // S2: second finally handler
1013:                    LABEL(S2);
1014:                    ASTORE(r2);
1015:                    ILOAD(b);
1016:                    IFNE(X);
1017:                    RET(r2);
1018:
1019:                    // W: test for the while loop
1020:                    LABEL(W);
1021:                    ILOAD(b);
1022:                    IFNE(L); // falls through to X
1023:
1024:                    // X: exit from finally{} block
1025:                    LABEL(X);
1026:                    RET(r1);
1027:
1028:                    TRYCATCH(T1, C1, C1);
1029:                    TRYCATCH(L, C2, C2);
1030:
1031:                    END(1, 6);
1032:                }
1033:
1034:                {
1035:                    Label T1 = new Label();
1036:                    Label C1 = new Label();
1037:                    Label S1_1a = new Label();
1038:                    Label S1_1b = new Label();
1039:                    Label S1_2a = new Label();
1040:                    Label S1_2b = new Label();
1041:                    Label L_1 = new Label();
1042:                    Label L_2 = new Label();
1043:                    Label C2_1 = new Label();
1044:                    Label C2_2 = new Label();
1045:                    Label S2_1_1a = new Label();
1046:                    Label S2_1_1b = new Label();
1047:                    Label S2_1_2a = new Label();
1048:                    Label S2_1_2b = new Label();
1049:                    Label S2_2_1a = new Label();
1050:                    Label S2_2_1b = new Label();
1051:                    Label S2_2_2a = new Label();
1052:                    Label S2_2_2b = new Label();
1053:                    Label W_1 = new Label();
1054:                    Label W_2 = new Label();
1055:                    Label X_1 = new Label();
1056:                    Label X_2 = new Label();
1057:
1058:                    // variable numbers:
1059:                    int b = 1;
1060:                    int e1 = 2;
1061:                    int e2 = 3;
1062:                    int r1 = 4;
1063:                    int r2 = 5;
1064:
1065:                    setCurrent(exp);
1066:
1067:                    // --- Main Subroutine ---
1068:
1069:                    ICONST_0();
1070:                    ISTORE(1);
1071:
1072:                    // T1: first try:
1073:                    LABEL(T1);
1074:                    ACONST_NULL();
1075:                    GOTO(S1_1a);
1076:                    LABEL(S1_1b);
1077:                    RETURN();
1078:
1079:                    // C1: exception handler for first try
1080:                    LABEL(C1);
1081:                    ASTORE(e1);
1082:                    ACONST_NULL();
1083:                    GOTO(S1_2a);
1084:                    LABEL(S1_2b);
1085:                    ALOAD(e1);
1086:                    ATHROW();
1087:                    LABEL(new Label()); // extra label emitted due to impl quirks
1088:
1089:                    // --- First instantiation of first subroutine ---
1090:
1091:                    // S1: first finally handler
1092:                    LABEL(S1_1a);
1093:                    ASTORE(r1);
1094:                    GOTO(W_1);
1095:
1096:                    // L_1: body of while loop, also second try
1097:                    LABEL(L_1);
1098:                    ACONST_NULL();
1099:                    GOTO(S2_1_1a);
1100:                    LABEL(S2_1_1b);
1101:                    RETURN();
1102:
1103:                    // C2_1: exception handler for second try
1104:                    LABEL(C2_1);
1105:                    ASTORE(e2);
1106:                    ACONST_NULL();
1107:                    GOTO(S2_1_2a);
1108:                    LABEL(S2_1_2b);
1109:                    ALOAD(e2);
1110:                    ATHROW();
1111:
1112:                    // W_1: test for the while loop
1113:                    LABEL(W_1);
1114:                    ILOAD(b);
1115:                    IFNE(L_1); // falls through to X_1
1116:
1117:                    // X_1: exit from finally{} block
1118:                    LABEL(X_1);
1119:                    GOTO(S1_1b);
1120:
1121:                    // --- Second instantiation of first subroutine ---
1122:
1123:                    // S1: first finally handler
1124:                    LABEL(S1_2a);
1125:                    ASTORE(r1);
1126:                    GOTO(W_2);
1127:
1128:                    // L_2: body of while loop, also second try
1129:                    LABEL(L_2);
1130:                    ACONST_NULL();
1131:                    GOTO(S2_2_1a);
1132:                    LABEL(S2_2_1b);
1133:                    RETURN();
1134:
1135:                    // C2_2: exception handler for second try
1136:                    LABEL(C2_2);
1137:                    ASTORE(e2);
1138:                    ACONST_NULL();
1139:                    GOTO(S2_2_2a);
1140:                    LABEL(S2_2_2b);
1141:                    ALOAD(e2);
1142:                    ATHROW();
1143:
1144:                    // W_2: test for the while loop
1145:                    LABEL(W_2);
1146:                    ILOAD(b);
1147:                    IFNE(L_2); // falls through to X_2
1148:
1149:                    // X_2: exit from finally{} block
1150:                    LABEL(X_2);
1151:                    GOTO(S1_2b);
1152:
1153:                    // --- Second subroutine's 4 instantiations ---
1154:
1155:                    // S2_1_1a:
1156:                    LABEL(S2_1_1a);
1157:                    ASTORE(r2);
1158:                    ILOAD(b);
1159:                    IFNE(X_1);
1160:                    GOTO(S2_1_1b);
1161:                    LABEL(new Label()); // extra label emitted due to impl quirks
1162:
1163:                    // S2_1_2a:
1164:                    LABEL(S2_1_2a);
1165:                    ASTORE(r2);
1166:                    ILOAD(b);
1167:                    IFNE(X_1);
1168:                    GOTO(S2_1_2b);
1169:                    LABEL(new Label()); // extra label emitted due to impl quirks
1170:
1171:                    // S2_2_1a:
1172:                    LABEL(S2_2_1a);
1173:                    ASTORE(r2);
1174:                    ILOAD(b);
1175:                    IFNE(X_2);
1176:                    GOTO(S2_2_1b);
1177:                    LABEL(new Label()); // extra label emitted due to impl quirks
1178:
1179:                    // S2_2_2a:
1180:                    LABEL(S2_2_2a);
1181:                    ASTORE(r2);
1182:                    ILOAD(b);
1183:                    IFNE(X_2);
1184:                    GOTO(S2_2_2b);
1185:                    LABEL(new Label()); // extra label emitted due to impl quirks
1186:
1187:                    TRYCATCH(T1, C1, C1);
1188:                    TRYCATCH(L_1, C2_1, C2_1); // duplicated try/finally for each...
1189:                    TRYCATCH(L_2, C2_2, C2_2); // ...instantiation of first sub
1190:
1191:                    END(1, 6);
1192:                }
1193:
1194:                assertEquals(exp, jsr);
1195:            }
1196:
1197:            /**
1198:             * This tests two subroutines, neither of which exit. Instead, they both
1199:             * branch to a common set of code which returns from the method. This code
1200:             * is not reachable except through these subroutines, and since they do not
1201:             * invoke each other, it must be copied into both of them.
1202:             * 
1203:             * I don't believe this can be represented in Java.
1204:             */
1205:            public void testCommonCodeWhichMustBeDuplicated() {
1206:                {
1207:                    Label L1 = new Label();
1208:                    Label L2 = new Label();
1209:                    Label L3 = new Label();
1210:
1211:                    setCurrent(jsr);
1212:                    ICONST_0();
1213:                    ISTORE(1);
1214:
1215:                    // Invoke the two subroutines, each twice:
1216:                    JSR(L1);
1217:                    JSR(L1);
1218:                    JSR(L2);
1219:                    JSR(L2);
1220:                    RETURN();
1221:
1222:                    // L1: subroutine 1
1223:                    LABEL(L1);
1224:                    IINC(1, 1);
1225:                    GOTO(L3); // ...note that it does not return!
1226:
1227:                    // L2: subroutine 2
1228:                    LABEL(L2);
1229:                    IINC(1, 2);
1230:                    GOTO(L3); // ...note that it does not return!
1231:
1232:                    // L3: common code to both subroutines: exit method
1233:                    LABEL(L3);
1234:                    RETURN();
1235:
1236:                    END(1, 2);
1237:                }
1238:
1239:                {
1240:                    Label L1_1a = new Label();
1241:                    Label L1_1b = new Label();
1242:                    Label L1_2a = new Label();
1243:                    Label L1_2b = new Label();
1244:                    Label L2_1a = new Label();
1245:                    Label L2_1b = new Label();
1246:                    Label L2_2a = new Label();
1247:                    Label L2_2b = new Label();
1248:                    Label L3_1 = new Label();
1249:                    Label L3_2 = new Label();
1250:                    Label L3_3 = new Label();
1251:                    Label L3_4 = new Label();
1252:
1253:                    setCurrent(exp);
1254:                    ICONST_0();
1255:                    ISTORE(1);
1256:
1257:                    // Invoke the two subroutines, each twice:
1258:                    ACONST_NULL();
1259:                    GOTO(L1_1a);
1260:                    LABEL(L1_1b);
1261:                    ACONST_NULL();
1262:                    GOTO(L1_2a);
1263:                    LABEL(L1_2b);
1264:                    ACONST_NULL();
1265:                    GOTO(L2_1a);
1266:                    LABEL(L2_1b);
1267:                    ACONST_NULL();
1268:                    GOTO(L2_2a);
1269:                    LABEL(L2_2b);
1270:                    RETURN();
1271:                    LABEL(new Label()); // extra label emitted due to impl quirks
1272:
1273:                    // L1_1a: instantiation 1 of subroutine 1
1274:                    LABEL(L1_1a);
1275:                    IINC(1, 1);
1276:                    GOTO(L3_1); // ...note that it does not return!
1277:                    LABEL(L3_1);
1278:                    RETURN();
1279:
1280:                    // L1_2a: instantiation 2 of subroutine 1
1281:                    LABEL(L1_2a);
1282:                    IINC(1, 1);
1283:                    GOTO(L3_2); // ...note that it does not return!
1284:                    LABEL(L3_2);
1285:                    RETURN();
1286:
1287:                    // L2_1a: instantiation 1 of subroutine 2
1288:                    LABEL(L2_1a);
1289:                    IINC(1, 2);
1290:                    GOTO(L3_3); // ...note that it does not return!
1291:                    LABEL(L3_3);
1292:                    RETURN();
1293:
1294:                    // L2_2a: instantiation 2 of subroutine 2
1295:                    LABEL(L2_2a);
1296:                    IINC(1, 2);
1297:                    GOTO(L3_4); // ...note that it does not return!
1298:                    LABEL(L3_4);
1299:                    RETURN();
1300:
1301:                    END(1, 2);
1302:                }
1303:
1304:                assertEquals(exp, jsr);
1305:            }
1306:
1307:            /**
1308:             * This tests a simple subroutine where the control flow jumps back and
1309:             * forth between the subroutine and the caller.
1310:             * 
1311:             * This would not normally be produced by a java compiler.
1312:             */
1313:            public void testInterleavedCode() {
1314:                {
1315:                    Label L1 = new Label();
1316:                    Label L2 = new Label();
1317:                    Label L3 = new Label();
1318:                    Label L4 = new Label();
1319:
1320:                    setCurrent(jsr);
1321:                    ICONST_0();
1322:                    ISTORE(1);
1323:
1324:                    // Invoke the subroutine, each twice:
1325:                    JSR(L1);
1326:                    GOTO(L2);
1327:
1328:                    // L1: subroutine 1
1329:                    LABEL(L1);
1330:                    ASTORE(2);
1331:                    IINC(1, 1);
1332:                    GOTO(L3);
1333:
1334:                    // L2: second part of main subroutine
1335:                    LABEL(L2);
1336:                    IINC(1, 2);
1337:                    GOTO(L4);
1338:
1339:                    // L3: second part of subroutine 1
1340:                    LABEL(L3);
1341:                    IINC(1, 4);
1342:                    RET(2);
1343:
1344:                    // L4: third part of main subroutine
1345:                    LABEL(L4);
1346:                    JSR(L1);
1347:                    RETURN();
1348:
1349:                    END(1, 3);
1350:                }
1351:
1352:                {
1353:                    Label L1_1a = new Label();
1354:                    Label L1_1b = new Label();
1355:                    Label L1_2a = new Label();
1356:                    Label L1_2b = new Label();
1357:                    Label L2 = new Label();
1358:                    Label L3_1 = new Label();
1359:                    Label L3_2 = new Label();
1360:                    Label L4 = new Label();
1361:
1362:                    setCurrent(exp);
1363:
1364:                    // Main routine:
1365:                    ICONST_0();
1366:                    ISTORE(1);
1367:                    ACONST_NULL();
1368:                    GOTO(L1_1a);
1369:                    LABEL(L1_1b);
1370:                    GOTO(L2);
1371:                    LABEL(L2);
1372:                    IINC(1, 2);
1373:                    GOTO(L4);
1374:                    LABEL(L4);
1375:                    ACONST_NULL();
1376:                    GOTO(L1_2a);
1377:                    LABEL(L1_2b);
1378:                    RETURN();
1379:
1380:                    // L1_1: instantiation #1
1381:                    LABEL(L1_1a);
1382:                    ASTORE(2);
1383:                    IINC(1, 1);
1384:                    GOTO(L3_1);
1385:                    LABEL(L3_1);
1386:                    IINC(1, 4);
1387:                    GOTO(L1_1b);
1388:                    LABEL(new Label()); // extra label emitted due to impl quirks
1389:
1390:                    // L1_2: instantiation #2
1391:                    LABEL(L1_2a);
1392:                    ASTORE(2);
1393:                    IINC(1, 1);
1394:                    GOTO(L3_2);
1395:                    LABEL(L3_2);
1396:                    IINC(1, 4);
1397:                    GOTO(L1_2b);
1398:                    LABEL(new Label()); // extra label emitted due to impl quirks
1399:
1400:                    END(1, 3);
1401:                }
1402:
1403:                assertEquals(exp, jsr);
1404:            }
1405:
1406:            /**
1407:             * Tests a nested try/finally with implicit exit from one subroutine to the
1408:             * other subroutine, and with a surrounding try/catch thrown in the mix.
1409:             * Equivalent to the following java code:
1410:             * 
1411:             * <pre>
1412:             * void m(int b) {
1413:             *   try {
1414:             *     try {
1415:             *       return;
1416:             *     } finally {
1417:             *       while (b) {
1418:             *         try {
1419:             *           return;
1420:             *         } finally {
1421:             *           // NOTE --- this break avoids the second return above (weird)
1422:             *           if (b) break;
1423:             *         }
1424:             *       }
1425:             *     } 
1426:             *   } catch (Exception e) {
1427:             *     b += 3;
1428:             *     return;
1429:             *   }
1430:             * }
1431:             * </pre>
1432:             */
1433:            public void testImplicitExitInTryCatch() {
1434:                {
1435:                    Label T1 = new Label();
1436:                    Label C1 = new Label();
1437:                    Label S1 = new Label();
1438:                    Label L = new Label();
1439:                    Label C2 = new Label();
1440:                    Label S2 = new Label();
1441:                    Label W = new Label();
1442:                    Label X = new Label();
1443:                    Label OT = new Label();
1444:                    Label OC = new Label();
1445:
1446:                    // variable numbers:
1447:                    int b = 1;
1448:                    int e1 = 2;
1449:                    int e2 = 3;
1450:                    int r1 = 4;
1451:                    int r2 = 5;
1452:
1453:                    setCurrent(jsr);
1454:
1455:                    ICONST_0();
1456:                    ISTORE(1);
1457:
1458:                    // OT: outermost try
1459:                    LABEL(OT);
1460:
1461:                    // T1: first try:
1462:                    LABEL(T1);
1463:                    JSR(S1);
1464:                    RETURN();
1465:
1466:                    // C1: exception handler for first try
1467:                    LABEL(C1);
1468:                    ASTORE(e1);
1469:                    JSR(S1);
1470:                    ALOAD(e1);
1471:                    ATHROW();
1472:
1473:                    // S1: first finally handler
1474:                    LABEL(S1);
1475:                    ASTORE(r1);
1476:                    GOTO(W);
1477:
1478:                    // L: body of while loop, also second try
1479:                    LABEL(L);
1480:                    JSR(S2);
1481:                    RETURN();
1482:
1483:                    // C2: exception handler for second try
1484:                    LABEL(C2);
1485:                    ASTORE(e2);
1486:                    JSR(S2);
1487:                    ALOAD(e2);
1488:                    ATHROW();
1489:
1490:                    // S2: second finally handler
1491:                    LABEL(S2);
1492:                    ASTORE(r2);
1493:                    ILOAD(b);
1494:                    IFNE(X);
1495:                    RET(r2);
1496:
1497:                    // W: test for the while loop
1498:                    LABEL(W);
1499:                    ILOAD(b);
1500:                    IFNE(L); // falls through to X
1501:
1502:                    // X: exit from finally{} block
1503:                    LABEL(X);
1504:                    RET(r1);
1505:
1506:                    // OC: outermost catch
1507:                    LABEL(OC);
1508:                    IINC(b, 3);
1509:                    RETURN();
1510:
1511:                    TRYCATCH(T1, C1, C1);
1512:                    TRYCATCH(L, C2, C2);
1513:                    TRYCATCH(OT, OC, OC);
1514:
1515:                    END(1, 6);
1516:                }
1517:
1518:                {
1519:                    Label T1 = new Label();
1520:                    Label C1 = new Label();
1521:                    Label S1_1a = new Label();
1522:                    Label S1_1b = new Label();
1523:                    Label S1_2a = new Label();
1524:                    Label S1_2b = new Label();
1525:                    Label L_1 = new Label();
1526:                    Label L_2 = new Label();
1527:                    Label C2_1 = new Label();
1528:                    Label C2_2 = new Label();
1529:                    Label S2_1_1a = new Label();
1530:                    Label S2_1_1b = new Label();
1531:                    Label S2_1_2a = new Label();
1532:                    Label S2_1_2b = new Label();
1533:                    Label S2_2_1a = new Label();
1534:                    Label S2_2_1b = new Label();
1535:                    Label S2_2_2a = new Label();
1536:                    Label S2_2_2b = new Label();
1537:                    Label W_1 = new Label();
1538:                    Label W_2 = new Label();
1539:                    Label X_1 = new Label();
1540:                    Label X_2 = new Label();
1541:                    Label OT_1 = S1_1a;
1542:                    Label OT_2 = S1_2a;
1543:                    Label OT_1_1 = S2_1_1a;
1544:                    Label OT_1_2 = S2_1_2a;
1545:                    Label OT_2_1 = S2_2_1a;
1546:                    Label OT_2_2 = S2_2_2a;
1547:                    Label OC = new Label();
1548:                    Label OC_1 = new Label();
1549:                    Label OC_2 = new Label();
1550:                    Label OC_1_1 = new Label();
1551:                    Label OC_1_2 = new Label();
1552:                    Label OC_2_1 = new Label();
1553:                    Label OC_2_2 = new Label();
1554:
1555:                    // variable numbers:
1556:                    int b = 1;
1557:                    int e1 = 2;
1558:                    int e2 = 3;
1559:                    int r1 = 4;
1560:                    int r2 = 5;
1561:
1562:                    setCurrent(exp);
1563:
1564:                    // --- Main Subroutine ---
1565:
1566:                    ICONST_0();
1567:                    ISTORE(1);
1568:
1569:                    // T1: outermost try / first try:
1570:                    LABEL(T1);
1571:                    ACONST_NULL();
1572:                    GOTO(S1_1a);
1573:                    LABEL(S1_1b);
1574:                    RETURN();
1575:
1576:                    // C1: exception handler for first try
1577:                    LABEL(C1);
1578:                    ASTORE(e1);
1579:                    ACONST_NULL();
1580:                    GOTO(S1_2a);
1581:                    LABEL(S1_2b);
1582:                    ALOAD(e1);
1583:                    ATHROW();
1584:
1585:                    // OC: Outermost catch
1586:                    LABEL(OC);
1587:                    IINC(b, 3);
1588:                    RETURN();
1589:
1590:                    // --- First instantiation of first subroutine ---
1591:
1592:                    // S1: first finally handler
1593:                    LABEL(S1_1a);
1594:                    ASTORE(r1);
1595:                    GOTO(W_1);
1596:
1597:                    // L_1: body of while loop, also second try
1598:                    LABEL(L_1);
1599:                    ACONST_NULL();
1600:                    GOTO(S2_1_1a);
1601:                    LABEL(S2_1_1b);
1602:                    RETURN();
1603:
1604:                    // C2_1: exception handler for second try
1605:                    LABEL(C2_1);
1606:                    ASTORE(e2);
1607:                    ACONST_NULL();
1608:                    GOTO(S2_1_2a);
1609:                    LABEL(S2_1_2b);
1610:                    ALOAD(e2);
1611:                    ATHROW();
1612:
1613:                    // W_1: test for the while loop
1614:                    LABEL(W_1);
1615:                    ILOAD(b);
1616:                    IFNE(L_1); // falls through to X_1
1617:
1618:                    // X_1: exit from finally{} block
1619:                    LABEL(X_1);
1620:                    GOTO(S1_1b);
1621:
1622:                    LABEL(OC_1);
1623:
1624:                    // --- Second instantiation of first subroutine ---
1625:
1626:                    // S1: first finally handler
1627:                    LABEL(S1_2a);
1628:                    ASTORE(r1);
1629:                    GOTO(W_2);
1630:
1631:                    // L_2: body of while loop, also second try
1632:                    LABEL(L_2);
1633:                    ACONST_NULL();
1634:                    GOTO(S2_2_1a);
1635:                    LABEL(S2_2_1b);
1636:                    RETURN();
1637:
1638:                    // C2_2: exception handler for second try
1639:                    LABEL(C2_2);
1640:                    ASTORE(e2);
1641:                    ACONST_NULL();
1642:                    GOTO(S2_2_2a);
1643:                    LABEL(S2_2_2b);
1644:                    ALOAD(e2);
1645:                    ATHROW();
1646:
1647:                    // W_2: test for the while loop
1648:                    LABEL(W_2);
1649:                    ILOAD(b);
1650:                    IFNE(L_2); // falls through to X_2
1651:
1652:                    // X_2: exit from finally{} block
1653:                    LABEL(X_2);
1654:                    GOTO(S1_2b);
1655:
1656:                    LABEL(OC_2);
1657:
1658:                    // --- Second subroutine's 4 instantiations ---
1659:
1660:                    // S2_1_1a:
1661:                    LABEL(S2_1_1a);
1662:                    ASTORE(r2);
1663:                    ILOAD(b);
1664:                    IFNE(X_1);
1665:                    GOTO(S2_1_1b);
1666:                    LABEL(OC_1_1);
1667:
1668:                    // S2_1_2a:
1669:                    LABEL(S2_1_2a);
1670:                    ASTORE(r2);
1671:                    ILOAD(b);
1672:                    IFNE(X_1);
1673:                    GOTO(S2_1_2b);
1674:                    LABEL(OC_1_2);
1675:
1676:                    // S2_2_1a:
1677:                    LABEL(S2_2_1a);
1678:                    ASTORE(r2);
1679:                    ILOAD(b);
1680:                    IFNE(X_2);
1681:                    GOTO(S2_2_1b);
1682:                    LABEL(OC_2_1);
1683:
1684:                    // S2_2_2a:
1685:                    LABEL(S2_2_2a);
1686:                    ASTORE(r2);
1687:                    ILOAD(b);
1688:                    IFNE(X_2);
1689:                    GOTO(S2_2_2b);
1690:                    LABEL(OC_2_2);
1691:
1692:                    // main subroutine handlers:
1693:                    TRYCATCH(T1, C1, C1);
1694:                    TRYCATCH(T1, OC, OC);
1695:
1696:                    // first instance of first sub try/catch handlers:
1697:                    TRYCATCH(L_1, C2_1, C2_1);
1698:                    TRYCATCH(OT_1, OC_1, OC); // note: reuses handler code from main
1699:                    // sub
1700:
1701:                    // second instance of first sub try/catch handlers:
1702:                    TRYCATCH(L_2, C2_2, C2_2);
1703:                    TRYCATCH(OT_2, OC_2, OC);
1704:
1705:                    // all 4 instances of second sub:
1706:                    TRYCATCH(OT_1_1, OC_1_1, OC);
1707:                    TRYCATCH(OT_1_2, OC_1_2, OC);
1708:                    TRYCATCH(OT_2_1, OC_2_1, OC);
1709:                    TRYCATCH(OT_2_2, OC_2_2, OC);
1710:
1711:                    END(1, 6);
1712:                }
1713:
1714:                assertEquals(exp, jsr);
1715:            }
1716:
1717:            /**
1718:             * Tests a method which has line numbers and local variable declarations.
1719:             * 
1720:             * <pre>
1721:             *   public void a() {
1722:             * 1    int a = 0;
1723:             * 2    try {
1724:             * 3      a++;
1725:             * 4    } finally {
1726:             * 5      a--;
1727:             * 6    }
1728:             *   }
1729:             *   LV "a" from 1 to 6
1730:             * </pre>
1731:             */
1732:            public void testBasicLineNumberAndLocalVars() {
1733:                {
1734:                    Label LM1 = new Label();
1735:                    Label L0 = new Label();
1736:                    Label L1 = new Label();
1737:                    Label L2 = new Label();
1738:                    Label L3 = new Label();
1739:                    Label L4 = new Label();
1740:
1741:                    setCurrent(jsr);
1742:                    LABEL(LM1);
1743:                    LINE(1, LM1);
1744:                    ICONST_0();
1745:                    ISTORE(1);
1746:
1747:                    /* L0: body of try block */
1748:                    LABEL(L0);
1749:                    LINE(3, L0);
1750:                    IINC(1, 1);
1751:                    GOTO(L1);
1752:
1753:                    /* L2: exception handler */
1754:                    LABEL(L2);
1755:                    ASTORE(3);
1756:                    JSR(L3);
1757:                    ALOAD(3);
1758:                    ATHROW();
1759:
1760:                    /* L3: subroutine */
1761:                    LABEL(L3);
1762:                    LINE(5, L3);
1763:                    ASTORE(2);
1764:                    IINC(1, -1);
1765:                    RET(2);
1766:
1767:                    /* L1: non-exceptional exit from try block */
1768:                    LABEL(L1);
1769:                    JSR(L3);
1770:                    LABEL(L4); // L4
1771:                    RETURN();
1772:
1773:                    TRYCATCH(L0, L2, L2);
1774:                    TRYCATCH(L1, L4, L2);
1775:                    LOCALVAR("a", "I", 1, LM1, L4);
1776:
1777:                    END(1, 4);
1778:                }
1779:
1780:                {
1781:                    Label LM1 = new Label();
1782:                    Label L0 = new Label();
1783:                    Label L1 = new Label();
1784:                    Label L2 = new Label();
1785:                    Label L3_1a = new Label();
1786:                    Label L3_1b = new Label();
1787:                    Label L3_1c = new Label();
1788:                    Label L3_2a = new Label();
1789:                    Label L3_2b = new Label();
1790:                    Label L3_2c = new Label();
1791:                    Label L4 = new Label();
1792:
1793:                    setCurrent(exp);
1794:                    LABEL(LM1);
1795:                    LINE(1, LM1);
1796:                    ICONST_0();
1797:                    ISTORE(1);
1798:                    // L0: try/catch block
1799:                    LABEL(L0);
1800:                    LINE(3, L0);
1801:                    IINC(1, 1);
1802:                    GOTO(L1);
1803:
1804:                    // L2: Exception handler:
1805:                    LABEL(L2);
1806:                    ASTORE(3);
1807:                    ACONST_NULL();
1808:                    GOTO(L3_1a);
1809:                    LABEL(L3_1b); // L3_1b;
1810:                    ALOAD(3);
1811:                    ATHROW();
1812:
1813:                    // L1: On non-exceptional exit, try block leads here:
1814:                    LABEL(L1);
1815:                    ACONST_NULL();
1816:                    GOTO(L3_2a);
1817:                    LABEL(L3_2b); // L3_2b
1818:                    LABEL(L4); // L4
1819:                    RETURN();
1820:
1821:                    // L3_1a: First instantiation of subroutine:
1822:                    LABEL(L3_1a);
1823:                    LINE(5, L3_1a);
1824:                    ASTORE(2);
1825:                    IINC(1, -1);
1826:                    GOTO(L3_1b);
1827:                    LABEL(L3_1c);
1828:
1829:                    // L3_2a: Second instantiation of subroutine:
1830:                    LABEL(L3_2a);
1831:                    LINE(5, L3_2a);
1832:                    ASTORE(2);
1833:                    IINC(1, -1);
1834:                    GOTO(L3_2b);
1835:                    LABEL(L3_2c);
1836:
1837:                    TRYCATCH(L0, L2, L2);
1838:                    TRYCATCH(L1, L4, L2);
1839:                    LOCALVAR("a", "I", 1, LM1, L4);
1840:                    LOCALVAR("a", "I", 1, L3_1a, L3_1c);
1841:                    LOCALVAR("a", "I", 1, L3_2a, L3_2c);
1842:
1843:                    END(1, 4);
1844:                }
1845:
1846:                assertEquals(exp, jsr);
1847:            }
1848:
1849:            public void assertEquals(final MethodNode exp,
1850:                    final MethodNode actual) {
1851:                String textexp = getText(exp);
1852:                String textact = getText(actual);
1853:                System.err.println("Expected=" + textexp);
1854:                System.err.println("Actual=" + textact);
1855:                assertEquals(textexp, textact);
1856:            }
1857:
1858:            private String getText(final MethodNode mn) {
1859:                TraceMethodVisitor tmv = new TraceMethodVisitor(null);
1860:                mn.accept(tmv);
1861:
1862:                StringBuffer sb = new StringBuffer();
1863:                for (int i = 0; i < tmv.text.size(); i++) {
1864:                    sb.append(tmv.text.get(i));
1865:                }
1866:                return sb.toString();
1867:            }
1868:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.