Skip to content

Commit ee13ca9

Browse files
committed
Fixes with arrays
1 parent 7354d9f commit ee13ca9

6 files changed

Lines changed: 44 additions & 4 deletions

File tree

usvm-ts/src/main/kotlin/org/usvm/machine/expr/CallApproximations.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package org.usvm.machine.expr
22

33
import io.ksmt.utils.asExpr
44
import mu.KotlinLogging
5+
import org.jacodb.ets.model.EtsAnyType
56
import org.jacodb.ets.model.EtsArrayType
67
import org.jacodb.ets.model.EtsClassSignature
78
import org.jacodb.ets.model.EtsInstanceCallExpr
@@ -301,7 +302,14 @@ private fun TsExprResolver.handleArrayPush(
301302
index = length,
302303
type = arrayType,
303304
)
304-
memory.write(newIndexLValue, arg.asExpr(elementSort), guard = trueExpr)
305+
306+
if (arg.sort != elementSort && (arrayType.elementType is EtsUnknownType || arrayType.elementType is EtsAnyType)) {
307+
val wrappedArg = arg.toFakeObject(scope)
308+
lValuesToAllocatedFakeObjects += newIndexLValue to wrappedArg
309+
memory.write(newIndexLValue, wrappedArg.asExpr(elementSort), guard = trueExpr)
310+
} else {
311+
memory.write(newIndexLValue, arg.asExpr(elementSort), guard = trueExpr)
312+
}
305313

306314
// Return the new length of the array (as per ECMAScript spec for Array.push)
307315
mkBvToFpExpr(

usvm-ts/src/main/kotlin/org/usvm/machine/interpreter/TsInterpreter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ class TsInterpreter(
738738
state.pathConstraints += mkNot(mkHeapRefEq(ref, mkUndefinedValue()))
739739

740740
if (parameterType is EtsArrayType) {
741-
state.pathConstraints += state.memory.types.evalTypeEquals(ref, parameterType)
741+
state.pathConstraints += state.memory.types.evalIsSubtype(ref, parameterType)
742742
return@run
743743
}
744744

usvm-ts/src/main/kotlin/org/usvm/machine/types/TsTypeSystem.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,11 @@ class TsTypeSystem(
304304
is EtsClassType,
305305
->
306306
if ((t as? EtsClassType)?.signature == EtsHierarchy.OBJECT_CLASS.signature) { // TODO change it
307-
scene.projectAndSdkClasses.asSequence().map { it.type } + EtsStringType + EtsAnyType
307+
val classes = scene.projectAndSdkClasses.asSequence().map { it.type } + EtsStringType + EtsAnyType
308+
309+
classes + classes.map { EtsArrayType(it, 1) } +
310+
EtsArrayType(EtsNumberType, 1) +
311+
EtsArrayType(EtsBooleanType, 1)
308312
} else {
309313
hierarchy.classesForType(t)
310314
.asSequence()

usvm-ts/src/test/kotlin/org/usvm/samples/arrays/ArrayMethods.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,24 @@ class ArrayMethods : TsMethodTestRunner() {
2525
)
2626
}
2727

28+
@Test
29+
fun testArrayPushIntoNumber() {
30+
val method = getMethod("arrayPushIntoNumber")
31+
discoverProperties<TsTestValue.TsArray<*>, TsTestValue.TsArray<*>>(
32+
method = method,
33+
{ x, r -> x.values.size == r.values.size - 1 && (r.values.last() as TsTestValue.TsNumber).number == 123.0 }
34+
)
35+
}
36+
37+
@Test
38+
fun testArrayPushIntoUnknown() {
39+
val method = getMethod("arrayPushIntoUnknown")
40+
discoverProperties<TsTestValue.TsArray<*>, TsTestValue.TsArray<*>>(
41+
method = method,
42+
{ x, r -> x.values.size == r.values.size - 1 && (r.values.last() as TsTestValue.TsNumber).number == 123.0 }
43+
)
44+
}
45+
2846
@Test
2947
fun testArrayPop() {
3048
val method = getMethod("arrayPop")

usvm-ts/src/test/kotlin/org/usvm/util/TsTestResolver.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ open class TsTestStateResolver(
308308
"Other sorts must be resolved above, but got: $sort"
309309
}
310310

311-
val lValue = mkArrayIndexLValue(sort, concreteRef, index, type)
311+
val lValue = mkArrayIndexLValue(sort, heapRef, index, type)
312312
val value = memory.read(lValue)
313313

314314
if (value.sort is UAddressSort) {

usvm-ts/src/test/resources/samples/arrays/ArrayMethods.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ class ArrayMethods {
1212
}
1313
}
1414

15+
arrayPushIntoNumber(x: number[]) {
16+
x.push(123);
17+
return x;
18+
}
19+
20+
arrayPushIntoUnknown(x: any[]) {
21+
x.push(123);
22+
return x;
23+
}
24+
1525
arrayPop(x: boolean) {
1626
const arr = [10, 20, 30];
1727
const lastElement = arr.pop();

0 commit comments

Comments
 (0)