Avoid true condition generation for do while loop, since it confuses the Java verifier.
Change-Id: I96eca6623a91a8365090768f42c6e865b612e1cc
This commit is contained in:
committed by
max-kammerer
parent
59fda8d7ce
commit
eec25dbea2
+27
-23
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages
|
|||||||
import org.jetbrains.kotlin.codegen.inline.TypeParameterMappings
|
import org.jetbrains.kotlin.codegen.inline.TypeParameterMappings
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty
|
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty
|
||||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
||||||
|
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysTrueIfeq
|
||||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fixStackAndJump
|
import org.jetbrains.kotlin.codegen.pseudoInsns.fixStackAndJump
|
||||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
@@ -881,28 +882,34 @@ class ExpressionCodegen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avoid true condition generation for tailrec
|
||||||
|
// ASM and the Java verifier assume that L1 is reachable which causes several verifications to fail.
|
||||||
|
// To avoid them, trivial jump elimination is required.
|
||||||
|
// L0
|
||||||
|
// ICONST_1 //could be eliminated
|
||||||
|
// IFEQ L1 //could be eliminated
|
||||||
|
// .... // no jumps
|
||||||
|
// GOTO L0
|
||||||
|
// L1
|
||||||
|
//TODO: write elimination lower
|
||||||
|
private fun generateLoopJump(condition: IrExpression, data: BlockInfo, label: Label, jumpIfFalse: Boolean) {
|
||||||
|
condition.markLineNumber(true)
|
||||||
|
if (condition is IrConst<*> && condition.value == true) {
|
||||||
|
if (jumpIfFalse) {
|
||||||
|
mv.fakeAlwaysFalseIfeq(label)
|
||||||
|
} else {
|
||||||
|
mv.fakeAlwaysTrueIfeq(label)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gen(condition, data)
|
||||||
|
BranchedValue.condJump(StackValue.onStack(condition.asmType), label, jumpIfFalse, mv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitWhileLoop(loop: IrWhileLoop, data: BlockInfo): StackValue {
|
override fun visitWhileLoop(loop: IrWhileLoop, data: BlockInfo): StackValue {
|
||||||
val continueLabel = markNewLabel()
|
val continueLabel = markNewLabel()
|
||||||
val endLabel = Label()
|
val endLabel = Label()
|
||||||
val condition = loop.condition
|
generateLoopJump(loop.condition, data, endLabel, true)
|
||||||
|
|
||||||
// Avoid true condition generation for tailrec
|
|
||||||
// ASM and Java verifier assumes that L1 is reachable that cause several verification to fail,
|
|
||||||
// to avoid them trivial jump elumination is required
|
|
||||||
// L0
|
|
||||||
// ICONST_1 //could be eliminated
|
|
||||||
// IFEQ L1 //could be eliminated
|
|
||||||
// .... // no jumps
|
|
||||||
// GOTO L0
|
|
||||||
// L1
|
|
||||||
//TODO: write elimination lower
|
|
||||||
condition.markLineNumber(startOffset = true)
|
|
||||||
if (!(condition is IrConst<*> && condition.value == true)) {
|
|
||||||
gen(condition, data)
|
|
||||||
BranchedValue.condJump(StackValue.onStack(condition.asmType), endLabel, true, mv)
|
|
||||||
} else {
|
|
||||||
mv.fakeAlwaysFalseIfeq(endLabel)
|
|
||||||
}
|
|
||||||
|
|
||||||
with(LoopInfo(loop, continueLabel, endLabel)) {
|
with(LoopInfo(loop, continueLabel, endLabel)) {
|
||||||
data.addInfo(this)
|
data.addInfo(this)
|
||||||
@@ -973,10 +980,7 @@ class ExpressionCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
mv.visitLabel(continueLabel)
|
mv.visitLabel(continueLabel)
|
||||||
val condition = loop.condition
|
generateLoopJump(loop.condition, data, entry, false)
|
||||||
condition.markLineNumber(startOffset = true)
|
|
||||||
gen(condition, data)
|
|
||||||
BranchedValue.condJump(StackValue.onStack(condition.asmType), entry, false, mv)
|
|
||||||
mv.mark(endLabel)
|
mv.mark(endLabel)
|
||||||
|
|
||||||
return loop.onStack
|
return loop.onStack
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
var field: Int = 0
|
var field: Int = 0
|
||||||
|
|
||||||
fun next(): Int {
|
fun next(): Int {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
var field: Int = 0
|
var field: Int = 0
|
||||||
|
|
||||||
fun next(): Int {
|
fun next(): Int {
|
||||||
|
|||||||
Reference in New Issue
Block a user