refactoring

This commit is contained in:
Igor Chevdar
2017-02-21 17:46:20 +03:00
parent bb82109ded
commit eced9bb11a
4 changed files with 56 additions and 42 deletions
@@ -23,7 +23,7 @@ internal class OverriddenFunctionDescriptor(val descriptor: FunctionDescriptor,
get() = descriptor.target.bridgeDirectionsTo(overriddenDescriptor) get() = descriptor.target.bridgeDirectionsTo(overriddenDescriptor)
val canBeCalledVirtually: Boolean val canBeCalledVirtually: Boolean
// We check that either method is open, or one of declarations it overrides is open. // We check that either method is open, or one of declarations it overrides is open.
get() = overriddenDescriptor.isOverridable get() = overriddenDescriptor.isOverridable
|| DescriptorUtils.getAllOverriddenDeclarations(overriddenDescriptor).any { it.isOverridable } || DescriptorUtils.getAllOverriddenDeclarations(overriddenDescriptor).any { it.isOverridable }
@@ -70,30 +70,29 @@ internal class ClassVtablesBuilder(val classDescriptor: ClassDescriptor, val con
if (overridingMethod == null) { if (overridingMethod == null) {
superMethod superMethod
} else { } else {
// Add all possible (descriptor, overriddenDescriptor) edges for now, redundant will be removed later.
newVtableSlots.add(OverriddenFunctionDescriptor(overridingMethod, superMethod.descriptor)) newVtableSlots.add(OverriddenFunctionDescriptor(overridingMethod, superMethod.descriptor))
newVtableSlots.add(OverriddenFunctionDescriptor(overridingMethod, overridingMethod))
OverriddenFunctionDescriptor(overridingMethod, superMethod.overriddenDescriptor) OverriddenFunctionDescriptor(overridingMethod, superMethod.overriddenDescriptor)
} }
} }
println("VTABLE_ENTRIES inherited vtable:") println("VTABLE_ENTRIES inherited vtable:")
inheritedVtableSlots.forEach { inheritedVtableSlots.forEach {
println(" VTABLE_ENTRIES descriptor: ${it.descriptor}") println(" VTABLE_ENTRIES descriptor: ${it.descriptor}")
println(" VTABLE_ENTRIES overriddenDescriptor: ${it.overriddenDescriptor}") println(" VTABLE_ENTRIES overriddenDescriptor: ${it.overriddenDescriptor}")
println(" VTABLE_ENTRIES needBridge: ${it.needBridge}") println(" VTABLE_ENTRIES needBridge: ${it.needBridge}")
if (it.needBridge) if (it.needBridge)
println(" VTABLE_ENTRIES bridgeDirections: ${it.bridgeDirections.toString()}") println(" VTABLE_ENTRIES bridgeDirections: ${it.bridgeDirections.toString()}")
} }
println() println()
val zzz = inheritedVtableSlots.map { it.descriptor to it.bridgeDirections }.toSet()
// Add all possible (descriptor, overriddenDescriptor) edges for now, redundant will be removed later.
methods.mapTo(newVtableSlots) { OverriddenFunctionDescriptor(it, it) } methods.mapTo(newVtableSlots) { OverriddenFunctionDescriptor(it, it) }
val inheritedVtableSlotsSet = inheritedVtableSlots.map { it.descriptor to it.bridgeDirections }.toSet()
val filteredNewVtableSlots = newVtableSlots val filteredNewVtableSlots = newVtableSlots
.filter { !zzz.contains(it.descriptor to it.bridgeDirections) } .filterNot { inheritedVtableSlotsSet.contains(it.descriptor to it.bridgeDirections) }
.distinctBy { it.descriptor to it.bridgeDirections } .distinctBy { it.descriptor to it.bridgeDirections }
.filter { it.descriptor.isOverridable } .filter { it.descriptor.isOverridable }
println("VTABLE_ENTRIES new vtable:") println("VTABLE_ENTRIES new vtable:")
@@ -109,16 +108,16 @@ internal class ClassVtablesBuilder(val classDescriptor: ClassDescriptor, val con
val list = inheritedVtableSlots + filteredNewVtableSlots.sortedBy { it.overriddenDescriptor.functionName.localHash.value } val list = inheritedVtableSlots + filteredNewVtableSlots.sortedBy { it.overriddenDescriptor.functionName.localHash.value }
println("VTABLE_ENTRIES vtable:") println("VTABLE_ENTRIES vtable:")
list.forEach { list.forEach {
println(" VTABLE_ENTRIES descriptor: ${it.descriptor}") println(" VTABLE_ENTRIES descriptor: ${it.descriptor}")
println(" VTABLE_ENTRIES overriddenDescriptor: ${it.overriddenDescriptor}") println(" VTABLE_ENTRIES overriddenDescriptor: ${it.overriddenDescriptor}")
println(" VTABLE_ENTRIES needBridge: ${it.needBridge}") println(" VTABLE_ENTRIES needBridge: ${it.needBridge}")
if (it.needBridge) if (it.needBridge)
println(" VTABLE_ENTRIES bridgeDirections: ${it.bridgeDirections.toString()}") println(" VTABLE_ENTRIES bridgeDirections: ${it.bridgeDirections.toString()}")
} }
println() println()
println() println()
return list return list
@@ -126,11 +125,12 @@ internal class ClassVtablesBuilder(val classDescriptor: ClassDescriptor, val con
fun vtableIndex(function: FunctionDescriptor): Int { fun vtableIndex(function: FunctionDescriptor): Int {
val target = function.target val target = function.target
println("VTABLE_INDEX function: $function") val bridgeDirections = target.bridgeDirectionsTo(function.original)
println("VTABLE_INDEX function: $function")
println("VTABLE_INDEX original: ${function.original}") println("VTABLE_INDEX original: ${function.original}")
println("VTABLE_INDEX target: ${target}") println("VTABLE_INDEX target: ${target}")
println("VTABLE_INDEX bridgeDirections: ${target.bridgeDirectionsTo(function.original).toString()}") println("VTABLE_INDEX bridgeDirections: ${target.bridgeDirectionsTo(function.original).toString()}")
val index = vtableEntries.indexOfFirst { it.descriptor == function.original && it.bridgeDirections == target.bridgeDirectionsTo(function.original) } val index = vtableEntries.indexOfFirst { it.descriptor == function.original && it.bridgeDirections == bridgeDirections }
if (index < 0) throw Error(function.toString() + " not in vtable of " + classDescriptor.toString()) if (index < 0) throw Error(function.toString() + " not in vtable of " + classDescriptor.toString())
return index.apply { println("VTABLE_INDEX index: $this"); println() } return index.apply { println("VTABLE_INDEX index: $this"); println() }
} }
@@ -153,18 +153,18 @@ internal class ClassVtablesBuilder(val classDescriptor: ClassDescriptor, val con
val contributedMethodsWithOverridden = classDescriptor.contributedMethodsWithOverridden val contributedMethodsWithOverridden = classDescriptor.contributedMethodsWithOverridden
println("METHOD_TABLE_ENTRIES: contributed methods") println("METHOD_TABLE_ENTRIES: contributed methods")
contributedMethodsWithOverridden.forEach { contributedMethodsWithOverridden.forEach {
println(" METHOD_TABLE_ENTRIES: descriptor = ${it.descriptor}") println(" METHOD_TABLE_ENTRIES: descriptor = ${it.descriptor}")
println(" METHOD_TABLE_ENTRIES: overriddenDescriptor = ${it.overriddenDescriptor}") println(" METHOD_TABLE_ENTRIES: overriddenDescriptor = ${it.overriddenDescriptor}")
println(" METHOD_TABLE_ENTRIES: overriddenDescriptor.isOverridable = ${it.overriddenDescriptor.isOverridable}") println(" METHOD_TABLE_ENTRIES: overriddenDescriptor.isOverridable = ${it.overriddenDescriptor.isOverridable}")
} }
val result = contributedMethodsWithOverridden.filter { it.canBeCalledVirtually } val result = contributedMethodsWithOverridden.filter { it.canBeCalledVirtually }
println("METHOD_TABLE_ENTRIES: result") println("METHOD_TABLE_ENTRIES: result")
result.forEach { result.forEach {
println(" METHOD_TABLE_ENTRIES: descriptor = ${it.descriptor}") println(" METHOD_TABLE_ENTRIES: descriptor = ${it.descriptor}")
println(" METHOD_TABLE_ENTRIES: overriddenDescriptor = ${it.overriddenDescriptor}") println(" METHOD_TABLE_ENTRIES: overriddenDescriptor = ${it.overriddenDescriptor}")
} }
return result return result
// TODO: probably method table should contain all accessible methods to improve binary compatibility // TODO: probably method table should contain all accessible methods to improve binary compatibility
} }
@@ -269,7 +269,10 @@ internal fun FunctionDescriptor.bridgeDirectionsTo(overriddenDescriptor: Functio
for (index in ourDirections.array.indices) for (index in ourDirections.array.indices)
ourDirections.array[index] = this.bridgeDirectionToAt(overriddenDescriptor, index) ourDirections.array[index] = this.bridgeDirectionToAt(overriddenDescriptor, index)
if (!kind.isReal && OverridingUtil.overrides(this.target, overriddenDescriptor) && ourDirections == this.target.bridgeDirectionsTo(overriddenDescriptor)) { val target = this.target
if (!kind.isReal
&& OverridingUtil.overrides(target, overriddenDescriptor)
&& ourDirections == target.bridgeDirectionsTo(overriddenDescriptor)) {
// Bridge is inherited from supers // Bridge is inherited from supers
return BridgeDirections(this.valueParameters.size) return BridgeDirections(this.valueParameters.size)
} }
@@ -181,8 +181,13 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
val target = descriptor.target val target = descriptor.target
println("IMPLEMENTATION target: ${target}") println("IMPLEMENTATION target: ${target}")
if (!needBridge) return target if (!needBridge) return target
//val bridgeOwner = if (!descriptor.kind.isReal && OverridingUtil.overrides(target, overriddenDescriptor) && !descriptor.needBridgeTo(overriddenDescriptor)) if (descriptor.bridgeDirectionsTo(overriddenDescriptor).allNotNeeded()) target else descriptor val bridgeOwner = if (!descriptor.kind.isReal
val bridgeOwner = if (!descriptor.kind.isReal && OverridingUtil.overrides(target, overriddenDescriptor) && descriptor.bridgeDirectionsTo(overriddenDescriptor).allNotNeeded()) target else descriptor && OverridingUtil.overrides(target, overriddenDescriptor)
&& descriptor.bridgeDirectionsTo(overriddenDescriptor).allNotNeeded()) {
target // Bridge is inherited from supers
} else {
descriptor
}
println("IMPLEMENTATION owner: ${bridgeOwner}") println("IMPLEMENTATION owner: ${bridgeOwner}")
return context.specialDescriptorsFactory.getBridgeDescriptor(OverriddenFunctionDescriptor(bridgeOwner, overriddenDescriptor)) return context.specialDescriptorsFactory.getBridgeDescriptor(OverriddenFunctionDescriptor(bridgeOwner, overriddenDescriptor))
} }
@@ -36,7 +36,12 @@ internal class DirectBridgesCallsLowering(val context: Context) : BodyLoweringPa
if (descriptor.kind != CallableMemberDescriptor.Kind.DELEGATION && !needBridge) if (descriptor.kind != CallableMemberDescriptor.Kind.DELEGATION && !needBridge)
return expression return expression
val toCall = if (needBridge) target else context.specialDescriptorsFactory.getBridgeDescriptor(OverriddenFunctionDescriptor(descriptor, target)) val toCall = if (needBridge) {
target
} else {
// Need to call delegating fun.
context.specialDescriptorsFactory.getBridgeDescriptor(OverriddenFunctionDescriptor(descriptor, target))
}
return IrCallImpl(expression.startOffset, expression.endOffset, return IrCallImpl(expression.startOffset, expression.endOffset,
toCall, remapTypeArguments(expression, toCall)).apply { toCall, remapTypeArguments(expression, toCall)).apply {
@@ -150,8 +155,9 @@ internal class BridgesBuilding(val context: Context) : ClassLoweringPass {
.filter { !it.bridgeDirections.allNotNeeded() } .filter { !it.bridgeDirections.allNotNeeded() }
.filter { it.canBeCalledVirtually } .filter { it.canBeCalledVirtually }
.distinctBy { it.bridgeDirections } .distinctBy { it.bridgeDirections }
.forEach { buildBridge(it, irClass) .forEach {
} buildBridge(it, irClass)
}
} }
} }
} }