01: /**************************************************************************************
02: * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved. *
03: * http://aspectwerkz.codehaus.org *
04: * ---------------------------------------------------------------------------------- *
05: * The software in this package is published under the terms of the LGPL license *
06: * a copy of which has been included with this distribution in the license.txt file. *
07: **************************************************************************************/package org.codehaus.aspectwerkz.transform.inlining.weaver;
08:
09: import org.objectweb.asm.CodeAdapter;
10: import org.objectweb.asm.CodeVisitor;
11: import org.codehaus.aspectwerkz.transform.TransformationConstants;
12: import org.codehaus.aspectwerkz.annotation.instrumentation.asm.AsmAnnotationHelper;
13:
14: /**
15: * A visitor that keeps track of NEW and INVOKESPECIAL when within a constructor
16: * to flag when the object initialization has been reached (after this/super call).
17: * <p/>
18: * No regular weaving should occur before it since this(XXJP.invoke(this)) is not allowed Java code
19: *
20: * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
21: */
22: public class AfterObjectInitializationCodeAdapter extends CodeAdapter
23: 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,
31: String callerMemberName) {
32: super (cv);
33: m_callerMemberName = callerMemberName;
34: // object initialization matters within constructors only
35: if (!m_callerMemberName.equals(INIT_METHOD_NAME)) {
36: m_isObjectInitialized = true;
37: }
38: }
39:
40: public void visitTypeInsn(int opcode, String desc) {
41: if (opcode == NEW) {
42: m_newCount++;
43: }
44: super .visitTypeInsn(opcode, desc);
45: }
46:
47: protected boolean queryCurrentMethodInsn(final int opcode,
48: final String calleeClassName,
49: final String calleeMethodName, 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, final String calleeMethodDesc) {
77: if (opcode == INVOKESPECIAL) {
78: m_invokeSpecialCount++;
79: }
80:
81: if (m_callerMemberName.equals(INIT_METHOD_NAME)) {
82: // in ctor
83: // make sure we are after object initialization ie after
84: // the INVOKESPECIAL for this(..) / super(..)
85: // that is we have seen an INVOKESPECIAL while newCount == 0
86: // or while newCount == invokeSpecialCount - 1
87: // [ ie same with numberOfInvokeSpecialCount = 1 ]
88: if (opcode == INVOKESPECIAL) {
89: if (m_newCount == m_invokeSpecialCount - 1) {
90: m_isObjectInitialized = true;
91: }
92: }
93: }
94: super.visitMethodInsn(opcode, calleeClassName,
95: calleeMethodName, calleeMethodDesc);
96: }
97: }
|