Skip to content

Commit 5b52243

Browse files
committed
Handle symbolic objects
1 parent 28290b4 commit 5b52243

3 files changed

Lines changed: 59 additions & 4 deletions

File tree

usvm-ts/src/main/kotlin/org/usvm/machine/operator/TsBinaryOperator.kt

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -384,10 +384,16 @@ sealed interface TsBinaryOperator {
384384
rhs: UHeapRef,
385385
scope: TsStepScope,
386386
): UBoolExpr {
387-
// Note: in JavaScript, `undefined == null`
388-
if (lhs == mkUndefinedValue() && rhs == mkTsNullValue()) return mkTrue()
389-
if (lhs == mkTsNullValue() && rhs == mkUndefinedValue()) return mkTrue()
390-
return mkEq(lhs, rhs)
387+
// Note: in JavaScript, `null == undefined`
388+
val lhsIsNull = mkEq(lhs, mkTsNullValue())
389+
val rhsIsNull = mkEq(rhs, mkTsNullValue())
390+
val lhsIsUndefined = mkEq(lhs, mkUndefinedValue())
391+
val rhsIsUndefined = mkEq(rhs, mkUndefinedValue())
392+
return mkOr(
393+
mkAnd(lhsIsUndefined, rhsIsNull),
394+
mkAnd(lhsIsNull, rhsIsUndefined),
395+
mkHeapRefEq(lhs, rhs)
396+
)
391397
}
392398

393399
override fun TsContext.resolveFakeObject(

usvm-ts/src/test/kotlin/org/usvm/samples/operators/Equality.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,4 +181,29 @@ class Equality : TsMethodTestRunner() {
181181
)
182182
)
183183
}
184+
185+
@Test
186+
fun `test eqAnyWithNull`() {
187+
val method = getMethod("eqAnyWithNull")
188+
discoverProperties<TsTestValue, TsTestValue.TsNumber>(
189+
method,
190+
{ a, r ->
191+
(r eq 1) && (a is TsTestValue.TsNull)
192+
},
193+
{ a, r ->
194+
(r eq 2) && (a is TsTestValue.TsUndefined)
195+
},
196+
{ a, r ->
197+
(r eq 5) && (a !is TsTestValue.TsNull)
198+
},
199+
{ a, r ->
200+
(r eq 10) && (a !is TsTestValue.TsNull) && (a !is TsTestValue.TsUndefined)
201+
},
202+
invariants = arrayOf(
203+
{ _, r -> r.number > 0 },
204+
{ a, r -> if (r eq 1) a is TsTestValue.TsNull else true },
205+
{ a, r -> if (r eq 2) a is TsTestValue.TsUndefined else true },
206+
)
207+
)
208+
}
184209
}

usvm-ts/src/test/resources/samples/operators/Equality.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,28 @@ class Equality {
7676
if (undefined == null) return 1;
7777
return -1; // unreachable
7878
}
79+
80+
eqAnyWithNull(a: any): number {
81+
if (typeof a === "object") {
82+
// Note: `a == null` is true when `a` is null or undefined,
83+
// but here `a` cannot be undefined because `typeof undefined` is "undefined".
84+
// Thus, `a == null` is true only if `a === null`.
85+
if (a == null) {
86+
if (a === null) return 1; // null
87+
return -1; // unreachable
88+
}
89+
return 5; // non-null object
90+
}
91+
if (typeof a === "undefined") {
92+
// Note: `a == null` is true when `a` is null or undefined,
93+
// but here `a` cannot be null because `typeof null` is "object".
94+
// Thus, `a == null` is true only if `a === undefined`.
95+
if (a == null) {
96+
if (a === undefined) return 2; // undefined
97+
return -1; // unreachable
98+
}
99+
return -1; // unreachable
100+
}
101+
return 100; // non-object, non-undefined
102+
}
79103
}

0 commit comments

Comments
 (0)