@@ -2,6 +2,7 @@ package org.usvm.machine
22
33import io.ksmt.sort.KFp64Sort
44import io.ksmt.utils.asExpr
5+ import org.jacodb.ets.base.EtsAnyType
56import org.jacodb.ets.base.EtsBooleanType
67import org.jacodb.ets.base.EtsNullType
78import org.jacodb.ets.base.EtsNumberType
@@ -19,10 +20,13 @@ import org.usvm.UContext
1920import org.usvm.UExpr
2021import org.usvm.USort
2122import org.usvm.collection.field.UFieldLValue
23+ import org.usvm.isTrue
2224import org.usvm.machine.expr.TsUndefinedSort
2325import org.usvm.machine.expr.TsUnresolvedSort
2426import org.usvm.machine.interpreter.TsStepScope
2527import org.usvm.machine.types.FakeType
28+ import org.usvm.types.single
29+ import org.usvm.util.mkFieldLValue
2630import kotlin.contracts.ExperimentalContracts
2731import kotlin.contracts.contract
2832
@@ -51,6 +55,7 @@ class TsContext(
5155 is EtsUndefinedType -> addressSort
5256 is EtsUnknownType -> unresolvedSort
5357 is EtsUnionType -> unresolvedSort
58+ is EtsAnyType -> unresolvedSort
5459 else -> TODO (" Support all JacoDB types, encountered $type " )
5560 }
5661
@@ -70,7 +75,7 @@ class TsContext(
7075
7176 val ref = createFakeObjectRef()
7277
73- scope.calcOnState {
78+ scope.doWithState {
7479 when (sort) {
7580 boolSort -> {
7681 val lvalue = getIntermediateBoolLValue(ref.address)
@@ -86,8 +91,8 @@ class TsContext(
8691
8792 addressSort -> {
8893 val lValue = getIntermediateRefLValue(ref.address)
89- memory.types.allocate(ref.address, FakeType .fromRef(this @TsContext))
9094 memory.write(lValue, this @toFakeObject.asExpr(addressSort), guard = trueExpr)
95+ memory.types.allocate(ref.address, FakeType .fromRef(this @TsContext))
9196 }
9297
9398 else -> TODO (" Not yet supported" )
@@ -97,6 +102,35 @@ class TsContext(
97102 return ref
98103 }
99104
105+ fun UExpr <out USort >.extractSingleValueFromFakeObjectOrNull (scope : TsStepScope ): UExpr <out USort >? {
106+ if (! isFakeObject()) return null
107+
108+ val type = scope.calcOnState {
109+ memory.types.getTypeStream(this @extractSingleValueFromFakeObjectOrNull).single() as FakeType
110+ }
111+
112+ return scope.calcOnState {
113+ when {
114+ type.boolTypeExpr.isTrue -> {
115+ val lValue = getIntermediateBoolLValue(address)
116+ memory.read(lValue).asExpr(boolSort)
117+ }
118+
119+ type.fpTypeExpr.isTrue -> {
120+ val lValue = getIntermediateFpLValue(address)
121+ memory.read(lValue).asExpr(fp64Sort)
122+ }
123+
124+ type.refTypeExpr.isTrue -> {
125+ val lValue = getIntermediateRefLValue(address)
126+ memory.read(lValue).asExpr(addressSort)
127+ }
128+
129+ else -> null
130+ }
131+ }
132+ }
133+
100134 fun createFakeObjectRef (): UConcreteHeapRef {
101135 val address = mkAddressCounter().freshAllocatedAddress() + MAGIC_OFFSET
102136 return mkConcreteHeapRef(address)
@@ -108,15 +142,15 @@ class TsContext(
108142 private val nullValue: UConcreteHeapRef = mkConcreteHeapRef(addressCounter.freshStaticAddress())
109143
110144 fun getIntermediateBoolLValue (addr : Int ): UFieldLValue <IntermediateLValueField , UBoolSort > {
111- return UFieldLValue (boolSort, mkConcreteHeapRef(addr), IntermediateLValueField .BOOL )
145+ return mkFieldLValue (boolSort, mkConcreteHeapRef(addr), IntermediateLValueField .BOOL )
112146 }
113147
114148 fun getIntermediateFpLValue (addr : Int ): UFieldLValue <IntermediateLValueField , KFp64Sort > {
115- return UFieldLValue (fp64Sort, mkConcreteHeapRef(addr), IntermediateLValueField .FP )
149+ return mkFieldLValue (fp64Sort, mkConcreteHeapRef(addr), IntermediateLValueField .FP )
116150 }
117151
118152 fun getIntermediateRefLValue (addr : Int ): UFieldLValue <IntermediateLValueField , UAddressSort > {
119- return UFieldLValue (addressSort, mkConcreteHeapRef(addr), IntermediateLValueField .REF )
153+ return mkFieldLValue (addressSort, mkConcreteHeapRef(addr), IntermediateLValueField .REF )
120154 }
121155}
122156
0 commit comments