1/******************************************************************************* 2 * Copyright (c) 2009, 2015 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 * Marc R. Hoffmann - initial API and implementation 10 * 11 *******************************************************************************/ 12package org.jacoco.core.internal.flow; 13 14import org.jacoco.core.JaCoCo; 15import org.objectweb.asm.Label; 16import org.objectweb.asm.MethodVisitor; 17import org.objectweb.asm.commons.JSRInlinerAdapter; 18 19/** 20 * This method visitor fixes two potential issues with Java byte code: 21 * 22 * <ul> 23 * <li>Remove JSR/RET instructions by inlining subroutines which are deprecated 24 * since Java 6. The RET statement complicates control flow analysis as the jump 25 * target is not explicitly given.</li> 26 * <li>Remove code attributes line number and local variable name if they point 27 * to invalid offsets which some tools create. When writing out such invalid 28 * labels with ASM class files do not verify any more.</li> 29 * </ul> 30 */ 31class MethodSanitizer extends JSRInlinerAdapter { 32 33 MethodSanitizer(final MethodVisitor mv, final int access, 34 final String name, final String desc, final String signature, 35 final String[] exceptions) { 36 super(JaCoCo.ASM_API_VERSION, mv, access, name, desc, signature, 37 exceptions); 38 } 39 40 @Override 41 public void visitLocalVariable(final String name, final String desc, 42 final String signature, final Label start, final Label end, 43 final int index) { 44 // Here we rely on the usage of the info fields by the tree API. If the 45 // labels have been properly used before the info field contains a 46 // reference to the LabelNode, otherwise null. 47 if (start.info != null && end.info != null) { 48 super.visitLocalVariable(name, desc, signature, start, end, index); 49 } 50 } 51 52 @Override 53 public void visitLineNumber(final int line, final Label start) { 54 // Here we rely on the usage of the info fields by the tree API. If the 55 // labels have been properly used before the info field contains a 56 // reference to the LabelNode, otherwise null. 57 if (start.info != null) { 58 super.visitLineNumber(line, start); 59 } 60 } 61 62} 63