Skip to content

Commit 419eb50

Browse files
CaelmBleiddLipen
andauthored
[TS] Arrays methods (#304)
Co-authored-by: Konstantin Chukharev <[email protected]>
1 parent 5efe4be commit 419eb50

File tree

9 files changed

+1479
-215
lines changed

9 files changed

+1479
-215
lines changed

usvm-ts/src/main/kotlin/org/usvm/machine/TsContext.kt

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import org.usvm.UExpr
2727
import org.usvm.UHeapRef
2828
import org.usvm.USort
2929
import org.usvm.api.allocateConcreteRef
30-
import org.usvm.api.initializeArray
30+
import org.usvm.api.allocateStaticRef
3131
import org.usvm.api.typeStreamOf
3232
import org.usvm.collection.field.UFieldLValue
3333
import org.usvm.isTrue
@@ -39,7 +39,6 @@ import org.usvm.machine.expr.TsVoidValue
3939
import org.usvm.machine.interpreter.TsStepScope
4040
import org.usvm.machine.types.EtsFakeType
4141
import org.usvm.memory.UReadOnlyMemory
42-
import org.usvm.sizeSort
4342
import org.usvm.types.single
4443
import org.usvm.util.mkFieldLValue
4544
import kotlin.contracts.ExperimentalContracts
@@ -70,9 +69,48 @@ class TsContext(
7069
private val undefinedValue: UHeapRef = nullRef
7170
fun mkUndefinedValue(): UHeapRef = undefinedValue
7271

73-
private val nullValue: UConcreteHeapRef = mkConcreteHeapRef(addressCounter.freshStaticAddress())
72+
private val nullValue: UConcreteHeapRef = allocateStaticRef()
7473
fun mkTsNullValue(): UConcreteHeapRef = nullValue
7574

75+
// String constant caching at context level
76+
private val stringConstants: MutableMap<String, UConcreteHeapRef> = mutableMapOf()
77+
78+
/**
79+
* Reverse mapping from heap references to their original string constant values.
80+
* This is used during test resolution to retrieve the actual string content when
81+
* encountering a heap reference that represents a string constant.
82+
*/
83+
private val heapRefToStringConstant: MutableMap<UConcreteHeapRef, String> = mutableMapOf()
84+
85+
/**
86+
* Returns a heap reference for a string constant without any initialization.
87+
*/
88+
fun mkStringConstantRef(value: String): UConcreteHeapRef {
89+
return stringConstants.getOrPut(value) {
90+
val ref = allocateConcreteRef()
91+
heapRefToStringConstant[ref] = value
92+
ref
93+
}
94+
}
95+
96+
/**
97+
* Creates a fully initialized string constant in the given state.
98+
* This should be used when you need a complete string object with memory initialization.
99+
*/
100+
fun mkStringConstant(value: String, scope: TsStepScope): UConcreteHeapRef {
101+
return scope.calcOnState {
102+
mkInitializedStringConstant(value)
103+
}
104+
}
105+
106+
/**
107+
* Gets the original string value for a heap reference that represents a string constant.
108+
* Used by test resolver to retrieve string values.
109+
*/
110+
fun getStringConstantValue(ref: UConcreteHeapRef): String? {
111+
return heapRefToStringConstant[ref]
112+
}
113+
76114
fun typeToSort(type: EtsType): USort = when (type) {
77115
is EtsBooleanType -> boolSort
78116
is EtsNumberType -> fp64Sort
@@ -234,41 +272,7 @@ class TsContext(
234272
fun UConcreteHeapRef.extractRef(scope: TsStepScope): UHeapRef {
235273
return scope.calcOnState { extractRef(memory) }
236274
}
237-
238-
private val stringConstantAllocatedRefs: MutableMap<String, UConcreteHeapRef> = hashMapOf()
239-
internal val heapRefToStringConstant: MutableMap<UConcreteHeapRef, String> = hashMapOf()
240-
241-
fun mkStringConstant(value: String, scope: TsStepScope): UConcreteHeapRef {
242-
return stringConstantAllocatedRefs.getOrPut(value) {
243-
val ref = allocateConcreteRef()
244-
heapRefToStringConstant[ref] = value
245-
246-
scope.doWithState {
247-
// Mark `ref` with String type
248-
memory.types.allocate(ref.address, EtsStringType)
249-
250-
// Initialize char array
251-
val valueType = EtsArrayType(EtsNumberType, dimensions = 1)
252-
val descriptor = arrayDescriptorOf(valueType)
253-
254-
val charArray = memory.allocConcrete(valueType.elementType)
255-
memory.initializeArray(
256-
arrayHeapRef = charArray,
257-
type = descriptor,
258-
sort = bv16Sort,
259-
sizeSort = sizeSort,
260-
contents = value.asSequence().map { mkBv(it.code, bv16Sort) },
261-
)
262-
263-
// Write char array to `ref.value`
264-
val valueLValue = mkFieldLValue(addressSort, ref, "value")
265-
memory.write(valueLValue, charArray, guard = trueExpr)
266-
}
267-
268-
ref
269-
}
270-
}
271-
275+
272276
// This is an identifier for a special function representing the 'resolve' function used in promises.
273277
// It is not a real function in the code, but we need it to handle promise resolution.
274278
val resolveFunctionRef: UConcreteHeapRef = allocateConcreteRef()

0 commit comments

Comments
 (0)