Files
kotlin/compiler/testData/codegen/bytecodeText/boxingOptimization/unsignedRangeIteratorSpecialization.kt
pyos 82fb5c4d19 JVM_IR: move lambda captures to end of signature when inlining
For example, a lambda `{ param -> captured }` of type `E.(T) -> U` will
be transformed by LocalDeclarationsLowering into a private static method

    fun f$lambda-0($this: E, $captured: U, param: T) = $captured

The reason for such an ordering is that a lambda looks the same as a
local function, and local function can have default arguments, and those
arguments can reference captured variables; thus, captured variables
must come before actual declared arguments.

However, this is not the order that the inliner wants. Moreover, since
it was written to handle lambdas represented as `invoke` methods of
anonymous objects, it does not expect the actual callable method to have
any parameters corresponding to captured variables at all. This results
in it attempting to generate a temporary node with descriptor

    (LE;LU;LT;LU;)LU;

while still using locals 1 and 2 as `param` and `$captured` respectively.
In the example above, this is not critical, as they both have reference
type and the lambda will eventually be pasted into a different node
anyway; however, if it happens that one of them is a primitive, or both
are primitives of different types, the bytecode will use incorrect
instructions, causing verification errors. The correct descriptor is

    (LE;LT;LU;)LU;
2019-11-11 13:46:42 +01:00

37 lines
747 B
Kotlin
Vendored

// WITH_RUNTIME
fun testUIntRangeForEach() {
var s = 0
(1u .. 5u).forEach {
s = s * 10 + it.toInt()
}
if (s != 12345) throw AssertionError("$s")
}
fun testUIntProgressionForEach() {
var s = 0
(5u downTo 1u).forEach {
s = s * 10 + it.toInt()
}
if (s != 54321) throw AssertionError("$s")
}
fun testULongRangeForEach() {
var s = 0
(1UL .. 5UL).forEach {
s = s * 10 + it.toInt()
}
if (s != 12345) throw AssertionError("$s")
}
fun testULongProgressionForEach() {
var s = 0
(5UL downTo 1UL).forEach {
s = s * 10 + it.toInt()
}
if (s != 54321) throw AssertionError("$s")
}
// 0 java/util/Iterator.next \(\)Ljava/lang/Object;
// 2 nextUInt
// 2 nextULong