From 882e6da0bb82e7b661b1eda15bf0b0dc3ce4aa13 Mon Sep 17 00:00:00 2001 From: Azat Abdullin Date: Mon, 9 Oct 2023 17:19:09 +0300 Subject: [PATCH] m --- pom.xml | 2 +- .../research/kfg/builder/asm/ClassBuilder.kt | 2 +- .../kfg/builder/cfg/impl/FrameState.kt | 4 ++-- .../org/vorpal/research/kfg/ir/Class.kt | 15 ++++++++---- .../value/instruction/InstructionFactory.kt | 5 ++++ .../vorpal/research/kfg/type/PrimitiveType.kt | 16 ++++++------- .../org/vorpal/research/kfg/type/Reference.kt | 24 ++++++++++++------- .../research/kfg/type/SystemTypeNames.kt | 3 +++ .../org/vorpal/research/kfg/type/Type.kt | 5 ++-- .../org/vorpal/research/kfg/type/VoidType.kt | 2 +- .../org/vorpal/research/kfg/util/jar.kt | 6 +++++ 11 files changed, 56 insertions(+), 28 deletions(-) diff --git a/pom.xml b/pom.xml index e95c979..f050fa1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.vorpal.research kfg - 0.4.10 + 0.4.11 1.8 diff --git a/src/main/kotlin/org/vorpal/research/kfg/builder/asm/ClassBuilder.kt b/src/main/kotlin/org/vorpal/research/kfg/builder/asm/ClassBuilder.kt index 79e3792..733c72b 100644 --- a/src/main/kotlin/org/vorpal/research/kfg/builder/asm/ClassBuilder.kt +++ b/src/main/kotlin/org/vorpal/research/kfg/builder/asm/ClassBuilder.kt @@ -49,4 +49,4 @@ class ClassBuilder(override val cm: ClassManager, val `class`: Class) : ClassVis } operator fun invoke(): ClassNode = build() -} \ No newline at end of file +} diff --git a/src/main/kotlin/org/vorpal/research/kfg/builder/cfg/impl/FrameState.kt b/src/main/kotlin/org/vorpal/research/kfg/builder/cfg/impl/FrameState.kt index 2de6a19..4cb9720 100644 --- a/src/main/kotlin/org/vorpal/research/kfg/builder/cfg/impl/FrameState.kt +++ b/src/main/kotlin/org/vorpal/research/kfg/builder/cfg/impl/FrameState.kt @@ -25,7 +25,7 @@ private object TopType : Type() { override val isConcrete: Boolean get() = true - override fun isSubtypeOf(other: Type) = false + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean) = false } private object UninitializedThisType : Type() { @@ -41,7 +41,7 @@ private object UninitializedThisType : Type() { override val isConcrete: Boolean get() = true - override fun isSubtypeOf(other: Type) = false + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean) = false } private fun parsePrimitiveType(tf: TypeFactory, opcode: Int) = when (opcode) { diff --git a/src/main/kotlin/org/vorpal/research/kfg/ir/Class.kt b/src/main/kotlin/org/vorpal/research/kfg/ir/Class.kt index 1178340..44e8ea8 100644 --- a/src/main/kotlin/org/vorpal/research/kfg/ir/Class.kt +++ b/src/main/kotlin/org/vorpal/research/kfg/ir/Class.kt @@ -8,6 +8,7 @@ import org.vorpal.research.kfg.InvalidStateException import org.vorpal.research.kfg.Package import org.vorpal.research.kfg.UnknownInstanceException import org.vorpal.research.kfg.type.ClassType +import org.vorpal.research.kfg.type.SystemTypeNames import org.vorpal.research.kfg.type.Type import org.vorpal.research.kfg.type.TypeFactory import org.vorpal.research.kthelper.assert.ktassert @@ -126,8 +127,8 @@ abstract class Class : Node { val asType: ClassType by lazy { ClassType(this) } - abstract fun isAncestorOf(other: Class): Boolean - fun isInheritorOf(other: Class) = other.isAncestorOf(this) + abstract fun isAncestorOf(other: Class, outerClassBehavior: Boolean = true): Boolean + fun isInheritorOf(other: Class, outerClassBehavior: Boolean = true) = other.isAncestorOf(this, outerClassBehavior) abstract fun getFieldConcrete(name: String, type: Type): Field? abstract fun getMethodConcrete(name: String, desc: MethodDescriptor): Method? @@ -246,13 +247,13 @@ class ConcreteClass : Class { } } - override fun isAncestorOf(other: Class): Boolean { + override fun isAncestorOf(other: Class, outerClassBehavior: Boolean): Boolean { if (this == other) return true else { other.superClass?.let { if (isAncestorOf(it)) return true } - for (it in other.interfaces) if (isAncestorOf(it)) return true + for (it in other.interfaces) if (isAncestorOf(it, outerClassBehavior)) return true } return false } @@ -277,5 +278,9 @@ class OuterClass( } } - override fun isAncestorOf(other: Class) = true + override fun isAncestorOf(other: Class, outerClassBehavior: Boolean) = when (this.fullName) { + other.fullName -> true + SystemTypeNames.objectClass -> true + else -> outerClassBehavior + } } diff --git a/src/main/kotlin/org/vorpal/research/kfg/ir/value/instruction/InstructionFactory.kt b/src/main/kotlin/org/vorpal/research/kfg/ir/value/instruction/InstructionFactory.kt index 5a0a89e..0179602 100644 --- a/src/main/kotlin/org/vorpal/research/kfg/ir/value/instruction/InstructionFactory.kt +++ b/src/main/kotlin/org/vorpal/research/kfg/ir/value/instruction/InstructionFactory.kt @@ -4,6 +4,7 @@ import org.vorpal.research.kfg.ClassManager import org.vorpal.research.kfg.ir.BasicBlock import org.vorpal.research.kfg.ir.Class import org.vorpal.research.kfg.ir.Field +import org.vorpal.research.kfg.ir.Location import org.vorpal.research.kfg.ir.Method import org.vorpal.research.kfg.ir.MethodDescriptor import org.vorpal.research.kfg.ir.value.Name @@ -682,6 +683,10 @@ interface InstructionBuilder { * unknown value wrapper */ fun unknownValue(name: Name, type: Type) = instructions.getUnknownValueInst(ctx, name, type) + + fun Instruction.withLocation(location: Location) { + this.location = location + } } class InstructionBuilderImpl( diff --git a/src/main/kotlin/org/vorpal/research/kfg/type/PrimitiveType.kt b/src/main/kotlin/org/vorpal/research/kfg/type/PrimitiveType.kt index d0c6994..e8d73f9 100644 --- a/src/main/kotlin/org/vorpal/research/kfg/type/PrimitiveType.kt +++ b/src/main/kotlin/org/vorpal/research/kfg/type/PrimitiveType.kt @@ -32,7 +32,7 @@ object BoolType : Integer() { override val signed = false override val asmDesc = "Z" - override fun isSubtypeOf(other: Type) = other is BoolType + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean) = other is BoolType } object ByteType : Integer() { @@ -42,7 +42,7 @@ object ByteType : Integer() { override val isByte = true override val asmDesc = "B" - override fun isSubtypeOf(other: Type) = when (other) { + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean) = when (other) { is ByteType -> true is ShortType, is IntType, is LongType, is Real -> true else -> false @@ -56,7 +56,7 @@ object ShortType : Integer() { override val isShort = true override val asmDesc = "S" - override fun isSubtypeOf(other: Type) = when (other) { + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean) = when (other) { is ShortType -> true is IntType, is LongType, is Real -> true else -> false @@ -70,7 +70,7 @@ object IntType : Integer() { override val isInt = true override val asmDesc = "I" - override fun isSubtypeOf(other: Type) = when (other) { + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean) = when (other) { is IntType -> true is LongType, is Real -> true else -> false @@ -86,7 +86,7 @@ object LongType : Integer() { override val isDWord = true override val asmDesc = "J" - override fun isSubtypeOf(other: Type) = when (other) { + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean) = when (other) { is LongType -> true is Real -> true else -> false @@ -100,7 +100,7 @@ object CharType : Integer() { override val isChar = true override val asmDesc = "C" - override fun isSubtypeOf(other: Type) = when (other) { + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean) = when (other) { is CharType -> true is IntType, is LongType, is Real -> true else -> false @@ -124,7 +124,7 @@ object FloatType : Real() { override val name = "float" override val asmDesc = "F" - override fun isSubtypeOf(other: Type) = when (other) { + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean) = when (other) { is FloatType -> true is DoubleType -> true else -> false @@ -137,7 +137,7 @@ object DoubleType : Real() { override val isDWord = true override val asmDesc = "D" - override fun isSubtypeOf(other: Type) = when (other) { + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean) = when (other) { is DoubleType -> true else -> false } diff --git a/src/main/kotlin/org/vorpal/research/kfg/type/Reference.kt b/src/main/kotlin/org/vorpal/research/kfg/type/Reference.kt index ec10dc9..df8feb7 100644 --- a/src/main/kotlin/org/vorpal/research/kfg/type/Reference.kt +++ b/src/main/kotlin/org/vorpal/research/kfg/type/Reference.kt @@ -28,8 +28,9 @@ open class ClassType(val klass: Class) : Reference() { override val isConcrete: Boolean get() = klass is ConcreteClass - override fun isSubtypeOf(other: Type): Boolean = when (other) { - is ClassType -> this.klass.isInheritorOf(other.klass) + + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean): Boolean = when (other) { + is ClassType -> this.klass.isInheritorOf(other.klass, outerClassBehavior) else -> false } } @@ -50,18 +51,24 @@ open class ArrayType(val component: Type) : Reference() { override val isConcrete: Boolean get() = component.isConcrete - override fun isSubtypeOf(other: Type): Boolean = when (other) { + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean): Boolean = when (other) { this -> true is ArrayType -> when { - this.component.isReference && other.component.isReference -> this.component.isSubtypeOf(other.component) + this.component.isReference && other.component.isReference -> this.component.isSubtypeOf( + other.component, + outerClassBehavior + ) + else -> false } + is ClassType -> when (other.klass.fullName) { - "java/lang/Object" -> true - "java/lang/Cloneable" -> true - "java/io/Serializable" -> true + SystemTypeNames.objectClass -> true + SystemTypeNames.cloneableClass -> true + SystemTypeNames.serializableClass -> true else -> false } + else -> false } } @@ -77,5 +84,6 @@ object NullType : Reference() { override val isConcrete: Boolean get() = true - override fun isSubtypeOf(other: Type) = true + + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean) = true } diff --git a/src/main/kotlin/org/vorpal/research/kfg/type/SystemTypeNames.kt b/src/main/kotlin/org/vorpal/research/kfg/type/SystemTypeNames.kt index 323cc9c..3c946f9 100644 --- a/src/main/kotlin/org/vorpal/research/kfg/type/SystemTypeNames.kt +++ b/src/main/kotlin/org/vorpal/research/kfg/type/SystemTypeNames.kt @@ -77,4 +77,7 @@ object SystemTypeNames { const val illegalArgumentClass = "java/lang/IllegalArgumentException" const val runtimeException = "java/lang/RuntimeException" + + const val cloneableClass = "java/lang/Cloneable" + const val serializableClass = "java/io/Serializable" } diff --git a/src/main/kotlin/org/vorpal/research/kfg/type/Type.kt b/src/main/kotlin/org/vorpal/research/kfg/type/Type.kt index 2157358..8d2f46c 100644 --- a/src/main/kotlin/org/vorpal/research/kfg/type/Type.kt +++ b/src/main/kotlin/org/vorpal/research/kfg/type/Type.kt @@ -35,8 +35,9 @@ abstract class Type { abstract val bitSize: Int abstract val isConcrete: Boolean - abstract fun isSubtypeOf(other: Type): Boolean - fun isSupertypeOf(other: Type): Boolean = other.isSubtypeOf(this) + abstract fun isSubtypeOf(other: Type, outerClassBehavior: Boolean = true): Boolean + fun isSupertypeOf(other: Type, outerClassBehavior: Boolean = true): Boolean = + other.isSubtypeOf(this, outerClassBehavior) val asArray: ArrayType by lazy { ArrayType(this) diff --git a/src/main/kotlin/org/vorpal/research/kfg/type/VoidType.kt b/src/main/kotlin/org/vorpal/research/kfg/type/VoidType.kt index 4257e28..a044846 100644 --- a/src/main/kotlin/org/vorpal/research/kfg/type/VoidType.kt +++ b/src/main/kotlin/org/vorpal/research/kfg/type/VoidType.kt @@ -14,5 +14,5 @@ object VoidType : Type() { override fun toString(): String = name override val isConcrete get() = true - override fun isSubtypeOf(other: Type) = false + override fun isSubtypeOf(other: Type, outerClassBehavior: Boolean) = false } diff --git a/src/main/kotlin/org/vorpal/research/kfg/util/jar.kt b/src/main/kotlin/org/vorpal/research/kfg/util/jar.kt index 4b53273..2329546 100644 --- a/src/main/kotlin/org/vorpal/research/kfg/util/jar.kt +++ b/src/main/kotlin/org/vorpal/research/kfg/util/jar.kt @@ -196,6 +196,12 @@ internal fun ClassNode.write( this.writeBytes(this@write.toByteArray(loader, flags, checkClass)) } +fun Class.toByteArray( + loader: ClassLoader, + flags: Flags = Flags.writeComputeAll, + checkClass: Boolean = false +): ByteArray = ClassBuilder(cm, this).build().toByteArray(loader, flags, checkClass) + fun Class.write( cm: ClassManager, loader: ClassLoader, path: Path = Paths.get("$fullName.class"),