1 /******************************************************************************* 2 * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * Evgeny Mandrikov - initial API and implementation 10 * 11 *******************************************************************************/ 12 package org.jacoco.core.internal.analysis.filter; 13 14 import static org.junit.Assert.assertEquals; 15 import static org.junit.Assert.assertNull; 16 import static org.junit.Assert.fail; 17 18 import org.jacoco.core.internal.instr.InstrSupport; 19 import org.junit.Test; 20 import org.objectweb.asm.Label; 21 import org.objectweb.asm.Opcodes; 22 import org.objectweb.asm.tree.AbstractInsnNode; 23 import org.objectweb.asm.tree.LabelNode; 24 import org.objectweb.asm.tree.MethodNode; 25 26 public class SynchronizedFilterTest implements IFilterOutput { 27 28 private final SynchronizedFilter filter = new SynchronizedFilter(); 29 30 private final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, 31 "name", "()V", null, null); 32 33 private AbstractInsnNode fromInclusive; 34 private AbstractInsnNode toInclusive; 35 36 @Test 37 public void javac() { 38 final Label start = new Label(); 39 final Label end = new Label(); 40 final Label handler = new Label(); 41 final Label handlerEnd = new Label(); 42 m.visitTryCatchBlock(start, end, handler, null); 43 m.visitTryCatchBlock(handler, handlerEnd, handler, null); 44 45 m.visitVarInsn(Opcodes.ALOAD, 0); 46 m.visitFieldInsn(Opcodes.GETFIELD, "Fun", "lock", "Ljava/lang/Object;"); 47 m.visitInsn(Opcodes.DUP); 48 m.visitVarInsn(Opcodes.ASTORE, 1); 49 m.visitInsn(Opcodes.MONITORENTER); 50 m.visitLabel(start); 51 m.visitInsn(Opcodes.NOP); 52 m.visitVarInsn(Opcodes.ALOAD, 1); 53 m.visitInsn(Opcodes.MONITOREXIT); 54 m.visitLabel(end); 55 final Label exit = new Label(); 56 m.visitJumpInsn(Opcodes.GOTO, exit); 57 m.visitLabel(handler); 58 m.visitVarInsn(Opcodes.ASTORE, 2); 59 m.visitVarInsn(Opcodes.ALOAD, 1); 60 m.visitInsn(Opcodes.MONITOREXIT); 61 m.visitLabel(handlerEnd); 62 m.visitVarInsn(Opcodes.ALOAD, 2); 63 m.visitInsn(Opcodes.ATHROW); 64 m.visitLabel(exit); 65 m.visitInsn(Opcodes.RETURN); 66 67 filter.filter("Foo", "java/lang/Object", m, this); 68 assertEquals(handler.info, fromInclusive); 69 assertEquals(((LabelNode) exit.info).getPrevious(), toInclusive); 70 } 71 72 /** 73 * <pre> 74 * try { 75 * ... 76 * } catch (Exception e) { 77 * ... 78 * } finally { 79 * ... 80 * } 81 * </pre> 82 */ 83 @Test 84 public void javacTryCatchFinally() { 85 final Label start = new Label(); 86 final Label end = new Label(); 87 final Label catchHandler = new Label(); 88 final Label finallyHandler = new Label(); 89 final Label catchHandlerEnd = new Label(); 90 m.visitTryCatchBlock(start, end, catchHandler, "java/lang/Exception"); 91 m.visitTryCatchBlock(start, end, finallyHandler, null); 92 m.visitTryCatchBlock(catchHandler, catchHandlerEnd, finallyHandler, 93 null); 94 95 m.visitLabel(start); 96 // body 97 m.visitInsn(Opcodes.NOP); 98 m.visitLabel(end); 99 // finally 100 m.visitInsn(Opcodes.NOP); 101 final Label exit = new Label(); 102 m.visitJumpInsn(Opcodes.GOTO, exit); 103 m.visitLabel(catchHandler); 104 m.visitVarInsn(Opcodes.ASTORE, 1); 105 // catch 106 m.visitInsn(Opcodes.NOP); 107 m.visitLabel(catchHandlerEnd); 108 // finally 109 m.visitInsn(Opcodes.NOP); 110 m.visitJumpInsn(Opcodes.GOTO, exit); 111 m.visitLabel(finallyHandler); 112 m.visitVarInsn(Opcodes.ASTORE, 2); 113 // finally 114 m.visitInsn(Opcodes.NOP); 115 m.visitVarInsn(Opcodes.ALOAD, 2); 116 m.visitInsn(Opcodes.ATHROW); 117 m.visitLabel(exit); 118 m.visitInsn(Opcodes.RETURN); 119 120 filter.filter("Foo", "java/lang/Object", m, this); 121 assertNull(fromInclusive); 122 } 123 124 @Test 125 public void ecj() { 126 final Label start = new Label(); 127 final Label end = new Label(); 128 final Label handler = new Label(); 129 final Label handlerEnd = new Label(); 130 m.visitTryCatchBlock(start, end, handler, null); 131 m.visitTryCatchBlock(handler, handlerEnd, handler, null); 132 133 m.visitVarInsn(Opcodes.ALOAD, 0); 134 m.visitFieldInsn(Opcodes.GETFIELD, "Target", "lock", 135 "Ljava/lang/Object;"); 136 m.visitInsn(Opcodes.DUP); 137 m.visitVarInsn(Opcodes.ASTORE, 1); 138 m.visitInsn(Opcodes.MONITORENTER); 139 m.visitLabel(start); 140 m.visitVarInsn(Opcodes.ALOAD, 0); 141 m.visitInsn(Opcodes.NOP); 142 m.visitVarInsn(Opcodes.ALOAD, 1); 143 m.visitInsn(Opcodes.MONITOREXIT); 144 m.visitLabel(end); 145 final Label exit = new Label(); 146 m.visitJumpInsn(Opcodes.GOTO, exit); 147 m.visitLabel(handler); 148 m.visitVarInsn(Opcodes.ALOAD, 1); 149 m.visitInsn(Opcodes.MONITOREXIT); 150 m.visitLabel(handlerEnd); 151 m.visitInsn(Opcodes.ATHROW); 152 m.visitLabel(exit); 153 m.visitInsn(Opcodes.RETURN); 154 155 filter.filter("Foo", "java/lang/Object", m, this); 156 assertEquals(handler.info, fromInclusive); 157 assertEquals(((LabelNode) exit.info).getPrevious(), toInclusive); 158 } 159 160 public void ignore(AbstractInsnNode fromInclusive, 161 AbstractInsnNode toInclusive) { 162 assertNull(this.fromInclusive); 163 this.fromInclusive = fromInclusive; 164 this.toInclusive = toInclusive; 165 } 166 167 public void merge(final AbstractInsnNode i1, final AbstractInsnNode i2) { 168 fail(); 169 } 170 171 } 172