/** * 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.symbolic; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map; import org.evosuite.dse.VM; import org.evosuite.runtime.testdata.EvoSuiteFile; import org.evosuite.runtime.testdata.EvoSuiteLocalAddress; import org.evosuite.runtime.testdata.EvoSuiteRemoteAddress; import org.evosuite.runtime.testdata.EvoSuiteURL; import org.evosuite.symbolic.expr.Expression; import org.evosuite.symbolic.expr.bv.IntegerConstant; import org.evosuite.symbolic.expr.bv.IntegerValue; import org.evosuite.symbolic.expr.bv.IntegerVariable; import org.evosuite.symbolic.expr.bv.RealToIntegerCast; import org.evosuite.symbolic.expr.fp.IntegerToRealCast; import org.evosuite.symbolic.expr.fp.RealValue; import org.evosuite.symbolic.expr.fp.RealVariable; import org.evosuite.symbolic.expr.ref.ReferenceConstant; import org.evosuite.symbolic.expr.ref.ReferenceExpression; import org.evosuite.symbolic.expr.str.StringValue; import org.evosuite.symbolic.expr.str.StringVariable; import org.evosuite.symbolic.vm.ExpressionFactory; import org.evosuite.symbolic.vm.SymbolicEnvironment; import org.evosuite.symbolic.vm.SymbolicHeap; import org.evosuite.symbolic.vm.wrappers.Types; import org.evosuite.testcase.execution.CodeUnderTestException; import org.evosuite.testcase.execution.EvosuiteError; import org.evosuite.testcase.execution.ExecutionObserver; import org.evosuite.testcase.execution.ExecutionResult; import org.evosuite.testcase.execution.Scope; import org.evosuite.testcase.statements.ArrayStatement; import org.evosuite.testcase.statements.AssignmentStatement; import org.evosuite.testcase.statements.ClassPrimitiveStatement; import org.evosuite.testcase.statements.ConstructorStatement; import org.evosuite.testcase.statements.EnumPrimitiveStatement; import org.evosuite.testcase.statements.FieldStatement; import org.evosuite.testcase.statements.FunctionalMockStatement; import org.evosuite.testcase.statements.MethodStatement; import org.evosuite.testcase.statements.NullStatement; import org.evosuite.testcase.statements.PrimitiveExpression; import org.evosuite.testcase.statements.Statement; import org.evosuite.testcase.statements.StringPrimitiveStatement; import org.evosuite.testcase.statements.environment.FileNamePrimitiveStatement; import org.evosuite.testcase.statements.environment.LocalAddressPrimitiveStatement; import org.evosuite.testcase.statements.environment.RemoteAddressPrimitiveStatement; import org.evosuite.testcase.statements.environment.UrlPrimitiveStatement; import org.evosuite.testcase.statements.numeric.BooleanPrimitiveStatement; import org.evosuite.testcase.statements.numeric.BytePrimitiveStatement; import org.evosuite.testcase.statements.numeric.CharPrimitiveStatement; import org.evosuite.testcase.statements.numeric.DoublePrimitiveStatement; import org.evosuite.testcase.statements.numeric.FloatPrimitiveStatement; import org.evosuite.testcase.statements.numeric.IntPrimitiveStatement; import org.evosuite.testcase.statements.numeric.LongPrimitiveStatement; import org.evosuite.testcase.statements.numeric.ShortPrimitiveStatement; import org.evosuite.testcase.variable.ArrayIndex; import org.evosuite.testcase.variable.ArrayReference; import org.evosuite.testcase.variable.FieldReference; import org.evosuite.testcase.variable.VariableReference; import org.objectweb.asm.Type; public class SymbolicObserver extends ExecutionObserver { private static final String INIT = "<init>"; private final SymbolicEnvironment env; public SymbolicObserver(SymbolicEnvironment env) { this.env = env; } @Override public void output(int position, String output) { // TODO Auto-generated method stub } private void before(ConstructorStatement stmt, Scope scope) { String className = stmt.getConstructor().getDeclaringClass().getName(); VM.NEW(className); VM.DUP(); String desc = Type.getConstructorDescriptor(stmt.getConstructor().getConstructor()); pushParameterList(stmt.getParameterReferences(), scope, desc); String owner = className.replace('.', '/'); /* indicates if the following code is instrumented or not */ VM.INVOKESPECIAL(owner, INIT, desc); boolean needThis = true; call_vm_caller_stack_params(needThis, stmt.getParameterReferences(), scope, desc); } private void after(ConstructorStatement stmt, Scope scope) { String className = stmt.getConstructor().getDeclaringClass().getName(); String desc = Type.getConstructorDescriptor(stmt.getConstructor().getConstructor()); /* pops operands if previous code was not instrumented */ // constructor return type is always VOID String onwer = className.replace('.', '/'); VM.CALL_RESULT(onwer, INIT, desc); VariableReference varRef = stmt.getReturnValue(); ReferenceConstant nonNullRef = (ReferenceConstant) env.topFrame().operandStack.popRef(); String varName = varRef.getName(); symb_references.put(varName, nonNullRef); } @Override public void beforeStatement(Statement s, Scope scope) { if (VM.getInstance().isStopped()) { return; } VM.enableCallBacks(); try { if (env.isEmpty()) { env.prepareStack(null); } if (s instanceof NullStatement) { before((NullStatement) s, scope); } else if (s instanceof AssignmentStatement) { before((AssignmentStatement) s, scope); } else if (s instanceof EnumPrimitiveStatement<?>) { before((EnumPrimitiveStatement<?>) s, scope); } else if (s instanceof ArrayStatement) { before((ArrayStatement) s, scope); } else if (s instanceof FieldStatement) { before((FieldStatement) s, scope); } else if (s instanceof ConstructorStatement) { before((ConstructorStatement) s, scope); } else if (s instanceof MethodStatement) { before((MethodStatement) s, scope); } else if (s instanceof FunctionalMockStatement) { before((FunctionalMockStatement) s, scope); } /* primitive statements */ else if (s instanceof BooleanPrimitiveStatement) { before((BooleanPrimitiveStatement) s, scope); } else if (s instanceof BytePrimitiveStatement) { before((BytePrimitiveStatement) s, scope); } else if (s instanceof CharPrimitiveStatement) { before((CharPrimitiveStatement) s, scope); } else if (s instanceof DoublePrimitiveStatement) { before((DoublePrimitiveStatement) s, scope); } else if (s instanceof FloatPrimitiveStatement) { before((FloatPrimitiveStatement) s, scope); } else if (s instanceof IntPrimitiveStatement) { before((IntPrimitiveStatement) s, scope); } else if (s instanceof LongPrimitiveStatement) { before((LongPrimitiveStatement) s, scope); } else if (s instanceof ShortPrimitiveStatement) { before((ShortPrimitiveStatement) s, scope); } else if (s instanceof StringPrimitiveStatement) { before((StringPrimitiveStatement) s, scope); } else if (s instanceof ClassPrimitiveStatement) { before((ClassPrimitiveStatement) s, scope); } else if (s instanceof FileNamePrimitiveStatement) { before((FileNamePrimitiveStatement) s, scope); } else if (s instanceof LocalAddressPrimitiveStatement) { before((LocalAddressPrimitiveStatement) s, scope); } else if (s instanceof RemoteAddressPrimitiveStatement) { before((RemoteAddressPrimitiveStatement) s, scope); } else if (s instanceof UrlPrimitiveStatement) { before((UrlPrimitiveStatement) s, scope); } else if (s instanceof PrimitiveExpression) { before((PrimitiveExpression) s, scope); } else { throw new UnsupportedOperationException("Cannot handle statement of type " + s.getClass()); } } catch (Throwable t) { throw new EvosuiteError(t); } } private void before(PrimitiveExpression s, Scope scope) { // TODO Auto-generated method stub throw new UnsupportedOperationException("This method should be implemented!"); } private void before(ClassPrimitiveStatement s, Scope scope) { /* do nothing */ } private static final int COMPONENT_TYPE_BOOLEAN = 4; private static final int COMPONENT_TYPE_CHAR = 5; private static final int COMPONENT_TYPE_FLOAT = 6; private static final int COMPONENT_TYPE_DOUBLE = 7; private static final int COMPONENT_TYPE_BYTE = 8; private static final int COMPONENT_TYPE_SHORT = 9; private static final int COMPONENT_TYPE_INT = 10; private static final int COMPONENT_TYPE_LONG = 11; private void after(ArrayStatement s, Scope scope) { try { ArrayReference arrayRef = (ArrayReference) s.getReturnValue(); Object conc_array; conc_array = arrayRef.getObject(scope); if (arrayRef.getArrayDimensions() == 1) { int length = arrayRef.getArrayLength(); IntegerConstant lengthExpr = ExpressionFactory.buildNewIntegerConstant(length); Class<?> component_class = arrayRef.getComponentClass(); env.topFrame().operandStack.pushBv32(lengthExpr); if (component_class.equals(int.class)) { VM.NEWARRAY(length, COMPONENT_TYPE_INT); } else if (component_class.equals(char.class)) { VM.NEWARRAY(length, COMPONENT_TYPE_CHAR); } else if (component_class.equals(short.class)) { VM.NEWARRAY(length, COMPONENT_TYPE_SHORT); } else if (component_class.equals(byte.class)) { VM.NEWARRAY(length, COMPONENT_TYPE_BYTE); } else if (component_class.equals(float.class)) { VM.NEWARRAY(length, COMPONENT_TYPE_FLOAT); } else if (component_class.equals(long.class)) { VM.NEWARRAY(length, COMPONENT_TYPE_LONG); } else if (component_class.equals(boolean.class)) { VM.NEWARRAY(length, COMPONENT_TYPE_BOOLEAN); } else if (component_class.equals(double.class)) { VM.NEWARRAY(length, COMPONENT_TYPE_DOUBLE); } else { // push arguments String componentTypeName = component_class.getName().replace('.', '/'); VM.ANEWARRAY(length, componentTypeName); } } else { // push dimensions List<Integer> dimensions = arrayRef.getLengths(); for (int i = 0; i < arrayRef.getArrayDimensions(); i++) { int length = dimensions.get(i); IntegerConstant lengthExpr = ExpressionFactory.buildNewIntegerConstant(length); env.topFrame().operandStack.pushBv32(lengthExpr); } String arrayTypeDesc = Type.getDescriptor(conc_array.getClass()); VM.MULTIANEWARRAY(arrayTypeDesc, arrayRef.getArrayDimensions()); } ReferenceConstant symb_array = (ReferenceConstant) env.topFrame().operandStack.popRef(); env.heap.initializeReference(conc_array, symb_array); String varRef_name = arrayRef.getName(); symb_references.put(varRef_name, symb_array); } catch (CodeUnderTestException e) { throw new RuntimeException(e); } } private void before(EnumPrimitiveStatement<?> s, Scope scope) { /* do nothing */ } private void before(NullStatement s, Scope scope) { /* do nothing */ } private void before(FieldStatement s, Scope scope) { /* do nothing */ } private static class ReferenceExpressionPair { private final ReferenceExpression ref; private final Expression<?> expr; public ReferenceExpressionPair(ReferenceExpression ref, Expression<?> expr) { this.ref = ref; this.expr = expr; } public ReferenceExpression getReference() { return ref; } public Expression<?> getExpression() { return expr; } } private void after(AssignmentStatement s, Scope scope) { VariableReference lhs = s.getReturnValue(); VariableReference rhs = s.getValue(); ReferenceExpressionPair readResult = read(rhs, scope); if (lhs instanceof FieldReference) { writeField((FieldReference) lhs, readResult, scope); } else if (lhs instanceof ArrayIndex) { writeArray((ArrayIndex) lhs, readResult, scope); } else { writeVariable(lhs, readResult); } } private ReferenceExpressionPair read(VariableReference rhs, Scope scope) { if (rhs instanceof FieldReference) { return readField((FieldReference) rhs, scope); } else if (rhs instanceof ArrayIndex) { return readArray((ArrayIndex) rhs, scope); } else { return readVariable(rhs, scope); } } /** * Reads a VariableReference from the stored symbolic references and * symbolic expressions. * * @throws IllegalArgumentException * if no value was found * * @param rhs * @param scope * @return */ private ReferenceExpressionPair readVariable(VariableReference rhs, Scope scope) { String rhs_name = rhs.getName(); ReferenceExpression symb_ref = symb_references.get(rhs_name); Expression<?> symb_expr = symb_expressions.get(rhs_name); return new ReferenceExpressionPair(symb_ref, symb_expr); } private ReferenceExpressionPair readArray(ArrayIndex rhs, Scope scope) { ArrayReference arrayReference = rhs.getArray(); ReferenceConstant symb_array = (ReferenceConstant) symb_references.get(arrayReference.getName()); int conc_index = rhs.getArrayIndex(); Class<?> componentClass = arrayReference.getComponentClass(); try { Object conc_array = arrayReference.getObject(scope); if (componentClass.equals(int.class)) { int conc_value = Array.getInt(conc_array, conc_index); IntegerValue expr = env.heap.array_load(symb_array, conc_index, conc_value); ReferenceConstant newIntegerRef = newIntegerReference(conc_value, expr); return new ReferenceExpressionPair(newIntegerRef, expr); } else if (componentClass.equals(char.class)) { char conc_value = Array.getChar(conc_array, conc_index); IntegerValue expr = env.heap.array_load(symb_array, conc_index, conc_value); ReferenceConstant newCharacterRef = newCharacterReference(conc_value, expr); return new ReferenceExpressionPair(newCharacterRef, expr); } else if (componentClass.equals(boolean.class)) { boolean conc_value = Array.getBoolean(conc_array, conc_index); IntegerValue expr = env.heap.array_load(symb_array, conc_index, conc_value ? 1 : 0); ReferenceConstant newBooleanRef = newBooleanReference(conc_value, expr); return new ReferenceExpressionPair(newBooleanRef, expr); } else if (componentClass.equals(byte.class)) { byte conc_value = Array.getByte(conc_array, conc_index); IntegerValue expr = env.heap.array_load(symb_array, conc_index, conc_value); ReferenceConstant newByteRef = newByteReference(conc_value, expr); return new ReferenceExpressionPair(newByteRef, expr); } else if (componentClass.equals(short.class)) { short conc_value = Array.getShort(conc_array, conc_index); IntegerValue expr = env.heap.array_load(symb_array, conc_index, conc_value); ReferenceConstant newShortRef = newShortReference(conc_value, expr); return new ReferenceExpressionPair(newShortRef, expr); } else if (componentClass.equals(long.class)) { long conc_value = Array.getLong(conc_array, conc_index); IntegerValue expr = env.heap.array_load(symb_array, conc_index, conc_value); ReferenceConstant newLongRef = newLongReference(conc_value, expr); return new ReferenceExpressionPair(newLongRef, expr); } else if (componentClass.equals(float.class)) { float conc_value = Array.getFloat(conc_array, conc_index); RealValue expr = env.heap.array_load(symb_array, conc_index, conc_value); ReferenceConstant newFloatRef = newFloatReference(conc_value, expr); return new ReferenceExpressionPair(newFloatRef, expr); } else if (componentClass.equals(double.class)) { double conc_value = Array.getDouble(conc_array, conc_index); RealValue expr = env.heap.array_load(symb_array, conc_index, conc_value); ReferenceConstant newDoubleRef = newDoubleReference(conc_value, expr); return new ReferenceExpressionPair(newDoubleRef, expr); } else { Object conc_value = Array.get(conc_array, conc_index); if (conc_value instanceof String) { StringValue expr = env.heap.array_load(symb_array, conc_index, (String) conc_value); ReferenceConstant newStringRef = newStringReference((String) conc_value, expr); return new ReferenceExpressionPair(newStringRef, expr); } else { ReferenceExpression ref = env.heap.getReference(conc_value); if (conc_value != null && isWrapper(conc_value)) { ReferenceConstant nonNullRef = (ReferenceConstant) ref; Expression<?> expr = findOrCreate(conc_value, nonNullRef); return new ReferenceExpressionPair(ref, expr); } else { return new ReferenceExpressionPair(ref, null); } } } } catch (CodeUnderTestException e) { throw new RuntimeException(e); } } private ReferenceExpressionPair readField(FieldReference rhs, Scope scope) { if (rhs.getSource() != null) { /* instance field */ return readInstanceField(rhs.getSource(), rhs.getField().getField(), scope); } else { /* static field */ return readStaticField(rhs.getField().getField()); } } private ReferenceExpressionPair readStaticField(Field field) { String owner = field.getDeclaringClass().getName().replace('.', '/'); String name = field.getName(); Class<?> fieldClazz = field.getType(); try { if (fieldClazz.equals(int.class)) { int conc_value = field.getInt(null); IntegerValue expr = env.heap.getStaticField(owner, name, conc_value); ReferenceConstant newIntegerRef = newIntegerReference(conc_value, expr); return new ReferenceExpressionPair(newIntegerRef, expr); } else if (fieldClazz.equals(char.class)) { char conc_value = field.getChar(null); IntegerValue expr = env.heap.getStaticField(owner, name, conc_value); ReferenceConstant newCharacterRef = newCharacterReference(conc_value, expr); return new ReferenceExpressionPair(newCharacterRef, expr); } else if (fieldClazz.equals(long.class)) { long conc_value = field.getLong(null); IntegerValue expr = env.heap.getStaticField(owner, name, conc_value); ReferenceConstant newLongRef = newLongReference(conc_value, expr); return new ReferenceExpressionPair(newLongRef, expr); } else if (fieldClazz.equals(short.class)) { short conc_value = field.getShort(null); IntegerValue expr = env.heap.getStaticField(owner, name, conc_value); ReferenceConstant newShortRef = newShortReference(conc_value, expr); return new ReferenceExpressionPair(newShortRef, expr); } else if (fieldClazz.equals(byte.class)) { byte conc_value = field.getByte(null); IntegerValue expr = env.heap.getStaticField(owner, name, conc_value); ReferenceConstant newByteRef = newByteReference(conc_value, expr); return new ReferenceExpressionPair(newByteRef, expr); } else if (fieldClazz.equals(boolean.class)) { boolean conc_value = field.getBoolean(null); IntegerValue expr = env.heap.getStaticField(owner, name, conc_value ? 1 : 0); ReferenceConstant newBooleanRef = newBooleanReference(conc_value, expr); return new ReferenceExpressionPair(newBooleanRef, expr); } else if (fieldClazz.equals(float.class)) { float conc_value = field.getFloat(null); RealValue expr = env.heap.getStaticField(owner, name, conc_value); ReferenceConstant newFloatRef = newFloatReference(conc_value, expr); return new ReferenceExpressionPair(newFloatRef, expr); } else if (fieldClazz.equals(double.class)) { double conc_value = field.getDouble(null); RealValue expr = env.heap.getStaticField(owner, name, conc_value); ReferenceConstant newDoubleRef = newDoubleReference(conc_value, expr); return new ReferenceExpressionPair(newDoubleRef, expr); } else { Object conc_value = field.get(null); if (conc_value instanceof String) { String string = (String) conc_value; StringValue expr = env.heap.getStaticField(owner, name, string); ReferenceConstant newStringRef = newStringReference(string, expr); return new ReferenceExpressionPair(newStringRef, expr); } else { ReferenceExpression ref = env.heap.getReference(conc_value); if (conc_value != null && isWrapper(conc_value)) { ReferenceConstant nonNullRef = (ReferenceConstant) ref; Expression<?> expr = findOrCreate(conc_value, nonNullRef); return new ReferenceExpressionPair(ref, expr); } else { return new ReferenceExpressionPair(ref, null); } } } } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } private ReferenceExpressionPair readInstanceField(VariableReference source, Field field, Scope scope) { String owner = field.getDeclaringClass().getName().replace('.', '/'); String name = field.getName(); Class<?> fieldClazz = field.getType(); String source_name = source.getName(); ReferenceConstant symb_receiver = (ReferenceConstant) symb_references.get(source_name); try { Object conc_receiver = source.getObject(scope); if (fieldClazz.equals(int.class)) { int conc_value = field.getInt(conc_receiver); IntegerValue expr = env.heap.getField(owner, name, conc_receiver, symb_receiver, conc_value); ReferenceConstant newIntegerRef = newIntegerReference(conc_value, expr); return new ReferenceExpressionPair(newIntegerRef, expr); } else if (fieldClazz.equals(char.class)) { char conc_value = field.getChar(conc_receiver); IntegerValue expr = env.heap.getField(owner, name, conc_receiver, symb_receiver, conc_value); ReferenceConstant newCharacterRef = newCharacterReference(conc_value, expr); return new ReferenceExpressionPair(newCharacterRef, expr); } else if (fieldClazz.equals(long.class)) { long conc_value = field.getLong(conc_receiver); IntegerValue expr = env.heap.getField(owner, name, conc_receiver, symb_receiver, conc_value); ReferenceConstant newLongRef = newLongReference(conc_value, expr); return new ReferenceExpressionPair(newLongRef, expr); } else if (fieldClazz.equals(short.class)) { short conc_value = field.getShort(conc_receiver); IntegerValue expr = env.heap.getField(owner, name, conc_receiver, symb_receiver, conc_value); ReferenceConstant newShortRef = newShortReference(conc_value, expr); return new ReferenceExpressionPair(newShortRef, expr); } else if (fieldClazz.equals(byte.class)) { byte conc_value = field.getByte(conc_receiver); IntegerValue expr = env.heap.getField(owner, name, conc_receiver, symb_receiver, conc_value); ReferenceConstant newByteRef = newByteReference(conc_value, expr); return new ReferenceExpressionPair(newByteRef, expr); } else if (fieldClazz.equals(boolean.class)) { boolean conc_value = field.getBoolean(conc_receiver); IntegerValue expr = env.heap.getField(owner, name, conc_receiver, symb_receiver, conc_value ? 1 : 0); ReferenceConstant newBooleanRef = newBooleanReference(conc_value, expr); return new ReferenceExpressionPair(newBooleanRef, expr); } else if (fieldClazz.equals(float.class)) { float conc_value = field.getFloat(conc_receiver); RealValue expr = env.heap.getField(owner, name, conc_receiver, symb_receiver, conc_value); ReferenceConstant newFloatRef = newFloatReference(conc_value, expr); return new ReferenceExpressionPair(newFloatRef, expr); } else if (fieldClazz.equals(double.class)) { double conc_value = field.getDouble(conc_receiver); RealValue expr = env.heap.getField(owner, name, conc_receiver, symb_receiver, conc_value); ReferenceConstant newDoubleRef = newDoubleReference(conc_value, expr); return new ReferenceExpressionPair(newDoubleRef, expr); } else { Object conc_value = field.get(conc_receiver); if (conc_value instanceof String) { String string = (String) conc_value; StringValue expr = env.heap.getField(owner, name, conc_receiver, symb_receiver, string); ReferenceConstant newStringRef = newStringReference(string, expr); return new ReferenceExpressionPair(newStringRef, expr); } else { ReferenceExpression ref = env.heap.getReference(conc_value); if (conc_value != null && isWrapper(conc_value)) { ReferenceConstant nonNullRef = (ReferenceConstant) ref; Expression<?> expr = findOrCreate(conc_value, nonNullRef); return new ReferenceExpressionPair(ref, expr); } else { return new ReferenceExpressionPair(ref, null); } } } } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (CodeUnderTestException e) { throw new RuntimeException(e); } } private void before(AssignmentStatement s, Scope scope) { /* do nothing */ } private void writeVariable(VariableReference lhs, ReferenceExpressionPair readResult) { String lhs_name = lhs.getName(); Expression<?> expr = readResult.getExpression(); if (expr != null) symb_expressions.put(lhs_name, expr); ReferenceExpression ref = readResult.getReference(); if (ref != null) symb_references.put(lhs_name, ref); } private void writeArray(ArrayIndex lhs, ReferenceExpressionPair readResult, Scope scope) { ArrayReference arrayReference = lhs.getArray(); int conc_index = lhs.getArrayIndex(); Object conc_array; try { conc_array = arrayReference.getObject(scope); } catch (CodeUnderTestException e) { throw new EvosuiteError(e); } Type arrayType = Type.getType(conc_array.getClass()); Type elementType = arrayType.getElementType(); if (isValue(elementType) || elementType.equals(Type.getType(String.class))) { Expression<?> symb_value = readResult.getExpression(); symb_value = castIfNeeded(elementType, symb_value); String array_name = arrayReference.getName(); ReferenceExpression symb_ref = symb_references.get(array_name); ReferenceConstant symb_array = (ReferenceConstant) symb_ref; env.heap.array_store(conc_array, symb_array, conc_index, symb_value); } else { /* ignore storing references (we use objects to find them) */ } } private Expression<?> castIfNeeded(Type elementType, Expression<?> symb_value) { // cast integer to real if needed if ((isFp32(elementType) || isFp64(elementType)) && symb_value instanceof IntegerValue) { IntegerValue intExpr = (IntegerValue) symb_value; double concValue = intExpr.getConcreteValue().doubleValue(); symb_value = new IntegerToRealCast(intExpr, concValue); } else if ((isBv32(elementType) || isBv64(elementType)) && symb_value instanceof RealValue) { RealValue realExpr = (RealValue) symb_value; long concValue = realExpr.getConcreteValue().longValue(); symb_value = new RealToIntegerCast(realExpr, concValue); } return symb_value; } private void writeField(FieldReference lhs, ReferenceExpressionPair readResult, Scope scope) { Field field = lhs.getField().getField(); String className = field.getDeclaringClass().getName().replace('.', '/'); String fieldName = field.getName(); Class<?> fieldClass = field.getType(); Type fieldType = Type.getType(fieldClass); if (isValue(fieldType) || fieldType.equals(Type.getType(String.class))) { Expression<?> symb_value = readResult.getExpression(); symb_value = castIfNeeded(fieldType, symb_value); VariableReference source = lhs.getSource(); if (source != null) { /* write symbolic expression to instance field */ String source_name = source.getName(); Object conc_receiver; try { conc_receiver = source.getObject(scope); } catch (CodeUnderTestException e) { throw new RuntimeException(e); } ReferenceConstant symb_receiver = (ReferenceConstant) symb_references.get(source_name); env.heap.putField(className, fieldName, conc_receiver, symb_receiver, symb_value); } else { /* write symbolic expression to static field */ env.heap.putStaticField(className, fieldName, symb_value); } } else { /* * ignore writing of references (DSE does not store Reference * fields) */ } } private void before(ShortPrimitiveStatement statement, Scope scope) { /* do nothing */ } private void before(LongPrimitiveStatement statement, Scope scope) { /* do nothing */ } private void before(FloatPrimitiveStatement statement, Scope scope) { /* do nothing */ } private void before(CharPrimitiveStatement statement, Scope scope) { /* do nothing */ } private void before(BytePrimitiveStatement statement, Scope scope) { /* do nothing */ } private void before(BooleanPrimitiveStatement statement, Scope scope) { /* do nothing */ } private void before(DoublePrimitiveStatement statement, Scope scope) { /* do nothing */ } private void before(MethodStatement statement, Scope scope) { Method method = statement.getMethod().getMethod(); String owner = method.getDeclaringClass().getName().replace('.', '/'); String name = method.getName(); String desc = Type.getMethodDescriptor(method); boolean needThis = statement.getCallee() != null; if (needThis) { VariableReference callee = statement.getCallee(); ReferenceExpressionPair refExprPair = read(callee, scope); ReferenceExpression ref = refExprPair.getReference(); this.env.topFrame().operandStack.pushRef(ref); } List<VariableReference> parameters = statement.getParameterReferences(); pushParameterList(parameters, scope, desc); if (needThis) { VariableReference callee = statement.getCallee(); Object receiver; try { receiver = callee.getObject(scope); } catch (CodeUnderTestException e) { throw new RuntimeException(e); } Class<?> ownerClass = env.ensurePrepared(owner); if (ownerClass.isInterface()) { VM.INVOKEINTERFACE(receiver, owner, name, desc); } else { VM.INVOKEVIRTUAL(receiver, owner, name, desc); } } else { VM.INVOKESTATIC(owner, name, desc); } call_vm_caller_stack_params(needThis, parameters, scope, desc); } private void call_vm_caller_stack_params(boolean needThis, List<VariableReference> parameters, Scope scope, String desc) { int calleeLocalsIndex = 0; if (needThis) calleeLocalsIndex++; for (int i = 0; i < parameters.size(); i++) { VariableReference p = parameters.get(i); calleeLocalsIndex += getSize(p.getType()); } Type[] argTypes = Type.getArgumentTypes(desc); for (int i = parameters.size() - 1; i >= 0; i--) { Type argType = argTypes[i]; VariableReference p = parameters.get(i); try { Object param_object = p.getObject(scope); calleeLocalsIndex -= getSize(p.getType()); if (argType.equals(Type.INT_TYPE)) { int intValue = getIntValue(param_object); VM.CALLER_STACK_PARAM(intValue, i, calleeLocalsIndex); } else if (argType.equals(Type.CHAR_TYPE)) { char charValue = getCharValue(param_object); VM.CALLER_STACK_PARAM(charValue, i, calleeLocalsIndex); } else if (argType.equals(Type.BYTE_TYPE)) { byte byteValue = getByteValue(param_object); VM.CALLER_STACK_PARAM(byteValue, i, calleeLocalsIndex); } else if (argType.equals(Type.BOOLEAN_TYPE)) { boolean booleanValue = getBooleanValue(param_object); VM.CALLER_STACK_PARAM(booleanValue, i, calleeLocalsIndex); } else if (argType.equals(Type.SHORT_TYPE)) { short shortValue = getShortValue(param_object); VM.CALLER_STACK_PARAM(shortValue, i, calleeLocalsIndex); } else if (argType.equals(Type.LONG_TYPE)) { long longValue = getLongValue(param_object); VM.CALLER_STACK_PARAM(longValue, i, calleeLocalsIndex); } else if (argType.equals(Type.FLOAT_TYPE)) { float floatValue = getFloatValue(param_object); VM.CALLER_STACK_PARAM(floatValue, i, calleeLocalsIndex); } else if (argType.equals(Type.DOUBLE_TYPE)) { double doubleValue = getDoubleValue(param_object); VM.CALLER_STACK_PARAM(doubleValue, i, calleeLocalsIndex); } else { VM.CALLER_STACK_PARAM(param_object, i, calleeLocalsIndex); } } catch (CodeUnderTestException e) { throw new RuntimeException(e); } } } private static double getDoubleValue(Object o) { if (o == null) { return 0; } if (o instanceof Boolean) { return ((Boolean) o).booleanValue() ? 1 : 0; } else if (o instanceof Short) { return ((Short) o).shortValue(); } else if (o instanceof Byte) { return ((Byte) o).byteValue(); } else if (o instanceof Character) { return ((Character) o).charValue(); } else if (o instanceof Integer) { return ((Integer) o).intValue(); } else if (o instanceof Long) { return ((Long) o).longValue(); } else if (o instanceof Float) { return ((Float) o).floatValue(); } else if (o instanceof Double) { return ((Double) o).doubleValue(); } else { throw new EvosuiteError("Unreachable code!"); } } private static float getFloatValue(Object o) { if (o == null) { return 0; } if (o instanceof Boolean) { return ((Boolean) o).booleanValue() ? 1 : 0; } else if (o instanceof Short) { return ((Short) o).shortValue(); } else if (o instanceof Byte) { return ((Byte) o).byteValue(); } else if (o instanceof Character) { return ((Character) o).charValue(); } else if (o instanceof Integer) { return ((Integer) o).intValue(); } else if (o instanceof Long) { return ((Long) o).longValue(); } else if (o instanceof Float) { return ((Float) o).floatValue(); } else if (o instanceof Double) { return (float) ((Double) o).doubleValue(); } else { throw new EvosuiteError("Unreachable code!"); } } private static long getLongValue(Object o) { if (o == null) { return 0; } if (o instanceof Boolean) { return ((Boolean) o).booleanValue() ? 1 : 0; } else if (o instanceof Short) { return ((Short) o).shortValue(); } else if (o instanceof Byte) { return ((Byte) o).byteValue(); } else if (o instanceof Character) { return ((Character) o).charValue(); } else if (o instanceof Integer) { return ((Integer) o).intValue(); } else if (o instanceof Long) { return ((Long) o).longValue(); } else if (o instanceof Float) { return (long) ((Float) o).floatValue(); } else if (o instanceof Double) { return (long) ((Double) o).doubleValue(); } else { throw new EvosuiteError("Unreachable code!"); } } private static int getIntValue(Object o) { if (o == null) { return 0; } if (o instanceof Boolean) { return ((Boolean) o).booleanValue() ? 1 : 0; } else if (o instanceof Short) { return ((Short) o).shortValue(); } else if (o instanceof Byte) { return ((Byte) o).byteValue(); } else if (o instanceof Character) { return ((Character) o).charValue(); } else if (o instanceof Integer) { return ((Integer) o).intValue(); } else if (o instanceof Long) { return (int) ((Long) o).longValue(); } else if (o instanceof Float) { return (int) ((Float) o).floatValue(); } else if (o instanceof Double) { return (int) ((Double) o).doubleValue(); } else { throw new EvosuiteError("Unreachable code!"); } } private static short getShortValue(Object o) { if (o == null) { return 0; } if (o instanceof Boolean) { return (short) (((Boolean) o).booleanValue() ? 1 : 0); } else if (o instanceof Short) { return ((Short) o).shortValue(); } else if (o instanceof Byte) { return ((Byte) o).byteValue(); } else if (o instanceof Character) { return (short) ((Character) o).charValue(); } else if (o instanceof Integer) { return (short) ((Integer) o).intValue(); } else if (o instanceof Long) { return (short) ((Long) o).longValue(); } else if (o instanceof Float) { return (short) ((Float) o).floatValue(); } else if (o instanceof Double) { return (short) ((Double) o).doubleValue(); } else { throw new EvosuiteError("Unreachable code!"); } } private static byte getByteValue(Object o) { if (o == null) { return 0; } if (o instanceof Boolean) { return (byte) (((Boolean) o).booleanValue() ? 1 : 0); } else if (o instanceof Short) { return (byte) ((Short) o).shortValue(); } else if (o instanceof Byte) { return ((Byte) o).byteValue(); } else if (o instanceof Character) { return (byte) ((Character) o).charValue(); } else if (o instanceof Integer) { return (byte) ((Integer) o).intValue(); } else if (o instanceof Long) { return (byte) ((Long) o).longValue(); } else if (o instanceof Float) { return (byte) ((Float) o).floatValue(); } else if (o instanceof Double) { return (byte) ((Double) o).doubleValue(); } else { throw new EvosuiteError("Unreachable code!"); } } private static char getCharValue(Object o) { if (o == null) { return 0; } if (o instanceof Boolean) { return (char) (((Boolean) o).booleanValue() ? 1 : 0); } else if (o instanceof Short) { return (char) ((Short) o).shortValue(); } else if (o instanceof Byte) { return (char) ((Byte) o).byteValue(); } else if (o instanceof Character) { return ((Character) o).charValue(); } else if (o instanceof Integer) { return (char) ((Integer) o).intValue(); } else if (o instanceof Long) { return (char) ((Long) o).longValue(); } else if (o instanceof Float) { return (char) ((Float) o).floatValue(); } else if (o instanceof Double) { return (char) ((Double) o).doubleValue(); } else { throw new EvosuiteError("Unreachable code!"); } } private static boolean getBooleanValue(Object o) { if (o == null) { return false; } if (o instanceof Boolean) { return ((Boolean) o).booleanValue(); } else if (o instanceof Short) { return ((Short) o).shortValue() == 1; } else if (o instanceof Byte) { return ((Byte) o).byteValue() == 1; } else if (o instanceof Character) { return ((Character) o).charValue() == 1; } else if (o instanceof Integer) { return ((Integer) o).intValue() == 1; } else if (o instanceof Long) { return ((Long) o).longValue() == 1; } else if (o instanceof Float) { return ((Float) o).floatValue() == 1; } else if (o instanceof Double) { return ((Double) o).doubleValue() == 1; } else { throw new EvosuiteError("Unreachable code!"); } } private int getSize(java.lang.reflect.Type type) { if (type.equals(double.class)) return 2; else if (type.equals(long.class)) return 2; else return 1; } private void pushParameterList(List<VariableReference> parameters, Scope scope, String desc) { Type[] argTypes = Type.getArgumentTypes(desc); for (int i = 0; i < parameters.size(); i++) { VariableReference varRef = parameters.get(i); Type argType = argTypes[i]; ReferenceExpressionPair readResult = this.read(varRef, scope); Expression<?> symb_expr = readResult.getExpression(); ReferenceExpression symb_ref = readResult.getReference(); if (isValue(argType)) { if (symb_expr instanceof RealValue) { RealValue realExpr = (RealValue) symb_expr; if (isFp32(argType)) { env.topFrame().operandStack.pushFp32(realExpr); } else if (isFp64(argType)) { env.topFrame().operandStack.pushFp64(realExpr); } else if (isBv32(argType)) { int concV = realExpr.getConcreteValue().intValue(); RealToIntegerCast castExpr = new RealToIntegerCast(realExpr, (long) concV); env.topFrame().operandStack.pushBv32(castExpr); } else if (isBv64(argType)) { long concV = realExpr.getConcreteValue().longValue(); RealToIntegerCast castExpr = new RealToIntegerCast(realExpr, concV); env.topFrame().operandStack.pushBv64(castExpr); } else { /* unreachable code */ } } else if (symb_expr instanceof IntegerValue) { IntegerValue integerExpr = (IntegerValue) symb_expr; if (isBv32(argType)) { env.topFrame().operandStack.pushBv32(integerExpr); } else if (isBv64(argType)) { env.topFrame().operandStack.pushBv64(integerExpr); } else if (isFp32(argType)) { float concV = integerExpr.getConcreteValue().floatValue(); IntegerToRealCast castExpr = new IntegerToRealCast(integerExpr, (double) concV); env.topFrame().operandStack.pushFp32(castExpr); } else if (isFp64(argType)) { double concV = integerExpr.getConcreteValue().doubleValue(); IntegerToRealCast castExpr = new IntegerToRealCast(integerExpr, concV); env.topFrame().operandStack.pushFp64(castExpr); } else { /* unreachable code */ } } else { if (symb_ref.getConcreteValue() == null) { // although this will lead in the JVM to a NPE, we push // a dummy // value to prevent the DSE VM from crashing pushDummyValue(argType); } else { // auto unboxing reference ReferenceConstant non_null_symb_ref = (ReferenceConstant) symb_ref; Object conc_object = scope.getObject(varRef); Expression<?> unboxed_expr = unboxReference(argType, conc_object, non_null_symb_ref); pushValue(argType, unboxed_expr); } } } else { ReferenceExpression ref = readResult.getReference(); env.topFrame().operandStack.pushRef(ref); } } } private Expression<?> unboxReference(Type argType, Object conc_object, ReferenceConstant non_null_symb_ref) { switch (argType.getSort()) { case Type.BOOLEAN: { Expression<?> symb_expr = env.heap.getField(Types.JAVA_LANG_BOOLEAN, SymbolicHeap.$BOOLEAN_VALUE, conc_object, non_null_symb_ref); return symb_expr; } case Type.BYTE: { Expression<?> symb_expr = env.heap.getField(Types.JAVA_LANG_BYTE, SymbolicHeap.$BYTE_VALUE, conc_object, non_null_symb_ref); return symb_expr; } case Type.CHAR: { Expression<?> symb_expr = env.heap.getField(Types.JAVA_LANG_CHARACTER, SymbolicHeap.$CHAR_VALUE, conc_object, non_null_symb_ref); return symb_expr; } case Type.DOUBLE: { Expression<?> symb_expr = env.heap.getField(Types.JAVA_LANG_DOUBLE, SymbolicHeap.$DOUBLE_VALUE, conc_object, non_null_symb_ref); return symb_expr; } case Type.FLOAT: { Expression<?> symb_expr = env.heap.getField(Types.JAVA_LANG_FLOAT, SymbolicHeap.$FLOAT_VALUE, conc_object, non_null_symb_ref); return symb_expr; } case Type.INT: { Expression<?> symb_expr = env.heap.getField(Types.JAVA_LANG_INTEGER, SymbolicHeap.$INT_VALUE, conc_object, non_null_symb_ref); return symb_expr; } case Type.LONG: { Expression<?> symb_expr = env.heap.getField(Types.JAVA_LANG_LONG, SymbolicHeap.$LONG_VALUE, conc_object, non_null_symb_ref); return symb_expr; } case Type.SHORT: { Expression<?> symb_expr = env.heap.getField(Types.JAVA_LANG_SHORT, SymbolicHeap.$SHORT_VALUE, conc_object, non_null_symb_ref); return symb_expr; } default: { throw new EvosuiteError(argType.toString() + " cannot be automatically unboxed"); } } } private void pushValue(Type argType, Expression<?> symb_expr) { if (isBv32(argType)) { IntegerValue booleanExpr = (IntegerValue) symb_expr; env.topFrame().operandStack.pushBv32(booleanExpr); } else if (isBv64(argType)) { IntegerValue longExpr = (IntegerValue) symb_expr; env.topFrame().operandStack.pushBv64(longExpr); } else if (isFp32(argType)) { RealValue realExpr = (RealValue) symb_expr; env.topFrame().operandStack.pushFp32(realExpr); } else if (isFp64(argType)) { RealValue realExpr = (RealValue) symb_expr; env.topFrame().operandStack.pushFp64(realExpr); } else { throw new EvosuiteError(argType.toString() + " is not a value type!"); } } private void pushDummyValue(Type argType) { if (isBv32(argType)) { IntegerValue integerExpr = ExpressionFactory.buildNewIntegerConstant(0); env.topFrame().operandStack.pushBv32(integerExpr); } else if (isBv64(argType)) { IntegerValue integerExpr = ExpressionFactory.buildNewIntegerConstant(0); env.topFrame().operandStack.pushBv64(integerExpr); } else if (isFp32(argType)) { RealValue realExpr = ExpressionFactory.buildNewRealConstant(0); env.topFrame().operandStack.pushFp32(realExpr); } else if (isFp64(argType)) { RealValue realExpr = ExpressionFactory.buildNewRealConstant(0); env.topFrame().operandStack.pushFp64(realExpr); } else { throw new EvosuiteError(argType.toString() + " is not a value type!"); } } private static boolean isValue(Type t) { return isBv32(t) || isBv64(t) || isFp32(t) || isFp64(t); } private static boolean isFp64(Type t) { return t.equals(Type.DOUBLE_TYPE); } private static boolean isFp32(Type t) { return t.equals(Type.FLOAT_TYPE); } private static boolean isBv64(Type t) { return t.equals(Type.LONG_TYPE); } private static boolean isBv32(Type t) { return t.equals(Type.CHAR_TYPE) || t.equals(Type.BOOLEAN_TYPE) || t.equals(Type.SHORT_TYPE) || t.equals(Type.BYTE_TYPE) || t.equals(Type.INT_TYPE); } /** * This method forbids using the same interning String in two separate * string primitive statements. * * @param statement * @param scope */ private void before(StringPrimitiveStatement statement, Scope scope) { /* do nothing */ } private void before(FileNamePrimitiveStatement statement, Scope scope) { /* do nothing */ } private void before(LocalAddressPrimitiveStatement statement, Scope scope) { /* do nothing */ } private void before(RemoteAddressPrimitiveStatement statement, Scope scope) { /* do nothing */ } private void before(UrlPrimitiveStatement statement, Scope scope) { /* do nothing */ } private void before(FunctionalMockStatement statement, Scope scope) { /* do nothing */ } private void before(IntPrimitiveStatement statement, Scope scope) { /* do nothing */ } @Override public void afterStatement(Statement s, Scope scope, Throwable exception) { if (exception != null) { return; } if (VM.getInstance().isStopped()) { return; } try { if (s instanceof NullStatement) { after((NullStatement) s, scope); } else if (s instanceof EnumPrimitiveStatement<?>) { after((EnumPrimitiveStatement<?>) s, scope); } else if (s instanceof ArrayStatement) { after((ArrayStatement) s, scope); } else if (s instanceof AssignmentStatement) { after((AssignmentStatement) s, scope); } else if (s instanceof FieldStatement) { after((FieldStatement) s, scope); } else if (s instanceof ConstructorStatement) { after((ConstructorStatement) s, scope); } /* primitive statements */ else if (s instanceof BooleanPrimitiveStatement) { after((BooleanPrimitiveStatement) s, scope); } else if (s instanceof MethodStatement) { after((MethodStatement) s, scope); } else if (s instanceof BytePrimitiveStatement) { after((BytePrimitiveStatement) s, scope); } else if (s instanceof CharPrimitiveStatement) { after((CharPrimitiveStatement) s, scope); } else if (s instanceof DoublePrimitiveStatement) { after((DoublePrimitiveStatement) s, scope); } else if (s instanceof FloatPrimitiveStatement) { after((FloatPrimitiveStatement) s, scope); } else if (s instanceof IntPrimitiveStatement) { after((IntPrimitiveStatement) s, scope); } else if (s instanceof LongPrimitiveStatement) { after((LongPrimitiveStatement) s, scope); } else if (s instanceof ShortPrimitiveStatement) { after((ShortPrimitiveStatement) s, scope); } else if (s instanceof StringPrimitiveStatement) { after((StringPrimitiveStatement) s, scope); } else if (s instanceof ClassPrimitiveStatement) { after((ClassPrimitiveStatement) s, scope); } else if (s instanceof FileNamePrimitiveStatement) { after((FileNamePrimitiveStatement) s, scope); } else if (s instanceof LocalAddressPrimitiveStatement) { after((LocalAddressPrimitiveStatement) s, scope); } else if (s instanceof RemoteAddressPrimitiveStatement) { after((RemoteAddressPrimitiveStatement) s, scope); } else if (s instanceof UrlPrimitiveStatement) { after((UrlPrimitiveStatement) s, scope); } else if (s instanceof PrimitiveExpression) { after((PrimitiveExpression) s, scope); } else if (s instanceof FunctionalMockStatement) { after((FunctionalMockStatement) s, scope); } else { throw new UnsupportedOperationException("Cannot handle statement of type " + s.getClass()); } } catch (Throwable t) { throw new EvosuiteError(t); } } private void after(UrlPrimitiveStatement s, Scope scope) { EvoSuiteURL conc_url = s.getValue(); VariableReference varRef = s.getReturnValue(); String varRefName = varRef.getName(); ReferenceExpression urlRef; if (conc_url == null) { urlRef = env.heap.getReference(null); if (urlRef.getConcreteValue() != null) { throw new IllegalStateException("Expected null concrete value"); } } else { urlRef = (ReferenceConstant) env.heap.getReference(conc_url); if (urlRef.getConcreteValue() == null) { throw new IllegalStateException("Expected non-null concrete value"); } } symb_references.put(varRefName, urlRef); } private void after(RemoteAddressPrimitiveStatement s, Scope scope) { EvoSuiteRemoteAddress conc_remote_address = s.getValue(); VariableReference varRef = s.getReturnValue(); String varRefName = varRef.getName(); ReferenceExpression addressRef; if (conc_remote_address == null) { addressRef = env.heap.getReference(null); if (addressRef.getConcreteValue() != null) { throw new IllegalStateException("Expected null concrete value"); } } else { addressRef = env.heap.getReference(conc_remote_address); if (addressRef.getConcreteValue() == null) { throw new IllegalStateException("Expected non-null concrete value"); } } symb_references.put(varRefName, addressRef); } private void after(LocalAddressPrimitiveStatement s, Scope scope) { EvoSuiteLocalAddress conc_local_address = s.getValue(); VariableReference varRef = s.getReturnValue(); String varRefName = varRef.getName(); ReferenceExpression addressRef; if (conc_local_address == null) { addressRef = env.heap.getReference(null); if (addressRef.getConcreteValue() != null) { throw new IllegalStateException("Expected null concrete object"); } } else { addressRef = env.heap.getReference(conc_local_address); if (addressRef.getConcreteValue() == null) { throw new IllegalStateException("Expected non-null concrete object"); } } symb_references.put(varRefName, addressRef); } private void after(PrimitiveExpression s, Scope scope) { // TODO Auto-generated method stub throw new UnsupportedOperationException("This method should be implemented!"); } private void after(ClassPrimitiveStatement s, Scope scope) { VariableReference varRef = s.getReturnValue(); Class<?> concrete_reference = s.getValue(); String varName = varRef.getName(); ReferenceExpression symb_ref = env.heap.getReference(concrete_reference); symb_references.put(varName, symb_ref); } private void before(ArrayStatement s, Scope scope) { /* do nothing */ } private void after(EnumPrimitiveStatement<?> s, Scope scope) { VariableReference varRef = s.getReturnValue(); String varName = varRef.getName(); Object conc_value = s.getValue(); ReferenceExpression symb_value = env.heap.getReference(conc_value); symb_references.put(varName, symb_value); } private void after(NullStatement s, Scope scope) { VariableReference lhs = s.getReturnValue(); String lhs_name = lhs.getName(); ReferenceExpression nullConstant = ExpressionFactory.buildNewNullExpression(); symb_references.put(lhs_name, nullConstant); } private void after(FunctionalMockStatement statement, Scope scope) { Type returnType = Type.getType(statement.getReturnClass()); VariableReference varRef = statement.getReturnValue(); String varName = varRef.getName(); try { if (varRef.getType().equals(void.class)) { } else if (returnType.equals(Type.INT_TYPE) || returnType.equals(Type.BOOLEAN_TYPE) || returnType.equals(Type.DOUBLE_TYPE) || returnType.equals(Type.FLOAT_TYPE) || returnType.equals(Type.LONG_TYPE) || returnType.equals(Type.SHORT_TYPE) || returnType.equals(Type.BYTE_TYPE) || returnType.equals(Type.CHAR_TYPE)) { throw new EvosuiteError("mocking of primitive types is not supported!"); } else { Object res = varRef.getObject(scope); ReferenceExpression ref = env.heap.getReference(res); if (res != null && res instanceof String) { String string = (String) res; ReferenceConstant newStringRef = (ReferenceConstant) env.heap.getReference(string); StringValue str_expr = env.heap.getField(Types.JAVA_LANG_STRING, SymbolicHeap.$STRING_VALUE, string, newStringRef, string); symb_references.put(varName, newStringRef); symb_expressions.put(varName, str_expr); } else { symb_references.put(varName, ref); if (res != null && isWrapper(res)) { ReferenceConstant nonNullRef = (ReferenceConstant) ref; Expression<?> expr = findOrCreate(res, nonNullRef); symb_expressions.put(varName, expr); } } } } catch (CodeUnderTestException e) { throw new RuntimeException(e); } } private void after(FieldStatement s, Scope scope) { ReferenceExpressionPair readResult; if (s.getSource() != null) { readResult = readInstanceField(s.getSource(), s.getField().getField(), scope); } else { readResult = readStaticField(s.getField().getField()); } String lhs_name = s.getReturnValue().getName(); Expression<?> expr = readResult.getExpression(); ReferenceExpression ref = readResult.getReference(); if (expr != null) symb_expressions.put(lhs_name, expr); if (ref != null) symb_references.put(lhs_name, ref); } private void after(ShortPrimitiveStatement statement, Scope scope) { short valueOf = statement.getValue(); VariableReference varRef = statement.getReturnValue(); String varRefName = varRef.getName(); IntegerVariable integerVariable = buildIntegerVariable(varRefName, valueOf, Short.MIN_VALUE, Short.MAX_VALUE); symb_expressions.put(varRefName, integerVariable); Short short_instance; try { short_instance = (Short) varRef.getObject(scope); } catch (CodeUnderTestException e) { throw new EvosuiteError(e); } ReferenceConstant shortRef = newShortReference(short_instance, integerVariable); symb_references.put(varRefName, shortRef); } private ReferenceConstant newShortReference(Short conc_short, IntegerValue symb_value) { ReferenceConstant shortRef = (ReferenceConstant) env.heap.getReference(conc_short); env.heap.putField(Types.JAVA_LANG_SHORT, SymbolicHeap.$SHORT_VALUE, conc_short, shortRef, symb_value); return shortRef; } private void after(LongPrimitiveStatement statement, Scope scope) { long valueOf = statement.getValue(); VariableReference varRef = statement.getReturnValue(); String varRefName = varRef.getName(); IntegerVariable integerVariable = buildIntegerVariable(varRefName, valueOf, Long.MIN_VALUE, Long.MAX_VALUE); symb_expressions.put(varRefName, integerVariable); Long long_instance; try { long_instance = (Long) varRef.getObject(scope); } catch (CodeUnderTestException e) { throw new EvosuiteError(e); } ReferenceConstant longRef = newLongReference(long_instance, integerVariable); symb_references.put(varRefName, longRef); } private ReferenceConstant newLongReference(Long conc_long, IntegerValue symb_value) { ReferenceConstant longRef = (ReferenceConstant) env.heap.getReference(conc_long); env.heap.putField(Types.JAVA_LANG_LONG, SymbolicHeap.$LONG_VALUE, conc_long, longRef, symb_value); return longRef; } private void after(FloatPrimitiveStatement statement, Scope scope) { float valueOf = statement.getValue(); VariableReference varRef = statement.getReturnValue(); String varRefName = varRef.getName(); RealVariable realVariable = buildRealVariable(varRefName, valueOf, -Float.MAX_VALUE, Float.MAX_VALUE); symb_expressions.put(varRefName, realVariable); Float float_instance; try { float_instance = (Float) varRef.getObject(scope); } catch (CodeUnderTestException e) { throw new EvosuiteError(e); } ReferenceConstant floatRef = newFloatReference(float_instance, realVariable); symb_references.put(varRefName, floatRef); } private ReferenceConstant newFloatReference(Float conc_float, RealValue symb_value) { ReferenceConstant floatRef = (ReferenceConstant) env.heap.getReference(conc_float); env.heap.putField(Types.JAVA_LANG_FLOAT, SymbolicHeap.$FLOAT_VALUE, conc_float, floatRef, symb_value); return floatRef; } private void after(CharPrimitiveStatement statement, Scope scope) { char valueOf = statement.getValue(); VariableReference varRef = statement.getReturnValue(); String varRefName = varRef.getName(); IntegerVariable integerVariable = buildIntegerVariable(varRefName, valueOf, Character.MIN_VALUE, Character.MAX_VALUE); symb_expressions.put(varRefName, integerVariable); Character character0; try { character0 = (Character) varRef.getObject(scope); } catch (CodeUnderTestException e) { throw new EvosuiteError(e); } ReferenceConstant charRef = newCharacterReference(character0, integerVariable); symb_references.put(varRefName, charRef); } private ReferenceConstant newCharacterReference(Character conc_char, IntegerValue symb_value) { ReferenceConstant charRef = (ReferenceConstant) env.heap.getReference(conc_char); env.heap.putField(Types.JAVA_LANG_CHARACTER, SymbolicHeap.$CHAR_VALUE, conc_char, charRef, symb_value); return charRef; } private void after(BytePrimitiveStatement statement, Scope scope) { byte valueOf = statement.getValue(); VariableReference varRef = statement.getReturnValue(); String varRefName = varRef.getName(); IntegerVariable integerVariable = buildIntegerVariable(varRefName, valueOf, Byte.MIN_VALUE, Byte.MAX_VALUE); symb_expressions.put(varRefName, integerVariable); Byte byte_instance; try { byte_instance = (Byte) varRef.getObject(scope); } catch (CodeUnderTestException e) { throw new EvosuiteError(e); } ReferenceConstant byteRef = newByteReference(byte_instance, integerVariable); symb_references.put(varRefName, byteRef); } private ReferenceConstant newByteReference(Byte conc_byte, IntegerValue symb_value) { ReferenceConstant byteRef = (ReferenceConstant) env.heap.getReference(conc_byte); env.heap.putField(Types.JAVA_LANG_BYTE, SymbolicHeap.$BYTE_VALUE, conc_byte, byteRef, symb_value); return byteRef; } private void after(BooleanPrimitiveStatement statement, Scope scope) { boolean valueOf = statement.getValue(); VariableReference varRef = statement.getReturnValue(); String varRefName = varRef.getName(); IntegerVariable integerVariable = buildIntegerVariable(varRefName, valueOf ? 1 : 0, 0, 1); Boolean boolean_instance; try { boolean_instance = (Boolean) varRef.getObject(scope); } catch (CodeUnderTestException e) { throw new EvosuiteError(e); } symb_expressions.put(varRefName, integerVariable); ReferenceConstant booleanRef = newBooleanReference(boolean_instance, integerVariable); symb_references.put(varRefName, booleanRef); } private ReferenceConstant newBooleanReference(Boolean conc_boolean, IntegerValue symb_value) { ReferenceConstant booleanRef = (ReferenceConstant) env.heap.getReference(conc_boolean); env.heap.putField(Types.JAVA_LANG_BOOLEAN, SymbolicHeap.$BOOLEAN_VALUE, conc_boolean, booleanRef, symb_value); return booleanRef; } private void after(DoublePrimitiveStatement statement, Scope scope) { double valueOf = statement.getValue(); VariableReference varRef = statement.getReturnValue(); String varRefName = varRef.getName(); RealVariable realVariable = buildRealVariable(varRefName, valueOf, -Double.MAX_VALUE, Double.MAX_VALUE); symb_expressions.put(varRefName, realVariable); Double double_instance; try { double_instance = (Double) varRef.getObject(scope); } catch (CodeUnderTestException e) { throw new EvosuiteError(e); } ReferenceConstant doubleRef = newDoubleReference(double_instance, realVariable); symb_references.put(varRefName, doubleRef); } private ReferenceConstant newDoubleReference(Double conc_double, RealValue symb_value) { ReferenceConstant doubleRef = (ReferenceConstant) env.heap.getReference(conc_double); env.heap.putField(Types.JAVA_LANG_DOUBLE, SymbolicHeap.$DOUBLE_VALUE, conc_double, doubleRef, symb_value); return doubleRef; } private void after(MethodStatement statement, Scope scope) { String owner = statement.getMethod().getDeclaringClass().getName().replace('.', '/'); String name = statement.getMethod().getName(); String desc = Type.getMethodDescriptor(statement.getMethod().getMethod()); Type returnType = Type.getReturnType(statement.getMethod().getMethod()); VariableReference varRef = statement.getReturnValue(); String varName = varRef.getName(); try { if (varRef.getType().equals(void.class)) { VM.CALL_RESULT(owner, name, desc); } else if (returnType.equals(Type.INT_TYPE)) { Integer res = (Integer) varRef.getObject(scope); VM.CALL_RESULT(res.intValue(), owner, name, desc); IntegerValue intExpr = env.topFrame().operandStack.popBv32(); ReferenceConstant newIntegerRef = newIntegerReference(res, intExpr); symb_references.put(varName, newIntegerRef); symb_expressions.put(varName, intExpr); } else if (returnType.equals(Type.BOOLEAN_TYPE)) { Boolean res = (Boolean) varRef.getObject(scope); VM.CALL_RESULT(res.booleanValue(), owner, name, desc); IntegerValue intExpr = env.topFrame().operandStack.popBv32(); ReferenceConstant newBooleanRef = newBooleanReference(res, intExpr); symb_references.put(varName, newBooleanRef); symb_expressions.put(varName, intExpr); } else if (returnType.equals(Type.DOUBLE_TYPE)) { Double res = (Double) varRef.getObject(scope); VM.CALL_RESULT(res.doubleValue(), owner, name, desc); RealValue realExpr = env.topFrame().operandStack.popFp64(); ReferenceConstant newDoubleRef = newDoubleReference(res, realExpr); symb_references.put(varName, newDoubleRef); symb_expressions.put(varName, realExpr); } else if (returnType.equals(Type.FLOAT_TYPE)) { Float res = (Float) varRef.getObject(scope); VM.CALL_RESULT(res.floatValue(), owner, name, desc); RealValue realExpr = env.topFrame().operandStack.popFp32(); ReferenceConstant newFloatRef = newFloatReference(res, realExpr); symb_references.put(varName, newFloatRef); symb_expressions.put(varName, realExpr); } else if (returnType.equals(Type.LONG_TYPE)) { Long res = (Long) varRef.getObject(scope); VM.CALL_RESULT(res.longValue(), owner, name, desc); IntegerValue intExpr = env.topFrame().operandStack.popBv64(); ReferenceConstant newBooleanRef = newLongReference(res, intExpr); symb_references.put(varName, newBooleanRef); symb_expressions.put(varName, intExpr); } else if (returnType.equals(Type.SHORT_TYPE)) { Short res = (Short) varRef.getObject(scope); VM.CALL_RESULT(res.shortValue(), owner, name, desc); IntegerValue intExpr = env.topFrame().operandStack.popBv32(); ReferenceConstant newShortRef = newShortReference(res, intExpr); symb_references.put(varName, newShortRef); symb_expressions.put(varName, intExpr); } else if (returnType.equals(Type.BYTE_TYPE)) { Byte res = (Byte) varRef.getObject(scope); VM.CALL_RESULT(res.byteValue(), owner, name, desc); IntegerValue intExpr = env.topFrame().operandStack.popBv32(); ReferenceConstant newByteRef = newByteReference(res, intExpr); symb_references.put(varName, newByteRef); symb_expressions.put(varName, intExpr); } else if (returnType.equals(Type.CHAR_TYPE)) { Character res = (Character) varRef.getObject(scope); VM.CALL_RESULT(res.charValue(), owner, name, desc); IntegerValue intExpr = env.topFrame().operandStack.popBv32(); ReferenceConstant newCharacterRef = newCharacterReference(res, intExpr); symb_references.put(varName, newCharacterRef); symb_expressions.put(varName, intExpr); } else { Object res = varRef.getObject(scope); VM.CALL_RESULT(res, owner, name, desc); ReferenceExpression ref = env.topFrame().operandStack.peekRef(); if (res != null && res instanceof String) { String string = (String) res; ReferenceConstant newStringRef = (ReferenceConstant) env.heap.getReference(string); StringValue str_expr = env.heap.getField(Types.JAVA_LANG_STRING, SymbolicHeap.$STRING_VALUE, string, newStringRef, string); symb_references.put(varName, newStringRef); symb_expressions.put(varName, str_expr); } else { symb_references.put(varName, ref); if (res != null && isWrapper(res)) { ReferenceConstant nonNullRef = (ReferenceConstant) ref; Expression<?> expr = findOrCreate(res, nonNullRef); symb_expressions.put(varName, expr); } } } } catch (CodeUnderTestException e) { throw new RuntimeException(e); } // dispose all other arguments env.topFrame().operandStack.clearOperands(); } private Expression<?> findOrCreate(Object conc_ref, ReferenceConstant symb_ref) { if (conc_ref instanceof Boolean) { Boolean boolean0 = (Boolean) conc_ref; int conc_val = boolean0.booleanValue() ? 1 : 0; return env.heap.getField(Types.JAVA_LANG_BOOLEAN, SymbolicHeap.$BOOLEAN_VALUE, boolean0, symb_ref, conc_val); } else if (conc_ref instanceof Byte) { Byte byte0 = (Byte) conc_ref; byte conc_val = byte0.byteValue(); return env.heap.getField(Types.JAVA_LANG_BYTE, SymbolicHeap.$BYTE_VALUE, byte0, symb_ref, conc_val); } else if (conc_ref instanceof Short) { Short short0 = (Short) conc_ref; short conc_val = short0.shortValue(); return env.heap.getField(Types.JAVA_LANG_SHORT, SymbolicHeap.$SHORT_VALUE, short0, symb_ref, conc_val); } else if (conc_ref instanceof Character) { Character character0 = (Character) conc_ref; char conc_val = character0.charValue(); return env.heap.getField(Types.JAVA_LANG_CHARACTER, SymbolicHeap.$CHAR_VALUE, character0, symb_ref, conc_val); } else if (conc_ref instanceof Integer) { Integer integer0 = (Integer) conc_ref; int conc_val = integer0.intValue(); return env.heap.getField(Types.JAVA_LANG_INTEGER, SymbolicHeap.$INT_VALUE, integer0, symb_ref, conc_val); } else if (conc_ref instanceof Long) { Long long0 = (Long) conc_ref; long conc_val = long0.longValue(); return env.heap.getField(Types.JAVA_LANG_LONG, SymbolicHeap.$LONG_VALUE, long0, symb_ref, conc_val); } else if (conc_ref instanceof Float) { Float float0 = (Float) conc_ref; float conc_val = float0.floatValue(); return env.heap.getField(Types.JAVA_LANG_FLOAT, SymbolicHeap.$FLOAT_VALUE, float0, symb_ref, conc_val); } else if (conc_ref instanceof Double) { Double double0 = (Double) conc_ref; double conc_val = double0.doubleValue(); return env.heap.getField(Types.JAVA_LANG_FLOAT, SymbolicHeap.$DOUBLE_VALUE, double0, symb_ref, conc_val); } else { throw new EvosuiteError("Unreachable code!"); } } private static boolean isWrapper(Object res) { return res instanceof Boolean || res instanceof Short || res instanceof Byte || res instanceof Integer || res instanceof Character || res instanceof Long || res instanceof Float || res instanceof Double; } private void after(StringPrimitiveStatement statement, Scope scope) { String valueOf = statement.getValue(); VariableReference varRef = statement.getReturnValue(); String varRefName = varRef.getName(); StringVariable stringVariable = buildStringVariable(varRefName, valueOf); symb_expressions.put(varRefName, stringVariable); String string_instance; try { String string_interned = (String) varRef.getObject(scope); string_instance = new String(string_interned); scope.setObject(varRef, string_instance); } catch (CodeUnderTestException e) { throw new EvosuiteError(e); } ReferenceConstant stringRef = newStringReference(string_instance, stringVariable); symb_references.put(varRefName, stringRef); } private void after(FileNamePrimitiveStatement statement, Scope scope) { EvoSuiteFile conc_evosuite_file = statement.getValue(); VariableReference varRef = statement.getReturnValue(); String varRefName = varRef.getName(); ReferenceExpression fileRef; if (conc_evosuite_file == null) { fileRef = env.heap.getReference(null); if (fileRef.getConcreteValue() != null) { throw new IllegalStateException("Expected null concrete object"); } } else { fileRef = (ReferenceConstant) env.heap.getReference(conc_evosuite_file); if (fileRef.getConcreteValue() == null) { throw new IllegalStateException("Expected non-null concrete object"); } } symb_references.put(varRefName, fileRef); } private ReferenceConstant newStringReference(String conc_string, StringValue str_expr) { ReferenceConstant stringRef = (ReferenceConstant) env.heap.getReference(conc_string); env.heap.putField(Types.JAVA_LANG_STRING, SymbolicHeap.$STRING_VALUE, conc_string, stringRef, str_expr); return stringRef; } private final Map<String, Expression<?>> symb_expressions = new HashMap<String, Expression<?>>(); private final Map<String, ReferenceExpression> symb_references = new HashMap<String, ReferenceExpression>(); private final Map<String, IntegerVariable> integerVariables = new HashMap<String, IntegerVariable>(); private final Map<String, RealVariable> realVariables = new HashMap<String, RealVariable>(); private final Map<String, StringVariable> stringVariables = new HashMap<String, StringVariable>(); private void after(IntPrimitiveStatement statement, Scope scope) { int valueOf = statement.getValue(); VariableReference varRef = statement.getReturnValue(); String varRefName = varRef.getName(); IntegerVariable integerVariable = buildIntegerVariable(varRefName, valueOf, Integer.MIN_VALUE, Integer.MAX_VALUE); symb_expressions.put(varRefName, integerVariable); Integer integer_instance; try { integer_instance = (Integer) varRef.getObject(scope); } catch (CodeUnderTestException e) { throw new EvosuiteError(e); } ReferenceConstant integerRef = newIntegerReference(integer_instance, integerVariable); symb_references.put(varRefName, integerRef); } private ReferenceConstant newIntegerReference(Integer conc_integer, IntegerValue symb_value) { ReferenceConstant integerRef = (ReferenceConstant) env.heap.getReference(conc_integer); env.heap.putField(Types.JAVA_LANG_INTEGER, SymbolicHeap.$INT_VALUE, conc_integer, integerRef, symb_value); return integerRef; } @Override public void clear() { symb_expressions.clear(); symb_references.clear(); } private IntegerVariable buildIntegerVariable(String name, long conV, long minValue, long maxValue) { IntegerVariable integerVariable; if (integerVariables.containsKey(name)) { integerVariable = integerVariables.get(name); integerVariable.setConcreteValue(conV); assert minValue == integerVariable.getMinValue(); assert maxValue == integerVariable.getMaxValue(); } else { integerVariable = new IntegerVariable(name, conV, minValue, maxValue); integerVariables.put(name, integerVariable); } return integerVariable; } private RealVariable buildRealVariable(String name, double conV, double minValue, double maxValue) { RealVariable realVariable; if (realVariables.containsKey(name)) { realVariable = realVariables.get(name); realVariable.setConcreteValue(conV); assert minValue == realVariable.getMinValue(); assert maxValue == realVariable.getMaxValue(); } else { realVariable = new RealVariable(name, conV, minValue, maxValue); realVariables.put(name, realVariable); } return realVariable; } private StringVariable buildStringVariable(String name, String concVal) { StringVariable stringVariable; if (stringVariables.containsKey(name)) { stringVariable = stringVariables.get(name); stringVariable.setConcreteValue(concVal); } else { stringVariable = new StringVariable(name, concVal); stringVariables.put(name, stringVariable); } return stringVariable; } @Override public void testExecutionFinished(ExecutionResult r, Scope s) { // do nothing } }