// store the Object[] array on stack if proceed with args
if (isProceedWithArgs) {
// STORE the Object[] into a local variable
Type objectArrayType = Type.OBJECT_ARRAY;
int theObjectArrayLocalNumber = localAdviceMethod.allocateLocal(objectArrayType);
ret.append(InstructionFactory.createStore(objectArrayType, theObjectArrayLocalNumber));
// STORE the ProceedingJoinPoint instance into a local variable
Type proceedingJpType = Type.getType("Lorg/aspectj/lang/ProceedingJoinPoint;");
int pjpLocalNumber = localAdviceMethod.allocateLocal(proceedingJpType);
ret.append(InstructionFactory.createStore(proceedingJpType, pjpLocalNumber));
// Aim here initially is to determine whether the user will have provided a new
// this/target in the object array and consume them if they have, leaving us the rest of
// the arguments to process as regular arguments to the invocation at the original join point
boolean pointcutBindsThis = bindsThis(munger);
boolean pointcutBindsTarget = bindsTarget(munger);
boolean targetIsSameAsThis = getKind().isTargetSameAsThis();
int nextArgumentToProvideForCallback = 0;
if (hasThis()) {
if (!(pointcutBindsTarget && targetIsSameAsThis)) {
if (pointcutBindsThis) {
// they have supplied new this as first entry in object array, consume it
ret.append(InstructionFactory.createLoad(objectArrayType, theObjectArrayLocalNumber));
ret.append(Utility.createConstant(fact, 0));
ret.append(InstructionFactory.createArrayLoad(Type.OBJECT));
ret.append(Utility.createConversion(fact, Type.OBJECT, callbackMethod.getArgumentTypes()[0]));
} else {
// use local variable 0
ret.append(InstructionFactory.createALOAD(0));
}
nextArgumentToProvideForCallback++;
}
}
if (hasTarget()) {
if (pointcutBindsTarget) {
if (getKind().isTargetSameAsThis()) {
ret.append(InstructionFactory.createLoad(objectArrayType, theObjectArrayLocalNumber));
ret.append(Utility.createConstant(fact, pointcutBindsThis ? 1 : 0));
ret.append(InstructionFactory.createArrayLoad(Type.OBJECT));
ret.append(Utility.createConversion(fact, Type.OBJECT, callbackMethod.getArgumentTypes()[0]));
} else {
int position = (hasThis()/* && pointcutBindsThis */? 1 : 0);
ret.append(InstructionFactory.createLoad(objectArrayType, theObjectArrayLocalNumber));
ret.append(Utility.createConstant(fact, position));
ret.append(InstructionFactory.createArrayLoad(Type.OBJECT));
ret.append(Utility.createConversion(fact, Type.OBJECT, callbackMethod.getArgumentTypes()[position]));
}
nextArgumentToProvideForCallback++;
} else {
if (getKind().isTargetSameAsThis()) {
// ret.append(new ALOAD(0));
} else {
ret.append(InstructionFactory.createLoad(localAdviceMethod.getArgumentTypes()[0], hasThis() ? 1 : 0));
nextArgumentToProvideForCallback++;
}
}
}
// Where to start in the object array in order to pick up arguments
int indexIntoObjectArrayForArguments = (pointcutBindsThis ? 1 : 0) + (pointcutBindsTarget ? 1 : 0);
int len = callbackMethod.getArgumentTypes().length;
for (int i = nextArgumentToProvideForCallback; i < len; i++) {
Type stateType = callbackMethod.getArgumentTypes()[i];
BcelWorld.fromBcel(stateType).resolve(world);
if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
ret.append(new InstructionLV(Constants.ALOAD, pjpLocalNumber));
} else {
ret.append(InstructionFactory.createLoad(objectArrayType, theObjectArrayLocalNumber));
ret.append(Utility
.createConstant(fact, i - nextArgumentToProvideForCallback + indexIntoObjectArrayForArguments));
ret.append(InstructionFactory.createArrayLoad(Type.OBJECT));
ret.append(Utility.createConversion(fact, Type.OBJECT, stateType));
}
}
} else {
Type proceedingJpType = Type.getType("Lorg/aspectj/lang/ProceedingJoinPoint;");
int localJp = localAdviceMethod.allocateLocal(proceedingJpType);
ret.append(InstructionFactory.createStore(proceedingJpType, localJp));
int idx = 0;
for (int i = 0, len = callbackMethod.getArgumentTypes().length; i < len; i++) {
Type stateType = callbackMethod.getArgumentTypes()[i];
/* ResolvedType stateTypeX = */
BcelWorld.fromBcel(stateType).resolve(world);
if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
ret.append(InstructionFactory.createALOAD(localJp));// from localAdvice signature
// } else if ("Lorg/aspectj/lang/ProceedingJoinPoint;".equals(stateType.getSignature())) {
// //FIXME ALEX?
// ret.append(new ALOAD(localJp));// from localAdvice signature
// // ret.append(fact.createCheckCast(
// // (ReferenceType) BcelWorld.makeBcelType(stateTypeX)
// // ));
// // cast ?
//
idx++;
} else {
ret.append(InstructionFactory.createLoad(stateType, idx));
idx += stateType.getSize();
}
}
}
// do the callback invoke