All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.evosuite.instrumentation.error.ArrayInstrumentation Maven / Gradle / Ivy

/**
 * Copyright (C) 2010-2018 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 .
 */
package org.evosuite.instrumentation.error;

import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

public class ArrayInstrumentation extends ErrorBranchInstrumenter {

	public ArrayInstrumentation(ErrorConditionMethodAdapter mv) {
		super(mv);
	}
	
	@Override
	public void visitInsn(int opcode) {
		// Check array accesses
		if (opcode == Opcodes.IALOAD || opcode == Opcodes.BALOAD
				|| opcode == Opcodes.CALOAD || opcode == Opcodes.SALOAD
				|| opcode == Opcodes.LALOAD || opcode == Opcodes.FALOAD
				|| opcode == Opcodes.DALOAD || opcode == Opcodes.AALOAD) {

			mv.visitInsn(Opcodes.DUP);
			insertBranch(Opcodes.IFGE, "java/lang/ArrayIndexOutOfBoundsException");

			mv.visitInsn(Opcodes.DUP2);
			mv.visitInsn(Opcodes.SWAP);
			//mv.visitInsn(Opcodes.POP);
			mv.visitInsn(Opcodes.ARRAYLENGTH);
			insertBranch(Opcodes.IF_ICMPLT, "java/lang/ArrayIndexOutOfBoundsException");
	
			
		} else if (opcode == Opcodes.IASTORE || opcode == Opcodes.BASTORE
				|| opcode == Opcodes.CASTORE || opcode == Opcodes.SASTORE
				|| opcode == Opcodes.AASTORE || opcode == Opcodes.LASTORE
				|| opcode == Opcodes.FASTORE || opcode == Opcodes.DASTORE) {

			int loc = 0;
			if (opcode == Opcodes.IASTORE)
				loc = mv.newLocal(Type.INT_TYPE);
			else if (opcode == Opcodes.BASTORE)
				loc = mv.newLocal(Type.BYTE_TYPE);
			else if (opcode == Opcodes.CASTORE)
				loc = mv.newLocal(Type.CHAR_TYPE);
			else if (opcode == Opcodes.SASTORE)
				loc = mv.newLocal(Type.SHORT_TYPE);
			else if (opcode == Opcodes.AASTORE)
				loc = mv.newLocal(Type.getType(Object.class));
			else if (opcode == Opcodes.LASTORE)
				loc = mv.newLocal(Type.LONG_TYPE);
			else if (opcode == Opcodes.FASTORE)
				loc = mv.newLocal(Type.FLOAT_TYPE);
			else if (opcode == Opcodes.DASTORE)
				loc = mv.newLocal(Type.DOUBLE_TYPE);
			else
				throw new RuntimeException("Unknown type");
			mv.storeLocal(loc);

			mv.visitInsn(Opcodes.DUP);
			insertBranch(Opcodes.IFGE, "java/lang/ArrayIndexOutOfBoundsException");

			mv.visitInsn(Opcodes.DUP2);
			mv.visitInsn(Opcodes.SWAP);
			//mv.visitInsn(Opcodes.POP);
			mv.visitInsn(Opcodes.ARRAYLENGTH);
			insertBranch(Opcodes.IF_ICMPLT, "java/lang/ArrayIndexOutOfBoundsException");

			mv.loadLocal(loc);
		}
	}
	
	@Override
	public void visitIntInsn(int opcode, int operand) {
		if(opcode == Opcodes.NEWARRAY) {
			mv.visitInsn(Opcodes.DUP);
			insertBranch(Opcodes.IFGE, "java/lang/NegativeArraySizeException");	
		}
	}

	public void visitMultiANewArrayInsn(String desc, int dims) {
		mv.visitLdcInsn(dims);
		// Number of dimensions
		insertBranch(Opcodes.IFGE, "java/lang/NegativeArraySizeException");
		// TODO: Check for each dimension that it is geq 0
	}

	@Override
	public void visitTypeInsn(int opcode,
							  String type) {
		if(opcode == Opcodes.ANEWARRAY) {
			mv.visitInsn(Opcodes.DUP);
			insertBranch(Opcodes.IFGE, "java/lang/NegativeArraySizeException");
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy