Skip to content

Commit 7b0b716

Browse files
committed
Fix everything
1 parent 84d4aeb commit 7b0b716

9 files changed

Lines changed: 77 additions & 39 deletions

File tree

usvm-ts/src/main/kotlin/org/usvm/api/TsTest.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ sealed interface TsTestValue {
4848
}
4949
}
5050

51-
data class TsObject(val addr: Int) : TsTestValue
52-
5351
data class TsClass(
5452
val name: String,
5553
val properties: Map<String, TsTestValue>,

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

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ import org.usvm.UExpr
8585
import org.usvm.UHeapRef
8686
import org.usvm.USort
8787
import org.usvm.api.allocateArray
88+
import org.usvm.api.evalTypeEquals
8889
import org.usvm.dataflow.ts.infer.tryGetKnownType
8990
import org.usvm.dataflow.ts.util.type
9091
import org.usvm.isTrue
@@ -275,17 +276,39 @@ class TsExprResolver(
275276
return mkStringConstant("boolean", scope)
276277
}
277278
if (arg.sort == addressSort) {
279+
// val ref = arg.asExpr(addressSort)
280+
// if (ref == mkTsNullValue()) {
281+
// return mkStringConstant("object", scope)
282+
// } else if (ref == mkUndefinedValue()) {
283+
// return mkStringConstant("undefined", scope)
284+
// }
285+
// val isStringLValue = mkFieldLValue(boolSort, ref, "_isString")
286+
// if (scope.calcOnState { memory.read(isStringLValue) }.isTrue) {
287+
// return mkStringConstant("string", scope)
288+
// }
289+
// return mkStringConstant("object", scope)
290+
278291
val ref = arg.asExpr(addressSort)
279-
if (ref == mkTsNullValue()) {
280-
return mkStringConstant("object", scope)
281-
} else if (ref == mkUndefinedValue()) {
282-
return mkStringConstant("undefined", scope)
283-
}
284-
val isStringLValue = mkFieldLValue(boolSort, ref, "_isString")
285-
if (scope.calcOnState { memory.read(isStringLValue) }.isTrue) {
286-
return mkStringConstant("string", scope)
287-
}
288-
return mkStringConstant("object", scope)
292+
// if (ref == mkTsNullValue()) {
293+
// return mkStringConstant("object", scope)
294+
// }
295+
// if (ref == mkUndefinedValue()) {
296+
// return mkStringConstant("undefined", scope)
297+
// }
298+
return mkIte(
299+
condition = mkHeapRefEq(ref, mkTsNullValue()),
300+
trueBranch = mkStringConstant("object", scope),
301+
falseBranch = mkIte(
302+
condition = mkHeapRefEq(ref, mkUndefinedValue()),
303+
trueBranch = mkStringConstant("undefined", scope),
304+
falseBranch = mkIte(
305+
// condition = scope.calcOnState { memory.read( mkFieldLValue(boolSort, ref, "_isString"))},
306+
condition = scope.calcOnState { memory.types.evalTypeEquals(ref, EtsStringType) },
307+
trueBranch = mkStringConstant("string", scope),
308+
falseBranch = mkStringConstant("object", scope),
309+
)
310+
)
311+
)
289312
}
290313

291314
logger.warn { "visit(${expr::class.simpleName}) is not implemented yet" }

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

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import org.jacodb.ets.model.EtsRefType
1919
import org.jacodb.ets.model.EtsReturnStmt
2020
import org.jacodb.ets.model.EtsStaticFieldRef
2121
import org.jacodb.ets.model.EtsStmt
22+
import org.jacodb.ets.model.EtsStringType
2223
import org.jacodb.ets.model.EtsThis
2324
import org.jacodb.ets.model.EtsThrowStmt
2425
import org.jacodb.ets.model.EtsType
@@ -622,6 +623,8 @@ class TsInterpreter(
622623
targets = UTargetsSet.from(targets),
623624
)
624625

626+
state.memory.types.allocate(mkTsNullValue().address, EtsNullType)
627+
625628
val solver = ctx.solver<EtsType>()
626629

627630
// TODO check for statics
@@ -637,10 +640,13 @@ class TsInterpreter(
637640
state.pathConstraints += state.memory.types.evalTypeEquals(thisRef, method.enclosingClass!!.type)
638641

639642
method.parameters.forEachIndexed { i, param ->
643+
val ref by lazy {
644+
val lValue= mkRegisterStackLValue(addressSort, i)
645+
state.memory.read(lValue).asExpr(addressSort)
646+
}
647+
640648
val parameterType = param.type
641649
if (parameterType is EtsRefType) {
642-
val argLValue = mkRegisterStackLValue(addressSort, i)
643-
val ref = state.memory.read(argLValue).asExpr(addressSort)
644650
val resolvedParameterType = graph.cp
645651
.projectAndSdkClasses
646652
.singleOrNull { it.name == parameterType.typeName }
@@ -653,12 +659,20 @@ class TsInterpreter(
653659
?: resolvedParameterType
654660
state.pathConstraints += state.memory.types.evalIsSubtype(ref, auxiliaryType)
655661

656-
if (parameterType != EtsUndefinedType) {
657-
state.pathConstraints += mkNot(mkHeapRefEq(ref, mkUndefinedValue()))
658-
}
659-
if (parameterType != EtsNullType) {
660-
state.pathConstraints += mkNot(mkHeapRefEq(ref, mkTsNullValue()))
661-
}
662+
state.pathConstraints += mkNot(mkHeapRefEq(ref, mkTsNullValue()))
663+
state.pathConstraints += mkNot(mkHeapRefEq(ref, mkUndefinedValue()))
664+
}
665+
if (parameterType == EtsNullType) {
666+
state.pathConstraints += mkHeapRefEq(ref, mkTsNullValue())
667+
}
668+
if (parameterType == EtsUndefinedType) {
669+
state.pathConstraints += mkHeapRefEq(ref, mkUndefinedValue())
670+
}
671+
if (parameterType == EtsStringType) {
672+
state.pathConstraints += state.memory.types.evalTypeEquals(ref, EtsStringType)
673+
674+
state.pathConstraints += mkNot(mkHeapRefEq(ref, mkTsNullValue()))
675+
state.pathConstraints += mkNot(mkHeapRefEq(ref, mkUndefinedValue()))
662676
}
663677
}
664678

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ class TsTypeSystem(
288288
is EtsUnclearRefType,
289289
is EtsClassType ->
290290
if ((t as? EtsClassType)?.signature == EtsHierarchy.OBJECT_CLASS.signature) { // TODO change it
291-
scene.projectAndSdkClasses.asSequence().map { it.type }
291+
scene.projectAndSdkClasses.asSequence().map { it.type } + EtsStringType
292292
} else {
293293
hierarchy.classesForType(t)
294294
.asSequence()

usvm-ts/src/test/kotlin/org/usvm/samples/Strings.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.usvm.samples
22

33
import org.jacodb.ets.model.EtsScene
4+
import org.junit.jupiter.api.Disabled
45
import org.junit.jupiter.api.Test
56
import org.usvm.api.TsTestValue
67
import org.usvm.util.TsMethodTestRunner
@@ -74,6 +75,7 @@ class Strings : TsMethodTestRunner() {
7475
)
7576
}
7677

78+
@Disabled("Functions are not supported yet")
7779
@Test
7880
fun `test typeOfFunction`() {
7981
val method = getMethod(className, "typeOfFunction")
@@ -131,7 +133,7 @@ class Strings : TsMethodTestRunner() {
131133
@Test
132134
fun `test typeOfInputObject`() {
133135
val method = getMethod(className, "typeOfInputObject")
134-
discoverProperties<TsTestValue.TsObject, TsTestValue.TsString>(
136+
discoverProperties<TsTestValue, TsTestValue.TsString>(
135137
method = method,
136138
{ _, r -> r.value == "object" },
137139
)
@@ -146,10 +148,11 @@ class Strings : TsMethodTestRunner() {
146148
)
147149
}
148150

151+
@Disabled("Functions are not supported yet")
149152
@Test
150153
fun `test typeOfInputFunction`() {
151154
val method = getMethod(className, "typeOfInputFunction")
152-
discoverProperties<TsTestValue.TsObject, TsTestValue.TsString>(
155+
discoverProperties<TsTestValue, TsTestValue.TsString>(
153156
method = method,
154157
{ _, r -> r.value == "function" },
155158
)

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,21 @@ class InputArrays : TsMethodTestRunner() {
1313
@Test
1414
fun testInputArrayOfNumbers() {
1515
val method = getMethod(className, "inputArrayOfNumbers")
16-
discoverProperties<TsTestValue, TsTestValue>(
16+
discoverProperties<TsTestValue.TsArray<*>, TsTestValue>(
1717
method = method,
18-
{ x, r -> x is TsTestValue.TsUndefined && r is TsTestValue.TsException },
18+
{ x, r -> r is TsTestValue.TsException },
1919
{ x, r ->
2020
r as TsTestValue.TsNumber
21-
22-
x is TsTestValue.TsArray<*> && (x.values[0] as? TsTestValue.TsNumber)?.number == 1.0 && r.number == 1.0
21+
(x.values[0] as TsTestValue.TsNumber).number == 1.0 && r.number == 1.0
2322
},
2423
{ x, r ->
2524
r as TsTestValue.TsNumber
26-
27-
x is TsTestValue.TsArray<*> && (x.values[0] as? TsTestValue.TsNumber)?.number != 1.0 && r.number == 2.0
25+
(x.values[0] as TsTestValue.TsNumber).number != 1.0 && r.number == 2.0
2826
},
2927
invariants = arrayOf(
30-
{ _, r -> r !is TsTestValue.TsNumber || r.number != -1.0 }
28+
{ _, r ->
29+
r !is TsTestValue.TsNumber || r.number != -1.0
30+
}
3131
)
3232
)
3333
}

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,3 @@ fun isTruthy(x: TsTestValue.TsNumber): Boolean {
1313
fun isTruthy(x: TsTestValue.TsClass): Boolean {
1414
return true
1515
}
16-
17-
fun isTruthy(x: TsTestValue.TsObject): Boolean {
18-
return x.addr != 0
19-
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,6 @@ abstract class TsMethodTestRunner : TestRunner<TsTest, EtsMethod, EtsType?, TsMe
310310
TsTestValue.TsNumber.TsDouble::class -> EtsNumberType
311311
TsTestValue.TsNumber.TsInteger::class -> EtsNumberType
312312
TsTestValue.TsUndefined::class -> EtsUndefinedType
313-
// TODO: EtsUnknownType is mock up here. Correct implementation required.
314-
TsTestValue.TsObject::class -> EtsUnknownType
315313
// For untyped tests, not to limit objects serialized from models after type coercion.
316314
TsTestValue.TsUnknown::class -> EtsUnknownType
317315
TsTestValue.TsNull::class -> EtsNullType

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import org.usvm.api.typeStreamOf
3636
import org.usvm.collection.array.UArrayIndexLValue
3737
import org.usvm.collection.field.UFieldLValue
3838
import org.usvm.isAllocated
39+
import org.usvm.isAllocatedConcreteHeapRef
3940
import org.usvm.isTrue
4041
import org.usvm.machine.TsContext
4142
import org.usvm.machine.expr.TsUnresolvedSort
@@ -226,7 +227,11 @@ open class TsTestStateResolver(
226227
}
227228

228229
is EtsStringType -> {
229-
resolveAllocatedString(concreteRef)
230+
if (isAllocatedConcreteHeapRef(concreteRef)) {
231+
resolveAllocatedString(concreteRef)
232+
} else {
233+
TsTestValue.TsString("String construction is not yet implemented")
234+
}
230235
}
231236

232237
else -> error("Unexpected type: $type")
@@ -299,8 +304,9 @@ open class TsTestStateResolver(
299304
private fun resolveAllocatedString(
300305
ref: UConcreteHeapRef,
301306
): TsTestValue.TsString = with(ctx) {
302-
val value = ctx.heapRefToStringConstant[ref]
303-
?: error("String constant not found for ref: $ref")
307+
val value = ctx.heapRefToStringConstant[ref] ?: run {
308+
error("String constant not found for ref: $ref")
309+
}
304310
return TsTestValue.TsString(value)
305311
}
306312

0 commit comments

Comments
 (0)