Skip to content

Commit dd06e5c

Browse files
Split processResult
1 parent 38224ee commit dd06e5c

2 files changed

Lines changed: 34 additions & 18 deletions

File tree

utbot-framework/src/main/kotlin/org/utbot/engine/ExecutionState.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ data class ExecutionState(
252252
)
253253
}
254254

255-
fun updateMemory(
255+
fun update(
256256
stateUpdate: SymbolicStateUpdate
257257
): ExecutionState {
258258
val last = executionStack.last()

utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,7 +1747,7 @@ class Traverser(
17471747
}
17481748

17491749
queuedSymbolicStateUpdates += arrayUpdateWithValue(arrayValue.addr, CharType.v().arrayType, newArray)
1750-
environment.state = environment.state.updateMemory(queuedSymbolicStateUpdates)
1750+
environment.state = environment.state.update(queuedSymbolicStateUpdates)
17511751
queuedSymbolicStateUpdates = queuedSymbolicStateUpdates.copy(memoryUpdates = MemoryUpdate())
17521752
}
17531753

@@ -3682,52 +3682,68 @@ class Traverser(
36823682
queuedSymbolicStateUpdates += mkNot(mkEq(symbolicResult.value.addr, nullObjectAddr)).asHardConstraint()
36833683
}
36843684

3685-
val newSolver = solver.add(
3686-
hard = queuedSymbolicStateUpdates.hardConstraints,
3687-
soft = queuedSymbolicStateUpdates.softConstraints
3688-
)
3689-
3690-
val updatedMemory = memory.update(queuedSymbolicStateUpdates.memoryUpdates)
3685+
val state = environment.state.update(queuedSymbolicStateUpdates)
3686+
val memory = state.memory
3687+
val solver = state.solver
36913688

36923689
//no need to respect soft constraints in NestedMethod
3693-
val holder = newSolver.check(respectSoft = !environment.state.isInNestedMethod())
3690+
val holder = solver.check(respectSoft = !state.isInNestedMethod())
36943691

36953692
if (holder !is UtSolverStatusSAT) {
36963693
logger.trace { "processResult<${environment.method.signature}> UNSAT" }
36973694
return
36983695
}
3696+
val methodResult = MethodResult(symbolicResult)
36993697

37003698
//execution frame from level 2 or above
3701-
if (environment.state.isInNestedMethod()) {
3699+
if (state.isInNestedMethod()) {
37023700
// static fields substitution
37033701
// TODO: JIRA:1610 -- better way of working with statics
37043702
val updates = if (environment.method.name == STATIC_INITIALIZER && substituteStaticsWithSymbolicVariable) {
37053703
substituteStaticFieldsWithSymbolicVariables(
37063704
environment.method.declaringClass,
3707-
updatedMemory.queuedStaticMemoryUpdates()
3705+
memory.queuedStaticMemoryUpdates()
37083706
)
37093707
} else {
37103708
MemoryUpdate() // all memory updates are already added in [environment.state]
37113709
}
3712-
val methodResult = MethodResult(
3713-
symbolicResult,
3714-
queuedSymbolicStateUpdates + updates
3715-
)
3716-
val stateToOffer = environment.state.pop(methodResult)
3710+
val stateToOffer = state.pop(methodResult.copy(symbolicStateUpdate = updates.asUpdate()))
37173711
pathSelector.offer(stateToOffer)
37183712

37193713
logger.trace { "processResult<${environment.method.signature}> return from nested method" }
37203714
return
37213715
}
37223716

37233717
//toplevel method
3718+
val terminalExecutionState =
3719+
state.copy(
3720+
methodResult = methodResult, // a way to put SymbolicResult into terminal state
3721+
label = StateLabel.TERMINAL
3722+
)
3723+
consumeTerminalState(terminalExecutionState)
3724+
}
3725+
3726+
private suspend fun FlowCollector<UtResult>.consumeTerminalState(
3727+
state: ExecutionState,
3728+
) {
3729+
// some checks to be sure the state is correct
3730+
require(state.label == StateLabel.TERMINAL) { "Can't process non-terminal state!" }
3731+
require(!state.isInNestedMethod()) { "The state has to correspond to the MUT"}
3732+
3733+
val memory = state.memory
3734+
val solver = state.solver
3735+
val parameters = state.parameters.map { it.value }
3736+
val symbolicResult = requireNotNull(state.methodResult?.symbolicResult) { "The state must have symbolicResult"}
3737+
// it's free to make a check, because in the result is SAT, it should be already cached
3738+
val holder = requireNotNull(solver.check(respectSoft = true) as? UtSolverStatusSAT) { "The state must be SAT!" }
3739+
37243740
val predictedTestName = Predictors.testName.predict(environment.state.path)
37253741
Predictors.testName.provide(environment.state.path, predictedTestName, "")
37263742

37273743
val resolver =
3728-
Resolver(hierarchy, updatedMemory, typeRegistry, typeResolver, holder, methodUnderTest, softMaxArraySize)
3744+
Resolver(hierarchy, memory, typeRegistry, typeResolver, holder, methodUnderTest, softMaxArraySize)
37293745

3730-
val (modelsBefore, modelsAfter, instrumentation) = resolver.resolveModels(resolvedParameters)
3746+
val (modelsBefore, modelsAfter, instrumentation) = resolver.resolveModels(parameters)
37313747

37323748
val symbolicExecutionResult = resolver.resolveResult(symbolicResult)
37333749

0 commit comments

Comments
 (0)