Generate accessors for super calls if necessary

Current implementation of calls with super qualifier relies on
invokespecial, which has some more constraints than regular virtual
invocations. When those constraints aren't met, accessors are needed.
This commit is contained in:
Ting-Yuan Huang
2019-04-09 10:49:57 -07:00
committed by max-kammerer
parent c90e6c1f18
commit 1c3b895fc0
26 changed files with 73 additions and 51 deletions
@@ -213,30 +213,41 @@ private fun IrTypeParameter.copySuperTypesFrom(source: IrTypeParameter) {
}
}
// Copy value parameters, dispatch receiver, and extension receiver from source to value parameters of this function.
// Type of dispatch receiver defaults to source's dispatch receiver. It is overridable in case the new function and the old one are used in
// different contexts and expect different type of dispatch receivers. The overriding type should be assign compatible to the old type.
fun IrFunction.copyValueParametersToStatic(
source: IrFunction,
origin: IrDeclarationOrigin
origin: IrDeclarationOrigin,
dispatchReceiverType: IrType? = source.dispatchReceiverParameter?.type
) {
val target = this
assert(target.valueParameters.isEmpty())
var shift = 0
source.dispatchReceiverParameter?.let { p ->
source.dispatchReceiverParameter?.let { originalDispatchReceiver ->
assert(dispatchReceiverType!!.isSubtypeOfClass(originalDispatchReceiver.type.classOrNull!!))
val type = dispatchReceiverType.remapTypeParameters(
(originalDispatchReceiver.parent as IrTypeParametersContainer).classIfConstructor,
target.classIfConstructor
)
target.valueParameters.add(
p.copyTo(
originalDispatchReceiver.copyTo(
target,
origin = p.origin,
index = p.index + shift++,
origin = originalDispatchReceiver.origin,
index = originalDispatchReceiver.index + shift++,
type = type,
name = Name.identifier("\$this")
)
)
}
source.extensionReceiverParameter?.let { p ->
source.extensionReceiverParameter?.let { originalExtensionReceiver ->
target.valueParameters.add(
p.copyTo(
originalExtensionReceiver.copyTo(
target,
origin = p.origin,
index = p.index + shift++,
origin = originalExtensionReceiver.origin,
index = originalExtensionReceiver.index + shift++,
name = Name.identifier("\$receiver")
)
)