@@ -1797,7 +1797,7 @@ class Traverser(
1797
1797
}
1798
1798
1799
1799
queuedSymbolicStateUpdates + = arrayUpdateWithValue(arrayValue.addr, CharType .v().arrayType, newArray)
1800
- environment.state = environment.state.updateMemory (queuedSymbolicStateUpdates)
1800
+ environment.state = environment.state.update (queuedSymbolicStateUpdates)
1801
1801
queuedSymbolicStateUpdates = queuedSymbolicStateUpdates.copy(memoryUpdates = MemoryUpdate ())
1802
1802
}
1803
1803
@@ -3770,52 +3770,68 @@ class Traverser(
3770
3770
queuedSymbolicStateUpdates + = mkNot(mkEq(symbolicResult.value.addr, nullObjectAddr)).asHardConstraint()
3771
3771
}
3772
3772
3773
- val newSolver = solver.add(
3774
- hard = queuedSymbolicStateUpdates.hardConstraints,
3775
- soft = queuedSymbolicStateUpdates.softConstraints
3776
- )
3777
-
3778
- val updatedMemory = memory.update(queuedSymbolicStateUpdates.memoryUpdates)
3773
+ val state = environment.state.update(queuedSymbolicStateUpdates)
3774
+ val memory = state.memory
3775
+ val solver = state.solver
3779
3776
3780
3777
// no need to respect soft constraints in NestedMethod
3781
- val holder = newSolver .check(respectSoft = ! environment. state.isInNestedMethod())
3778
+ val holder = solver .check(respectSoft = ! state.isInNestedMethod())
3782
3779
3783
3780
if (holder !is UtSolverStatusSAT ) {
3784
3781
logger.trace { " processResult<${environment.method.signature} > UNSAT" }
3785
3782
return
3786
3783
}
3784
+ val methodResult = MethodResult (symbolicResult)
3787
3785
3788
3786
// execution frame from level 2 or above
3789
- if (environment. state.isInNestedMethod()) {
3787
+ if (state.isInNestedMethod()) {
3790
3788
// static fields substitution
3791
3789
// TODO: JIRA:1610 -- better way of working with statics
3792
3790
val updates = if (environment.method.name == STATIC_INITIALIZER && substituteStaticsWithSymbolicVariable) {
3793
3791
substituteStaticFieldsWithSymbolicVariables(
3794
3792
environment.method.declaringClass,
3795
- updatedMemory .queuedStaticMemoryUpdates()
3793
+ memory .queuedStaticMemoryUpdates()
3796
3794
)
3797
3795
} else {
3798
3796
MemoryUpdate () // all memory updates are already added in [environment.state]
3799
3797
}
3800
- val methodResult = MethodResult (
3801
- symbolicResult,
3802
- queuedSymbolicStateUpdates + updates
3803
- )
3804
- val stateToOffer = environment.state.pop(methodResult)
3798
+ val stateToOffer = state.pop(methodResult.copy(symbolicStateUpdate = updates.asUpdate()))
3805
3799
pathSelector.offer(stateToOffer)
3806
3800
3807
3801
logger.trace { " processResult<${environment.method.signature} > return from nested method" }
3808
3802
return
3809
3803
}
3810
3804
3811
3805
// toplevel method
3806
+ val terminalExecutionState =
3807
+ state.copy(
3808
+ methodResult = methodResult, // a way to put SymbolicResult into terminal state
3809
+ label = StateLabel .TERMINAL
3810
+ )
3811
+ consumeTerminalState(terminalExecutionState)
3812
+ }
3813
+
3814
+ private suspend fun FlowCollector<UtResult>.consumeTerminalState (
3815
+ state : ExecutionState ,
3816
+ ) {
3817
+ // some checks to be sure the state is correct
3818
+ require(state.label == StateLabel .TERMINAL ) { " Can't process non-terminal state!" }
3819
+ require(! state.isInNestedMethod()) { " The state has to correspond to the MUT" }
3820
+
3821
+ val memory = state.memory
3822
+ val solver = state.solver
3823
+ val parameters = state.parameters.map { it.value }
3824
+ val symbolicResult = requireNotNull(state.methodResult?.symbolicResult) { " The state must have symbolicResult" }
3825
+ // it's free to make a check, because in the result is SAT, it should be already cached
3826
+ val holder = requireNotNull(solver.check(respectSoft = true ) as ? UtSolverStatusSAT ) { " The state must be SAT!" }
3827
+
3812
3828
val predictedTestName = Predictors .testName.predict(environment.state.path)
3813
3829
Predictors .testName.provide(environment.state.path, predictedTestName, " " )
3814
3830
3815
3831
val resolver =
3816
- Resolver (hierarchy, updatedMemory , typeRegistry, typeResolver, holder, methodUnderTest, softMaxArraySize)
3832
+ Resolver (hierarchy, memory , typeRegistry, typeResolver, holder, methodUnderTest, softMaxArraySize)
3817
3833
3818
- val (modelsBefore, modelsAfter, instrumentation) = resolver.resolveModels(resolvedParameters )
3834
+ val (modelsBefore, modelsAfter, instrumentation) = resolver.resolveModels(parameters )
3819
3835
3820
3836
val symbolicExecutionResult = resolver.resolveResult(symbolicResult)
3821
3837
0 commit comments