JVM_IR: redirect to correct function in special brigdes

The fix in MethodSignatureMapper allows us to avoid the hack
with orphanedCopy() in BridgeLowering.
This commit is contained in:
Georgy Bronnikov
2019-11-20 18:26:44 +03:00
parent ef567c868e
commit 307c82e3a4
7 changed files with 15 additions and 19 deletions
@@ -346,7 +346,7 @@ class ExpressionCodegen(
classCodegen.context.irIntrinsics.getIntrinsic(expression.symbol)
?.invoke(expression, this, data)?.let { return it }
val callable = methodSignatureMapper.mapToCallableMethod(expression)
val callable = methodSignatureMapper.mapToCallableMethod(irFunction, expression)
val callee = expression.symbol.owner
val callGenerator = getOrCreateCallGenerator(expression, data, callable.signature)
val asmType = if (expression is IrConstructorCall) typeMapper.mapTypeAsDeclaration(expression.type) else expression.asmType
@@ -286,7 +286,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
if (valueArgumentsCount > 0) (getValueArgument(0) as? IrConst<*>)?.value as? Boolean ?: true else null
}
fun mapToCallableMethod(expression: IrFunctionAccessExpression): IrCallableMethod {
fun mapToCallableMethod(caller: IrFunction, expression: IrFunctionAccessExpression): IrCallableMethod {
val callee = expression.symbol.owner.getOrCreateSuspendFunctionViewIfNeeded(context)
val calleeParent = callee.parent
if (calleeParent !is IrClass) {
@@ -316,14 +316,17 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
}
val declaration = findSuperDeclaration(callee, isSuperCall)
val signature = mapOverriddenSpecialBuiltinIfNeeded(declaration, isSuperCall)
val signature = mapOverriddenSpecialBuiltinIfNeeded(caller, declaration, isSuperCall)
?: mapSignatureSkipGeneric(declaration)
return IrCallableMethod(owner, invokeOpcode, signature, isInterface)
}
// TODO: get rid of this (probably via some special lowering)
private fun mapOverriddenSpecialBuiltinIfNeeded(callee: IrFunction, superCall: Boolean): JvmMethodSignature? {
private fun mapOverriddenSpecialBuiltinIfNeeded(caller: IrFunction, callee: IrFunction, superCall: Boolean): JvmMethodSignature? {
// Do not remap special builtin methods when called from a bridge. The bridges are there to provide the
// remapped name or signature and forward to the actually declared method.
if (caller.origin == IrDeclarationOrigin.BRIDGE || caller.origin == IrDeclarationOrigin.BRIDGE_SPECIAL) return null
val overriddenSpecialBuiltinFunction = callee.descriptor.original.getOverriddenBuiltinReflectingJvmDescriptor()
if (overriddenSpecialBuiltinFunction != null && !superCall) {
return mapSignatureSkipGeneric(context.referenceFunction(overriddenSpecialBuiltinFunction.original).owner)
@@ -120,6 +120,8 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass
irFunction.overriddenSymbols.all { it.owner.getJvmName() != ourMethodName }
) {
// Bridges for abstract fake overrides whose JVM names differ from overridden functions.
// The orphaned copy will get irFunction's name; the original irFunction will be renamed
// according to its overrides,
val bridge = irFunction.orphanedCopy()
irClass.declarations.add(bridge)
targetForCommonBridges = bridge
@@ -320,18 +322,13 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass
isSpecial: Boolean,
invokeStatically: Boolean = false
) {
val maybeOrphanedTarget = if (isSpecial)
target.orphanedCopy()
else
target
context.createIrBuilder(symbol).run {
body = irBlockBody {
if (specialMethodInfo != null) {
valueParameters.take(specialMethodInfo.argumentsToCheck).forEach {
addParameterTypeCheck(
it,
maybeOrphanedTarget.valueParameters[it.index].type,
target.valueParameters[it.index].type,
specialMethodInfo.defaultValueGenerator,
this@createBridgeBody
)
@@ -341,17 +338,17 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass
irImplicitCast(
IrCallImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
maybeOrphanedTarget.returnType,
maybeOrphanedTarget.symbol, origin = IrStatementOrigin.BRIDGE_DELEGATION,
superQualifierSymbol = if (invokeStatically) maybeOrphanedTarget.parentAsClass.symbol else null
target.returnType,
target.symbol, origin = IrStatementOrigin.BRIDGE_DELEGATION,
superQualifierSymbol = if (invokeStatically) target.parentAsClass.symbol else null
).apply {
passTypeArgumentsFrom(this@createBridgeBody)
dispatchReceiver = irGet(dispatchReceiverParameter!!)
extensionReceiverParameter?.let {
extensionReceiver = irImplicitCast(irGet(it), maybeOrphanedTarget.extensionReceiverParameter!!.type)
extensionReceiver = irImplicitCast(irGet(it), target.extensionReceiverParameter!!.type)
}
valueParameters.forEach {
putValueArgument(it.index, irImplicitCast(irGet(it), maybeOrphanedTarget.valueParameters[it.index].type))
putValueArgument(it.index, irImplicitCast(irGet(it), target.valueParameters[it.index].type))
}
},
returnType
@@ -1,6 +1,5 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
// FILE: J.java
@@ -1,5 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// FILE: J.java
@@ -1,5 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS
private object NotEmptyMap : MutableMap<Any, Int> {
@@ -1,6 +1,5 @@
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: NATIVE
interface A0 {