Skip to content

Commit 396a4fb

Browse files
committed
Move SimpleUtExecutionInstrumentation to a separate file
1 parent 744124d commit 396a4fb

File tree

2 files changed

+174
-165
lines changed

2 files changed

+174
-165
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
package org.utbot.instrumentation.instrumentation.execution
2+
3+
import org.utbot.framework.plugin.api.EnvironmentModels
4+
import org.utbot.framework.plugin.api.FieldId
5+
import org.utbot.framework.plugin.api.UtModel
6+
import org.utbot.framework.plugin.api.util.singleExecutableId
7+
import org.utbot.instrumentation.instrumentation.ArgumentList
8+
import org.utbot.instrumentation.instrumentation.InvokeInstrumentation
9+
import org.utbot.instrumentation.instrumentation.et.TraceHandler
10+
import org.utbot.instrumentation.instrumentation.execution.constructors.ConstructOnlyUserClassesOrCachedObjectsStrategy
11+
import org.utbot.instrumentation.instrumentation.execution.constructors.UtModelConstructor
12+
import org.utbot.instrumentation.instrumentation.execution.context.InstrumentationContext
13+
import org.utbot.instrumentation.instrumentation.execution.context.SimpleInstrumentationContext
14+
import org.utbot.instrumentation.instrumentation.execution.ndd.NonDeterministicClassVisitor
15+
import org.utbot.instrumentation.instrumentation.execution.ndd.NonDeterministicDetector
16+
import org.utbot.instrumentation.instrumentation.execution.phases.PhasesController
17+
import org.utbot.instrumentation.instrumentation.instrumenter.Instrumenter
18+
import org.utbot.instrumentation.instrumentation.mock.MockClassVisitor
19+
import java.security.ProtectionDomain
20+
import kotlin.reflect.jvm.javaMethod
21+
22+
class SimpleUtExecutionInstrumentation(
23+
private val pathsToUserClasses: Set<String>,
24+
private val instrumentationContext: InstrumentationContext = SimpleInstrumentationContext()
25+
) : UtExecutionInstrumentation {
26+
private val delegateInstrumentation = InvokeInstrumentation()
27+
28+
private val traceHandler = TraceHandler()
29+
private val ndDetector = NonDeterministicDetector()
30+
31+
/**
32+
* Ignores [arguments], because concrete arguments will be constructed
33+
* from models passed via [parameters].
34+
*
35+
* Argument [parameters] must be of type [UtConcreteExecutionData].
36+
*/
37+
override fun invoke(
38+
clazz: Class<*>,
39+
methodSignature: String,
40+
arguments: ArgumentList,
41+
parameters: Any?,
42+
phasesWrapper: PhasesController.(invokeBasePhases: () -> UtConcreteExecutionResult) -> UtConcreteExecutionResult
43+
): UtConcreteExecutionResult {
44+
if (parameters !is UtConcreteExecutionData) {
45+
throw IllegalArgumentException("Argument parameters must be of type UtConcreteExecutionData, but was: ${parameters?.javaClass}")
46+
}
47+
val (stateBefore, instrumentations, timeout) = parameters // smart cast to UtConcreteExecutionData
48+
49+
return PhasesController(
50+
instrumentationContext,
51+
traceHandler,
52+
delegateInstrumentation,
53+
timeout
54+
).computeConcreteExecutionResult {
55+
phasesWrapper {
56+
try {
57+
// some preparation actions for concrete execution
58+
val constructedData = applyPreprocessing(parameters)
59+
60+
val (params, statics, cache) = constructedData
61+
62+
// invocation
63+
val concreteResult = executePhaseInTimeout(invocationPhase) {
64+
invoke(clazz, methodSignature, params.map { it.value })
65+
}
66+
67+
// statistics collection
68+
val (coverage, ndResults) = executePhaseInTimeout(statisticsCollectionPhase) {
69+
getCoverage(clazz) to getNonDeterministicResults()
70+
}
71+
72+
// model construction
73+
val (executionResult, stateAfter, newInstrumentation) = executePhaseInTimeout(modelConstructionPhase) {
74+
configureConstructor {
75+
this.cache = cache
76+
strategy = ConstructOnlyUserClassesOrCachedObjectsStrategy(
77+
pathsToUserClasses,
78+
cache
79+
)
80+
}
81+
82+
val ndStatics = constructStaticInstrumentation(ndResults.statics)
83+
val ndNews = constructNewInstrumentation(ndResults.news, ndResults.calls)
84+
val newInstrumentation = mergeInstrumentations(instrumentations, ndStatics, ndNews)
85+
86+
val returnType = clazz.singleExecutableId(methodSignature).returnType
87+
val executionResult = convertToExecutionResult(concreteResult, returnType)
88+
89+
val stateAfterParametersWithThis = constructParameters(params)
90+
val stateAfterStatics = constructStatics(stateBefore, statics)
91+
val (stateAfterThis, stateAfterParameters) = if (stateBefore.thisInstance == null) {
92+
null to stateAfterParametersWithThis
93+
} else {
94+
stateAfterParametersWithThis.first() to stateAfterParametersWithThis.drop(1)
95+
}
96+
val stateAfter = EnvironmentModels(stateAfterThis, stateAfterParameters, stateAfterStatics)
97+
98+
Triple(executionResult, stateAfter, newInstrumentation)
99+
}
100+
101+
UtConcreteExecutionResult(
102+
stateAfter,
103+
executionResult,
104+
coverage,
105+
newInstrumentation
106+
)
107+
} finally {
108+
// restoring data after concrete execution
109+
applyPostprocessing()
110+
}
111+
}
112+
}
113+
}
114+
115+
override fun getStaticField(fieldId: FieldId): Result<UtModel> =
116+
delegateInstrumentation.getStaticField(fieldId).map { value ->
117+
UtModelConstructor.createOnlyUserClassesConstructor(pathsToUserClasses)
118+
.construct(value, fieldId.type)
119+
}
120+
121+
override fun transform(
122+
loader: ClassLoader?,
123+
className: String,
124+
classBeingRedefined: Class<*>?,
125+
protectionDomain: ProtectionDomain,
126+
classfileBuffer: ByteArray
127+
): ByteArray {
128+
val instrumenter = Instrumenter(classfileBuffer, loader)
129+
130+
traceHandler.registerClass(className)
131+
instrumenter.visitInstructions(traceHandler.computeInstructionVisitor(className))
132+
133+
instrumenter.visitClass { writer ->
134+
NonDeterministicClassVisitor(writer, ndDetector)
135+
}
136+
137+
val mockClassVisitor = instrumenter.visitClass { writer ->
138+
MockClassVisitor(
139+
writer,
140+
InstrumentationContext.MockGetter::getMock.javaMethod!!,
141+
InstrumentationContext.MockGetter::checkCallSite.javaMethod!!,
142+
InstrumentationContext.MockGetter::hasMock.javaMethod!!
143+
)
144+
}
145+
146+
mockClassVisitor.signatureToId.forEach { (method, id) ->
147+
instrumentationContext.methodSignatureToId += method to id
148+
}
149+
150+
return instrumenter.classByteCode
151+
}
152+
153+
class Factory(
154+
private val pathsToUserClasses: Set<String>
155+
) : UtExecutionInstrumentation.Factory<UtExecutionInstrumentation> {
156+
override fun create(): UtExecutionInstrumentation = SimpleUtExecutionInstrumentation(pathsToUserClasses)
157+
158+
override fun create(instrumentationContext: InstrumentationContext): UtExecutionInstrumentation =
159+
SimpleUtExecutionInstrumentation(pathsToUserClasses, instrumentationContext)
160+
161+
override fun equals(other: Any?): Boolean {
162+
if (this === other) return true
163+
if (javaClass != other?.javaClass) return false
164+
165+
other as Factory
166+
167+
return pathsToUserClasses == other.pathsToUserClasses
168+
}
169+
170+
override fun hashCode(): Int {
171+
return pathsToUserClasses.hashCode()
172+
}
173+
}
174+
}

utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/instrumentation/execution/UtExecutionInstrumentation.kt

Lines changed: 0 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,11 @@ package org.utbot.instrumentation.instrumentation.execution
22

33
import org.utbot.framework.UtSettings
44
import org.utbot.framework.plugin.api.*
5-
import org.utbot.framework.plugin.api.util.singleExecutableId
65
import org.utbot.instrumentation.instrumentation.ArgumentList
76
import org.utbot.instrumentation.instrumentation.Instrumentation
8-
import org.utbot.instrumentation.instrumentation.InvokeInstrumentation
9-
import org.utbot.instrumentation.instrumentation.et.TraceHandler
10-
import org.utbot.instrumentation.instrumentation.execution.constructors.ConstructOnlyUserClassesOrCachedObjectsStrategy
11-
import org.utbot.instrumentation.instrumentation.execution.constructors.UtModelConstructor
127
import org.utbot.instrumentation.instrumentation.execution.context.InstrumentationContext
138
import org.utbot.instrumentation.instrumentation.execution.context.SimpleInstrumentationContext
14-
import org.utbot.instrumentation.instrumentation.execution.ndd.NonDeterministicClassVisitor
15-
import org.utbot.instrumentation.instrumentation.execution.ndd.NonDeterministicDetector
169
import org.utbot.instrumentation.instrumentation.execution.phases.PhasesController
17-
import org.utbot.instrumentation.instrumentation.instrumenter.Instrumenter
18-
import org.utbot.instrumentation.instrumentation.mock.MockClassVisitor
19-
import java.security.ProtectionDomain
20-
import kotlin.reflect.jvm.javaMethod
2110

2211
/**
2312
* Consists of the data needed to execute the method concretely. Also includes method arguments stored in models.
@@ -71,157 +60,3 @@ interface UtExecutionInstrumentation : Instrumentation<UtConcreteExecutionResult
7160
fun create(instrumentationContext: InstrumentationContext): TInstrumentation
7261
}
7362
}
74-
75-
class SimpleUtExecutionInstrumentation(
76-
private val pathsToUserClasses: Set<String>,
77-
private val instrumentationContext: InstrumentationContext = SimpleInstrumentationContext()
78-
) : UtExecutionInstrumentation {
79-
private val delegateInstrumentation = InvokeInstrumentation()
80-
81-
private val traceHandler = TraceHandler()
82-
private val ndDetector = NonDeterministicDetector()
83-
84-
/**
85-
* Ignores [arguments], because concrete arguments will be constructed
86-
* from models passed via [parameters].
87-
*
88-
* Argument [parameters] must be of type [UtConcreteExecutionData].
89-
*/
90-
override fun invoke(
91-
clazz: Class<*>,
92-
methodSignature: String,
93-
arguments: ArgumentList,
94-
parameters: Any?,
95-
phasesWrapper: PhasesController.(invokeBasePhases: () -> UtConcreteExecutionResult) -> UtConcreteExecutionResult
96-
): UtConcreteExecutionResult {
97-
if (parameters !is UtConcreteExecutionData) {
98-
throw IllegalArgumentException("Argument parameters must be of type UtConcreteExecutionData, but was: ${parameters?.javaClass}")
99-
}
100-
val (stateBefore, instrumentations, timeout) = parameters // smart cast to UtConcreteExecutionData
101-
102-
return PhasesController(
103-
instrumentationContext,
104-
traceHandler,
105-
delegateInstrumentation,
106-
timeout
107-
).computeConcreteExecutionResult {
108-
phasesWrapper {
109-
try {
110-
// some preparation actions for concrete execution
111-
val constructedData = applyPreprocessing(parameters)
112-
113-
val (params, statics, cache) = constructedData
114-
115-
// invocation
116-
val concreteResult = executePhaseInTimeout(invocationPhase) {
117-
invoke(clazz, methodSignature, params.map { it.value })
118-
}
119-
120-
// statistics collection
121-
val (coverage, ndResults) = executePhaseInTimeout(statisticsCollectionPhase) {
122-
getCoverage(clazz) to getNonDeterministicResults()
123-
}
124-
125-
// model construction
126-
val (executionResult, stateAfter, newInstrumentation) = executePhaseInTimeout(modelConstructionPhase) {
127-
configureConstructor {
128-
this.cache = cache
129-
strategy = ConstructOnlyUserClassesOrCachedObjectsStrategy(
130-
pathsToUserClasses,
131-
cache
132-
)
133-
}
134-
135-
val ndStatics = constructStaticInstrumentation(ndResults.statics)
136-
val ndNews = constructNewInstrumentation(ndResults.news, ndResults.calls)
137-
val newInstrumentation = mergeInstrumentations(instrumentations, ndStatics, ndNews)
138-
139-
val returnType = clazz.singleExecutableId(methodSignature).returnType
140-
val executionResult = convertToExecutionResult(concreteResult, returnType)
141-
142-
val stateAfterParametersWithThis = constructParameters(params)
143-
val stateAfterStatics = constructStatics(stateBefore, statics)
144-
val (stateAfterThis, stateAfterParameters) = if (stateBefore.thisInstance == null) {
145-
null to stateAfterParametersWithThis
146-
} else {
147-
stateAfterParametersWithThis.first() to stateAfterParametersWithThis.drop(1)
148-
}
149-
val stateAfter = EnvironmentModels(stateAfterThis, stateAfterParameters, stateAfterStatics)
150-
151-
Triple(executionResult, stateAfter, newInstrumentation)
152-
}
153-
154-
UtConcreteExecutionResult(
155-
stateAfter,
156-
executionResult,
157-
coverage,
158-
newInstrumentation
159-
)
160-
} finally {
161-
// restoring data after concrete execution
162-
applyPostprocessing()
163-
}
164-
}
165-
}
166-
}
167-
168-
override fun getStaticField(fieldId: FieldId): Result<UtModel> =
169-
delegateInstrumentation.getStaticField(fieldId).map { value ->
170-
UtModelConstructor.createOnlyUserClassesConstructor(pathsToUserClasses)
171-
.construct(value, fieldId.type)
172-
}
173-
174-
override fun transform(
175-
loader: ClassLoader?,
176-
className: String,
177-
classBeingRedefined: Class<*>?,
178-
protectionDomain: ProtectionDomain,
179-
classfileBuffer: ByteArray
180-
): ByteArray {
181-
val instrumenter = Instrumenter(classfileBuffer, loader)
182-
183-
traceHandler.registerClass(className)
184-
instrumenter.visitInstructions(traceHandler.computeInstructionVisitor(className))
185-
186-
instrumenter.visitClass { writer ->
187-
NonDeterministicClassVisitor(writer, ndDetector)
188-
}
189-
190-
val mockClassVisitor = instrumenter.visitClass { writer ->
191-
MockClassVisitor(
192-
writer,
193-
InstrumentationContext.MockGetter::getMock.javaMethod!!,
194-
InstrumentationContext.MockGetter::checkCallSite.javaMethod!!,
195-
InstrumentationContext.MockGetter::hasMock.javaMethod!!
196-
)
197-
}
198-
199-
mockClassVisitor.signatureToId.forEach { (method, id) ->
200-
instrumentationContext.methodSignatureToId += method to id
201-
}
202-
203-
return instrumenter.classByteCode
204-
}
205-
206-
class Factory(
207-
private val pathsToUserClasses: Set<String>
208-
) : UtExecutionInstrumentation.Factory<UtExecutionInstrumentation> {
209-
override fun create(): UtExecutionInstrumentation = SimpleUtExecutionInstrumentation(pathsToUserClasses)
210-
211-
override fun create(instrumentationContext: InstrumentationContext): UtExecutionInstrumentation =
212-
SimpleUtExecutionInstrumentation(pathsToUserClasses, instrumentationContext)
213-
214-
override fun equals(other: Any?): Boolean {
215-
if (this === other) return true
216-
if (javaClass != other?.javaClass) return false
217-
218-
other as Factory
219-
220-
return pathsToUserClasses == other.pathsToUserClasses
221-
}
222-
223-
override fun hashCode(): Int {
224-
return pathsToUserClasses.hashCode()
225-
}
226-
}
227-
}

0 commit comments

Comments
 (0)