Skip to content

Commit 761d4dd

Browse files
authored
Optional Snapshot Generation in Consume (#879)
1 parent 2257d9c commit 761d4dd

11 files changed

Lines changed: 269 additions & 164 deletions

src/main/scala/rules/ChunkSupporter.scala

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ trait ChunkSupportRules extends SymbolicExecutionRules {
2929
argsExp: Option[Seq[ast.Exp]],
3030
perms: Term,
3131
permsExp: Option[ast.Exp],
32+
returnSnap: Boolean,
3233
ve: VerificationError,
3334
v: Verifier,
3435
description: String)
35-
(Q: (State, Heap, Term, Verifier) => VerificationResult)
36+
(Q: (State, Heap, Option[Term], Verifier) => VerificationResult)
3637
: VerificationResult
3738

3839
def produce(s: State, h: Heap, ch: NonQuantifiedChunk, v: Verifier)
@@ -71,17 +72,18 @@ object chunkSupporter extends ChunkSupportRules {
7172
argsExp: Option[Seq[ast.Exp]],
7273
perms: Term,
7374
permsExp: Option[ast.Exp],
75+
returnSnap: Boolean,
7476
ve: VerificationError,
7577
v: Verifier,
7678
description: String)
77-
(Q: (State, Heap, Term, Verifier) => VerificationResult)
79+
(Q: (State, Heap, Option[Term], Verifier) => VerificationResult)
7880
: VerificationResult = {
7981

80-
consume2(s, h, resource, args, argsExp, perms, permsExp, ve, v)((s2, h2, optSnap, v2) =>
82+
consume2(s, h, resource, args, argsExp, perms, permsExp, returnSnap, ve, v)((s2, h2, optSnap, v2) =>
8183
optSnap match {
8284
case Some(snap) =>
83-
Q(s2, h2, snap.convert(sorts.Snap), v2)
84-
case None =>
85+
Q(s2, h2, Some(snap.convert(sorts.Snap)), v2)
86+
case None if returnSnap =>
8587
/* Not having consumed anything could mean that we are in an infeasible
8688
* branch, or that the permission amount to consume was zero.
8789
*
@@ -91,7 +93,8 @@ object chunkSupporter extends ChunkSupportRules {
9193
*/
9294
val fresh = v2.decider.fresh(sorts.Snap, Option.when(withExp)(PUnknown()))
9395
val s3 = s2.copy(functionRecorder = s2.functionRecorder.recordFreshSnapshot(fresh.applicable))
94-
Q(s3, h2, fresh, v2)
96+
Q(s3, h2, Some(fresh), v2)
97+
case None => Q(s2, h2, None, v2)
9598
})
9699
}
97100

@@ -102,6 +105,7 @@ object chunkSupporter extends ChunkSupportRules {
102105
argsExp: Option[Seq[ast.Exp]],
103106
perms: Term,
104107
permsExp: Option[ast.Exp],
108+
returnSnap: Boolean,
105109
ve: VerificationError,
106110
v: Verifier)
107111
(Q: (State, Heap, Option[Term], Verifier) => VerificationResult)
@@ -111,24 +115,28 @@ object chunkSupporter extends ChunkSupportRules {
111115
if (s.exhaleExt) {
112116
val failure = createFailure(ve, v, s, "chunk consume in package")
113117
magicWandSupporter.transfer(s, perms, permsExp, failure, Seq(), v)(consumeGreedy(_, _, id, args, _, _, _))((s1, optCh, v1) =>
114-
Q(s1, h, optCh.flatMap(ch => Some(ch.snap)), v1))
118+
if (returnSnap){
119+
Q(s1, h, optCh.flatMap(ch => Some(ch.snap)), v1)
120+
} else {
121+
Q(s1, h, None, v1)
122+
})
115123
} else {
116124
executionFlowController.tryOrFail2[Heap, Option[Term]](s.copy(h = h), v)((s1, v1, QS) =>
117125
if (s1.moreCompleteExhale) {
118-
moreCompleteExhaleSupporter.consumeComplete(s1, s1.h, resource, args, argsExp, perms, permsExp, ve, v1)((s2, h2, snap2, v2) => {
126+
moreCompleteExhaleSupporter.consumeComplete(s1, s1.h, resource, args, argsExp, perms, permsExp, returnSnap, ve, v1)((s2, h2, snap2, v2) => {
119127
QS(s2.copy(h = s.h), h2, snap2, v2)
120128
})
121129
} else {
122130
consumeGreedy(s1, s1.h, id, args, perms, permsExp, v1) match {
123131
case (Complete(), s2, h2, optCh2) =>
124132
val snap = optCh2 match {
125-
case None => None
126-
case Some(ch) =>
133+
case Some(ch) if returnSnap =>
127134
if (v1.decider.check(IsPositive(perms), Verifier.config.checkTimeout())) {
128135
Some(ch.snap)
129136
} else {
130137
Some(Ite(IsPositive(perms), ch.snap.convert(sorts.Snap), Unit))
131138
}
139+
case _ => None
132140
}
133141
QS(s2.copy(h = s.h), h2, snap, v1)
134142
case _ if v1.decider.checkSmoke(true) =>

0 commit comments

Comments
 (0)