diff --git a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/rd/InstrumentedProcess.kt b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/rd/InstrumentedProcess.kt index 81b31d6c2f..d58b39e365 100644 --- a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/rd/InstrumentedProcess.kt +++ b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/rd/InstrumentedProcess.kt @@ -81,14 +81,14 @@ class InstrumentedProcess private constructor() { } private suspend fun initProcess(classpath: String) { - fileClassPath = classpath.split(':').map { File(it) } + fileClassPath = classpath.split(File.pathSeparatorChar).map { File(it) } val db = jacodb { loadByteCode(fileClassPath) installFeatures(InMemoryHierarchy) jre = File(InstrumentationModuleConstants.pathToJava) //persistent(location = "/home/.usvm/jcdb.db", clearOnStart = false) } - jcClasspath = db.asyncClasspath(fileClassPath).get() + jcClasspath = db.classpath(fileClassPath) serializationCtx = SerializationContext(jcClasspath) ucp = URLClassPathLoader(fileClassPath) uTestExecutor = UTestExecutor(jcClasspath, ucp) diff --git a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/rd/UTestExecutor.kt b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/rd/UTestExecutor.kt index f0b0b43af9..92f376f1d1 100644 --- a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/rd/UTestExecutor.kt +++ b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/rd/UTestExecutor.kt @@ -11,9 +11,7 @@ import org.usvm.instrumentation.instrumentation.JcInstructionTracer import org.usvm.instrumentation.mock.MockHelper import org.usvm.instrumentation.testcase.UTest import org.usvm.instrumentation.testcase.api.* -import org.usvm.instrumentation.testcase.descriptor.StaticDescriptorsBuilder -import org.usvm.instrumentation.testcase.descriptor.UTestExceptionDescriptor -import org.usvm.instrumentation.testcase.descriptor.Value2DescriptorConverter +import org.usvm.instrumentation.testcase.descriptor.* import org.usvm.instrumentation.testcase.executor.UTestExpressionExecutor import org.usvm.instrumentation.util.InstrumentationModuleConstants import org.usvm.instrumentation.util.URLClassPathLoader @@ -94,15 +92,6 @@ class UTestExecutor( accessedStatics = hashSetOf() ) - executor.clearCache() - executor.executeUTestInsts(uTest.initStatements) - ?.onFailure { - return UTestExecutionInitFailedResult( - cause = buildExceptionDescriptor(initStateDescriptorBuilder, it, false), - trace = JcInstructionTracer.getTrace().trace - ) - } - val methodInvocationResult = executor.executeUTestInst(callMethodExpr) val resultStateDescriptorBuilder = @@ -157,7 +146,8 @@ class UTestExecutor( exception: Throwable, raisedByUserCode: Boolean ): UTestExceptionDescriptor { - val descriptor = builder.buildDescriptorResultFromAny(any = exception, type = null).getOrNull() as? UTestExceptionDescriptor + val descriptor = + builder.buildDescriptorResultFromAny(any = exception, type = null).getOrNull() as? UTestExceptionDescriptor return descriptor ?.also { it.raisedByUserCode = raisedByUserCode } ?: UTestExceptionDescriptor( @@ -174,14 +164,14 @@ class UTestExecutor( descriptorBuilder: Value2DescriptorConverter, accessedStatics: MutableSet> ): UTestExecutionState = with(descriptorBuilder) { - descriptorBuilder.uTestExecutorCache.addAll(executor.objectToInstructionsCache) + uTestExecutorCache.addAll(executor.objectToInstructionsCache) val instanceDescriptor = callMethodExpr.instance?.let { buildDescriptorFromUTestExpr(it, executor).getOrNull() } val argsDescriptors = callMethodExpr.args.map { buildDescriptorFromUTestExpr(it, executor).getOrNull() } - val isInit = descriptorBuilder.previousState == null + val isInit = previousState == null val statics = if (isInit) { staticDescriptorsBuilder.builtInitialDescriptors .mapValues { it.value!! } diff --git a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/serializer/UTestValueDescriptorSerializer.kt b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/serializer/UTestValueDescriptorSerializer.kt index dddfde3e7d..a15a8cd966 100644 --- a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/serializer/UTestValueDescriptorSerializer.kt +++ b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/serializer/UTestValueDescriptorSerializer.kt @@ -38,15 +38,7 @@ class UTestValueDescriptorSerializer(private val ctx: SerializationContext) { UTestValueDescriptorKind.NULL -> deserializeNull() UTestValueDescriptorKind.STRING -> deserializeString() UTestValueDescriptorKind.CYCLIC_REF -> deserializeCyclicRef() - UTestValueDescriptorKind.INT_ARRAY -> deserializeIntArray() - UTestValueDescriptorKind.BOOLEAN_ARRAY -> deserializeBooleanArray() - UTestValueDescriptorKind.BYTE_ARRAY -> deserializeByteArray() - UTestValueDescriptorKind.SHORT_ARRAY -> deserializeShortArray() - UTestValueDescriptorKind.LONG_ARRAY -> deserializeLongArray() - UTestValueDescriptorKind.DOUBLE_ARRAY -> deserializeDoubleArray() - UTestValueDescriptorKind.FLOAT_ARRAY -> deserializeFloatArray() - UTestValueDescriptorKind.CHAR_ARRAY -> deserializeCharArray() - UTestValueDescriptorKind.OBJECT_ARRAY -> deserializeArray() + UTestValueDescriptorKind.ARRAY -> deserializeArray() UTestValueDescriptorKind.ENUM_VALUE -> deserializeEnumValue() UTestValueDescriptorKind.CLASS -> deserializeClass() UTestValueDescriptorKind.EXCEPTION -> deserializeException() @@ -59,16 +51,8 @@ class UTestValueDescriptorSerializer(private val ctx: SerializationContext) { private fun AbstractBuffer.serializeUTestValueDescriptor(uTestValueDescriptor: UTestValueDescriptor) { if (ctx.serializedDescriptors.contains(uTestValueDescriptor)) return when (uTestValueDescriptor) { - is UTestArrayDescriptor.Array -> serialize(uTestValueDescriptor) - is UTestArrayDescriptor.BooleanArray -> serialize(uTestValueDescriptor) - is UTestArrayDescriptor.ByteArray -> serialize(uTestValueDescriptor) - is UTestArrayDescriptor.CharArray -> serialize(uTestValueDescriptor) - is UTestArrayDescriptor.DoubleArray -> serialize(uTestValueDescriptor) - is UTestArrayDescriptor.FloatArray -> serialize(uTestValueDescriptor) - is UTestArrayDescriptor.IntArray -> serialize(uTestValueDescriptor) - is UTestArrayDescriptor.LongArray -> serialize(uTestValueDescriptor) - is UTestArrayDescriptor.ShortArray -> serialize(uTestValueDescriptor) is UTestConstantDescriptor.Boolean -> serialize(uTestValueDescriptor) + is UTestArrayDescriptor -> serialize(uTestValueDescriptor) is UTestConstantDescriptor.Byte -> serialize(uTestValueDescriptor) is UTestConstantDescriptor.Char -> serialize(uTestValueDescriptor) is UTestConstantDescriptor.Double -> serialize(uTestValueDescriptor) @@ -86,10 +70,10 @@ class UTestValueDescriptorSerializer(private val ctx: SerializationContext) { } } - private fun AbstractBuffer.serialize(uTestValueDescriptor: UTestArrayDescriptor.Array) = + private fun AbstractBuffer.serialize(uTestValueDescriptor: UTestArrayDescriptor) = serialize( uTestValueDescriptor = uTestValueDescriptor, - kind = UTestValueDescriptorKind.OBJECT_ARRAY, + kind = UTestValueDescriptorKind.ARRAY, serializeInternals = { value.forEach { serializeUTestValueDescriptor(it) } }, @@ -101,12 +85,12 @@ class UTestValueDescriptorSerializer(private val ctx: SerializationContext) { } ) - private fun AbstractBuffer.deserializeArray(): UTestArrayDescriptor.Array { + private fun AbstractBuffer.deserializeArray(): UTestArrayDescriptor { val elementType = readJcType(jcClasspath) ?: jcClasspath.objectType val refId = readInt() val length = readInt() val values = readList { readUTestValueDescriptor() } - return UTestArrayDescriptor.Array( + return UTestArrayDescriptor( elementType = elementType, length = length, value = values, @@ -114,150 +98,6 @@ class UTestValueDescriptorSerializer(private val ctx: SerializationContext) { ) } - private fun AbstractBuffer.serialize(uTestValueDescriptor: UTestArrayDescriptor.BooleanArray) = - serialize( - uTestValueDescriptor = uTestValueDescriptor, - kind = UTestValueDescriptorKind.BOOLEAN_ARRAY, - serializeInternals = {}, - serialize = { - writeInt(length) - writeBooleanArray(value) - } - ) - - private fun AbstractBuffer.deserializeBooleanArray(): UTestArrayDescriptor.BooleanArray = - UTestArrayDescriptor.BooleanArray( - elementType = jcClasspath.boolean, - length = readInt(), - value = readBooleanArray() - ) - - private fun AbstractBuffer.serialize(uTestValueDescriptor: UTestArrayDescriptor.ByteArray) = - serialize( - uTestValueDescriptor = uTestValueDescriptor, - kind = UTestValueDescriptorKind.BYTE_ARRAY, - serializeInternals = {}, - serialize = { - writeInt(length) - writeByteArray(value) - } - ) - - private fun AbstractBuffer.deserializeByteArray(): UTestArrayDescriptor.ByteArray = - UTestArrayDescriptor.ByteArray( - elementType = jcClasspath.byte, - length = readInt(), - value = readByteArray() - ) - - private fun AbstractBuffer.serialize(uTestValueDescriptor: UTestArrayDescriptor.ShortArray) = - serialize( - uTestValueDescriptor = uTestValueDescriptor, - kind = UTestValueDescriptorKind.SHORT_ARRAY, - serializeInternals = {}, - serialize = { - writeInt(length) - writeShortArray(value) - } - ) - - private fun AbstractBuffer.deserializeShortArray(): UTestArrayDescriptor.ShortArray = - UTestArrayDescriptor.ShortArray( - elementType = jcClasspath.short, - length = readInt(), - value = readShortArray() - ) - - private fun AbstractBuffer.serialize(uTestValueDescriptor: UTestArrayDescriptor.IntArray) = - serialize( - uTestValueDescriptor = uTestValueDescriptor, - kind = UTestValueDescriptorKind.INT_ARRAY, - serializeInternals = {}, - serialize = { - writeInt(length) - writeIntArray(value) - } - ) - - private fun AbstractBuffer.deserializeIntArray(): UTestArrayDescriptor.IntArray = - UTestArrayDescriptor.IntArray( - elementType = jcClasspath.int, - length = readInt(), - value = readIntArray() - ) - - private fun AbstractBuffer.serialize(uTestValueDescriptor: UTestArrayDescriptor.LongArray) = - serialize( - uTestValueDescriptor = uTestValueDescriptor, - kind = UTestValueDescriptorKind.LONG_ARRAY, - serializeInternals = {}, - serialize = { - writeInt(length) - writeLongArray(value) - } - ) - - private fun AbstractBuffer.deserializeLongArray(): UTestArrayDescriptor.LongArray = - UTestArrayDescriptor.LongArray( - elementType = jcClasspath.long, - length = readInt(), - value = readLongArray() - ) - - private fun AbstractBuffer.serialize(uTestValueDescriptor: UTestArrayDescriptor.FloatArray) = - serialize( - uTestValueDescriptor = uTestValueDescriptor, - kind = UTestValueDescriptorKind.FLOAT_ARRAY, - serializeInternals = {}, - serialize = { - writeInt(length) - writeFloatArray(value) - } - ) - - private fun AbstractBuffer.deserializeFloatArray(): UTestArrayDescriptor.FloatArray = - UTestArrayDescriptor.FloatArray( - elementType = jcClasspath.float, - length = readInt(), - value = readFloatArray() - ) - - private fun AbstractBuffer.serialize(uTestValueDescriptor: UTestArrayDescriptor.DoubleArray) = - serialize( - uTestValueDescriptor = uTestValueDescriptor, - kind = UTestValueDescriptorKind.DOUBLE_ARRAY, - serializeInternals = {}, - serialize = { - writeInt(length) - writeDoubleArray(value) - } - ) - - private fun AbstractBuffer.deserializeDoubleArray(): UTestArrayDescriptor.DoubleArray = - UTestArrayDescriptor.DoubleArray( - elementType = jcClasspath.double, - length = readInt(), - value = readDoubleArray() - ) - - private fun AbstractBuffer.serialize(uTestValueDescriptor: UTestArrayDescriptor.CharArray) = - serialize( - uTestValueDescriptor = uTestValueDescriptor, - kind = UTestValueDescriptorKind.CHAR_ARRAY, - serializeInternals = {}, - serialize = { - writeInt(length) - writeCharArray(value) - } - ) - - private fun AbstractBuffer.deserializeCharArray(): UTestArrayDescriptor.CharArray = - UTestArrayDescriptor.CharArray( - elementType = jcClasspath.char, - length = readInt(), - value = readCharArray() - ) - private fun AbstractBuffer.serialize(uTestValueDescriptor: UTestCyclicReferenceDescriptor) = serialize( uTestValueDescriptor = uTestValueDescriptor, @@ -531,15 +371,7 @@ class UTestValueDescriptorSerializer(private val ctx: SerializationContext) { CHAR, NULL, STRING, - INT_ARRAY, - BOOLEAN_ARRAY, - BYTE_ARRAY, - SHORT_ARRAY, - LONG_ARRAY, - DOUBLE_ARRAY, - FLOAT_ARRAY, - CHAR_ARRAY, - OBJECT_ARRAY, + ARRAY, CYCLIC_REF, ENUM_VALUE, CLASS, diff --git a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/testcase/descriptor/Descriptor.kt b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/testcase/descriptor/Descriptor.kt index d83d34e881..5501dedd64 100644 --- a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/testcase/descriptor/Descriptor.kt +++ b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/testcase/descriptor/Descriptor.kt @@ -50,114 +50,27 @@ sealed class UTestConstantDescriptor : UTestValueDescriptor() { } -sealed class UTestArrayDescriptor( +class UTestArrayDescriptor( val elementType: JcType, val length: Int, - val value: T -) : UTestValueDescriptor() { - + val value: List, + override val refId: Int +): UTestValueDescriptor(), UTestRefDescriptor { override val type: JcType get() = elementType.classpath.arrayTypeOf(elementType) - abstract fun valueToString(): String - - class BooleanArray( - elementType: JcType, - length: Int, - value: kotlin.BooleanArray - ) : UTestArrayDescriptor(elementType, length, value) { - override fun valueToString() = value.contentToString() - override fun structurallyEqual(other: UTestValueDescriptor): Boolean = - other is BooleanArray && other.value.contentEquals(value) - } - - class ByteArray( - elementType: JcType, - length: Int, - value: kotlin.ByteArray - ) : UTestArrayDescriptor(elementType, length, value) { - override fun valueToString() = value.contentToString() - override fun structurallyEqual(other: UTestValueDescriptor): Boolean = - other is ByteArray && other.value.contentEquals(value) - } - - class ShortArray( - elementType: JcType, - length: Int, - value: kotlin.ShortArray - ) : UTestArrayDescriptor(elementType, length, value) { - override fun valueToString() = value.contentToString() - override fun structurallyEqual(other: UTestValueDescriptor): Boolean = - other is ShortArray && other.value.contentEquals(value) - } - - class IntArray( - elementType: JcType, - length: Int, - value: kotlin.IntArray - ) : UTestArrayDescriptor(elementType, length, value) { - override fun valueToString() = value.contentToString() - override fun structurallyEqual(other: UTestValueDescriptor): Boolean = - other is IntArray && other.value.contentEquals(value) - } - - class LongArray( - elementType: JcType, - length: Int, - value: kotlin.LongArray - ) : UTestArrayDescriptor(elementType, length, value) { - override fun valueToString() = value.contentToString() - override fun structurallyEqual(other: UTestValueDescriptor): Boolean = - other is LongArray && other.value.contentEquals(value) - } - - class FloatArray( - elementType: JcType, - length: Int, - value: kotlin.FloatArray - ) : UTestArrayDescriptor(elementType, length, value) { - override fun valueToString() = value.contentToString() - override fun structurallyEqual(other: UTestValueDescriptor): Boolean = - other is FloatArray && other.value.contentEquals(value) - } - - class DoubleArray( - elementType: JcType, - length: Int, - value: kotlin.DoubleArray - ) : UTestArrayDescriptor(elementType, length, value) { - override fun valueToString() = value.contentToString() - override fun structurallyEqual(other: UTestValueDescriptor): Boolean = - other is DoubleArray && other.value.contentEquals(value) - } - - class CharArray( - elementType: JcType, - length: Int, - value: kotlin.CharArray - ) : UTestArrayDescriptor(elementType, length, value) { - override fun valueToString() = value.contentToString() - override fun structurallyEqual(other: UTestValueDescriptor): Boolean = - other is CharArray && other.value.contentEquals(value) - } - - class Array( - elementType: JcType, - length: Int, - value: List, - override val refId: Int - ) : UTestArrayDescriptor>(elementType, length, value), UTestRefDescriptor { - override fun valueToString() = value.toString() - override fun structurallyEqual(other: UTestValueDescriptor): Boolean { - if (other !is Array) return false - if (length != other.length) return false - if (elementType != other.elementType) return false - return value.zip(other.value).all { descriptorsAreEqual(it.first, it.second) } + override fun structurallyEqual(other: UTestValueDescriptor): Boolean { + if (other !is UTestArrayDescriptor) return false + if (length != other.length) return false + if (elementType != other.elementType) return false + for (i in value.indices) { + if (!value[i].structurallyEqual(other.value[i])) return false } + return true } override fun toString(): String { - return "UTestArrayDescriptor(elementType=$elementType, length=$length, value=${valueToString()})" + return "UTestArrayDescriptor(elementType=$elementType, length=$length, value=${value.joinToString(",")})" } } diff --git a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/testcase/descriptor/Descriptor2ValueConverter.kt b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/testcase/descriptor/Descriptor2ValueConverter.kt index f8737d8669..d9c150bf43 100644 --- a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/testcase/descriptor/Descriptor2ValueConverter.kt +++ b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/testcase/descriptor/Descriptor2ValueConverter.kt @@ -19,15 +19,6 @@ class Descriptor2ValueConverter(private val workerClassLoader: ClassLoader) { private fun build(descriptor: UTestValueDescriptor): Any? = when (descriptor) { - is UTestArrayDescriptor.Array -> array(descriptor) - is UTestArrayDescriptor.BooleanArray -> descriptor.value - is UTestArrayDescriptor.ByteArray -> descriptor.value - is UTestArrayDescriptor.CharArray -> descriptor.value - is UTestArrayDescriptor.DoubleArray -> descriptor.value - is UTestArrayDescriptor.FloatArray -> descriptor.value - is UTestArrayDescriptor.IntArray -> descriptor.value - is UTestArrayDescriptor.LongArray -> descriptor.value - is UTestArrayDescriptor.ShortArray -> descriptor.value is UTestConstantDescriptor.Boolean -> descriptor.value is UTestConstantDescriptor.Byte -> descriptor.value is UTestConstantDescriptor.Char -> descriptor.value @@ -38,6 +29,7 @@ class Descriptor2ValueConverter(private val workerClassLoader: ClassLoader) { is UTestConstantDescriptor.Null -> null is UTestConstantDescriptor.Short -> descriptor.value is UTestConstantDescriptor.String -> string(descriptor) + is UTestArrayDescriptor -> array(descriptor) is UTestCyclicReferenceDescriptor -> { descriptorToObject .toList() @@ -57,7 +49,7 @@ class Descriptor2ValueConverter(private val workerClassLoader: ClassLoader) { descriptor.value } - private fun array(descriptor: UTestArrayDescriptor.Array): Any { + private fun array(descriptor: UTestArrayDescriptor): Any { val jcElementType = descriptor.elementType val cp = descriptor.elementType.classpath val elementType = jcElementType.toJavaClass(workerClassLoader) diff --git a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/testcase/descriptor/Value2DescriptorConverter.kt b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/testcase/descriptor/Value2DescriptorConverter.kt index c21cdd21f4..15480686ac 100644 --- a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/testcase/descriptor/Value2DescriptorConverter.kt +++ b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/testcase/descriptor/Value2DescriptorConverter.kt @@ -76,15 +76,15 @@ open class Value2DescriptorConverter( is Float -> const(any) is Double -> const(any) is String -> const(any) - is BooleanArray -> array(any, depth + 1) - is ByteArray -> array(any, depth + 1) - is CharArray -> array(any, depth + 1) - is ShortArray -> array(any, depth + 1) - is IntArray -> array(any, depth + 1) - is LongArray -> array(any, depth + 1) - is FloatArray -> array(any, depth + 1) - is DoubleArray -> array(any, depth + 1) - is Array<*> -> array(any, depth + 1) + is BooleanArray -> `boolean array`(any) + is ByteArray -> `byte array`(any) + is CharArray -> `char array`(any) + is ShortArray -> `short array`(any) + is IntArray -> `int array`(any) + is LongArray -> `long array`(any) + is FloatArray -> `float array`(any) + is DoubleArray -> `double array`(any) + is Array<*> -> `object array`(any, depth + 1) is Enum<*> -> `enum`(any, depth + 1) is Class<*> -> `class`(any) is Throwable -> `exception`(any, depth + 1) @@ -119,33 +119,85 @@ open class Value2DescriptorConverter( else -> error("Unsupported type") } - private fun array(array: Any, depth: Int) = - when (array) { - is BooleanArray -> UTestArrayDescriptor.BooleanArray(jcClasspath.boolean, array.size, array) - is ByteArray -> UTestArrayDescriptor.ByteArray(jcClasspath.byte, array.size, array) - is ShortArray -> UTestArrayDescriptor.ShortArray(jcClasspath.short, array.size, array) - is IntArray -> UTestArrayDescriptor.IntArray(jcClasspath.int, array.size, array) - is LongArray -> UTestArrayDescriptor.LongArray(jcClasspath.long, array.size, array) - is FloatArray -> UTestArrayDescriptor.FloatArray(jcClasspath.float, array.size, array) - is DoubleArray -> UTestArrayDescriptor.DoubleArray(jcClasspath.double, array.size, array) - is CharArray -> UTestArrayDescriptor.CharArray(jcClasspath.char, array.size, array) - is Array<*> -> { - val listOfRefs = mutableListOf() - val descriptor = UTestArrayDescriptor.Array( - findTypeOrNull(array.javaClass.componentType)!!, - array.size, - listOfRefs, - System.identityHashCode(array) - ) - createCyclicRef(descriptor, array) { - for (i in array.indices) { - listOfRefs.add(buildDescriptorFromAny(array[i], elementType, depth)) - } - } - } + private fun `boolean array`(array: BooleanArray): UTestArrayDescriptor = + UTestArrayDescriptor( + jcClasspath.boolean, + array.size, + array.map { UTestConstantDescriptor.Boolean(it, jcClasspath.boolean) }, + System.identityHashCode(array) + ) + + private fun `byte array`(array: ByteArray): UTestArrayDescriptor = + UTestArrayDescriptor( + jcClasspath.byte, + array.size, + array.map { UTestConstantDescriptor.Byte(it, jcClasspath.byte) }, + System.identityHashCode(array) + ) + + private fun `char array`(array: CharArray): UTestArrayDescriptor = + UTestArrayDescriptor( + jcClasspath.char, + array.size, + array.map { UTestConstantDescriptor.Char(it, jcClasspath.char) }, + System.identityHashCode(array) + ) + + private fun `short array`(array: ShortArray): UTestArrayDescriptor = + UTestArrayDescriptor( + jcClasspath.short, + array.size, + array.map { UTestConstantDescriptor.Short(it, jcClasspath.short) }, + System.identityHashCode(array) + ) + + private fun `int array`(array: IntArray): UTestArrayDescriptor = + UTestArrayDescriptor( + jcClasspath.int, + array.size, + array.map { UTestConstantDescriptor.Int(it, jcClasspath.int) }, + System.identityHashCode(array) + ) + + private fun `long array`(array: LongArray): UTestArrayDescriptor = + UTestArrayDescriptor( + jcClasspath.long, + array.size, + array.map { UTestConstantDescriptor.Long(it, jcClasspath.long) }, + System.identityHashCode(array) + ) - else -> error("It is not array") + private fun `float array`(array: FloatArray): UTestArrayDescriptor = + UTestArrayDescriptor( + jcClasspath.float, + array.size, + array.map { UTestConstantDescriptor.Float(it, jcClasspath.float) }, + System.identityHashCode(array) + ) + + private fun `double array`(array: DoubleArray): UTestArrayDescriptor = + UTestArrayDescriptor( + jcClasspath.double, + array.size, + array.map { UTestConstantDescriptor.Double(it, jcClasspath.double) }, + System.identityHashCode(array) + ) + + private fun `object array`(array: Array<*>, depth: Int): UTestArrayDescriptor { + val listOfRefs = mutableListOf() + val descriptor = UTestArrayDescriptor( + findTypeOrNull(array.javaClass.componentType) ?: jcClasspath.objectType, + array.size, + listOfRefs, + System.identityHashCode(array) + ) + createCyclicRef(descriptor, array) { + for (i in array.indices) { + listOfRefs.add(buildDescriptorFromAny(array[i], elementType, depth)) + } } + return descriptor + } private fun createCyclicRef( valueDescriptor: T, @@ -170,14 +222,18 @@ open class Value2DescriptorConverter( val originUTestInst = uTestExecutorCache.find { it.first === value }?.second val jcClass = if (originUTestInst is UTestMock) { - originUTestInst.type.toJcClass() ?: - jcClasspath.findClass(value::class.java.name.substringBefore(MockHelper.MOCKED_CLASS_POSTFIX)) + originUTestInst.type.toJcClass() ?: jcClasspath.findClass( + value::class.java.name.substringBeforeLast( + MockHelper.MOCKED_CLASS_POSTFIX + ) + ) } else { jcClasspath.findClass(value::class.java.name) } val jcType = jcClass.toType() val fields = mutableMapOf() - val uTestObjectDescriptor = UTestObjectDescriptor(jcType, fields, originUTestInst, System.identityHashCode(value)) + val uTestObjectDescriptor = + UTestObjectDescriptor(jcType, fields, originUTestInst, System.identityHashCode(value)) return createCyclicRef(uTestObjectDescriptor, value) { jcClass.allDeclaredFields //TODO! Decide for which fields descriptors should be build diff --git a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/util/Jacodb.kt b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/util/Jacodb.kt index ed97a8479b..3ec8aced44 100644 --- a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/util/Jacodb.kt +++ b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/util/Jacodb.kt @@ -97,7 +97,12 @@ fun JcArrayType.toJvmType(strBuilder: StringBuilder = StringBuilder()): String { return strBuilder.toString() } -fun JcType.toJcClass(): JcClassOrInterface? = classpath.findClassOrNull(typeName.substringBefore('<')) +fun JcType.toJcClass(): JcClassOrInterface? = + when (this) { + is JcRefType -> jcClass + is JcPrimitiveType -> null + else -> error("Unexpected type") + } fun JcClassOrInterface.toJavaClass(classLoader: ClassLoader): Class<*> = findClassInLoader(name, classLoader) ?: throw TestExecutorException("Can't find class in classpath") diff --git a/usvm-jvm/src/samples/java/org/usvm/api/mock/UMock.kt b/usvm-jvm/src/samples/java/org/usvm/api/mock/UMock.kt index 41847a1c7c..39b2f33ff8 100644 --- a/usvm-jvm/src/samples/java/org/usvm/api/mock/UMock.kt +++ b/usvm-jvm/src/samples/java/org/usvm/api/mock/UMock.kt @@ -1,8 +1,12 @@ package org.usvm.api.mock import org.usvm.api.Engine +import org.usvm.api.exception.UMockAssumptionViolatedException fun assume(predicate: Boolean) { // TODO inline it - Engine.assume(predicate) + if (!predicate) { + Engine.assume(false) + throw UMockAssumptionViolatedException() + } } diff --git a/usvm-jvm/src/test/kotlin/org/usvm/samples/JavaMethodTestRunner.kt b/usvm-jvm/src/test/kotlin/org/usvm/samples/JavaMethodTestRunner.kt index 90358a082a..38e7e3399f 100644 --- a/usvm-jvm/src/test/kotlin/org/usvm/samples/JavaMethodTestRunner.kt +++ b/usvm-jvm/src/test/kotlin/org/usvm/samples/JavaMethodTestRunner.kt @@ -17,7 +17,6 @@ import org.usvm.test.util.TestRunner import org.usvm.test.util.checkers.AnalysisResultsNumberMatcher import org.usvm.test.util.checkers.ignoreNumberOfAnalysisResults import org.usvm.util.JcTestResolverType -import org.usvm.util.TestResolvingOptions import org.usvm.util.UTestRunnerController import kotlin.reflect.* import kotlin.reflect.full.instanceParameter @@ -738,8 +737,10 @@ open class JavaMethodTestRunner : TestRunner, KClass<*>?, J protected open val jacodbCpKey = samplesKey protected val cp = JacoDBContainer(jacodbCpKey).cp + protected open val resolverType: JcTestResolverType = JcTestResolverType.INTERPRETER + private val testResolver = - when (TestResolvingOptions.resolverType) { + when (resolverType) { JcTestResolverType.INTERPRETER -> JcTestInterpreter() JcTestResolverType.CONCRETE_EXECUTOR -> JcTestExecutor(classpath = cp) } diff --git a/usvm-jvm/src/test/kotlin/org/usvm/util/TestResolvingOptions.kt b/usvm-jvm/src/test/kotlin/org/usvm/util/TestResolvingOptions.kt index 6be8495e7c..01f9077b1b 100644 --- a/usvm-jvm/src/test/kotlin/org/usvm/util/TestResolvingOptions.kt +++ b/usvm-jvm/src/test/kotlin/org/usvm/util/TestResolvingOptions.kt @@ -9,8 +9,4 @@ enum class JcTestResolverType { * Uses concrete execution to resolve objects. */ CONCRETE_EXECUTOR -} - -object TestResolvingOptions { - val resolverType = JcTestResolverType.INTERPRETER } \ No newline at end of file