[JS IR] Lift lambdas that capture no context

If a lambda expression does not capture any local variables, convert
it to a global free function and replace the lambda creation with
a reference to that function.

Example: for the following Kotlin code

```kotlin
fun foo(f: () -> Unit) = f()

fun bar() = foo { console.log("hello") }
```

before this patch, we generated:

```js
function foo(f) {
  return f();
}
function bar() {
  return foo(bar$lambda());
}
function bar$lambda() {
  return function () {
    console.log('hello');
  };
}
```

after this patch, we generate:

```js
function foo(f) {
  return f();
}
function bar() {
  return foo(bar$lambda);
}
function bar$lambda() {
  console.log('hello');
}
```
This commit is contained in:
Sergej Jaskiewicz
2022-04-04 14:29:54 +03:00
committed by Space
parent 026f292f4f
commit d7d86a0e95
6 changed files with 167 additions and 79 deletions
+4 -2
View File
@@ -1,7 +1,9 @@
// EXPECTED_REACHABLE_NODES: 1284
package foo
// CHECK_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$lambda
// CHECK_FUNCTION_EXISTS: multiplyBy2$lambda
// CHECK_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$lambda TARGET_BACKENDS=JS
// HAS_NO_CAPTURED_VARS: function=multiplyBy2 except=multiplyBy2$lambda
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$lambda_0
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2 function=run
@@ -19,4 +21,4 @@ fun box(): String {
assertEquals(8, multiplyBy2(4))
return "OK"
}
}
+4 -2
View File
@@ -1,7 +1,9 @@
// EXPECTED_REACHABLE_NODES: 1284
package foo
// CHECK_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$lambda
// CHECK_FUNCTION_EXISTS: multiplyBy2$lambda
// CHECK_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$lambda TARGET_BACKENDS=JS
// HAS_NO_CAPTURED_VARS: function=multiplyBy2 except=multiplyBy2$lambda
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2 function=run
internal inline fun <T> run(noinline func: (T) -> T, arg: T): T {
@@ -18,4 +20,4 @@ fun box(): String {
assertEquals(8, multiplyBy2(4))
return "OK"
}
}