Generate old style lambda classes in jvm ir backend

This commit is contained in:
Mikhael Bogdanov
2018-08-13 11:45:16 +03:00
parent 08038d6de9
commit cb31962b38
4 changed files with 51 additions and 45 deletions
@@ -151,7 +151,9 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa
private lateinit var functionReferenceThis: IrValueParameterSymbol private lateinit var functionReferenceThis: IrValueParameterSymbol
private lateinit var argumentToPropertiesMap: Map<ParameterDescriptor, IrFieldSymbol> private lateinit var argumentToPropertiesMap: Map<ParameterDescriptor, IrFieldSymbol>
private val functionReference = context.ir.symbols.functionReference private val isLambda = irFunctionReference.origin == IrStatementOrigin.LAMBDA
private val functionReferenceOrLambda = if (isLambda) context.ir.symbols.lambdaClass else context.ir.symbols.functionReference
fun build(): BuiltFunctionReference { fun build(): BuiltFunctionReference {
val startOffset = irFunctionReference.startOffset val startOffset = irFunctionReference.startOffset
@@ -159,7 +161,7 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa
val returnType = functionDescriptor.returnType!! val returnType = functionDescriptor.returnType!!
val superTypes: MutableList<KotlinType> = mutableListOf( val superTypes: MutableList<KotlinType> = mutableListOf(
functionReference.descriptor.defaultType functionReferenceOrLambda.descriptor.defaultType
) )
val numberOfParameters = unboundFunctionParameters.size val numberOfParameters = unboundFunctionParameters.size
@@ -210,29 +212,6 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa
val invokeFunctionDescriptor = functionClassDescriptor.getFunction("invoke", functionClassTypeParameters) val invokeFunctionDescriptor = functionClassDescriptor.getFunction("invoke", functionClassTypeParameters)
val invokeMethodBuilder = createInvokeMethodBuilder(invokeFunctionDescriptor) val invokeMethodBuilder = createInvokeMethodBuilder(invokeFunctionDescriptor)
val getSignatureBuilder =
createGetSignatureMethodBuilder(functionReference.owner.descriptor.getFunction("getSignature", emptyList()))
val getNameBuilder = createGetNameMethodBuilder(functionReference.owner.descriptor.getProperty("name", emptyList()))
val getOwnerBuilder = createGetOwnerMethodBuilder(functionReference.owner.descriptor.getFunction("getOwner", emptyList()))
val suspendInvokeMethodBuilder =
if (suspendFunctionClassDescriptor != null) {
val suspendInvokeFunctionDescriptor =
suspendFunctionClassDescriptor.getFunction("invoke", suspendFunctionClassTypeParameters!!)
createInvokeMethodBuilder(suspendInvokeFunctionDescriptor)
} else null
val inheritedScope = functionReference.descriptor.unsubstitutedMemberScope
.getContributedDescriptors().mapNotNull { it.createFakeOverrideDescriptor(functionReferenceClassDescriptor) }
.filterNot { it.name.asString() == "getSignature" || it.name.asString() == "name" || it.name.asString() == "getOwner" }
contributedDescriptors.addAll(
(
inheritedScope + invokeMethodBuilder.symbol.descriptor +
suspendInvokeMethodBuilder?.symbol?.descriptor + getSignatureBuilder.symbol.descriptor
).filterNotNull()
)
constructorBuilder.initialize() constructorBuilder.initialize()
functionReferenceClass.declarations.add(constructorBuilder.ir) functionReferenceClass.declarations.add(constructorBuilder.ir)
@@ -240,18 +219,46 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa
invokeMethodBuilder.initialize() invokeMethodBuilder.initialize()
functionReferenceClass.declarations.add(invokeMethodBuilder.ir) functionReferenceClass.declarations.add(invokeMethodBuilder.ir)
getSignatureBuilder.initialize()
functionReferenceClass.declarations.add(getSignatureBuilder.ir)
getNameBuilder.initialize() if (!isLambda) {
functionReferenceClass.declarations.add(getNameBuilder.ir) val getSignatureBuilder =
createGetSignatureMethodBuilder(functionReferenceOrLambda.owner.descriptor.getFunction("getSignature", emptyList()))
val getNameBuilder = createGetNameMethodBuilder(functionReferenceOrLambda.owner.descriptor.getProperty("name", emptyList()))
val getOwnerBuilder =
createGetOwnerMethodBuilder(functionReferenceOrLambda.owner.descriptor.getFunction("getOwner", emptyList()))
getOwnerBuilder.initialize() val suspendInvokeMethodBuilder =
functionReferenceClass.declarations.add(getOwnerBuilder.ir) if (suspendFunctionClassDescriptor != null) {
val suspendInvokeFunctionDescriptor =
suspendFunctionClassDescriptor.getFunction("invoke", suspendFunctionClassTypeParameters!!)
createInvokeMethodBuilder(suspendInvokeFunctionDescriptor)
} else null
suspendInvokeMethodBuilder?.let { val inheritedScope = functionReferenceOrLambda.descriptor.unsubstitutedMemberScope
it.initialize() .getContributedDescriptors().mapNotNull { it.createFakeOverrideDescriptor(functionReferenceClassDescriptor) }
functionReferenceClass.declarations.add(it.ir) .filterNot { !isLambda && (it.name.asString() == "getSignature" || it.name.asString() == "name" || it.name.asString() == "getOwner") }
contributedDescriptors.addAll(
(
inheritedScope + invokeMethodBuilder.symbol.descriptor +
suspendInvokeMethodBuilder?.symbol?.descriptor + getSignatureBuilder.symbol.descriptor
).filterNotNull()
)
getSignatureBuilder.initialize()
functionReferenceClass.declarations.add(getSignatureBuilder.ir)
getNameBuilder.initialize()
functionReferenceClass.declarations.add(getNameBuilder.ir)
getOwnerBuilder.initialize()
functionReferenceClass.declarations.add(getOwnerBuilder.ir)
suspendInvokeMethodBuilder?.let {
it.initialize()
functionReferenceClass.declarations.add(it.ir)
}
} }
return BuiltFunctionReference(functionReferenceClass, constructorBuilder.ir) return BuiltFunctionReference(functionReferenceClass, constructorBuilder.ir)
@@ -260,7 +267,7 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa
private fun createConstructorBuilder() = object : SymbolWithIrBuilder<IrConstructorSymbol, IrConstructor>() { private fun createConstructorBuilder() = object : SymbolWithIrBuilder<IrConstructorSymbol, IrConstructor>() {
private val kFunctionRefConstructorSymbol = private val kFunctionRefConstructorSymbol =
functionReference.constructors.filter { it.descriptor.valueParameters.size == 2 }.single() functionReferenceOrLambda.constructors.filter { it.descriptor.valueParameters.size == if (isLambda) 1 else 2 }.single()
override fun buildSymbol() = IrConstructorSymbolImpl( override fun buildSymbol() = IrConstructorSymbolImpl(
ClassConstructorDescriptorImpl.create( ClassConstructorDescriptorImpl.create(
@@ -308,13 +315,15 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa
IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, unboundFunctionParameters.size) IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, unboundFunctionParameters.size)
putValueArgument(0, const) putValueArgument(0, const)
val irReceiver = valueParameters.firstOrNull() if (!isLambda) {
val receiver = boundFunctionParameters.singleOrNull() val irReceiver = valueParameters.firstOrNull()
//TODO pass proper receiver val receiver = boundFunctionParameters.singleOrNull()
val receiverValue = receiver?.let { //TODO pass proper receiver
irGet(irReceiver!!.symbol.owner) val receiverValue = receiver?.let {
} ?: irNull() irGet(irReceiver!!.symbol.owner)
putValueArgument(1, receiverValue) } ?: irNull()
putValueArgument(1, receiverValue)
}
} }
//TODO don't write receiver again: use it from base class //TODO don't write receiver again: use it from base class
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR
// WITH_RUNTIME // WITH_RUNTIME
// WITH_COROUTINES // WITH_COROUTINES
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt // FILE: 1.kt
inline fun <T> test(p: T) { inline fun <T> test(p: T) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt // FILE: 1.kt
inline fun test(p: Any) { inline fun test(p: Any) {