backend: use IR builders in CallableReferenceLowering
This commit is contained in:
committed by
SvyatoslavScherbina
parent
7b29f4854c
commit
7fd4b4fe34
+34
-30
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.lower
|
package org.jetbrains.kotlin.backend.konan.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.createFunctionIrGenerator
|
||||||
import org.jetbrains.kotlin.backend.konan.*
|
import org.jetbrains.kotlin.backend.konan.*
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||||
@@ -10,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
@@ -134,42 +136,44 @@ private class CallableReferencesUnbinder(val lower: CallableReferenceLowering,
|
|||||||
// Create new function descriptor:
|
// Create new function descriptor:
|
||||||
val newDescriptor = createSimpleFunctionImplTargetDescriptor(descriptor, unboundParams)
|
val newDescriptor = createSimpleFunctionImplTargetDescriptor(descriptor, unboundParams)
|
||||||
|
|
||||||
// Create new function declaration:
|
val generator = lower.context.createFunctionIrGenerator(newDescriptor)
|
||||||
|
val blockBody = generator.irBlockBody(startOffset, endOffset) {
|
||||||
val boundArgsArray = IrCallImpl(startOffset, endOffset, simpleFunctionImplBoundArgsGetter, null).apply {
|
val boundArgsGet = irCall(simpleFunctionImplBoundArgsGetter).apply {
|
||||||
dispatchReceiver = IrGetValueImpl(startOffset, endOffset, newDescriptor.valueParameters[0])
|
dispatchReceiver = irGet(newDescriptor.valueParameters[0])
|
||||||
}
|
|
||||||
// TODO: do not call boundArgs getter for each bound argument.
|
|
||||||
|
|
||||||
val arrayGet = boundArgsArray.type.memberScope.getContributedDescriptors()
|
|
||||||
.filterIsInstance<FunctionDescriptor>().single { it.name.asString() == "get" }
|
|
||||||
|
|
||||||
// TODO: some handling for type parameters is probably required here.
|
|
||||||
|
|
||||||
// Call to old function from new function:
|
|
||||||
val call = IrCallImpl(startOffset, endOffset, descriptor)
|
|
||||||
|
|
||||||
// unboundParams are received as all new function parameters except first:
|
|
||||||
val newUnboundParams = newDescriptor.valueParameters.drop(1)
|
|
||||||
assert (unboundParams.size == newUnboundParams.size)
|
|
||||||
call.addArguments(unboundParams.mapIndexed { index, param ->
|
|
||||||
param to IrGetValueImpl(startOffset, endOffset, newUnboundParams[index])
|
|
||||||
})
|
|
||||||
|
|
||||||
// boundParams are received in `SimpleFunctionImpl.boundArgs`:
|
|
||||||
call.addArguments(boundParams.mapIndexed { index, param ->
|
|
||||||
param to IrCallImpl(startOffset, endOffset, arrayGet).apply {
|
|
||||||
dispatchReceiver = boundArgsArray
|
|
||||||
putValueArgument(0, IrConstImpl.int(startOffset, endOffset, builtIns.intType, index))
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
val ret = IrReturnImpl(startOffset, endOffset, newDescriptor, call)
|
+irLet(boundArgsGet) { boundArgs ->
|
||||||
|
val arrayGet = boundArgs.type.memberScope.getContributedDescriptors()
|
||||||
|
.filterIsInstance<FunctionDescriptor>().single { it.name.asString() == "get" }
|
||||||
|
|
||||||
|
// TODO: some handling for type parameters is probably required here.
|
||||||
|
|
||||||
|
// Call to old function from new function:
|
||||||
|
val call = irCall(descriptor).apply {
|
||||||
|
// unboundParams are received as all new function parameters except first:
|
||||||
|
val newUnboundParams = newDescriptor.valueParameters.drop(1)
|
||||||
|
assert (unboundParams.size == newUnboundParams.size)
|
||||||
|
addArguments(unboundParams.mapIndexed { index, param ->
|
||||||
|
param to irGet(newUnboundParams[index])
|
||||||
|
})
|
||||||
|
|
||||||
|
// boundParams are received in `SimpleFunctionImpl.boundArgs`:
|
||||||
|
addArguments(boundParams.mapIndexed { index, param ->
|
||||||
|
param to irCall(arrayGet).apply {
|
||||||
|
dispatchReceiver = irGet(boundArgs)
|
||||||
|
putValueArgument(0, irInt(index))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
irReturn(call)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val newFunction = IrFunctionImpl(
|
val newFunction = IrFunctionImpl(
|
||||||
startOffset, endOffset, DECLARATION_ORIGIN_FUNCTION_FOR_CALLABLE_REFERENCE,
|
startOffset, endOffset, DECLARATION_ORIGIN_FUNCTION_FOR_CALLABLE_REFERENCE,
|
||||||
newDescriptor,
|
newDescriptor,
|
||||||
IrBlockBodyImpl(startOffset, endOffset, listOf(ret))
|
blockBody
|
||||||
)
|
)
|
||||||
|
|
||||||
return newFunction
|
return newFunction
|
||||||
|
|||||||
Reference in New Issue
Block a user