// add one case for each around advice invocation
for (int i = 0; i < m_aroundAdviceMethodInfos.length; i++) {
cv.visitLabel(caseLabels[i]);
// gather advice info
AdviceMethodInfo adviceInfo = m_aroundAdviceMethodInfos[i];
Label endInstanceOflabel = beginRuntimeCheck(cv, false, 0, adviceInfo.getAdviceInfo(), -1);
// get the aspect instance
loadAspect(cv, NON_OPTIMIZED_JOIN_POINT, 0, adviceInfo.getAspectInfo());
// load the arguments to the advice from the join point instance plus build up the advice method signature
int[] argIndexes = adviceInfo.getAdviceMethodArgIndexes();
for (int j = 0; j < argIndexes.length; j++) {
int argIndex = argIndexes[j];
if (argIndex >= 0) {
Type argumentType = m_argumentTypes[argIndex];
cv.visitVarInsn(ALOAD, 0);
cv.visitFieldInsn(
GETFIELD,
m_joinPointClassName,
ARGUMENT_FIELD + argIndex,
argumentType.getDescriptor()
);
} else if (argIndex == AdviceInfo.JOINPOINT_ARG ||
argIndex == AdviceInfo.STATIC_JOINPOINT_ARG ||
argIndex == AdviceInfo.VALID_NON_AW_AROUND_CLOSURE_TYPE) {
cv.visitVarInsn(ALOAD, 0);
} else if (argIndex == AdviceInfo.TARGET_ARG) {
loadCallee(cv, NON_OPTIMIZED_JOIN_POINT, 0, INDEX_NOTAVAILABLE);
// add a cast if runtime check was used
if (adviceInfo.getAdviceInfo().hasTargetWithRuntimeCheck()) {
cv.visitTypeInsn(
CHECKCAST, adviceInfo.getAdviceInfo().getMethodParameterTypes()[j].getInternalName()
);
}
} else if (argIndex == AdviceInfo.THIS_ARG) {
loadCaller(cv, NON_OPTIMIZED_JOIN_POINT, 0, INDEX_NOTAVAILABLE);
} else {
throw new Error("advice method argument index type is not supported: " + argIndex);
}
}
// invoke the advice method
cv.visitMethodInsn(
INVOKEVIRTUAL,
adviceInfo.getAspectInfo().getAspectClassName(),
adviceInfo.getAdviceInfo().getMethodName(),
adviceInfo.getAdviceInfo().getMethodSignature()
);
cv.visitVarInsn(ASTORE, 1);
// we need to handle the case when the advice was skept due to runtime check
// that is : if (runtimeCheck) { ret = advice() } else { ret = proceed() }
if (endInstanceOflabel != null) {
Label elseInstanceOfLabel = new Label();
cv.visitJumpInsn(GOTO, elseInstanceOfLabel);
endRuntimeCheck(cv, adviceInfo.getAdviceInfo(), endInstanceOflabel);
cv.visitVarInsn(ALOAD, 0);
cv.visitMethodInsn(INVOKESPECIAL, m_joinPointClassName, PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE);
cv.visitVarInsn(ASTORE, 1);
cv.visitLabel(elseInstanceOfLabel);
}