mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-05-09 08:31:29 +00:00
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;
37 lines
747 B
Kotlin
Vendored
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 |