后端(JVM)内部错误,求解决!


#1

代码:

infix fun Int.divmod(int: Int): Pair<Int, Int> {
    val div = this / int
    val rem = this - int * div
    return div to rem
}

class PrimeGenerator {
    val primesMap = mutableMapOf<Int, Int>()
    var number = 2
    var isPrime = true
    
    fun nextPrime(): Int {
        print("$number is prime?")
        while (true) {
            for ((i, j) in primesMap) {
                if (j == number) {
                    isPrime = false
                    primesMap[i] = i + j
               }
            }
            if (isPrime) {
                println(" Yes!")
                primesMap[number] = number * 2
                return number.also { number++ }
            } else {
                println(" No!")
                isPrime = true
                number++
            }
        }
    }
}

class Decomposer(val n: Int) {
    val generator = PrimeGenerator()
    var factor = generator.nextPrime()
    
    tailrec fun decompose(number: Int = n) {
        println("Now decomposing $number")
        while (true) {
            print("$factor is a factor of $number?")
            with(number divmod factor) {
                if (second != 0) {
                    println(" No!")
                    factor = generator.nextPrime()
                } else {
                    println(" Yes!")
                    if (first == 1) {
                        return
                    } else {
                       return decompose(first)
                    }
                }
            }
        }
    }
}

fun main() {
    val n = 10
    Decomposer(n).decompose()
}

错误信息:

Exception in thread "main" org.jetbrains.kotlin.codegen.CompilationException: Back-end (JVM) Internal error: Couldn't inline method call 'with' into
public final tailrec fun decompose(number: kotlin.Int = ...): kotlin.Unit defined in Decomposer
tailrec fun decompose(number: Int = n) {
        println("Now decomposing $number")
        while (true) {
            print("$factor is a factor of $number?")
            with(number divmod factor) {
                if (second != 0) {
                    println(" No!")
                    factor = generator.nextPrime()
                } else {
                    println(" Yes!")
                    if (first == 1) {
                        return
                    } else {
                       return decompose(first)
                    }
                }
            }
        }
    }
Cause: with (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;:
  @Lkotlin/internal/InlineOnly;() // invisible
   L0
    LDC 0
    ISTORE 2
   L1
    LINENUMBER 67 L1
    ICONST_0
    ISTORE 3
   L2
    LINENUMBER 70 L2
    ALOAD 1
    ALOAD 0
    INVOKEINTERFACE kotlin/jvm/functions/Function1.invoke (Ljava/lang/Object;)Ljava/lang/Object; (itf)
    ARETURN
   L3
    LOCALVARIABLE receiver Ljava/lang/Object; L0 L3 0
    LOCALVARIABLE block Lkotlin/jvm/functions/Function1; L0 L3 1
    LOCALVARIABLE $i$f$with I L1 L3 2
    MAXSTACK = 2
    MAXLOCALS = 4

File being compiled: (40,13) in /File.kt
The root cause java.lang.IllegalStateException was thrown at: org.jetbrains.kotlin.codegen.TailRecursionCodegen.getParameterVariableIndex(TailRecursionCodegen.kt:147)
 at org.jetbrains.kotlin.codegen.inline.InlineCodegen.throwCompilationException (InlineCodegen.kt:107) 
 at org.jetbrains.kotlin.codegen.inline.InlineCodegen.performInline (InlineCodegen.kt:152) 
 at org.jetbrains.kotlin.codegen.inline.PsiInlineCodegen.genCallInner (PsiInlineCodegen.kt:67) 
Caused by: org.jetbrains.kotlin.codegen.CompilationException: Back-end (JVM) Internal error: Couldn't inline method call 'with' into
public final tailrec fun decompose(number: kotlin.Int = ...): kotlin.Unit defined in Decomposer
tailrec fun decompose(number: Int = n) {
        println("Now decomposing $number")
        while (true) {
            print("$factor is a factor of $number?")
            with(number divmod factor) {
                if (second != 0) {
                    println(" No!")
                    factor = generator.nextPrime()
                } else {
                    println(" Yes!")
                    if (first == 1) {
                        return
                    } else {
                       return decompose(first)
                    }
                }
            }
        }
    }
Cause: with (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;:
  @Lkotlin/internal/InlineOnly;() // invisible
   L0
    LDC 0
    ISTORE 2
   L1
    LINENUMBER 67 L1
    ICONST_0
    ISTORE 3
   L2
    LINENUMBER 70 L2
    ALOAD 1
    ALOAD 0
    INVOKEINTERFACE kotlin/jvm/functions/Function1.invoke (Ljava/lang/Object;)Ljava/lang/Object; (itf)
    ARETURN
   L3
    LOCALVARIABLE receiver Ljava/lang/Object; L0 L3 0
    LOCALVARIABLE block Lkotlin/jvm/functions/Function1; L0 L3 1
    LOCALVARIABLE $i$f$with I L1 L3 2
    MAXSTACK = 2
    MAXLOCALS = 4

File being compiled: (40,13) in /File.kt
The root cause java.lang.IllegalStateException was thrown at: org.jetbrains.kotlin.codegen.TailRecursionCodegen.getParameterVariableIndex(TailRecursionCodegen.kt:147)
at org.jetbrains.kotlin.codegen.inline.InlineCodegen .throwCompilationException(InlineCodegen.kt:107)
at org.jetbrains.kotlin.codegen.inline.InlineCodegen .performInline(InlineCodegen.kt:152)
at org.jetbrains.kotlin.codegen.inline.PsiInlineCodegen .genCallInner(PsiInlineCodegen.kt:67)

#2

补充:去掉tailrec修饰符就能正常运行。


京ICP备16022265号-2 Kotlin China 2017 - 2018