From d18f636317adbf9a69158579926386b7021646fb Mon Sep 17 00:00:00 2001 From: SirYwell Date: Mon, 5 Aug 2024 10:47:00 +0200 Subject: [PATCH] fix: Branching support for more types --- .idea/gradle.xml | 17 ----------- .../sirywell/handlehints/dfa/SsaAnalyzer.kt | 28 ++++++++++++++++--- ...TypeResolver.kt => TypeElementResolver.kt} | 5 ++-- .../handlehints/type/MemoryLayoutType.kt | 7 +++-- 4 files changed, 31 insertions(+), 26 deletions(-) delete mode 100644 .idea/gradle.xml rename src/main/kotlin/de/sirywell/handlehints/dfa/{HandleTypeResolver.kt => TypeElementResolver.kt} (95%) diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index f2c1963..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/main/kotlin/de/sirywell/handlehints/dfa/SsaAnalyzer.kt b/src/main/kotlin/de/sirywell/handlehints/dfa/SsaAnalyzer.kt index 487797d..d957a3e 100644 --- a/src/main/kotlin/de/sirywell/handlehints/dfa/SsaAnalyzer.kt +++ b/src/main/kotlin/de/sirywell/handlehints/dfa/SsaAnalyzer.kt @@ -12,6 +12,7 @@ import de.sirywell.handlehints.foreign.MemoryLayoutHelper import de.sirywell.handlehints.foreign.PathElementHelper import de.sirywell.handlehints.mhtype.* import de.sirywell.handlehints.type.* +import kotlin.reflect.KClass class SsaAnalyzer(private val controlFlow: ControlFlow, val typeData: TypeData) { companion object { @@ -281,11 +282,22 @@ class SsaAnalyzer(private val controlFlow: ControlFlow, val typeData: TypeData) noMatch() } } - // TODO is there a better way for this? - val resolver = HandleTypeResolver(this, block, BotMethodHandleType, MethodHandleType::class) - val resolver2 = HandleTypeResolver(this, block, BotVarHandleType, VarHandleType::class) + return withResolver(expression, block) + } + + private fun withResolver(expression: PsiExpression, block: Block): TypeLatticeElement<*>? { + fun > ter(block: Block, t: T, clazz: KClass): TypeElementResolver { + return TypeElementResolver(this, block, t, clazz) + } + val resolver = (when (expression.type) { + methodHandleType(expression) -> ter(block, BotMethodHandleType, MethodHandleType::class) + varHandleType(expression) -> ter(block, BotVarHandleType, VarHandleType::class) + pathElementType(expression) -> ter(block, BotPathElementType, PathElementType::class) + in memoryLayoutTypes(expression) -> ter(block, BotMemoryLayoutType, MemoryLayoutType::class) + + else -> return noMatch() + }) expression.accept(resolver) - expression.accept(resolver2) return resolver.result } @@ -301,10 +313,12 @@ class SsaAnalyzer(private val controlFlow: ControlFlow, val typeData: TypeData) else if (arguments.size == 2) pathElementHelper.sequenceElement(arguments[0], arguments[1]) else noMatch() } + "groupElement" -> { if (arguments.size != 1) noMatch() else pathElementHelper.groupElement(arguments[0]) } + else -> noMatch() } } @@ -323,29 +337,35 @@ class SsaAnalyzer(private val controlFlow: ControlFlow, val typeData: TypeData) if (arguments.size != 1 || qualifier == null) return noMatch() memoryLayoutHelper.withName(qualifier, arguments[0], block) } + "withOrder" -> qualifier?.type(block) "withByteAlignment" -> { if (arguments.size != 1 || qualifier == null) return noMatch() memoryLayoutHelper.withByteAlignment(qualifier, arguments[0], block) } + "structLayout" -> memoryLayoutHelper.structLayout(arguments, block) "unionLayout" -> memoryLayoutHelper.unionLayout(arguments, block) "sequenceLayout" -> { if (arguments.size != 2) return noMatch() memoryLayoutHelper.sequenceLayout(arguments[0], arguments[1], block) } + "paddingLayout" -> { if (arguments.size != 1) return noMatch() memoryLayoutHelper.paddingLayout(arguments[0]) } + "scaleHandle" -> { if (arguments.isNotEmpty()) return noMatch() memoryLayoutHelper.scaleHandle() } + "arrayElementVarHandle" -> { if (qualifier == null) return noMatch() memoryLayoutHelper.arrayElementVarHandle(qualifier, arguments, block) } + "varHandle" -> { if (qualifier == null) return noMatch() memoryLayoutHelper.varHandle(qualifier, arguments, methodExpression, block) diff --git a/src/main/kotlin/de/sirywell/handlehints/dfa/HandleTypeResolver.kt b/src/main/kotlin/de/sirywell/handlehints/dfa/TypeElementResolver.kt similarity index 95% rename from src/main/kotlin/de/sirywell/handlehints/dfa/HandleTypeResolver.kt rename to src/main/kotlin/de/sirywell/handlehints/dfa/TypeElementResolver.kt index cc48924..188aa61 100644 --- a/src/main/kotlin/de/sirywell/handlehints/dfa/HandleTypeResolver.kt +++ b/src/main/kotlin/de/sirywell/handlehints/dfa/TypeElementResolver.kt @@ -7,13 +7,12 @@ import de.sirywell.handlehints.type.TypeLatticeElement import kotlin.reflect.KClass import kotlin.reflect.cast -class HandleTypeResolver>( +class TypeElementResolver>( private val ssaAnalyzer: SsaAnalyzer, private val block: SsaConstruction.Block, private val bot: T, private val clazz: KClass -) : - JavaRecursiveElementVisitor() { +) : JavaRecursiveElementVisitor() { var result: T? = null private set diff --git a/src/main/kotlin/de/sirywell/handlehints/type/MemoryLayoutType.kt b/src/main/kotlin/de/sirywell/handlehints/type/MemoryLayoutType.kt index d21f9fa..3b0e986 100644 --- a/src/main/kotlin/de/sirywell/handlehints/type/MemoryLayoutType.kt +++ b/src/main/kotlin/de/sirywell/handlehints/type/MemoryLayoutType.kt @@ -276,8 +276,11 @@ val WITHOUT_NAME = ExactLayoutName(null) data class ExactLayoutName(val name: String?) : LayoutName { override fun joinIdentical(other: LayoutName): Pair { - if (other is ExactLayoutName && this.name == other.name) { - return this to TriState.YES + if (other is ExactLayoutName) { + if (this.name == other.name) { + return this to TriState.YES + } + return TopLayoutName to TriState.NO } if (other is TopLayoutName) return TopLayoutName to TriState.UNKNOWN // BotLayoutName