}
return ret;
}
private void match(LazyMethodGen mg, InstructionHandle ih, BcelShadow enclosingShadow, List<BcelShadow> shadowAccumulator) {
Instruction i = ih.getInstruction();
// Exception handlers (pr230817)
if (canMatch(Shadow.ExceptionHandler) && !Range.isRangeHandle(ih)) {
Set<InstructionTargeter> targeters = ih.getTargetersCopy();
for (InstructionTargeter t : targeters) {
if (t instanceof ExceptionRange) {
// assert t.getHandler() == ih
ExceptionRange er = (ExceptionRange) t;
if (er.getCatchType() == null) {
continue;
}
if (isInitFailureHandler(ih)) {
return;
}
if (!ih.getInstruction().isStoreInstruction() && ih.getInstruction().getOpcode() != Constants.NOP) {
// If using cobertura, the catch block stats with
// INVOKESTATIC rather than ASTORE, in order that
// the
// ranges
// for the methodcall and exceptionhandler shadows
// that occur at this same
// line, we need to modify the instruction list to
// split them - adding a
// NOP before the invokestatic that gets all the
// targeters
// that were aimed at the INVOKESTATIC
mg.getBody().insert(ih, InstructionConstants.NOP);
InstructionHandle newNOP = ih.getPrev();
// what about a try..catch that starts at the start
// of the exception handler? need to only include
// certain targeters really.
er.updateTarget(ih, newNOP, mg.getBody());
for (InstructionTargeter t2 : targeters) {
newNOP.addTargeter(t2);
}
ih.removeAllTargeters();
match(BcelShadow.makeExceptionHandler(world, er, mg, newNOP, enclosingShadow), shadowAccumulator);
} else {
match(BcelShadow.makeExceptionHandler(world, er, mg, ih, enclosingShadow), shadowAccumulator);
}
}
}
}
if ((i instanceof FieldInstruction) && (canMatch(Shadow.FieldGet) || canMatch(Shadow.FieldSet))) {
FieldInstruction fi = (FieldInstruction) i;
if (fi.opcode == Constants.PUTFIELD || fi.opcode == Constants.PUTSTATIC) {
// check for sets of constant fields. We first check the
// previous
// instruction. If the previous instruction is a LD_WHATEVER
// (push
// constant on the stack) then we must resolve the field to
// determine
// if it's final. If it is final, then we don't generate a
// shadow.
InstructionHandle prevHandle = ih.getPrev();
Instruction prevI = prevHandle.getInstruction();
if (Utility.isConstantPushInstruction(prevI)) {
Member field = BcelWorld.makeFieldJoinPointSignature(clazz, (FieldInstruction) i);
ResolvedMember resolvedField = field.resolve(world);
if (resolvedField == null) {
// we can't find the field, so it's not a join point.