From 27820ea8f6fa1b06da724437011741db2068d294 Mon Sep 17 00:00:00 2001 From: Valentyn Sobol Date: Thu, 8 Aug 2024 15:46:43 +0300 Subject: [PATCH] Upgrade jacodb version --- buildSrc/src/main/kotlin/Dependencies.kt | 2 +- .../JcRuntimeTraceInstrumenter.kt | 2 +- .../usvm/instrumentation/mock/MockHelper.kt | 46 +++++++++---------- .../org/usvm/instrumentation/util/Jacodb.kt | 6 ++- .../kotlin/org/usvm/TSApplicationGraph.kt | 4 +- 5 files changed, 31 insertions(+), 29 deletions(-) diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 61810835b4..7df850fae6 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -5,7 +5,7 @@ import org.gradle.plugin.use.PluginDependenciesSpec object Versions { const val detekt = "1.18.1" const val ini4j = "0.5.4" - const val jacodb = "30594f5f7c" + const val jacodb = "ae2716b3f8" const val juliet = "1.3.2" const val junit = "5.9.3" const val kotlin = "1.9.20" diff --git a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/instrumentation/JcRuntimeTraceInstrumenter.kt b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/instrumentation/JcRuntimeTraceInstrumenter.kt index 5b217e2602..2c5ae45c1e 100644 --- a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/instrumentation/JcRuntimeTraceInstrumenter.kt +++ b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/instrumentation/JcRuntimeTraceInstrumenter.kt @@ -90,7 +90,7 @@ class JcRuntimeTraceInstrumenter( asmMethods.add(0, clinitCopy) } methodsToInstrument.forEach { jcMethod -> - val asmMethod = asmMethods.find { jcMethod.asmNode().isSameSignature(it) } ?: return@forEach + val asmMethod = asmMethods.find { jcMethod.isSameSignature(it) } ?: return@forEach val tracedMethod = instrumentMethod(jcMethod) asmMethods.replace(asmMethod, tracedMethod) } diff --git a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/mock/MockHelper.kt b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/mock/MockHelper.kt index 06606a6e1e..99b5204533 100644 --- a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/mock/MockHelper.kt +++ b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/mock/MockHelper.kt @@ -176,19 +176,18 @@ class MockHelper(val jcClasspath: JcClasspath, val classLoader: WorkerClassLoade private fun addMockInfoAndRedefineClass( jcClass: JcClassOrInterface, methods: List - ): Class<*> { - val classNode = jcClass.asmNode() + ): Class<*> = jcClass.withAsmNode { classNode -> val asmMethods = classNode.methods for (jcMethod in methods) { if (mockCache.contains(jcMethod)) continue - val asmMethod = asmMethods.find { jcMethod.asmNode().isSameSignature(it) } ?: continue + val asmMethod = asmMethods.find { jcMethod.isSameSignature(it) } ?: continue val encodedMethodId = encodeMethod(jcMethod) val mockedMethod = addMockToMethod(jcClass, jcMethod, encodedMethodId, false) asmMethods.replace(asmMethod, mockedMethod) } val jClass = jcClass.toJavaClass(classLoader) classLoader.redefineClass(jClass, classNode) - return classLoader.loadClass(jcClass.name) + return@withAsmNode classLoader.loadClass(jcClass.name) } @@ -196,41 +195,40 @@ class MockHelper(val jcClasspath: JcClasspath, val classLoader: WorkerClassLoade val filteredMethods = jcMethods.filter { it !in mockCache && !it.isAbstract } val groupedByClasses = filteredMethods.groupBy { it.enclosingClass } for ((jcClass, methodsToModify) in groupedByClasses) { - val jcClassByteCode = jcClass.asmNode() - val jClass = jcClass.toJavaClass(classLoader) - val asmMethods = jcClassByteCode.methods - for (jcMethod in methodsToModify) { - val encodedMethodId = encodeMethod(jcMethod) - val mockedMethod = addMockToMethod(jcClass, jcMethod, encodedMethodId, false) - val asmMethod = asmMethods.find { jcMethod.asmNode().isSameSignature(it) } ?: continue - asmMethods.replace(asmMethod, mockedMethod) + jcClass.withAsmNode { jcClassByteCode -> + val jClass = jcClass.toJavaClass(classLoader) + val asmMethods = jcClassByteCode.methods + for (jcMethod in methodsToModify) { + val encodedMethodId = encodeMethod(jcMethod) + val mockedMethod = addMockToMethod(jcClass, jcMethod, encodedMethodId, false) + val asmMethod = asmMethods.find { jcMethod.isSameSignature(it) } ?: continue + asmMethods.replace(asmMethod, mockedMethod) + } + classLoader.redefineClass(jClass, jcClassByteCode) } - classLoader.redefineClass(jClass, jcClassByteCode) } } private fun mockGlobal( jcClass: JcClassOrInterface, methods: List - ): Class<*> { - val classNode = jcClass.asmNode() + ): Class<*> = jcClass.withAsmNode { classNode -> val asmMethods = classNode.methods for (jcMethod in methods) { if (mockCache.contains(jcMethod)) continue - val asmMethod = asmMethods.find { jcMethod.asmNode().isSameSignature(it) } ?: continue + val asmMethod = asmMethods.find { jcMethod.isSameSignature(it) } ?: continue val encodedMethodId = encodeMethod(jcMethod) val mockedMethod = addMockToMethod(jcClass, jcMethod, encodedMethodId, true) asmMethods.replace(asmMethod, mockedMethod) } val jClass = jcClass.toJavaClass(classLoader) classLoader.redefineClass(jClass, classNode) - return classLoader.loadClass(jcClass.name) + return@withAsmNode classLoader.loadClass(jcClass.name) } //TODO Decide what to do with partially mocked classes private fun addMockInfoAndDefineNewClass( jcClass: JcClassOrInterface, methods: List - ): Class<*> { - val classNode = jcClass.asmNode() + ): Class<*> = jcClass.withAsmNode { classNode -> val mockedClassJVMName = "${classNode.name}${MOCKED_CLASS_POSTFIX}" val mockedClassName = mockedClassJVMName.replace('/', '.') val mockedClass = @@ -242,7 +240,7 @@ class MockHelper(val jcClasspath: JcClasspath, val classLoader: WorkerClassLoade if (mockedClass != null) { processMethodsWithDefaultImplementation(methods) - return mockedClass + return@withAsmNode mockedClass } val mockedClassNode = ClassNode() @@ -268,13 +266,13 @@ class MockHelper(val jcClasspath: JcClasspath, val classLoader: WorkerClassLoade for (jcMethod in abstractMethods) { val encodedMethodId = encodeMethod(jcMethod) val mockedMethod = addMockToAbstractMethod(jcMethod, encodedMethodId, classRebuilder) - val asmMethod = asmMethods.find { jcMethod.asmNode().isSameSignature(it) } ?: continue + val asmMethod = asmMethods.find { jcMethod.isSameSignature(it) } ?: continue asmMethods.replace(asmMethod, mockedMethod) } val defaultMethods = methods.filter { !it.isAbstract } for (jcMethod in defaultMethods) { - val asmMethod = asmMethods.find { jcMethod.asmNode().isSameSignature(it) } ?: continue + val asmMethod = asmMethods.find { jcMethod.isSameSignature(it) } ?: continue asmMethods.remove(asmMethod) } @@ -283,7 +281,7 @@ class MockHelper(val jcClasspath: JcClasspath, val classLoader: WorkerClassLoade for (jcConstructor in jcClass.constructors) { val newConstructor = rebuildConstructorForAbstractClass(jcConstructor, classRebuilder) val oldConstructor = - asmMethods.find { jcConstructor.asmNode().isSameSignature(it) } ?: error("cant find constructor in ASM") + asmMethods.find { jcConstructor.isSameSignature(it) } ?: error("cant find constructor in ASM") asmMethods.replace(oldConstructor, newConstructor) } @@ -293,7 +291,7 @@ class MockHelper(val jcClasspath: JcClasspath, val classLoader: WorkerClassLoade //Handle methods with default implementation processMethodsWithDefaultImplementation(methods) - return mockedJClass + return@withAsmNode mockedJClass } private fun rebuildConstructorForAbstractClass( 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 a4f5b1185a..bbdad00bd7 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 @@ -4,6 +4,7 @@ import org.jacodb.api.jvm.* import org.jacodb.api.jvm.cfg.JcInst import org.jacodb.api.jvm.ext.* import org.jacodb.impl.types.TypeNameImpl +import org.objectweb.asm.tree.MethodNode import org.usvm.instrumentation.testcase.executor.TestExecutorException import java.lang.reflect.Constructor import java.lang.reflect.Field @@ -166,4 +167,7 @@ private fun Array>.toJcdbFormat(): String = if (isEmpty()) "" else joinToString(";", postfix = ";") { it.typeName } fun Method.isSameSignatures(jcMethod: JcMethod) = - jcdbSignature == jcMethod.jcdbSignature \ No newline at end of file + jcdbSignature == jcMethod.jcdbSignature + +fun JcMethod.isSameSignature(mn: MethodNode): Boolean = + withAsmNode { it.isSameSignature(mn) } diff --git a/usvm-ts/src/main/kotlin/org/usvm/TSApplicationGraph.kt b/usvm-ts/src/main/kotlin/org/usvm/TSApplicationGraph.kt index dc734e37b4..b49d4033ee 100644 --- a/usvm-ts/src/main/kotlin/org/usvm/TSApplicationGraph.kt +++ b/usvm-ts/src/main/kotlin/org/usvm/TSApplicationGraph.kt @@ -1,13 +1,13 @@ package org.usvm import org.jacodb.ets.base.EtsStmt -import org.jacodb.ets.graph.EtsApplicationGraph +import org.jacodb.ets.graph.EtsApplicationGraphImpl import org.jacodb.ets.model.EtsFile import org.jacodb.ets.model.EtsMethod import org.usvm.statistics.ApplicationGraph class TSApplicationGraph(project: EtsFile) : ApplicationGraph { - private val applicationGraph = EtsApplicationGraph(project) + private val applicationGraph = EtsApplicationGraphImpl(project) override fun predecessors(node: EtsStmt): Sequence = applicationGraph.predecessors(node)