Eliminated all hacks related to IR bugs with delegated descriptors.

This commit is contained in:
Igor Chevdar
2017-03-03 15:39:40 +03:00
parent 8427612d59
commit cf32f89697
7 changed files with 9 additions and 96 deletions
@@ -71,8 +71,7 @@ internal class SpecialDescriptorsFactory(val context: Context) {
bridgeDescriptor.initialize(
extensionReceiverType,
// TODO: bug in descriptor - https://youtrack.jetbrains.com/issue/KT-16438.
(descriptor.containingDeclaration as ClassDescriptor).thisAsReceiverParameter,
descriptor.dispatchReceiverParameter,
descriptor.typeParameters,
descriptor.valueParameters.mapIndexed { index, valueParameterDescriptor ->
when (bridgeDirections[index + 2]) {
@@ -32,7 +32,6 @@ internal class KonanLower(val context: Context) {
InitializersLowering(context).runOnFilePostfix(irFile)
}
phaser.phase(KonanPhase.LOWER_DELEGATION) {
ClassDelegationLowering(context).runOnFilePostfix(irFile)
PropertyDelegationLowering(context).lower(irFile)
}
phaser.phase(KonanPhase.LOWER_TYPE_OPERATORS) {
@@ -15,8 +15,7 @@ internal class OverriddenFunctionDescriptor(val descriptor: FunctionDescriptor,
val needBridge: Boolean
get() {
if (descriptor.modality == Modality.ABSTRACT) return false
return descriptor.kind == CallableMemberDescriptor.Kind.DELEGATION
|| descriptor.target.needBridgeTo(overriddenDescriptor)
return descriptor.target.needBridgeTo(overriddenDescriptor)
}
val bridgeDirections: BridgeDirections
@@ -13,8 +13,6 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltinOperatorDescriptorBase
import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.util.getArguments
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
@@ -1246,10 +1244,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
private fun evaluateGetField(value: IrGetField): LLVMValueRef {
context.log("evaluateGetField : ${ir2string(value)}")
if (value.descriptor.dispatchReceiverParameter != null
// TODO: hack because of IR bug: https://github.com/JetBrains/kotlin/tree/rr/dispatch_receiver_for_delegate_descriptor.
|| value.descriptor is IrImplementingDelegateDescriptorImpl
|| (value.descriptor is IrPropertyDelegateDescriptorImpl && value.descriptor.containingDeclaration is ClassDescriptor)) {
if (value.descriptor.dispatchReceiverParameter != null) {
val thisPtr = evaluateExpression(value.receiver!!)
return codegen.loadSlot(
fieldPtrOfClass(thisPtr, value.descriptor), value.descriptor.isVar())
@@ -1279,10 +1274,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
context.log("evaluateSetField : ${ir2string(value)}")
val valueToAssign = evaluateExpression(value.value)
if (value.descriptor.dispatchReceiverParameter != null
// TODO: hack because of IR bug: https://github.com/JetBrains/kotlin/tree/rr/dispatch_receiver_for_delegate_descriptor.
|| value.descriptor is IrImplementingDelegateDescriptorImpl
|| (value.descriptor is IrPropertyDelegateDescriptorImpl && value.descriptor.containingDeclaration is ClassDescriptor)) {
if (value.descriptor.dispatchReceiverParameter != null) {
val thisPtr = evaluateExpression(value.receiver!!)
codegen.storeAnyGlobal(valueToAssign, fieldPtrOfClass(thisPtr, value.descriptor))
}
@@ -7,8 +7,6 @@ import org.jetbrains.kotlin.backend.konan.descriptors.*
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptorImpl
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.name.FqName
@@ -298,13 +296,8 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
val descriptor = declaration.descriptor
val dispatchReceiverParameter = descriptor.dispatchReceiverParameter
if (dispatchReceiverParameter != null
// TODO: hack because of IR bug: https://github.com/JetBrains/kotlin/tree/rr/dispatch_receiver_for_delegate_descriptor.
|| descriptor is IrImplementingDelegateDescriptorImpl
|| (descriptor is IrPropertyDelegateDescriptorImpl && descriptor.containingDeclaration is ClassDescriptor)) {
val containingClass = dispatchReceiverParameter?.containingDeclaration
// TODO: hack because of IR bug: https://github.com/JetBrains/kotlin/tree/rr/dispatch_receiver_for_delegate_descriptor.
?: descriptor.containingDeclaration
if (dispatchReceiverParameter != null) {
val containingClass = dispatchReceiverParameter.containingDeclaration
val classDeclarations = this.classes[containingClass] ?: error(containingClass.toString())
val allFields = classDeclarations.fields
@@ -34,20 +34,11 @@ internal class DirectBridgesCallsLowering(val context: Context) : BodyLoweringPa
}
val target = descriptor.target
val needBridge = descriptor.original.needBridgeTo(target)
if (descriptor.kind != CallableMemberDescriptor.Kind.DELEGATION && !needBridge)
return expression
val toCall = if (needBridge) {
target
} else {
// Need to call delegating function.
context.specialDescriptorsFactory.getBridgeDescriptor(OverriddenFunctionDescriptor(descriptor, target))
}
if (!descriptor.original.needBridgeTo(target)) return expression
return IrCallImpl(expression.startOffset, expression.endOffset,
toCall, remapTypeArguments(expression, toCall), expression.origin,
superQualifier = toCall.containingDeclaration as ClassDescriptor /* Call non-virtually */).apply {
target, remapTypeArguments(expression, target), expression.origin,
superQualifier = target.containingDeclaration as ClassDescriptor /* Call non-virtually */).apply {
dispatchReceiver = expression.dispatchReceiver
extensionReceiver = expression.extensionReceiver
mapValueParameters { expression.getValueArgument(it)!! }
@@ -27,66 +27,6 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.*
internal class ClassDelegationLowering(val context: Context) : DeclarationContainerLoweringPass {
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
irDeclarationContainer.declarations.transformFlat {
when (it) {
is IrFunction -> {
val transformedFun = transformBridgeToDelegatedMethod(irDeclarationContainer, it)
if (transformedFun == null) null
else listOf(transformedFun)
}
is IrProperty -> {
val getter = transformBridgeToDelegatedMethod(irDeclarationContainer, it.getter)
val setter = transformBridgeToDelegatedMethod(irDeclarationContainer, it.setter)
if (getter != null) it.getter = getter
if (setter != null) it.setter = setter
null
}
else -> null
}
}
}
private fun transformBridgeToDelegatedMethod(irDeclarationContainer: IrDeclarationContainer, irFunction: IrFunction?): IrFunction? {
if (irFunction == null) return null
val descriptor = irFunction.descriptor
if (descriptor.kind != CallableMemberDescriptor.Kind.DELEGATION) return null
// TODO: hack because of broken IR for synthesized delegated members: https://youtrack.jetbrains.com/issue/KT-16486.
val body = irFunction.body as? IrBlockBody
?: throw AssertionError("Unexpected method body: ${irFunction.body}")
val statement = body.statements.single()
val delegatedCall = ((statement as? IrReturn)?.value ?: statement) as? IrCall
?: throw AssertionError("Unexpected method body: $statement")
val delegated = context.specialDescriptorsFactory.getBridgeDescriptor(
OverriddenFunctionDescriptor(descriptor, delegatedCall.descriptor as FunctionDescriptor))
val newFunction = IrFunctionImpl(irFunction.startOffset, irFunction.endOffset, irFunction.origin, delegated)
val irBlockBody = IrBlockBodyImpl(irFunction.startOffset, irFunction.endOffset)
val returnType = delegatedCall.descriptor.returnType!!
val irCall = IrCallImpl(irFunction.startOffset, irFunction.endOffset, returnType, delegatedCall.descriptor, null)
irCall.dispatchReceiver = delegatedCall.dispatchReceiver
irCall.extensionReceiver = delegated.extensionReceiverParameter?.let { extensionReceiver ->
IrGetValueImpl(irFunction.startOffset, irFunction.endOffset, extensionReceiver)
}
irCall.mapValueParameters { overriddenValueParameter ->
val delegatedValueParameter = delegated.valueParameters[overriddenValueParameter.index]
IrGetValueImpl(irFunction.startOffset, irFunction.endOffset, delegatedValueParameter)
}
if (KotlinBuiltIns.isUnit(returnType) || KotlinBuiltIns.isNothing(returnType)) {
irBlockBody.statements.add(irCall)
} else {
val irReturn = IrReturnImpl(irFunction.startOffset, irFunction.endOffset, context.builtIns.nothingType, delegated, irCall)
irBlockBody.statements.add(irReturn)
}
newFunction.body = irBlockBody
return newFunction
}
}
internal class PropertyDelegationLowering(val context: Context) : FileLoweringPass {
private val kotlinReflectPackage = context.irModule!!.descriptor.getPackage(FqName.fromSegments(listOf("kotlin", "reflect")))
private val genericKPropertyImplType = kotlinReflectPackage.memberScope.getContributedClassifier(Name.identifier("KPropertyImpl"),