@@ -9,29 +9,32 @@ import org.usvm.api.initializeArrayLength
9
9
import org.usvm.api.memcpy
10
10
import org.usvm.api.typeStreamOf
11
11
import org.usvm.isAllocatedConcreteHeapRef
12
+ import org.usvm.machine.expr.TsExprApproximationResult.Companion.create
12
13
import org.usvm.sizeSort
13
14
import org.usvm.types.firstOrNull
14
15
import org.usvm.util.mkArrayIndexLValue
15
16
import org.usvm.util.mkArrayLengthLValue
16
17
17
- fun TsExprResolver.tryApproximateInstanceCall (expr : EtsInstanceCallExpr ): UExpr <* >? = with (ctx) {
18
- val resolvedInstance = scope.calcOnState { resolve(expr.instance)?.asExpr(ctx.addressSort) } ? : return null
18
+ fun TsExprResolver.tryApproximateInstanceCall (expr : EtsInstanceCallExpr ): TsExprApproximationResult = with (ctx) {
19
+ val resolvedInstance = scope.calcOnState { resolve(expr.instance)?.asExpr(ctx.addressSort) }
20
+ ? : return TsExprApproximationResult .ResolveFailure
19
21
20
22
if (expr.instance.name == " Number" ) {
21
23
if (expr.callee.name == " isNaN" ) {
22
24
check(expr.args.size == 1 ) { " Number.isNaN should have one argument" }
23
- return resolveAfterResolved(expr.args.single()) { arg ->
25
+ val expr = resolveAfterResolved(expr.args.single()) { arg ->
24
26
handleNumberIsNaN(arg)
25
27
}
28
+ return create(expr)
26
29
}
27
30
}
28
31
29
32
if (expr.instance.name == " Logger" ) {
30
- return mkUndefinedValue()
33
+ return create( mkUndefinedValue() )
31
34
}
32
35
33
36
if (expr.callee.name == " toString" ) {
34
- return mkStringConstant(" I am a string" , scope)
37
+ return create( mkStringConstant(" I am a string" , scope) )
35
38
}
36
39
37
40
val instanceType = if (isAllocatedConcreteHeapRef(resolvedInstance)) {
@@ -47,7 +50,7 @@ fun TsExprResolver.tryApproximateInstanceCall(expr: EtsInstanceCallExpr): UExpr<
47
50
48
51
// push
49
52
if (expr.callee.name == " push" ) {
50
- return scope.calcOnState {
53
+ val expr = scope.calcOnState {
51
54
val resolvedInstance = resolve(expr.instance)?.asExpr(ctx.addressSort) ? : return @calcOnState null
52
55
val lengthLValue = mkArrayLengthLValue(resolvedInstance, instanceType)
53
56
val length = memory.read(lengthLValue)
@@ -63,28 +66,46 @@ fun TsExprResolver.tryApproximateInstanceCall(expr: EtsInstanceCallExpr): UExpr<
63
66
memory.write(newIndexLValue, resolvedArg.asExpr(newIndexLValue.sort), guard = ctx.trueExpr)
64
67
newLength
65
68
}
69
+
70
+ return create(expr)
66
71
}
67
72
68
73
// fill
69
74
if (expr.callee.name == " fill" ) {
70
- return scope.calcOnState {
75
+ val expr = scope.calcOnState {
71
76
val resolvedInstance = resolve(expr.instance)?.asExpr(ctx.addressSort) ? : return @calcOnState null
72
77
val lengthLValue = mkArrayLengthLValue(resolvedInstance, instanceType)
73
78
val length = memory.read(lengthLValue)
74
79
val resolvedArg = resolve(expr.args.single()) ? : return @calcOnState null
75
80
76
81
val artificialArray = memory.allocConcrete(instanceType)
77
82
memory.initializeArrayLength(artificialArray, instanceType, sizeSort, 10_000 .toBv().asExpr(sizeSort))
78
- memory.initializeArray(artificialArray, instanceType, elementTypeSort, sizeSort, Array (10_000 ) { resolvedArg.asExpr(elementTypeSort) }.asSequence())
79
- memory.memcpy(artificialArray, resolvedInstance, instanceType, elementTypeSort, 0 .toBv(), 0 .toBv(), length)
83
+ memory.initializeArray(
84
+ artificialArray,
85
+ instanceType,
86
+ elementTypeSort,
87
+ sizeSort,
88
+ Array (10_000 ) { resolvedArg.asExpr(elementTypeSort) }.asSequence()
89
+ )
90
+ memory.memcpy(
91
+ artificialArray,
92
+ resolvedInstance,
93
+ instanceType,
94
+ elementTypeSort,
95
+ 0 .toBv(),
96
+ 0 .toBv(),
97
+ length
98
+ )
80
99
81
100
resolvedInstance
82
101
}
102
+
103
+ return create(expr)
83
104
}
84
105
85
106
// unshift
86
107
if (expr.callee.name == " unshift" ) {
87
- return scope.calcOnState {
108
+ val expr = scope.calcOnState {
88
109
val resolvedInstance = resolve(expr.instance)?.asExpr(ctx.addressSort) ? : return @calcOnState null
89
110
val lengthLValue = mkArrayLengthLValue(resolvedInstance, instanceType)
90
111
val length = memory.read(lengthLValue)
@@ -109,10 +130,12 @@ fun TsExprResolver.tryApproximateInstanceCall(expr: EtsInstanceCallExpr): UExpr<
109
130
memory.write(zeroIndexLValue, resolvedArg.asExpr(zeroIndexLValue.sort), guard = ctx.trueExpr)
110
131
newLength
111
132
}
133
+
134
+ return create(expr)
112
135
}
113
136
114
137
if (expr.callee.name == " shift" ) {
115
- return scope.calcOnState {
138
+ val expr = scope.calcOnState {
116
139
val resolvedInstance = resolve(expr.instance)?.asExpr(ctx.addressSort) ? : return @calcOnState null
117
140
val lengthLValue = mkArrayLengthLValue(resolvedInstance, instanceType)
118
141
val length = memory.read(lengthLValue)
@@ -136,10 +159,12 @@ fun TsExprResolver.tryApproximateInstanceCall(expr: EtsInstanceCallExpr): UExpr<
136
159
memory.write(lengthLValue, newLength, guard = ctx.trueExpr)
137
160
result
138
161
}
162
+
163
+ return create(expr)
139
164
}
140
165
141
166
if (expr.callee.name == " pop" ) {
142
- return scope.calcOnState {
167
+ val expr = scope.calcOnState {
143
168
val resolvedInstance = resolve(expr.instance)?.asExpr(ctx.addressSort) ? : return @calcOnState null
144
169
val lengthLValue = mkArrayLengthLValue(resolvedInstance, instanceType)
145
170
val length = memory.read(lengthLValue)
@@ -156,8 +181,25 @@ fun TsExprResolver.tryApproximateInstanceCall(expr: EtsInstanceCallExpr): UExpr<
156
181
)
157
182
memory.read(indexLValue)
158
183
}
184
+
185
+ return create(expr)
159
186
}
160
187
}
161
188
162
- return null
189
+ return TsExprApproximationResult .NoApproximation
190
+ }
191
+
192
+ sealed class TsExprApproximationResult {
193
+ data class SuccessfulApproximation (val expr : UExpr <* >) : TsExprApproximationResult()
194
+ data object NoApproximation : TsExprApproximationResult ()
195
+ data object ResolveFailure : TsExprApproximationResult ()
196
+
197
+ companion object {
198
+ fun create (expr : UExpr <* >? ): TsExprApproximationResult {
199
+ return when {
200
+ expr != null -> SuccessfulApproximation (expr)
201
+ else -> ResolveFailure
202
+ }
203
+ }
204
+ }
163
205
}
0 commit comments