Skip to content

Commit

Permalink
✨ Pass instanceof test
Browse files Browse the repository at this point in the history
  • Loading branch information
yhs0602 committed May 15, 2024
1 parent 8c23488 commit 3cf6d33
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/main/kotlin/vm/Environment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ class Environment(
return true
}

val targetType = classLoader.getClass(TypeId(targetTypeDescriptor))
val objectType = classLoader.getClass(objectRef.typeId)
return objectType.isAssignableTo(targetType)

// Check the interface first
when (val instance = objectRef.value) {
null -> return false
Expand Down
7 changes: 4 additions & 3 deletions src/main/kotlin/vm/classloader/DexClassLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ class DexClassLoader(
}
val superClassTypeId = parsedClass.classDef.superClassTypeId
val superClassType = if (superClassTypeId != null) {
loadedTypes[superClassTypeId] ?: error(
"Superclass ${superClassTypeId.descriptor} for ${parsedClass.classDef.typeId} not loaded"
)
loadedTypes[superClassTypeId] ?: getClass(superClassTypeId)
// error(
// "Superclass ${superClassTypeId.descriptor} for ${parsedClass.classDef.typeId} not loaded"
// )
} else {
null
}
Expand Down
12 changes: 12 additions & 0 deletions src/main/kotlin/vm/instruction/LitOpInstruction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,10 @@ class OrIntLit8(pc: Int, code: CodeItem) : Instruction._22b(pc, code) {
memory.registers[vAA] = RegisterValue.Int(value1.value or value2)
return pc + insnLength
}

override fun toString(): String {
return "OrIntLit8 v$vAA = v$vBB | $LCC"
}
}

class XorIntLit8(pc: Int, code: CodeItem) : Instruction._22b(pc, code) {
Expand All @@ -236,6 +240,10 @@ class XorIntLit8(pc: Int, code: CodeItem) : Instruction._22b(pc, code) {
memory.registers[vAA] = RegisterValue.Int(value1.value xor value2)
return pc + insnLength
}

override fun toString(): String {
return "XorIntLit8 v$vAA = v$vBB ^ $LCC"
}
}

class ShlIntLit8(pc: Int, code: CodeItem) : Instruction._22b(pc, code) {
Expand All @@ -249,6 +257,10 @@ class ShlIntLit8(pc: Int, code: CodeItem) : Instruction._22b(pc, code) {
memory.registers[vAA] = RegisterValue.Int(value1.value shl value2)
return pc + insnLength
}

override fun toString(): String {
return "ShlIntLit8 v$vAA = v$vBB << $LCC"
}
}

class ShrIntLit8(pc: Int, code: CodeItem) : Instruction._22b(pc, code) {
Expand Down
17 changes: 17 additions & 0 deletions src/test/kotlin/AdvancedTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,23 @@ class AdvancedTest {
executeMethod(codeItem, environment, args, args.size, 0)
}

@Test
fun TestInstanceOf() {
testInterpreter(
"src/test/resources/advanced/",
"com.example.sample",
"InstanceOfTestKt",
"testInstanceOf",
listOf(
GeneralMockedClass(StringBuilder::class.java),
GeneralMockedClass(System::class.java),
GeneralMockedClass(Intrinsics::class.java),
GeneralMockedClass(Object::class.java),
GeneralMockedClass(PrintStream::class.java),
)
)
}

@Test
fun TestStatic() {
testInterpreter(
Expand Down
Binary file modified src/test/resources/advanced/classes4.dex
Binary file not shown.
40 changes: 40 additions & 0 deletions src/test/resources/advanced/instanceoftest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.example.sample

open class B

open class C: B()

open class D: C()

open class E: D()

fun testInstanceOf() {
val b = B()
val c = C()
val d = D()
val e = E()

assert(b is B)
assert(c is C)
assert(d is D)
assert(e is E)

assert(b !is C)
assert(c !is D)
assert(d !is E)

assert(b !is E)
assert(c !is E)
assert(d !is E)

assert(e is D)
assert(e is C)
assert(e is B)

assert(d is C)
assert(d is B)

assert(c is B)

println("All tests passed!")
}

0 comments on commit 3cf6d33

Please sign in to comment.