refactoring
This commit is contained in:
+36
-36
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-2
@@ -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))
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-3
@@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user