View Javadoc

1   /***************************************************************************************
2    * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved.                 *
3    * http://aspectwerkz.codehaus.org                                                    *
4    * ---------------------------------------------------------------------------------- *
5    * The software in this package is published under the terms of the LGPL license      *
6    * a copy of which has been included with this distribution in the license.txt file.  *
7    **************************************************************************************/
8   package org.codehaus.aspectwerkz.transform.inlining.weaver;
9   
10  import org.objectweb.asm.CodeAdapter;
11  import org.objectweb.asm.CodeVisitor;
12  import org.codehaus.aspectwerkz.transform.TransformationConstants;
13  import org.codehaus.aspectwerkz.annotation.instrumentation.asm.AsmAnnotationHelper;
14  
15  /***
16   * A visitor that keeps track of NEW and INVOKESPECIAL when within a constructor
17   * to flag when the object initialization has been reached (after this/super call).
18   * <p/>
19   * No regular weaving should occur before it since this(XXJP.invoke(this)) is not allowed Java code
20   *
21   * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
22   */
23  public class AfterObjectInitializationCodeAdapter extends CodeAdapter implements TransformationConstants {
24  
25      private String m_callerMemberName;
26      private int m_newCount = 0;
27      private int m_invokeSpecialCount = 0;
28      protected boolean m_isObjectInitialized = false;
29  
30      public AfterObjectInitializationCodeAdapter(CodeVisitor cv, String callerMemberName) {
31          super(cv);
32          m_callerMemberName = callerMemberName;
33          // object initialization matters within constructors only
34          if (!m_callerMemberName.equals(INIT_METHOD_NAME)) {
35              m_isObjectInitialized = true;
36          }
37      }
38  
39      public void visitTypeInsn(int opcode, String desc) {
40          if (opcode == NEW) {
41              m_newCount++;
42          }
43          super.visitTypeInsn(opcode, desc);
44      }
45  
46      protected boolean queryCurrentMethodInsn(final int opcode,
47                                  final String calleeClassName,
48                                  final String calleeMethodName,
49                                  final String calleeMethodDesc) {
50          int localInvokeSpecialCount = m_invokeSpecialCount;
51          int localNewCount = m_newCount;
52  
53          if (opcode == INVOKESPECIAL) {
54              localInvokeSpecialCount++;
55          }
56  
57          if (m_callerMemberName.equals(INIT_METHOD_NAME)) {
58              // in ctor
59              // make sure we are after object initialization ie after
60              // the INVOKESPECIAL for this(..) / super(..)
61              // that is we have seen an INVOKESPECIAL while newCount == 0
62              // or while newCount == invokeSpecialCount - 1
63              // [ ie same with numberOfInvokeSpecialCount = 1 ]
64              if (opcode == INVOKESPECIAL) {
65                  if (localNewCount == localInvokeSpecialCount -1) {
66                      return true;
67                  }
68              }
69              return false;
70          }
71          return false;
72      }
73  
74      public void visitMethodInsn(final int opcode,
75                                  final String calleeClassName,
76                                  final String calleeMethodName,
77                                  final String calleeMethodDesc) {
78          if (opcode == INVOKESPECIAL) {
79              m_invokeSpecialCount++;
80          }
81  
82          if (m_callerMemberName.equals(INIT_METHOD_NAME)) {
83              // in ctor
84              // make sure we are after object initialization ie after
85              // the INVOKESPECIAL for this(..) / super(..)
86              // that is we have seen an INVOKESPECIAL while newCount == 0
87              // or while newCount == invokeSpecialCount - 1
88              // [ ie same with numberOfInvokeSpecialCount = 1 ]
89              if (opcode == INVOKESPECIAL) {
90                  if (m_newCount == m_invokeSpecialCount -1) {
91                      m_isObjectInitialized = true;
92                  }
93              }
94          }
95          super.visitMethodInsn(opcode, calleeClassName, calleeMethodName, calleeMethodDesc);
96      }
97  }