01: /*
02: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
03: */
04: package com.tc.aspectwerkz.transform.inlining.weaver;
05:
06: import com.tc.asm.MethodAdapter;
07: import com.tc.asm.MethodVisitor;
08:
09: import com.tc.aspectwerkz.transform.TransformationConstants;
10:
11: /**
12: * A visitor that keeps track of NEW and INVOKESPECIAL when within a constructor
13: * to flag when the object initialization has been reached (after this/super call).
14: * <p/>
15: * No regular weaving should occur before it since this(XXJP.invoke(this)) is not allowed Java code
16: *
17: * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
18: */
19: public class AfterObjectInitializationCodeAdapter extends MethodAdapter
20: implements TransformationConstants {
21:
22: private String m_callerMemberName;
23: private int m_newCount = 0;
24: private int m_invokeSpecialCount = 0;
25: protected boolean m_isObjectInitialized = false;
26:
27: public AfterObjectInitializationCodeAdapter(MethodVisitor cv,
28: String callerMemberName) {
29: super (cv);
30: m_callerMemberName = callerMemberName;
31: // object initialization matters within constructors only
32: if (!m_callerMemberName.equals(INIT_METHOD_NAME)) {
33: m_isObjectInitialized = true;
34: }
35: }
36:
37: public void visitTypeInsn(int opcode, String desc) {
38: if (opcode == NEW) {
39: m_newCount++;
40: }
41: super .visitTypeInsn(opcode, desc);
42: }
43:
44: protected boolean queryCurrentMethodInsn(final int opcode,
45: final String calleeClassName,
46: final String calleeMethodName, final String calleeMethodDesc) {
47: int localInvokeSpecialCount = m_invokeSpecialCount;
48: int localNewCount = m_newCount;
49:
50: if (opcode == INVOKESPECIAL) {
51: localInvokeSpecialCount++;
52: }
53:
54: if (m_callerMemberName.equals(INIT_METHOD_NAME)) {
55: // in ctor
56: // make sure we are after object initialization ie after
57: // the INVOKESPECIAL for this(..) / super(..)
58: // that is we have seen an INVOKESPECIAL while newCount == 0
59: // or while newCount == invokeSpecialCount - 1
60: // [ ie same with numberOfInvokeSpecialCount = 1 ]
61: if (opcode == INVOKESPECIAL) {
62: if (localNewCount == localInvokeSpecialCount - 1) {
63: return true;
64: }
65: }
66: return false;
67: }
68: return false;
69: }
70:
71: public void visitMethodInsn(final int opcode,
72: final String calleeClassName,
73: final String calleeMethodName, final String calleeMethodDesc) {
74: if (opcode == INVOKESPECIAL) {
75: m_invokeSpecialCount++;
76: }
77:
78: if (m_callerMemberName.equals(INIT_METHOD_NAME)) {
79: // in ctor
80: // make sure we are after object initialization ie after
81: // the INVOKESPECIAL for this(..) / super(..)
82: // that is we have seen an INVOKESPECIAL while newCount == 0
83: // or while newCount == invokeSpecialCount - 1
84: // [ ie same with numberOfInvokeSpecialCount = 1 ]
85: if (opcode == INVOKESPECIAL) {
86: if (m_newCount == m_invokeSpecialCount - 1) {
87: m_isObjectInitialized = true;
88: }
89: }
90: }
91: super.visitMethodInsn(opcode, calleeClassName,
92: calleeMethodName, calleeMethodDesc);
93: }
94: }
|