use of org.objectweb.asm.tree.TryCatchBlockNode in project dex2jar by pxb1988.
the class InvocationWeaver method wrapper.
public ClassVisitor wrapper(final ClassVisitor cv) {
return new RemappingClassAdapter(cv, remapper) {
Map<MtdInfo, MtdInfo> toCreate = new HashMap<MtdInfo, MtdInfo>();
String clzName;
private MtdInfo newMethodA(int opcode, MtdInfo t, MtdInfo mapTo) {
MtdInfo n = toCreate.get(t);
if (n != null) {
return n;
}
n = new MtdInfo();
n.owner = t.owner;
n.name = buildMethodAName(t.name);
boolean hasThis = opcode != INVOKESTATIC;
if (hasThis) {
Type[] args = Type.getArgumentTypes(t.desc);
Type ret = Type.getReturnType(t.desc);
List<Type> ts = new ArrayList<>(args.length + 1);
ts.add(Type.getType(t.owner));
ts.addAll(Arrays.asList(args));
n.desc = Type.getMethodDescriptor(ret, ts.toArray(new Type[ts.size()]));
} else {
n.desc = t.desc;
}
toCreate.put(t, n);
MethodVisitor mv = cv.visitMethod(ACC_SYNTHETIC | ACC_PRIVATE | ACC_STATIC, n.name, n.desc, null, null);
mv.visitCode();
genMethodACode(opcode, t, mapTo, mv, t);
return n;
}
private void genMethodACode(int opcode, MtdInfo t, MtdInfo mapTo, MethodVisitor mv, MtdInfo src) {
boolean hasThis = opcode != INVOKESTATIC;
Type[] args = Type.getArgumentTypes(t.desc);
Type ret = Type.getReturnType(t.desc);
final int start;
mv.visitTypeInsn(NEW, getCurrentInvocationName());
mv.visitInsn(DUP);
if (hasThis) {
mv.visitVarInsn(ALOAD, 0);
start = 1;
} else {
mv.visitInsn(ACONST_NULL);
start = 0;
}
if (args.length == 0) {
mv.visitInsn(ACONST_NULL);
} else {
mv.visitLdcInsn(args.length);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
for (int i = 0; i < args.length; i++) {
mv.visitInsn(DUP);
mv.visitLdcInsn(i);
mv.visitVarInsn(args[i].getOpcode(ILOAD), i + start);
box(args[i], mv);
mv.visitInsn(AASTORE);
}
}
int nextIdx = callbacks.size();
mv.visitLdcInsn(nextIdx);
mv.visitMethodInsn(INVOKESPECIAL, getCurrentInvocationName(), "<init>", "(Ljava/lang/Object;[Ljava/lang/Object;I)V");
mv.visitMethodInsn(INVOKESTATIC, toInternal(mapTo.owner), mapTo.name, mapTo.desc);
unBox(ret, Type.getReturnType(mapTo.desc), mv);
mv.visitInsn(ret.getOpcode(IRETURN));
mv.visitMaxs(-1, -1);
mv.visitEnd();
Callback cb = new Callback();
cb.idx = nextIdx;
cb.callback = newMethodCallback(opcode, t);
cb.target = src;
cb.isSpecial = opcode == INVOKESPECIAL;
cb.isStatic = opcode == INVOKESTATIC;
callbacks.add(cb);
}
private MtdInfo newMethodCallback(int opcode, MtdInfo t) {
MtdInfo n = new MtdInfo();
n.owner = "L" + className + ";";
n.name = buildCallbackMethodName(t.name);
if (opcode == INVOKESPECIAL || opcode == INVOKESTATIC) {
n.desc = "([Ljava/lang/Object;)Ljava/lang/Object;";
} else {
n.desc = "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;";
}
MethodVisitor mv = cv.visitMethod(opcode == INVOKESPECIAL ? ACC_PUBLIC : ACC_PUBLIC | ACC_STATIC, n.name, n.desc, null, null);
mv.visitCode();
int start;
if (opcode != INVOKESTATIC) {
mv.visitVarInsn(ALOAD, 0);
if (opcode != INVOKESPECIAL) {
mv.visitTypeInsn(CHECKCAST, toInternal(t.owner));
}
start = 1;
} else {
start = 0;
}
Type[] args = Type.getArgumentTypes(t.desc);
for (int i = 0; i < args.length; i++) {
mv.visitVarInsn(ALOAD, start);
mv.visitLdcInsn(i);
mv.visitInsn(AALOAD);
unBox(args[i], OBJECT_TYPE, mv);
}
mv.visitMethodInsn(opcode, toInternal(t.owner), t.name, t.desc);
Type ret = Type.getReturnType(t.desc);
box(ret, mv);
mv.visitInsn(ARETURN);
mv.visitMaxs(-1, -1);
mv.visitEnd();
return n;
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
clzName = name;
}
public MethodVisitor visitMethod(int access, final String name, String desc, String signature, String[] exceptions) {
final MethodVisitor superMv = superMethodVisitor(access, name, desc, signature, exceptions);
final MtdInfo mapTo = findDefinedTargetMethod("L" + clzName + ";", name, desc);
if (mapTo != null) {
final MtdInfo t1 = new MtdInfo();
t1.owner = "L" + clzName + ";";
t1.name = buildMethodAName(name);
t1.desc = desc;
final MtdInfo t = t1;
final MtdInfo src = new MtdInfo();
src.owner = t.owner;
src.name = name;
src.desc = desc;
return new MethodNode(Opcodes.ASM4, access, name, desc, signature, exceptions) {
@Override
public void visitEnd() {
InsnList instructions = this.instructions;
List<TryCatchBlockNode> tryCatchBlocks = this.tryCatchBlocks;
List<LocalVariableNode> localVariables = this.localVariables;
this.instructions = new InsnList();
this.tryCatchBlocks = new ArrayList<>();
this.localVariables = new ArrayList<>();
this.maxLocals = -1;
this.maxStack = -1;
accept(superMv);
int opcode;
if (Modifier.isStatic(access)) {
opcode = Opcodes.INVOKESTATIC;
} else {
opcode = Opcodes.INVOKEVIRTUAL;
}
genMethodACode(opcode, t, mapTo, superMv, src);
// make sure public
int newAccess = (access & ~(ACC_PRIVATE | ACC_PROTECTED)) | ACC_PUBLIC;
MethodVisitor rmv = wrap(superMethodVisitor(newAccess, t.name, desc, null, null));
if (rmv != null) {
rmv.visitCode();
int n, i;
n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
for (i = 0; i < n; ++i) {
tryCatchBlocks.get(i).accept(rmv);
}
instructions.accept(rmv);
n = localVariables == null ? 0 : localVariables.size();
for (i = 0; i < n; ++i) {
localVariables.get(i).accept(rmv);
}
rmv.visitMaxs(-1, -1);
rmv.visitEnd();
}
}
};
} else {
return wrap(superMv);
}
}
private MethodVisitor superMethodVisitor(int access, String name, String desc, String signature, String[] exceptions) {
return super.visitMethod(access, name, desc, signature, exceptions);
}
MethodVisitor wrap(MethodVisitor mv) {
return mv == null ? null : new ReplaceMethodVisitor(mv);
}
class ReplaceMethodVisitor extends MethodVisitor {
public ReplaceMethodVisitor(MethodVisitor mv) {
super(Opcodes.ASM4, mv);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
MtdInfo mapTo = findTargetMethod("L" + owner + ";", name, desc);
if (mapTo != null) {
boolean isStatic = opcode == INVOKESTATIC;
Type orgRet = Type.getReturnType(desc);
Type[] orgArgs = Type.getArgumentTypes(desc);
Type nRet = Type.getReturnType(mapTo.desc);
Type[] nArgs = Type.getArgumentTypes(mapTo.desc);
if (orgRet.getSort() != Type.VOID && nRet.getSort() == Type.VOID) {
throw new RuntimeException("can't cast " + nRet + " to " + orgRet);
}
if (nArgs.length == 1 && nArgs[0].getDescriptor().equals(invocationInterfaceDesc)) {
MtdInfo t = new MtdInfo();
t.owner = "L" + owner + ";";
t.name = name;
t.desc = desc;
MtdInfo n = newMethodA(opcode, t, mapTo);
super.visitMethodInsn(INVOKESTATIC, clzName, n.name, n.desc);
} else {
// checking for invalid replace
if (isStatic) {
if (!Arrays.deepEquals(orgArgs, nArgs)) {
throw new RuntimeException("arguments not equal: " + owner + "." + name + desc + " <> " + mapTo.owner + "." + mapTo.name + mapTo.desc);
}
} else {
if (nArgs.length != orgArgs.length + 1) {
throw new RuntimeException("arguments not equal: " + owner + "." + name + desc + " <> " + mapTo.owner + "." + mapTo.name + mapTo.desc);
}
if (orgArgs.length > 0) {
for (int i = 0; i < orgArgs.length; i++) {
if (!orgArgs[i].equals(nArgs[i + 1])) {
throw new RuntimeException("arguments not equal: " + owner + "." + name + desc + " <> " + mapTo.owner + "." + mapTo.name + mapTo.desc);
}
}
}
}
// replace it!
super.visitMethodInsn(INVOKESTATIC, toInternal(mapTo.owner), mapTo.name, mapTo.desc);
unBox(orgRet, nRet, this.mv);
}
} else {
super.visitMethodInsn(opcode, owner, name, desc);
}
}
}
};
}
use of org.objectweb.asm.tree.TryCatchBlockNode in project dex2jar by pxb1988.
the class TestUtils method verify.
@SuppressWarnings("rawtypes")
public static void verify(final ClassReader cr, PrintWriter out) throws AnalyzerException, IllegalArgumentException, IllegalAccessException {
ClassNode cn = new ClassNode();
cr.accept(new CheckClassAdapter(cn, false), ClassReader.SKIP_DEBUG);
List methods = cn.methods;
for (int i = 0; i < methods.size(); ++i) {
MethodNode method = (MethodNode) methods.get(i);
List tryCatchBlocks = method.tryCatchBlocks;
for (int j = 0; j < tryCatchBlocks.size(); j++) {
TryCatchBlockNode tcn = (TryCatchBlockNode) tryCatchBlocks.get(j);
if (tcn.start.equals(tcn.end)) {
throw new DexException("try/catch block %d in %s has same start(%s) and end(%s)", j, method.name, tcn.start.getLabel(), tcn.end.getLabel());
}
}
BasicVerifier verifier = new BasicVerifier();
Analyzer a = new Analyzer(verifier);
try {
a.analyze(cn.name, method);
} catch (Exception e) {
out.println(cr.getClassName() + "." + method.name + method.desc);
printAnalyzerResult(method, a, out);
e.printStackTrace(out);
out.flush();
throw new DexException("method " + method.name + " " + method.desc, e);
}
}
}
use of org.objectweb.asm.tree.TryCatchBlockNode in project quasar by puniverse.
the class InstrumentMethod method accept.
public void accept(MethodVisitor mv, boolean hasAnnotation) {
db.log(LogLevel.INFO, "Instrumenting method %s:%s#%s%s", sourceName, className, mn.name, mn.desc);
if (mn.name.charAt(0) == '<')
throw new UnableToInstrumentException("special method", className, mn.name, mn.desc);
collectCallsites();
final boolean skipInstrumentation = canInstrumentationBeSkipped(suspCallsBcis);
emitInstrumentedAnn(db, mv, mn, sourceName, className, skipInstrumentation, startSourceLine, endSourceLine, suspCallsSourceLines, suspCallsNames, null);
if (skipInstrumentation) {
db.log(LogLevel.INFO, "[OPTIMIZE] Skipping instrumentation for method %s:%s#%s%s", sourceName, className, mn.name, mn.desc);
// Dump
mn.accept(mv);
return;
}
// Else instrument
// Must be called first, sets flags & state used below
collectCodeBlocks();
// noinspection ConstantConditions
final boolean handleProxyInvocations = HANDLE_PROXY_INVOCATIONS && callsSuspendableSupers;
mv.visitCode();
Label lMethodStart = new Label();
Label lMethodStart2 = new Label();
Label lMethodEnd = new Label();
Label lCatchSEE = new Label();
Label lCatchUTE = new Label();
Label lCatchAll = new Label();
Label[] lMethodCalls = new Label[numCodeBlocks - 1];
Label[][] refInvokeTryCatch;
for (int i = 1; i < numCodeBlocks; i++) lMethodCalls[i - 1] = new Label();
mv.visitInsn(Opcodes.ACONST_NULL);
mv.visitVarInsn(Opcodes.ASTORE, lvarInvocationReturnValue);
// if (verifyInstrumentation) {
// mv.visitInsn(Opcodes.ICONST_0);
// mv.visitVarInsn(Opcodes.ISTORE, lvarSuspendableCalled);
// }
mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchSEE, SUSPEND_EXECUTION_NAME);
mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchSEE, RUNTIME_SUSPEND_EXECUTION_NAME);
if (handleProxyInvocations)
mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchUTE, UNDECLARED_THROWABLE_NAME);
// Prepare visitTryCatchBlocks for InvocationTargetException.
// With reflective invocations, the SuspendExecution exception will be wrapped in InvocationTargetException. We need to catch it and unwrap it.
// Note that the InvocationTargetException will be regenrated on every park, adding further overhead on top of the reflective call.
// This must be done here, before all other visitTryCatchBlock, because the exception's handler
// will be matched according to the order of in which visitTryCatchBlock has been called. Earlier calls take precedence.
refInvokeTryCatch = new Label[numCodeBlocks - 1][];
for (int i = 1; i < numCodeBlocks; i++) {
final FrameInfo fi = codeBlocks[i];
final AbstractInsnNode in = mn.instructions.get(fi.endInstruction);
if (mn.instructions.get(fi.endInstruction) instanceof MethodInsnNode) {
MethodInsnNode min = (MethodInsnNode) in;
if (isReflectInvocation(min.owner, min.name)) {
Label[] ls = new Label[3];
for (int k = 0; k < 3; k++) ls[k] = new Label();
refInvokeTryCatch[i - 1] = ls;
mv.visitTryCatchBlock(ls[0], ls[1], ls[2], "java/lang/reflect/InvocationTargetException");
}
}
}
// Output try-catch blocks
for (final Object o : mn.tryCatchBlocks) {
final TryCatchBlockNode tcb = (TryCatchBlockNode) o;
if (// we allow catch of SuspendExecution only in methods annotated with @Suspendable and in lambda-generated ones.
SUSPEND_EXECUTION_NAME.equals(tcb.type) && !hasAnnotation && !mn.name.startsWith(Classes.LAMBDA_METHOD_PREFIX))
throw new UnableToInstrumentException("catch for SuspendExecution", className, mn.name, mn.desc);
if (// we allow catch of SuspendExecution in method annotated with @Suspendable.
handleProxyInvocations && UNDECLARED_THROWABLE_NAME.equals(tcb.type))
throw new UnableToInstrumentException("catch for UndeclaredThrowableException", className, mn.name, mn.desc);
// if (INTERRUPTED_EXCEPTION_NAME.equals(tcb.type))
// throw new UnableToInstrumentException("catch for " + InterruptedException.class.getSimpleName(), className, mn.name, mn.desc);
tcb.accept(mv);
}
// Output parameter annotations
if (mn.visibleParameterAnnotations != null)
dumpParameterAnnotations(mv, mn.visibleParameterAnnotations, true);
if (mn.invisibleParameterAnnotations != null)
dumpParameterAnnotations(mv, mn.invisibleParameterAnnotations, false);
// Output method annotations
if (mn.visibleAnnotations != null) {
for (Object o : mn.visibleAnnotations) {
AnnotationNode an = (AnnotationNode) o;
an.accept(mv.visitAnnotation(an.desc, true));
}
}
mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchAll, null);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, STACK_NAME, "getStack", "()L" + STACK_NAME + ";", false);
mv.visitInsn(Opcodes.DUP);
mv.visitVarInsn(Opcodes.ASTORE, lvarStack);
// println(mv, "STACK: ", lvarStack);
// dumpStack(mv);
// DUAL
mv.visitJumpInsn(Opcodes.IFNULL, lMethodStart);
mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
// we'll assume we have been resumed
emitStoreResumed(mv, true);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "nextMethodEntry", "()I", false);
mv.visitTableSwitchInsn(1, numCodeBlocks - 1, lMethodStart2, lMethodCalls);
mv.visitLabel(lMethodStart2);
// the following code handles the case of an instrumented method called not as part of a suspendable code path
// isFirstInStack will return false in that case.
mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "isFirstInStackOrPushed", "()Z", false);
// if true
mv.visitJumpInsn(Opcodes.IFNE, lMethodStart);
// This will reset the fiber stack local if isFirstStack returns false.
mv.visitInsn(Opcodes.ACONST_NULL);
mv.visitVarInsn(Opcodes.ASTORE, lvarStack);
mv.visitLabel(lMethodStart);
// no, we have not been resumed
emitStoreResumed(mv, false);
dumpCodeBlock(mv, 0, 0);
// Blocks leading to suspendable calls
for (int i = 1; i < numCodeBlocks; i++) {
final FrameInfo fi = codeBlocks[i];
// Emit instrumented call
final AbstractInsnNode min = mn.instructions.get(fi.endInstruction);
final String owner = getMethodOwner(min), name = getMethodName(min), desc = getMethodDesc(min);
if (isYieldMethod(owner, name)) {
// special case - call to yield
if (min.getOpcode() != Opcodes.INVOKESTATIC)
throw new UnableToInstrumentException("invalid call to suspending method.", className, mn.name, mn.desc);
final int numYieldArgs = TypeAnalyzer.getNumArguments(desc);
final boolean yieldReturnsValue = (Type.getReturnType(desc) != Type.VOID_TYPE);
// we preserve the arguments for the call to yield on the operand stack
emitStoreState(mv, i, fi, numYieldArgs);
// we have not been resumed
emitStoreResumed(mv, false);
// emitSuspendableCalled(mv);
// we call the yield method
min.accept(mv);
if (yieldReturnsValue)
// we ignore the returned value...
mv.visitInsn(Opcodes.POP);
// we resume AFTER the call
mv.visitLabel(lMethodCalls[i - 1]);
final Label afterPostRestore = new Label();
mv.visitVarInsn(Opcodes.ILOAD, lvarResumed);
mv.visitJumpInsn(Opcodes.IFEQ, afterPostRestore);
emitPostRestore(mv);
mv.visitLabel(afterPostRestore);
emitRestoreState(mv, i, fi, numYieldArgs);
if (yieldReturnsValue)
// ... and replace the returned value with the value of resumed
mv.visitVarInsn(Opcodes.ILOAD, lvarResumed);
// See #211: if Fiber.park() is the last call before catch, ASM generates
// empty handlers (start_pc = end_pc) that won't pass ASM's nor JVM's bytecode checker because of
// exception_table's spec here: https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.3
mv.visitInsn(Opcodes.NOP);
dumpCodeBlock(mv, i, 1);
} else {
final Label lbl = new Label();
// DUAL
mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
mv.visitJumpInsn(Opcodes.IFNULL, lbl);
// normal case - call to a suspendable method - resume before the call
emitStoreState(mv, i, fi, 0);
// we have not been resumed
emitStoreResumed(mv, false);
// emitPreemptionPoint(mv, PREEMPTION_CALL);
mv.visitLabel(lMethodCalls[i - 1]);
emitRestoreState(mv, i, fi, 0);
// DUAL
mv.visitLabel(lbl);
if (isReflectInvocation(owner, name)) {
// We catch the InvocationTargetException and unwrap it if it wraps a SuspendExecution exception.
Label[] ls = refInvokeTryCatch[i - 1];
final Label startTry = ls[0];
final Label endTry = ls[1];
final Label startCatch = ls[2];
final Label endCatch = new Label();
final Label notSuspendExecution = new Label();
// mv.visitTryCatchBlock(startTry, endTry, startCatch, "java/lang/reflect/InvocationTargetException");
// try {
mv.visitLabel(startTry);
// method.invoke()
min.accept(mv);
// save return value
mv.visitVarInsn(Opcodes.ASTORE, lvarInvocationReturnValue);
// }
mv.visitLabel(endTry);
mv.visitJumpInsn(Opcodes.GOTO, endCatch);
// catch(InvocationTargetException ex) {
mv.visitLabel(startCatch);
mv.visitInsn(Opcodes.DUP);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;", false);
mv.visitTypeInsn(Opcodes.INSTANCEOF, SUSPEND_EXECUTION_NAME);
mv.visitJumpInsn(Opcodes.IFEQ, notSuspendExecution);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;", false);
mv.visitLabel(notSuspendExecution);
mv.visitInsn(Opcodes.ATHROW);
mv.visitLabel(endCatch);
// restore return value
mv.visitVarInsn(Opcodes.ALOAD, lvarInvocationReturnValue);
dumpCodeBlock(mv, i, 1);
} else {
// emitSuspendableCalled(mv);
dumpCodeBlock(mv, i, 0);
}
}
}
// Emit catchall's catch section
mv.visitLabel(lMethodEnd);
if (handleProxyInvocations) {
mv.visitLabel(lCatchUTE);
mv.visitInsn(Opcodes.DUP);
// println(mv, "CTCH: ");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;", false);
// println(mv, "CAUSE: ");
mv.visitTypeInsn(Opcodes.INSTANCEOF, SUSPEND_EXECUTION_NAME);
mv.visitJumpInsn(Opcodes.IFEQ, lCatchAll);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;", false);
mv.visitJumpInsn(Opcodes.GOTO, lCatchSEE);
}
mv.visitLabel(lCatchAll);
emitPopMethod(mv);
mv.visitLabel(lCatchSEE);
// println(mv, "THROW: ");
// rethrow shared between catchAll and catchSSE
mv.visitInsn(Opcodes.ATHROW);
if (mn.localVariables != null) {
for (Object o : mn.localVariables) ((LocalVariableNode) o).accept(mv);
}
// Needed by ASM analysis
mv.visitMaxs(mn.maxStack + ADD_OPERANDS, mn.maxLocals + NUM_LOCALS + additionalLocals);
mv.visitEnd();
}
use of org.objectweb.asm.tree.TryCatchBlockNode in project quasar by puniverse.
the class InstrumentMethod method splitTryCatch.
@SuppressWarnings("unchecked")
private void splitTryCatch(FrameInfo fi) {
for (int i = 0; i < mn.tryCatchBlocks.size(); i++) {
TryCatchBlockNode tcb = (TryCatchBlockNode) mn.tryCatchBlocks.get(i);
int start = getLabelIdx(tcb.start);
int end = getLabelIdx(tcb.end);
if (start <= fi.endInstruction && end >= fi.endInstruction) {
db.log(LogLevel.DEBUG, "Splitting try-catch in %s, block %d call at instruction %d", mn.name, i, fi.endInstruction);
// need to split try/catch around the suspendable call
if (start == fi.endInstruction) {
// Starts exactly at the suspendable call => just make it start after it
tcb.start = fi.createAfterLabel();
} else {
if (end > fi.endInstruction) {
TryCatchBlockNode tcb2 = new TryCatchBlockNode(fi.createAfterLabel(), tcb.end, tcb.handler, tcb.type);
mn.tryCatchBlocks.add(i + 1, tcb2);
}
// Make it end before the suspendable call
tcb.end = fi.createBeforeLabel();
}
}
}
}
use of org.objectweb.asm.tree.TryCatchBlockNode in project jacoco by jacoco.
the class SynchronizedFilter method filter.
public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) {
for (final TryCatchBlockNode tryCatch : methodNode.tryCatchBlocks) {
if (tryCatch.type != null) {
continue;
}
if (tryCatch.start == tryCatch.handler) {
continue;
}
final AbstractInsnNode to = new Matcher(tryCatch.handler).match();
if (to == null) {
continue;
}
output.ignore(tryCatch.handler, to);
}
}
Aggregations