![JAR search and dependency download from the Maven repository](/logo.png)
org.evosuite.symbolic.vm.SymbolicEnvironment Maven / Gradle / Ivy
The newest version!
/**
* 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.symbolic.vm;
import org.evosuite.dse.MainConfig;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import org.evosuite.symbolic.expr.ref.ReferenceExpression;
import org.evosuite.symbolic.instrument.ConcolicInstrumentingClassLoader;
import org.evosuite.testcase.execution.EvosuiteError;
import org.objectweb.asm.Type;
/**
*
* @author galeotti
*
*/
public final class SymbolicEnvironment {
/**
* Storage for symbolic information in the memory heap
*/
public final SymbolicHeap heap = new SymbolicHeap();
/**
* Stack of function/method/constructor invocation frames
*/
private final Deque stackFrame = new LinkedList();
/**
* Classes whose static fields have been set to the default zero value or a
* dummy value.
*/
private final Set> preparedClasses = new HashSet>();
private final ConcolicInstrumentingClassLoader classLoader;
public SymbolicEnvironment(ConcolicInstrumentingClassLoader classLoader) {
this.classLoader = classLoader;
}
public Frame topFrame() {
return stackFrame.peek();
}
public void pushFrame(Frame frame) {
stackFrame.push(frame);
}
public Frame callerFrame() {
Frame top = stackFrame.pop();
Frame res = stackFrame.peek();
stackFrame.push(top);
return res;
}
public Frame popFrame() {
return stackFrame.pop();
}
public Class> ensurePrepared(String className) {
Type ownerType = Type.getType(className);
if (ownerType.getSort() == Type.ARRAY) {
Type elemType = ownerType.getElementType();
if (isValueType(elemType))
return primitiveClassType(elemType);
else {
// ensurePrepared component class
className = elemType.getClassName();
Class> claz = classLoader.getClassForName(className);
ensurePrepared(claz);
// returns claz[] instead of claz
Class> arrayClaz = Array.newInstance(claz, 0).getClass();
return arrayClaz;
}
} else {
Class> claz = classLoader.getClassForName(className);
ensurePrepared(claz);
return claz;
}
}
private Class> primitiveClassType(Type t) {
if (t.equals(Type.BOOLEAN_TYPE))
return boolean[].class;
if (t.equals(Type.CHAR_TYPE))
return char[].class;
if (t.equals(Type.SHORT_TYPE))
return short[].class;
if (t.equals(Type.BYTE_TYPE))
return byte[].class;
if (t.equals(Type.INT_TYPE))
return int[].class;
if (t.equals(Type.LONG_TYPE))
return long[].class;
if (t.equals(Type.FLOAT_TYPE))
return float[].class;
if (t.equals(Type.DOUBLE_TYPE))
return double[].class;
throw new EvosuiteError(t.toString()
+ " is not a primitive value class!");
}
private boolean isValueType(Type t) {
return t.equals(Type.BOOLEAN_TYPE) || t.equals(Type.CHAR_TYPE)
|| t.equals(Type.SHORT_TYPE) || t.equals(Type.BYTE_TYPE)
|| t.equals(Type.INT_TYPE) || t.equals(Type.LONG_TYPE)
|| t.equals(Type.FLOAT_TYPE) || t.equals(Type.DOUBLE_TYPE);
}
public void ensurePrepared(Class> claz) {
if (preparedClasses.contains(claz))
return; // done, we have prepared this class earlier
Class> superClass = claz.getSuperclass();
if (superClass != null)
ensurePrepared(superClass); // prepare super class first
String className = claz.getCanonicalName();
if (className == null) {
// no canonical name
}
/*
* Field[] fields = claz.getDeclaredFields();
*
* final boolean isIgnored = MainConfig.get().isIgnored(className);
*
* for (Field field : fields) {
*
* final int fieldModifiers = field.getModifiers(); if (isIgnored &&
* Modifier.isPrivate(fieldModifiers)) continue; // skip private field
* of ignored class.
*
* }
*/
preparedClasses.add(claz);
}
/**
* Prepare stack of function invocation frames.
*
* Clear function invocation stack, push a frame that pretends to call the
* method under test. We push variables for our method onto the
* pseudo-callers stack, so our method can pop them from there.
*/
public void prepareStack(Method mainMethod) {
stackFrame.clear();
// bottom of the stack trace
this.pushFrame(new FakeBottomFrame());
// frame for argument purposes
final FakeMainCallerFrame fakeMainCallerFrame = new FakeMainCallerFrame(
mainMethod, MainConfig.get().MAX_LOCALS_DEFAULT); // fake caller
// of method
// under
// test
if (mainMethod != null) {
boolean isInstrumented = isInstrumented(mainMethod);
fakeMainCallerFrame.invokeInstrumentedCode(isInstrumented);
String[] emptyStringArray = new String[] {};
ReferenceExpression emptyStringRef = heap.getReference(emptyStringArray);
fakeMainCallerFrame.operandStack.pushRef(emptyStringRef);
}
this.pushFrame(fakeMainCallerFrame);
}
/**
* @return method is instrumented. It is neither native nor declared by an
* ignored JDK class, etc.
*/
private static boolean isInstrumented(Method method) {
if (Modifier.isNative(method.getModifiers()))
return false;
String declClass = method.getDeclaringClass().getCanonicalName();
return !MainConfig.get().isIgnored(declClass);
}
public boolean isEmpty() {
return stackFrame.isEmpty();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy