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;
This commit is contained in:
pyos
2019-09-16 11:50:52 +02:00
committed by max-kammerer
parent 433e0e4740
commit 82fb5c4d19
8 changed files with 57 additions and 14 deletions
@@ -1,5 +1,4 @@
// WITH_RUNTIME
// IGNORE_BACKEND: JVM_IR
fun testUIntRangeForEach() {
var s = 0