Skip to content

Commit 02b773d

Browse files
SokolovaMariamvicsokolova
authored andcommitted
Fixed looking for local variables scope labels
1 parent 23e5cc1 commit 02b773d

File tree

2 files changed

+38
-1
lines changed
  • atomicfu-transformer/src/main/kotlin/kotlinx/atomicfu/transformer
  • atomicfu/src/commonTest/kotlin/kotlinx/atomicfu/test

2 files changed

+38
-1
lines changed

atomicfu-transformer/src/main/kotlin/kotlinx/atomicfu/transformer/AsmUtil.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,19 @@ fun AbstractInsnNode.isReturn() =
7171

7272
@Suppress("UNCHECKED_CAST")
7373
fun MethodNode.localVar(v: Int, node: AbstractInsnNode): LocalVariableNode? =
74-
(localVariables as List<LocalVariableNode>).firstOrNull { it.index == v && node.next === it.start }
74+
(localVariables as List<LocalVariableNode>).firstOrNull { it.index == v && verifyLocalVarScopeStart(v, node, it.start)}
75+
76+
// checks that the store instruction is followed by the label equal to the local variable scope start from the local variables table
77+
private fun verifyLocalVarScopeStart(v: Int, node: AbstractInsnNode, scopeStart: LabelNode): Boolean {
78+
var i = node.next
79+
while (i != null) {
80+
// check that no other variable is stored into the same slot v before finding the scope start label
81+
if (i is VarInsnNode && i.`var` == v) return false
82+
if (i is LabelNode && i === scopeStart) return true
83+
i = i.next
84+
}
85+
return false
86+
}
7587

7688
inline fun forVarLoads(v: Int, start: LabelNode, end: LabelNode, block: (VarInsnNode) -> AbstractInsnNode?) {
7789
var cur: AbstractInsnNode? = start
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package kotlinx.atomicfu.test
2+
3+
import kotlinx.atomicfu.*
4+
import kotlin.test.Test
5+
import kotlin.test.assertEquals
6+
7+
class InlineCASTest {
8+
9+
private val a = atomic(0)
10+
private val ref = atomic(listOf("AAA"))
11+
12+
private inline fun AtomicInt.casLoop(to: Int): Int = loop { cur ->
13+
if (compareAndSet(cur, to)) return value
14+
}
15+
16+
private inline fun AtomicRef<List<String>>.casLoop(to: List<String>): List<String> = loop { cur ->
17+
if (compareAndSet(cur, to)) return value
18+
}
19+
20+
@Test
21+
fun testLocalVariableScope() {
22+
assertEquals(a.casLoop(5), 5)
23+
assertEquals(ref.casLoop(listOf("BBB")), listOf("BBB"))
24+
}
25+
}

0 commit comments

Comments
 (0)