/** * Copyright (C) 2010-2017 Gordon Fraser, Andrea Arcuri and EvoSuite * contributors * * This file is part of EvoSuite. * * EvoSuite is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3.0 of the License, or * (at your option) any later version. * * EvoSuite is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>. */ /** * */ package org.evosuite.instrumentation; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.InsnList; /** * <p>NodeRegularExpression class.</p> * * @author Gordon Fraser */ public class NodeRegularExpression { /** Constant <code>ICONST_0=3</code> */ protected static final int ICONST_0 = 3; /** Constant <code>ICONST_1=4</code> */ protected static final int ICONST_1 = 4; /** Constant <code>GOTO=167</code> */ protected static final int GOTO = 167; /** Constant <code>ACONST_NULL=1</code> */ protected static final int ACONST_NULL = 1; /** Constant <code>ACONST_M1=2</code> */ protected static final int ACONST_M1 = 2; /** Constant <code>ILOAD=21</code> */ protected static final int ILOAD = 21; /** Constant <code>ISTORE=54</code> */ protected static final int ISTORE = 54; /** Constant <code>IADD=96</code> */ protected static final int IADD = 96; /** Constant <code>ISUB=100</code> */ protected static final int ISUB = 100; /** Constant <code>IMUL=104</code> */ protected static final int IMUL = 104; /** Constant <code>IDIV=108</code> */ protected static final int IDIV = 108; /** Constant <code>IREM=112</code> */ protected static final int IREM = 112; /** Constant <code>INEG=116</code> */ protected static final int INEG = 116; /** Constant <code>IFEQ=153</code> */ protected static final int IFEQ = 153; /** Constant <code>IFNE=154</code> */ protected static final int IFNE = 154; /** Constant <code>IFLT=155</code> */ protected static final int IFLT = 155; /** Constant <code>IFGE=156</code> */ protected static final int IFGE = 156; /** Constant <code>IFGT=157</code> */ protected static final int IFGT = 157; /** Constant <code>IFLE=158</code> */ protected static final int IFLE = 158; /** Constant <code>IF_ICMPEQ=159</code> */ protected static final int IF_ICMPEQ = 159; /** Constant <code>IF_ICMPNE=160</code> */ protected static final int IF_ICMPNE = 160; /** Constant <code>IF_ICMPLT=161</code> */ protected static final int IF_ICMPLT = 161; /** Constant <code>IF_ICMPGE=162</code> */ protected static final int IF_ICMPGE = 162; /** Constant <code>IF_ICMPGT=163</code> */ protected static final int IF_ICMPGT = 163; /** Constant <code>IF_ICMPLE=164</code> */ protected static final int IF_ICMPLE = 164; /** Constant <code>IF_ACMPEQ=165</code> */ protected static final int IF_ACMPEQ = 165; /** Constant <code>IF_ACMPNE=166</code> */ protected static final int IF_ACMPNE = 166; /** Constant <code>IRETURN=172</code> */ protected static final int IRETURN = 172; /** Constant <code>GETSTATIC=178</code> */ protected static final int GETSTATIC = 178; /** Constant <code>PUTSTATIC=179</code> */ protected static final int PUTSTATIC = 179; /** Constant <code>GETFIELD=180</code> */ protected static final int GETFIELD = 180; /** Constant <code>PUTFIELD=181</code> */ protected static final int PUTFIELD = 181; /** Constant <code>INVOKEVIRTUAL=182</code> */ protected static final int INVOKEVIRTUAL = 182; /** Constant <code>INVOKESPECIAL=183</code> */ protected static final int INVOKESPECIAL = 183; /** Constant <code>INVOKESTATIC=184</code> */ protected static final int INVOKESTATIC = 184; /** Constant <code>INVOKEINTERFACE=185</code> */ protected static final int INVOKEINTERFACE = 185; /** Constant <code>NEWARRAY=188</code> */ protected static final int NEWARRAY = 188; /** Constant <code>INSTANCEOF=193</code> */ protected static final int INSTANCEOF = 193; /** Constant <code>IFNULL=198</code> */ protected static final int IFNULL = 198; /** Constant <code>IFNONNULL=199</code> */ protected static final int IFNONNULL = 199; /** Constant <code>ALOAD=new int[] { 25, 42, 43, 44, 45 }</code> */ protected static final int[] ALOAD = new int[] { 25, 42, 43, 44, 45 }; /** Constant <code>IF=new int[] { 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164 }</code> */ protected static final int[] IF = new int[] { 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164 }; /** Constant <code>BOOL=new int[] { ICONST_0, ICONST_1 }</code> */ protected static final int[] BOOL = new int[] { ICONST_0, ICONST_1 }; //public static NodeRegularExpression IFELSE = new NodeRegularExpression(new int[] { // 160, 4, 167, 3 }); /** Constant <code>IFELSE</code> */ public static NodeRegularExpression IFELSE = new NodeRegularExpression(new int[][] { IF, BOOL, { GOTO }, BOOL }); /** Constant <code>NESTED_STOREFLAG</code> */ public static NodeRegularExpression NESTED_STOREFLAG = new NodeRegularExpression( new int[][] { IF, IF, BOOL, { ISTORE } }); /** Constant <code>STOREFLAG</code> */ public static NodeRegularExpression STOREFLAG = new NodeRegularExpression( new int[][] { IF, BOOL, { ISTORE } }); /** Constant <code>STOREFLAG2</code> */ public static NodeRegularExpression STOREFLAG2 = new NodeRegularExpression( new int[][] { IF, BOOL, { PUTSTATIC } }); /** Constant <code>STOREFLAG3</code> */ public static NodeRegularExpression STOREFLAG3 = new NodeRegularExpression( new int[][] { IF, ALOAD, BOOL, { PUTFIELD } }); /** Constant <code>STOREFLAG4</code> */ public static NodeRegularExpression STOREFLAG4 = new NodeRegularExpression( new int[][] { IF, BOOL, { IRETURN } }); public final int[][] pattern; /** * <p>Constructor for NodeRegularExpression.</p> * * @param opcodes an array of int. */ public NodeRegularExpression(int[] opcodes) { this.pattern = new int[opcodes.length][]; for (int i = 0; i < opcodes.length; i++) { this.pattern[i] = new int[] { opcodes[i] }; } } /** * <p>Constructor for NodeRegularExpression.</p> * * @param opcodes an array of int. */ public NodeRegularExpression(int[][] opcodes) { this.pattern = opcodes; } /** * <p>matches</p> * * @param instructions a {@link org.objectweb.asm.tree.InsnList} object. * @return a boolean. */ public boolean matches(InsnList instructions) { int match = 0; AbstractInsnNode node = instructions.getFirst(); while (node != instructions.getLast()) { if (node.getType() == AbstractInsnNode.FRAME || node.getType() == AbstractInsnNode.LABEL || node.getType() == AbstractInsnNode.LINE) { node = node.getNext(); continue; } else { boolean found = false; for (int opcode : pattern[match]) { if (node.getOpcode() == opcode) { match++; found = true; break; } } if (!found) match = 0; } if (match == pattern.length) return true; node = node.getNext(); } return false; } /** * <p>getNextMatch</p> * * @param start a {@link org.objectweb.asm.tree.AbstractInsnNode} object. * @param instructions a {@link org.objectweb.asm.tree.InsnList} object. * @return a {@link org.objectweb.asm.tree.AbstractInsnNode} object. */ public AbstractInsnNode getNextMatch(AbstractInsnNode start, InsnList instructions) { int match = 0; AbstractInsnNode node = start; AbstractInsnNode startNode = start; while (node != instructions.getLast()) { if (node.getType() == AbstractInsnNode.FRAME || node.getType() == AbstractInsnNode.LABEL || node.getType() == AbstractInsnNode.LINE) { node = node.getNext(); continue; } else { boolean found = false; for (int opcode : pattern[match]) { if (node.getOpcode() == opcode) { if (match == 0) startNode = node; match++; found = true; break; } } if (!found) match = 0; } if (match == pattern.length) { return startNode; } node = node.getNext(); } return null; } }