Skip to content

Commit

Permalink
Upgrade jacodb version
Browse files Browse the repository at this point in the history
  • Loading branch information
Saloed committed Aug 8, 2024
1 parent e1e3ac7 commit 27820ea
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 29 deletions.
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,61 +176,59 @@ class MockHelper(val jcClasspath: JcClasspath, val classLoader: WorkerClassLoade

private fun addMockInfoAndRedefineClass(
jcClass: JcClassOrInterface, methods: List<JcMethod>
): 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)
}


private fun processMethodsWithDefaultImplementation(jcMethods: List<JcMethod>) {
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<JcMethod>
): 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<JcMethod>
): Class<*> {
val classNode = jcClass.asmNode()
): Class<*> = jcClass.withAsmNode { classNode ->
val mockedClassJVMName = "${classNode.name}${MOCKED_CLASS_POSTFIX}"
val mockedClassName = mockedClassJVMName.replace('/', '.')
val mockedClass =
Expand All @@ -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()
Expand All @@ -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)
}

Expand All @@ -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)
}

Expand All @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -166,4 +167,7 @@ private fun Array<Class<*>>.toJcdbFormat(): String =
if (isEmpty()) "" else joinToString(";", postfix = ";") { it.typeName }

fun Method.isSameSignatures(jcMethod: JcMethod) =
jcdbSignature == jcMethod.jcdbSignature
jcdbSignature == jcMethod.jcdbSignature

fun JcMethod.isSameSignature(mn: MethodNode): Boolean =
withAsmNode { it.isSameSignature(mn) }
4 changes: 2 additions & 2 deletions usvm-ts/src/main/kotlin/org/usvm/TSApplicationGraph.kt
Original file line number Diff line number Diff line change
@@ -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<EtsMethod, EtsStmt> {
private val applicationGraph = EtsApplicationGraph(project)
private val applicationGraph = EtsApplicationGraphImpl(project)

override fun predecessors(node: EtsStmt): Sequence<EtsStmt> =
applicationGraph.predecessors(node)
Expand Down

0 comments on commit 27820ea

Please sign in to comment.