[jboss-cvs] javassist/src/test/test/javassist/bytecode/analysis ...

Jason Thomas Greene jgreene at jboss.com
Sat May 24 01:13:15 EDT 2008


  User: jgreene 
  Date: 08/05/24 01:13:15

  Added:       src/test/test/javassist/bytecode/analysis   
                        AnalyzerTest.java ErrorFinder.java ScannerTest.java
  Log:
  Fix subtypeOf in CtArray
  Introduce full data-flow analysis API
  Fix AALOAD by using data-flow analysis to determine the type
  Introduce a testsuite to the project
  Add a framedump toolp
  
  Revision  Changes    Path
  1.1      date: 2008/05/24 05:13:15;  author: jgreene;  state: Exp;javassist/src/test/test/javassist/bytecode/analysis/AnalyzerTest.java
  
  Index: AnalyzerTest.java
  ===================================================================
  package test.javassist.bytecode.analysis;
  
  import java.io.Serializable;
  import java.util.ArrayList;
  import java.util.Iterator;
  
  import javassist.ClassPool;
  import javassist.CtClass;
  import javassist.CtMethod;
  import javassist.bytecode.AccessFlag;
  import javassist.bytecode.BadBytecode;
  import javassist.bytecode.Bytecode;
  import javassist.bytecode.CodeIterator;
  import javassist.bytecode.MethodInfo;
  import javassist.bytecode.Opcode;
  import javassist.bytecode.analysis.Analyzer;
  import javassist.bytecode.analysis.Frame;
  import javassist.bytecode.analysis.Type;
  import junit.framework.TestCase;
  
  /**
   * Tests Analyzer
   *
   * @author Jason T. Greene
   */
  public class AnalyzerTest extends TestCase {
  
      public void testCommonSupperArray() throws Exception {
          ClassPool pool = ClassPool.getDefault();
          CtClass clazz = pool.get(getClass().getName() + "$Dummy");
          CtMethod method = clazz.getDeclaredMethod("commonSuperArray");
          verifyArrayLoad(clazz, method, "java.lang.Number");
      }
  
      public  void testCommonInterfaceArray() throws Exception {
          ClassPool pool = ClassPool.getDefault();
          CtClass clazz = pool.get(getClass().getName() + "$Dummy");
          CtMethod method = clazz.getDeclaredMethod("commonInterfaceArray");
          verifyArrayLoad(clazz, method, "java.io.Serializable");
      }
  
      public  void testSharedInterfaceAndSuperClass() throws Exception {
          CtMethod method = ClassPool.getDefault().getMethod(
                  getClass().getName() + "$Dummy", "sharedInterfaceAndSuperClass");
          verifyReturn(method, "java.io.Serializable");
  
          method = ClassPool.getDefault().getMethod(
                  getClass().getName() + "$Dummy", "sharedOffsetInterfaceAndSuperClass");
          verifyReturn(method, "java.io.Serializable");
  
          method = ClassPool.getDefault().getMethod(
                  getClass().getName() + "$Dummy", "sharedSuperWithSharedInterface");
          verifyReturn(method, getClass().getName() + "$Dummy$A");
      }
  
      public  void testArrayDifferentDims() throws Exception {
          CtMethod method = ClassPool.getDefault().getMethod(
                  getClass().getName() + "$Dummy", "arrayDifferentDimensions1");
          verifyReturn(method, "java.lang.Cloneable[]");
  
          method = ClassPool.getDefault().getMethod(
                  getClass().getName() + "$Dummy", "arrayDifferentDimensions2");
          verifyReturn(method, "java.lang.Object[][]");
      }
  
      public  void testReusedLocalMerge() throws Exception {
          CtMethod method = ClassPool.getDefault().getMethod(
                  getClass().getName() + "$Dummy", "reusedLocalMerge");
  
          MethodInfo info = method.getMethodInfo2();
          Analyzer analyzer = new Analyzer();
          Frame[] frames = analyzer.analyze(method.getDeclaringClass(), info);
          assertNotNull(frames);
          int pos = findOpcode(info, Opcode.RETURN);
          Frame frame = frames[pos];
          assertEquals("java.lang.Object", frame.getLocal(2).getCtClass().getName());
      }
  
      private static int findOpcode(MethodInfo info, int opcode) throws BadBytecode {
          CodeIterator iter = info.getCodeAttribute().iterator();
  
          // find return
          int pos = 0;
          while (iter.hasNext()) {
              pos = iter.next();
              if (iter.byteAt(pos) == opcode)
                  break;
          }
          return pos;
      }
  
  
      private static void verifyReturn(CtMethod method, String expected) throws BadBytecode {
          MethodInfo info = method.getMethodInfo2();
          CodeIterator iter = info.getCodeAttribute().iterator();
  
          // find areturn
          int pos = 0;
          while (iter.hasNext()) {
              pos = iter.next();
              if (iter.byteAt(pos) == Opcode.ARETURN)
                  break;
          }
  
          Analyzer analyzer = new Analyzer();
          Frame[] frames = analyzer.analyze(method.getDeclaringClass(), info);
          assertNotNull(frames);
          Frame frame = frames[pos];
          assertEquals(expected, frame.peek().getCtClass().getName());
      }
  
      private static void verifyArrayLoad(CtClass clazz, CtMethod method, String component)
              throws BadBytecode {
          MethodInfo info = method.getMethodInfo2();
          CodeIterator iter = info.getCodeAttribute().iterator();
  
          // find aaload
          int pos = 0;
          while (iter.hasNext()) {
              pos = iter.next();
              if (iter.byteAt(pos) == Opcode.AALOAD)
                  break;
          }
  
          Analyzer analyzer = new Analyzer();
          Frame[] frames = analyzer.analyze(clazz, info);
          assertNotNull(frames);
          Frame frame = frames[pos];
          assertNotNull(frame);
  
          Type type = frame.getStack(frame.getTopIndex() - 1);
          assertEquals(component + "[]", type.getCtClass().getName());
  
          pos = iter.next();
          frame = frames[pos];
          assertNotNull(frame);
  
          type = frame.getStack(frame.getTopIndex());
          assertEquals(component, type.getCtClass().getName());
      }
  
      private static void addJump(Bytecode code, int opcode, int pos) {
          int current = code.currentPc();
          code.addOpcode(opcode);
          code.addIndex(pos - current);
      }
  
      public void testDeadCode() throws Exception {
          CtMethod method = generateDeadCode(ClassPool.getDefault());
          Analyzer analyzer = new Analyzer();
          Frame[] frames = analyzer.analyze(method.getDeclaringClass(), method.getMethodInfo2());
          assertNotNull(frames);
          assertNull(frames[4]);
          assertNotNull(frames[5]);
          verifyReturn(method, "java.lang.String");
      }
  
      public void testInvalidCode() throws Exception {
          CtMethod method = generateInvalidCode(ClassPool.getDefault());
          Analyzer analyzer = new Analyzer();
          try {
              analyzer.analyze(method.getDeclaringClass(), method.getMethodInfo2());
          } catch (BadBytecode e) {
              return;
          }
  
          fail("Invalid code should have triggered a BadBytecode exception");
      }
  
      public void testCodeFalloff() throws Exception {
          CtMethod method = generateCodeFalloff(ClassPool.getDefault());
          Analyzer analyzer = new Analyzer();
          try {
              analyzer.analyze(method.getDeclaringClass(), method.getMethodInfo2());
          } catch (BadBytecode e) {
              return;
          }
  
          fail("Code falloff should have triggered a BadBytecode exception");
      }
  
      public void testJsrMerge() throws Exception {
          CtMethod method = generateJsrMerge(ClassPool.getDefault());
          Analyzer analyzer = new Analyzer();
          analyzer.analyze(method.getDeclaringClass(), method.getMethodInfo2());
          verifyReturn(method, "java.lang.String");
      }
  
      public void testJsrMerge2() throws Exception {
          CtMethod method = generateJsrMerge2(ClassPool.getDefault());
          Analyzer analyzer = new Analyzer();
          analyzer.analyze(method.getDeclaringClass(), method.getMethodInfo2());
          verifyReturn(method, "java.lang.String");
      }
  
      private CtMethod generateDeadCode(ClassPool pool) throws Exception {
          CtClass clazz = pool.makeClass(getClass().getName() + "$Generated0");
          CtClass stringClass = pool.get("java.lang.String");
          CtMethod method = new CtMethod(stringClass, "foo", new CtClass[0], clazz);
          MethodInfo info = method.getMethodInfo2();
          info.setAccessFlags(AccessFlag.PUBLIC | AccessFlag.STATIC);
          Bytecode code = new Bytecode(info.getConstPool(), 1, 2);
          /* 0 */ code.addIconst(1);
          /* 1 */ addJump(code, Opcode.GOTO, 5);
          /* 4 */ code.addIconst(0); // DEAD
          /* 5 */ code.addIconst(1);
          /* 6 */ code.addInvokestatic(stringClass, "valueOf", stringClass, new CtClass[]{CtClass.intType});
          /* 9 */ code.addOpcode(Opcode.ARETURN);
          info.setCodeAttribute(code.toCodeAttribute());
          clazz.addMethod(method);
  
          return method;
      }
  
      private CtMethod generateInvalidCode(ClassPool pool) throws Exception {
          CtClass clazz = pool.makeClass(getClass().getName() + "$Generated4");
          CtClass intClass = pool.get("java.lang.Integer");
          CtClass stringClass = pool.get("java.lang.String");
          CtMethod method = new CtMethod(stringClass, "foo", new CtClass[0], clazz);
          MethodInfo info = method.getMethodInfo2();
          info.setAccessFlags(AccessFlag.PUBLIC | AccessFlag.STATIC);
          Bytecode code = new Bytecode(info.getConstPool(), 1, 2);
          /* 0 */ code.addIconst(1);
          /* 1 */ code.addInvokestatic(intClass, "valueOf", intClass, new CtClass[]{CtClass.intType});
          /* 4 */ code.addOpcode(Opcode.ARETURN);
          info.setCodeAttribute(code.toCodeAttribute());
          clazz.addMethod(method);
  
          return method;
      }
  
  
      private CtMethod generateCodeFalloff(ClassPool pool) throws Exception {
          CtClass clazz = pool.makeClass(getClass().getName() + "$Generated3");
          CtClass stringClass = pool.get("java.lang.String");
          CtMethod method = new CtMethod(stringClass, "foo", new CtClass[0], clazz);
          MethodInfo info = method.getMethodInfo2();
          info.setAccessFlags(AccessFlag.PUBLIC | AccessFlag.STATIC);
          Bytecode code = new Bytecode(info.getConstPool(), 1, 2);
          /* 0 */ code.addIconst(1);
          /* 1 */ code.addInvokestatic(stringClass, "valueOf", stringClass, new CtClass[]{CtClass.intType});
          info.setCodeAttribute(code.toCodeAttribute());
          clazz.addMethod(method);
  
          return method;
      }
  
      private CtMethod generateJsrMerge(ClassPool pool) throws Exception {
          CtClass clazz = pool.makeClass(getClass().getName() + "$Generated1");
          CtClass stringClass = pool.get("java.lang.String");
          CtMethod method = new CtMethod(stringClass, "foo", new CtClass[0], clazz);
          MethodInfo info = method.getMethodInfo2();
          info.setAccessFlags(AccessFlag.PUBLIC | AccessFlag.STATIC);
          Bytecode code = new Bytecode(info.getConstPool(), 1, 2);
          /* 0 */ code.addIconst(5);
          /* 1 */ code.addIstore(0);
          /* 2 */ addJump(code, Opcode.JSR, 7);
          /* 5 */ code.addAload(0);
          /* 6 */ code.addOpcode(Opcode.ARETURN);
          /* 7 */ code.addAstore(1);
          /* 8 */ code.addIconst(3);
          /* 9 */ code.addInvokestatic(stringClass, "valueOf", stringClass, new CtClass[]{CtClass.intType});
          /* 12 */ code.addAstore(0);
          /* 12 */ code.addRet(1);
          info.setCodeAttribute(code.toCodeAttribute());
          clazz.addMethod(method);
          //System.out.println(clazz.toClass().getMethod("foo", new Class[0]).invoke(null, new Object[0]));
  
          return method;
      }
  
      private CtMethod generateJsrMerge2(ClassPool pool) throws Exception {
          CtClass clazz = pool.makeClass(getClass().getName() + "$Generated2");
          CtClass stringClass = pool.get("java.lang.String");
          CtMethod method = new CtMethod(stringClass, "foo", new CtClass[0], clazz);
          MethodInfo info = method.getMethodInfo2();
          info.setAccessFlags(AccessFlag.PUBLIC | AccessFlag.STATIC);
          Bytecode code = new Bytecode(info.getConstPool(), 1, 2);
          /* 0 */ addJump(code, Opcode.JSR, 5);
          /* 3 */ code.addAload(0);
          /* 4 */ code.addOpcode(Opcode.ARETURN);
          /* 5 */ code.addAstore(1);
          /* 6 */ code.addIconst(4);
          /* 7 */ code.addInvokestatic(stringClass, "valueOf", stringClass, new CtClass[]{CtClass.intType});
          /* 10 */ code.addAstore(0);
          /* 11 */ code.addRet(1);
          info.setCodeAttribute(code.toCodeAttribute());
          clazz.addMethod(method);
  
          return method;
      }
  
      public static class Dummy {
          public Serializable commonSuperArray(int x) {
              Number[] n;
  
              if (x > 5) {
                  n = new Long[10];
              } else {
                  n = new Double[5];
              }
  
              return n[x];
          }
  
          public Serializable commonInterfaceArray(int x) {
              Serializable[] n;
  
              if (x > 5) {
                  n = new Long[10];
              } else if (x > 3) {
                  n = new Double[5];
              } else {
                  n = new String[3];
              }
  
              return n[x];
          }
  
  
          public static class A {};
          public static class B1 extends A implements Serializable {};
          public static class B2 extends A implements Serializable {};
          public static class A2 implements Serializable, Cloneable {};
          public static class A3 implements Serializable, Cloneable {};
  
          public static class B3 extends A {};
          public static class C31 extends B3 implements Serializable {};
  
  
          public void dummy(Serializable s) {}
  
          public Object sharedInterfaceAndSuperClass(int x) {
              Serializable s;
  
              if (x > 5) {
                  s = new B1();
              } else {
                  s = new B2();
              }
  
              dummy(s);
  
              return s;
          }
  
          public A sharedSuperWithSharedInterface(int x) {
              A a;
  
              if (x > 5) {
                  a = new B1();
              } else if (x > 3) {
                  a = new B2();
              } else {
                  a = new C31();
              }
  
              return a;
          }
  
  
          public void reusedLocalMerge() {
               ArrayList list = new ArrayList();
               try {
                 Iterator i = list.iterator();
                 i.hasNext();
               } catch (Exception e) {
               }
          }
  
          public Object sharedOffsetInterfaceAndSuperClass(int x) {
              Serializable s;
  
              if (x > 5) {
                  s = new B1();
              } else {
                  s = new C31();
              }
  
              dummy(s);
  
              return s;
          }
  
  
          public Object arrayDifferentDimensions1(int x) {
              Object[] n;
  
              if ( x > 5) {
                  n = new Number[1][1];
              } else {
                  n = new Cloneable[1];
              }
  
  
              return n;
          }
  
          public Object arrayDifferentDimensions2(int x) {
              Object[] n;
  
              if ( x> 5) {
                  n = new String[1][1];
              } else {
                  n = new Number[1][1][1][1];
              }
  
              return n;
          }
      }
  }
  
  
  
  1.1      date: 2008/05/24 05:13:15;  author: jgreene;  state: Exp;javassist/src/test/test/javassist/bytecode/analysis/ErrorFinder.java
  
  Index: ErrorFinder.java
  ===================================================================
  package test.javassist.bytecode.analysis;
  
  import java.io.BufferedReader;
  import java.io.FileReader;
  
  import javassist.ClassPool;
  import javassist.CtClass;
  import javassist.CtMethod;
  import javassist.bytecode.analysis.Analyzer;
  
  /**
   * Simple testing tool that verifies class files can be analyzed.
   *
   * @author Jason T. Greene
   */
  public class ErrorFinder {
  
      public static void main(String[] args) throws Exception {
          ClassPool pool = ClassPool.getDefault();
  
          String className = args[0];
          if (!className.equals("-file")) {
              analyzeClass(pool, className);
              return;
          }
  
          FileReader reader = new FileReader(args[1]);
          BufferedReader lineReader = new BufferedReader(reader);
  
  
          String line = lineReader.readLine();
          while (line != null) {
              analyzeClass(pool, line);
              line = lineReader.readLine();
          }
      }
  
      private static void analyzeClass(ClassPool pool, String className) {
          try {
  
              CtClass clazz = pool.get(className);
              CtMethod[] methods = clazz.getDeclaredMethods();
              for (int i = 0; i < methods.length; i++)
                  analyzeMethod(clazz, methods[i]);
          } catch (Throwable e) {
              System.out.println("FAIL: CLASS: " + className + " " + e.getClass() + ":" + e.getMessage());
          }
      }
  
      private static void analyzeMethod(CtClass clazz, CtMethod method) {
          String methodName = clazz.getName() + "." + method.getName() + method.getSignature();
          System.out.println("START: " + methodName);
          Analyzer analyzer = new Analyzer();
  
          try {
              analyzer.analyze(clazz, method.getMethodInfo2());
              System.out.println("SUCCESS: " + methodName);
          } catch (Exception e) {
              System.out.println("FAIL: " + methodName + " - " + (e.getMessage() == null ? e.getClass().getName() : e.getMessage()));
          }
      }
  }
  
  
  
  1.1      date: 2008/05/24 05:13:15;  author: jgreene;  state: Exp;javassist/src/test/test/javassist/bytecode/analysis/ScannerTest.java
  
  Index: ScannerTest.java
  ===================================================================
  package test.javassist.bytecode.analysis;
  
  import java.io.IOException;
  
  import javassist.CannotCompileException;
  import javassist.ClassPool;
  import javassist.CtClass;
  import javassist.CtMethod;
  import javassist.NotFoundException;
  import javassist.bytecode.AccessFlag;
  import javassist.bytecode.Bytecode;
  import javassist.bytecode.MethodInfo;
  import javassist.bytecode.Opcode;
  import javassist.bytecode.analysis.Subroutine;
  import javassist.bytecode.analysis.SubroutineScanner;
  import junit.framework.TestCase;
  
  /**
   * Tests Subroutine Scanner
   *
   * @author Jason T. Greene
   */
  public class ScannerTest extends TestCase {
  
      public void testNestedFinally() throws Exception {
          ClassPool pool = ClassPool.getDefault();
          generate(pool);
          CtClass clazz = pool.get("test.ScannerTest$GeneratedTest");
          CtMethod method = clazz.getDeclaredMethod("doit");
  
          SubroutineScanner scanner = new SubroutineScanner();
          Subroutine[] subs = scanner.scan(method.getMethodInfo2());
  
          verifySubroutine(subs, 31, 31, new int[]{125, 25});
          verifySubroutine(subs, 32, 31, new int[]{125, 25});
          verifySubroutine(subs, 33, 31, new int[]{125, 25});
          verifySubroutine(subs, 60, 31, new int[]{125, 25});
          verifySubroutine(subs, 61, 31, new int[]{125, 25});
          verifySubroutine(subs, 63, 31, new int[]{125, 25});
          verifySubroutine(subs, 66, 31, new int[]{125, 25});
          verifySubroutine(subs, 69, 31, new int[]{125, 25});
          verifySubroutine(subs, 71, 31, new int[]{125, 25});
          verifySubroutine(subs, 74, 31, new int[]{125, 25});
          verifySubroutine(subs, 76, 31, new int[]{125, 25});
          verifySubroutine(subs, 77, 77, new int[]{111, 71});
          verifySubroutine(subs, 79, 77, new int[]{111, 71});
          verifySubroutine(subs, 80, 77, new int[]{111, 71});
          verifySubroutine(subs, 82, 77, new int[]{111, 71});
          verifySubroutine(subs, 85, 77, new int[]{111, 71});
          verifySubroutine(subs, 88, 77, new int[]{111, 71});
          verifySubroutine(subs, 90, 77, new int[]{111, 71});
          verifySubroutine(subs, 93, 77, new int[]{111, 71});
          verifySubroutine(subs, 95, 77, new int[]{111, 71});
          verifySubroutine(subs, 96, 96, new int[]{106, 90});
          verifySubroutine(subs, 98, 96, new int[]{106, 90});
          verifySubroutine(subs, 99, 96, new int[]{106, 90});
          verifySubroutine(subs, 101, 96, new int[]{106, 90});
          verifySubroutine(subs, 104, 96, new int[]{106, 90});
          verifySubroutine(subs, 106, 77, new int[]{111, 71});
          verifySubroutine(subs, 109, 77, new int[]{111, 71});
          verifySubroutine(subs, 111, 31, new int[]{125, 25});
          verifySubroutine(subs, 114, 31, new int[]{125, 25});
          verifySubroutine(subs, 117, 31, new int[]{125, 25});
          verifySubroutine(subs, 118, 31, new int[]{125, 25});
          verifySubroutine(subs, 120, 31, new int[]{125, 25});
          verifySubroutine(subs, 123, 31, new int[]{125, 25});
      }
  
      private static void verifySubroutine(Subroutine[] subs, int pos, int start,
              int[] callers) {
          Subroutine sub = subs[pos];
          assertNotNull(sub);
          assertEquals(sub.start(), start);
          for (int i = 0; i < callers.length; i++)
              assertTrue(sub.callers().contains(Integer.valueOf(callers[i])));
      }
  
      private static void generate(ClassPool pool) throws CannotCompileException, IOException, NotFoundException {
          // Generated from eclipse JDK4 compiler:
          // public void doit(int x) {
          //    println("null");
          //    try {
          //        println("try");
          //    } catch (RuntimeException e) {
          //        e.printStackTrace();
          //    } finally {
          //        switch (x) {
          //        default:
          //        case 15:
          //        try {
          //            println("inner-try");
          //        } finally {
          //            try {
          //                println("inner-inner-try");
          //            } finally {
          //                println("inner-finally");
          //            }
          //        }
          //        break;
          //        case 1789:
          //        println("switch -17");
          //        }
          //    }
          //}
  
          CtClass clazz = pool.makeClass("test.ScannerTest$GeneratedTest");
          CtMethod method = new CtMethod(CtClass.voidType, "doit", new CtClass[] {CtClass.intType}, clazz);
          MethodInfo info = method.getMethodInfo2();
          info.setAccessFlags(AccessFlag.PUBLIC);
          CtClass stringClass = pool.get("java.lang.String");
          Bytecode code = new Bytecode(info.getConstPool(), 2, 9);
          /* 0   */ code.addAload(0);
          /* 1   */ code.addLdc("start");
          /* 3   */ code.addInvokevirtual(clazz, "println", CtClass.voidType, new CtClass[] {stringClass});
          /* 6   */ code.addAload(0);
          /* 7   */ code.addLdc("try");
          /* 9   */ code.addInvokevirtual(clazz, "println", CtClass.voidType, new CtClass[] {stringClass});
          /* 12  */ addJump(code, Opcode.GOTO, 125);
          /* 14  */ code.addAstore(2);
          /* 16  */ code.addAload(2);
          /* 17  */ code.addInvokevirtual("java.lang.Exception", "printStackTrace", "()V");
          /* 20  */ addJump(code, Opcode.GOTO, 125);
          /* 23  */ code.addAstore(4);
          /* 25  */ addJump(code, Opcode.JSR, 31);
          /* 28  */ code.addAload(4);
          /* 30  */ code.addOpcode(Opcode.ATHROW);
          /* 31  */ code.addAstore(3);
          /* 32  */ code.addIload(1);
          int spos = code.currentPc();
          /* 33  */ code.addOpcode(Opcode.LOOKUPSWITCH);
                    code.addIndex(0); // 2 bytes pad - gets us to 36
                    code.add32bit(60 - spos); // default
                    code.add32bit(2); // 2 pairs
                    code.add32bit(15); code.add32bit(60 - spos);
                    code.add32bit(1789); code.add32bit(117 - spos);
          /* 60  */ code.addAload(0);
          /* 61  */ code.addLdc("inner-try");
          /* 63  */ code.addInvokevirtual(clazz, "println", CtClass.voidType, new CtClass[] {stringClass});
          /* 66  */ addJump(code, Opcode.GOTO, 111);
          /* 69  */ code.addAstore(6);
          /* 71  */ addJump(code, Opcode.JSR, 77);
          /* 74  */ code.addAload(6);
          /* 76  */ code.add(Opcode.ATHROW);
          /* 77  */ code.addAstore(5);
          /* 79  */ code.addAload(0);
          /* 80  */ code.addLdc("inner-inner-try");
          /* 82  */ code.addInvokevirtual(clazz, "println", CtClass.voidType, new CtClass[] {stringClass});
          /* 85  */ addJump(code, Opcode.GOTO, 106);
          /* 88  */ code.addAstore(8);
          /* 90  */ addJump(code, Opcode.JSR, 96);
          /* 93  */ code.addAload(8);
          /* 95  */ code.add(Opcode.ATHROW);
          /* 96  */ code.addAstore(7);
          /* 98  */ code.addAload(0);
          /* 99  */ code.addLdc("inner-finally");
          /* 101 */ code.addInvokevirtual(clazz, "println", CtClass.voidType, new CtClass[] {stringClass});
          /* 104 */ code.addRet(7);
          /* 106 */ addJump(code, Opcode.JSR, 96);
          /* 109 */ code.addRet(5);
          /* 111 */ addJump(code, Opcode.JSR, 77);
          /* 114 */ addJump(code, Opcode.GOTO, 123);
          /* 117 */ code.addAload(0);
          /* 118 */ code.addLdc("switch - 1789");
          /* 120 */ code.addInvokevirtual(clazz, "println", CtClass.voidType, new CtClass[] {stringClass});
          /* 123 */ code.addRet(3);
          /* 125 */ addJump(code, Opcode.JSR, 31);
          /* 128 */ code.addOpcode(Opcode.RETURN);
          code.addExceptionHandler(6, 12, 15, "java.lang.RuntimeException");
          code.addExceptionHandler(6, 20, 23, 0);
          code.addExceptionHandler(125, 128, 23, 0);
          code.addExceptionHandler(60, 69, 69, 0);
          code.addExceptionHandler(111, 114, 69, 0);
          code.addExceptionHandler(79, 88, 88, 0);
          code.addExceptionHandler(106, 109, 88, 0);
          info.setCodeAttribute(code.toCodeAttribute());
          clazz.addMethod(method);
          clazz.writeFile("/tmp");
      }
  
      private static void addJump(Bytecode code, int opcode, int pos) {
          int current = code.currentPc();
          code.addOpcode(opcode);
          code.addIndex(pos - current);
      }
  }
  
  
  



More information about the jboss-cvs-commits mailing list