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
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
59
60
61
62
63
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
84
85
86
87
88
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 }