Skip to content

Commit

Permalink
m
Browse files Browse the repository at this point in the history
  • Loading branch information
AbdullinAM committed Oct 9, 2023
1 parent 28a717e commit 882e6da
Show file tree
Hide file tree
Showing 11 changed files with 56 additions and 28 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>org.vorpal.research</groupId>
<artifactId>kfg</artifactId>
<version>0.4.10</version>
<version>0.4.11</version>

<properties>
<jvm.version>1.8</jvm.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ class ClassBuilder(override val cm: ClassManager, val `class`: Class) : ClassVis
}

operator fun invoke(): ClassNode = build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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) {
Expand Down
15 changes: 10 additions & 5 deletions src/main/kotlin/org/vorpal/research/kfg/ir/Class.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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?
Expand Down Expand Up @@ -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
}
Expand All @@ -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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down
16 changes: 8 additions & 8 deletions src/main/kotlin/org/vorpal/research/kfg/type/PrimitiveType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
}
Expand Down
24 changes: 16 additions & 8 deletions src/main/kotlin/org/vorpal/research/kfg/type/Reference.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand All @@ -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
}
}
Expand All @@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
5 changes: 3 additions & 2 deletions src/main/kotlin/org/vorpal/research/kfg/type/Type.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/org/vorpal/research/kfg/type/VoidType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
6 changes: 6 additions & 0 deletions src/main/kotlin/org/vorpal/research/kfg/util/jar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down

0 comments on commit 882e6da

Please sign in to comment.