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  }