[Wasm] Generate [K][Suspend]FunctionN on demand and support big arity

This commit is contained in:
Svyatoslav Kuzmich
2021-10-06 14:09:41 +03:00
parent 64a30cd95e
commit 1ed2748334
19 changed files with 38 additions and 468 deletions
@@ -341,13 +341,6 @@ private val wasmNullSpecializationLowering = makeWasmModulePhase(
description = "Specialize assigning Nothing? values to other types."
)
private val wasmFunctionInterfaceReplacer = makeWasmModulePhase(
::WasmFunctionInterfaceReplacer,
name = "WasmFunctionInterfaceReplacer",
description = "Replace function interface with concrete runtime interfaces"
)
private val staticMembersLoweringPhase = makeWasmModulePhase(
::StaticMembersLowering,
name = "StaticMembersLowering",
@@ -527,7 +520,6 @@ val wasmPhases = NamedCompilerPhase(
virtualDispatchReceiverExtractionPhase then
staticMembersLoweringPhase then
wasmFunctionInterfaceReplacer then
wasmNullSpecializationLowering then
validateIrAfterLowering
)
@@ -168,18 +168,6 @@ class WasmSymbols(
val kTypeStub = getInternalFunction("kTypeStub")
private val functionNInterfaces = (0..22).map { arity ->
getIrClass(FqName("kotlin.wasm.internal.Function$arity"))
}
val functionNInvokeMethods by lazy {
functionNInterfaces.map { interfaceSymbol ->
interfaceSymbol.owner.declarations.filterIsInstance<IrSimpleFunction>().single { method ->
method.name == OperatorNameConventions.INVOKE
}.symbol
}
}
val arraysCopyInto = findFunctions(collectionsPackage.memberScope, Name.identifier("copyInto"))
.map { symbolTable.referenceSimpleFunction(it) }
@@ -208,9 +196,6 @@ class WasmSymbols(
}
}
override fun functionN(n: Int): IrClassSymbol =
functionNInterfaces[n]
private fun findClass(memberScope: MemberScope, name: Name): ClassDescriptor =
memberScope.getContributedClassifier(name, NoLookupLocation.FROM_BACKEND) as ClassDescriptor
@@ -32,7 +32,12 @@ fun compileWasm(
): WasmCompilerResult {
val mainModule = depsDescriptors.mainModule
val configuration = depsDescriptors.compilerConfiguration
val (moduleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer) = loadIr(depsDescriptors, irFactory, verifySignatures = false)
val (moduleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer) = loadIr(
depsDescriptors,
irFactory,
verifySignatures = false,
loadFunctionInterfacesIntoStdlib = true,
)
val allModules = when (mainModule) {
is MainModule.SourceFiles -> dependencyModules + listOf(moduleFragment)
@@ -180,12 +180,6 @@ class WasmModuleCodegenContextImpl(
override fun referenceInterfaceId(irInterface: IrClassSymbol): WasmSymbol<Int> {
// HACK to substitute kotlin.Function5 with kotlin.wasm.internal.Function5
val defaultType = irInterface.defaultType
if (defaultType.isFunction()) {
val n = irInterface.owner.typeParameters.size - 1
return wasmFragment.interfaceId.reference(backendContext.wasmSymbols.functionN(n))
}
return wasmFragment.interfaceId.reference(irInterface)
}
@@ -123,24 +123,9 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass {
}
}
val nativeInvokeArity = getKotlinFunctionInvokeArity(call)
if (nativeInvokeArity != null) {
return irCall(call, symbols.functionNInvokeMethods[nativeInvokeArity])
}
return call
}
private fun getKotlinFunctionInvokeArity(call: IrCall): Int? {
val simpleFunction = call.symbol.owner as? IrSimpleFunction ?: return null
val receiverType = simpleFunction.dispatchReceiverParameter?.type ?: return null
if (simpleFunction.isSuspend) return null
if (simpleFunction.name == OperatorNameConventions.INVOKE && receiverType.isFunction()) {
return simpleFunction.valueParameters.size
}
return null
}
override fun lower(irFile: IrFile) {
val builder = context.createIrBuilder(irFile.symbol)
irFile.transformChildrenVoid(object : IrElementTransformerVoidWithContext() {
@@ -1,54 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.wasm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.typeWithArguments
import org.jetbrains.kotlin.ir.util.isFunction
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
/**
* Replace kotlin.Function{N} etc super types with kotlin.wasm.internal.Function{N} super types.
* This is a workaround for having a concrete IR for these interfaces.
*/
class WasmFunctionInterfaceReplacer(val context: WasmBackendContext) : FileLoweringPass {
private fun replaceType(type: IrType): IrType {
if (type.isFunction()) {
require(type is IrSimpleType)
val klass: IrClass = type.classifier.owner as IrClass
// No need to replace just "kotlin.Function"
if (klass.name.identifier == "Function") {
return type
}
val arity = klass.typeParameters.size - 1
return context.wasmSymbols.functionN(arity).typeWithArguments(type.arguments)
}
return type
}
override fun lower(irFile: IrFile) {
irFile.transformChildrenVoid(object : IrElementTransformerVoidWithContext() {
override fun visitClassNew(declaration: IrClass): IrStatement {
if (declaration.superTypes.any { it.isFunction() }) {
declaration.superTypes = declaration.superTypes.map { replaceType(it) }
}
return super.visitClassNew(declaration)
}
})
}
}
@@ -83,8 +83,12 @@ abstract class IrAbstractDescriptorBasedFunctionFactory {
@OptIn(ObsoleteDescriptorBasedAPI::class)
class IrDescriptorBasedFunctionFactory(
private val irBuiltIns: IrBuiltInsOverDescriptors, private val symbolTable: SymbolTable
private val irBuiltIns: IrBuiltInsOverDescriptors,
private val symbolTable: SymbolTable,
getPackageFragment: ((PackageFragmentDescriptor) -> IrPackageFragment)? = null
) : IrAbstractDescriptorBasedFunctionFactory() {
val getPackageFragment =
getPackageFragment ?: symbolTable::declareExternalPackageFragmentIfNotExists
// TODO: Lazieness
@@ -230,18 +234,18 @@ class IrDescriptorBasedFunctionFactory(
private val kotlinPackageFragment: IrPackageFragment by lazy {
irBuiltIns.builtIns.getFunction(0).let {
symbolTable.declareExternalPackageFragmentIfNotExists(it.containingDeclaration as PackageFragmentDescriptor)
getPackageFragment(it.containingDeclaration as PackageFragmentDescriptor)
}
}
private val kotlinCoroutinesPackageFragment: IrPackageFragment by lazy {
irBuiltIns.builtIns.getSuspendFunction(0).let {
symbolTable.declareExternalPackageFragmentIfNotExists(it.containingDeclaration as PackageFragmentDescriptor)
getPackageFragment(it.containingDeclaration as PackageFragmentDescriptor)
}
}
private val kotlinReflectPackageFragment: IrPackageFragment by lazy {
irBuiltIns.kPropertyClass.descriptor.let {
symbolTable.declareExternalPackageFragmentIfNotExists(it.containingDeclaration as PackageFragmentDescriptor)
getPackageFragment(it.containingDeclaration as PackageFragmentDescriptor)
}
}
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.ir.IrBuiltIns
@@ -38,13 +39,12 @@ import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerIr
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.descriptors.IrBuiltInsOverDescriptors
import org.jetbrains.kotlin.ir.descriptors.IrDescriptorBasedFunctionFactory
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.ir.util.IrMessageLogger
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.noUnboundLeft
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
@@ -256,7 +256,8 @@ fun loadIr(
depsDescriptors: ModulesStructure,
irFactory: IrFactory,
verifySignatures: Boolean,
filesToLoad: Set<String>? = null
filesToLoad: Set<String>? = null,
loadFunctionInterfacesIntoStdlib: Boolean = false,
): IrModuleInfo {
val project = depsDescriptors.project
val mainModule = depsDescriptors.mainModule
@@ -268,11 +269,26 @@ fun loadIr(
val signaturer = IdSignatureDescriptor(JsManglerDesc)
val symbolTable = SymbolTable(signaturer, irFactory)
lateinit var stdlibModule: IrModuleFragment
val createFunctionFactoryCallback =
if (loadFunctionInterfacesIntoStdlib) {
{ packageFragmentDescriptor: PackageFragmentDescriptor ->
IrFileImpl(NaiveSourceBasedFileEntryImpl("[K][Suspend]Functions"), packageFragmentDescriptor, stdlibModule)
.also { stdlibModule.files += it }
}
} else {
null
}
when (mainModule) {
is MainModule.SourceFiles -> {
assert(filesToLoad == null)
val (psi2IrContext, _) = preparePsi2Ir(depsDescriptors, errorPolicy, symbolTable)
val irBuiltIns = psi2IrContext.irBuiltIns
(irBuiltIns as IrBuiltInsOverDescriptors).functionFactory =
IrDescriptorBasedFunctionFactory(irBuiltIns, symbolTable, createFunctionFactoryCallback)
val feContext = psi2IrContext.run {
JsIrLinker.JsFePluginContext(moduleDescriptor, symbolTable, typeTranslator, irBuiltIns)
}
@@ -301,6 +317,7 @@ fun loadIr(
}
}
}
stdlibModule = deserializedModuleFragments.first()
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, mainModule.files, irLinker, messageLogger)
symbolTable.noUnboundLeft("Unbound symbols left after linker")
@@ -332,6 +349,7 @@ fun loadIr(
val typeTranslator =
TypeTranslatorImpl(symbolTable, depsDescriptors.compilerConfiguration.languageVersionSettings, moduleDescriptor)
val irBuiltIns = IrBuiltInsOverDescriptors(moduleDescriptor.builtIns, typeTranslator, symbolTable)
irBuiltIns.functionFactory = IrDescriptorBasedFunctionFactory(irBuiltIns, symbolTable, createFunctionFactoryCallback)
val loweredIcData = if (!depsDescriptors.icUseStdlibCache && !depsDescriptors.icUseStdlibCache) emptyMap() else {
val result = mutableMapOf<ModuleDescriptor, SerializedIcData>()
@@ -390,6 +408,7 @@ fun loadIr(
}
}
}
stdlibModule = deserializedModuleFragments.first()
val moduleFragment = deserializedModuleFragments.last()
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: BIG_ARITY
// !LANGUAGE: +NewInference
fun foo(
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: FUNCTION_REFERENCES
// WITH_RUNTIME
// IGNORE_BACKEND: JS
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: BIG_ARITY
// IGNORE_BACKEND: NATIVE
var result = "Fail"
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: BIG_ARITY
// !LANGUAGE: +FunctionTypesWithBigArity
class A(val value: Int) {
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: BIG_ARITY
// !LANGUAGE: +FunctionTypesWithBigArity
// IGNORE_BACKEND: JS_IR, JS
// IGNORE_BACKEND: JS_IR_ES6
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: BIG_ARITY
// !LANGUAGE: +FunctionTypesWithBigArity
class A
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: BIG_ARITY
// !LANGUAGE: +FunctionTypesWithBigArity
class A(val value: Int)
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: BIG_ARITY
// !LANGUAGE: +FunctionTypesWithBigArity
class A {
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: BIG_ARITY
interface A
object O : A
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: WASM
inline class Z(val value: Long)
@@ -1,341 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("unused")
package kotlin.wasm.internal
/** A function that takes 0 arguments. */
public interface Function0<out R> : Function<R> {
/** Invokes the function. */
public operator fun invoke(): R
}
/** A function that takes 1 argument. */
public interface Function1<in P1, out R> : Function<R> {
/** Invokes the function with the specified argument. */
public operator fun invoke(p1: P1): R
}
/** A function that takes 2 arguments. */
public interface Function2<in P1, in P2, out R> : Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(p1: P1, p2: P2): R
}
/** A function that takes 3 arguments. */
public interface Function3<in P1, in P2, in P3, out R> : Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(p1: P1, p2: P2, p3: P3): R
}
/** A function that takes 4 arguments. */
public interface Function4<in P1, in P2, in P3, in P4, out R> : Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4): R
}
/** A function that takes 5 arguments. */
public interface Function5<in P1, in P2, in P3, in P4, in P5, out R> : Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5): R
}
/** A function that takes 6 arguments. */
public interface Function6<in P1, in P2, in P3, in P4, in P5, in P6, out R> : Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6): R
}
/** A function that takes 7 arguments. */
public interface Function7<in P1, in P2, in P3, in P4, in P5, in P6, in P7, out R> : Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7): R
}
/** A function that takes 8 arguments. */
public interface Function8<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, out R> : Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8): R
}
/** A function that takes 9 arguments. */
public interface Function9<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, out R> : Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9): R
}
/** A function that takes 10 arguments. */
public interface Function10<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, out R> : Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10): R
}
/** A function that takes 11 arguments. */
public interface Function11<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, out R> : Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11): R
}
/** A function that takes 12 arguments. */
public interface Function12<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, out R> : Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12): R
}
/** A function that takes 13 arguments. */
public interface Function13<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, in P13, out R> :
Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(
p1: P1,
p2: P2,
p3: P3,
p4: P4,
p5: P5,
p6: P6,
p7: P7,
p8: P8,
p9: P9,
p10: P10,
p11: P11,
p12: P12,
p13: P13
): R
}
/** A function that takes 14 arguments. */
public interface Function14<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, in P13, in P14, out R> :
Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(
p1: P1,
p2: P2,
p3: P3,
p4: P4,
p5: P5,
p6: P6,
p7: P7,
p8: P8,
p9: P9,
p10: P10,
p11: P11,
p12: P12,
p13: P13,
p14: P14
): R
}
/** A function that takes 15 arguments. */
public interface Function15<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, in P13, in P14, in P15, out R> :
Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(
p1: P1,
p2: P2,
p3: P3,
p4: P4,
p5: P5,
p6: P6,
p7: P7,
p8: P8,
p9: P9,
p10: P10,
p11: P11,
p12: P12,
p13: P13,
p14: P14,
p15: P15
): R
}
/** A function that takes 16 arguments. */
public interface Function16<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, in P13, in P14, in P15, in P16, out R> :
Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(
p1: P1,
p2: P2,
p3: P3,
p4: P4,
p5: P5,
p6: P6,
p7: P7,
p8: P8,
p9: P9,
p10: P10,
p11: P11,
p12: P12,
p13: P13,
p14: P14,
p15: P15,
p16: P16
): R
}
/** A function that takes 17 arguments. */
public interface Function17<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, in P13, in P14, in P15, in P16, in P17, out R> :
Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(
p1: P1,
p2: P2,
p3: P3,
p4: P4,
p5: P5,
p6: P6,
p7: P7,
p8: P8,
p9: P9,
p10: P10,
p11: P11,
p12: P12,
p13: P13,
p14: P14,
p15: P15,
p16: P16,
p17: P17
): R
}
/** A function that takes 18 arguments. */
public interface Function18<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, in P13, in P14, in P15, in P16, in P17, in P18, out R> :
Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(
p1: P1,
p2: P2,
p3: P3,
p4: P4,
p5: P5,
p6: P6,
p7: P7,
p8: P8,
p9: P9,
p10: P10,
p11: P11,
p12: P12,
p13: P13,
p14: P14,
p15: P15,
p16: P16,
p17: P17,
p18: P18
): R
}
/** A function that takes 19 arguments. */
public interface Function19<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, in P13, in P14, in P15, in P16, in P17, in P18, in P19, out R> :
Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(
p1: P1,
p2: P2,
p3: P3,
p4: P4,
p5: P5,
p6: P6,
p7: P7,
p8: P8,
p9: P9,
p10: P10,
p11: P11,
p12: P12,
p13: P13,
p14: P14,
p15: P15,
p16: P16,
p17: P17,
p18: P18,
p19: P19
): R
}
/** A function that takes 20 arguments. */
public interface Function20<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, in P13, in P14, in P15, in P16, in P17, in P18, in P19, in P20, out R> :
Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(
p1: P1,
p2: P2,
p3: P3,
p4: P4,
p5: P5,
p6: P6,
p7: P7,
p8: P8,
p9: P9,
p10: P10,
p11: P11,
p12: P12,
p13: P13,
p14: P14,
p15: P15,
p16: P16,
p17: P17,
p18: P18,
p19: P19,
p20: P20
): R
}
/** A function that takes 21 arguments. */
public interface Function21<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, in P13, in P14, in P15, in P16, in P17, in P18, in P19, in P20, in P21, out R> :
Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(
p1: P1,
p2: P2,
p3: P3,
p4: P4,
p5: P5,
p6: P6,
p7: P7,
p8: P8,
p9: P9,
p10: P10,
p11: P11,
p12: P12,
p13: P13,
p14: P14,
p15: P15,
p16: P16,
p17: P17,
p18: P18,
p19: P19,
p20: P20,
p21: P21
): R
}
/** A function that takes 22 arguments. */
public interface Function22<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, in P13, in P14, in P15, in P16, in P17, in P18, in P19, in P20, in P21, in P22, out R> :
Function<R> {
/** Invokes the function with the specified arguments. */
public operator fun invoke(
p1: P1,
p2: P2,
p3: P3,
p4: P4,
p5: P5,
p6: P6,
p7: P7,
p8: P8,
p9: P9,
p10: P10,
p11: P11,
p12: P12,
p13: P13,
p14: P14,
p15: P15,
p16: P16,
p17: P17,
p18: P18,
p19: P19,
p20: P20,
p21: P21,
p22: P22
): R
}