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:
+1
-1
@@ -346,7 +346,7 @@ class ExpressionCodegen(
|
|||||||
classCodegen.context.irIntrinsics.getIntrinsic(expression.symbol)
|
classCodegen.context.irIntrinsics.getIntrinsic(expression.symbol)
|
||||||
?.invoke(expression, this, data)?.let { return it }
|
?.invoke(expression, this, data)?.let { return it }
|
||||||
|
|
||||||
val callable = methodSignatureMapper.mapToCallableMethod(expression)
|
val callable = methodSignatureMapper.mapToCallableMethod(irFunction, expression)
|
||||||
val callee = expression.symbol.owner
|
val callee = expression.symbol.owner
|
||||||
val callGenerator = getOrCreateCallGenerator(expression, data, callable.signature)
|
val callGenerator = getOrCreateCallGenerator(expression, data, callable.signature)
|
||||||
val asmType = if (expression is IrConstructorCall) typeMapper.mapTypeAsDeclaration(expression.type) else expression.asmType
|
val asmType = if (expression is IrConstructorCall) typeMapper.mapTypeAsDeclaration(expression.type) else expression.asmType
|
||||||
|
|||||||
+6
-3
@@ -286,7 +286,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
|||||||
if (valueArgumentsCount > 0) (getValueArgument(0) as? IrConst<*>)?.value as? Boolean ?: true else null
|
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 callee = expression.symbol.owner.getOrCreateSuspendFunctionViewIfNeeded(context)
|
||||||
val calleeParent = callee.parent
|
val calleeParent = callee.parent
|
||||||
if (calleeParent !is IrClass) {
|
if (calleeParent !is IrClass) {
|
||||||
@@ -316,14 +316,17 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val declaration = findSuperDeclaration(callee, isSuperCall)
|
val declaration = findSuperDeclaration(callee, isSuperCall)
|
||||||
val signature = mapOverriddenSpecialBuiltinIfNeeded(declaration, isSuperCall)
|
val signature = mapOverriddenSpecialBuiltinIfNeeded(caller, declaration, isSuperCall)
|
||||||
?: mapSignatureSkipGeneric(declaration)
|
?: mapSignatureSkipGeneric(declaration)
|
||||||
|
|
||||||
return IrCallableMethod(owner, invokeOpcode, signature, isInterface)
|
return IrCallableMethod(owner, invokeOpcode, signature, isInterface)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get rid of this (probably via some special lowering)
|
// 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()
|
val overriddenSpecialBuiltinFunction = callee.descriptor.original.getOverriddenBuiltinReflectingJvmDescriptor()
|
||||||
if (overriddenSpecialBuiltinFunction != null && !superCall) {
|
if (overriddenSpecialBuiltinFunction != null && !superCall) {
|
||||||
return mapSignatureSkipGeneric(context.referenceFunction(overriddenSpecialBuiltinFunction.original).owner)
|
return mapSignatureSkipGeneric(context.referenceFunction(overriddenSpecialBuiltinFunction.original).owner)
|
||||||
|
|||||||
+8
-11
@@ -120,6 +120,8 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass
|
|||||||
irFunction.overriddenSymbols.all { it.owner.getJvmName() != ourMethodName }
|
irFunction.overriddenSymbols.all { it.owner.getJvmName() != ourMethodName }
|
||||||
) {
|
) {
|
||||||
// Bridges for abstract fake overrides whose JVM names differ from overridden functions.
|
// 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()
|
val bridge = irFunction.orphanedCopy()
|
||||||
irClass.declarations.add(bridge)
|
irClass.declarations.add(bridge)
|
||||||
targetForCommonBridges = bridge
|
targetForCommonBridges = bridge
|
||||||
@@ -320,18 +322,13 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass
|
|||||||
isSpecial: Boolean,
|
isSpecial: Boolean,
|
||||||
invokeStatically: Boolean = false
|
invokeStatically: Boolean = false
|
||||||
) {
|
) {
|
||||||
val maybeOrphanedTarget = if (isSpecial)
|
|
||||||
target.orphanedCopy()
|
|
||||||
else
|
|
||||||
target
|
|
||||||
|
|
||||||
context.createIrBuilder(symbol).run {
|
context.createIrBuilder(symbol).run {
|
||||||
body = irBlockBody {
|
body = irBlockBody {
|
||||||
if (specialMethodInfo != null) {
|
if (specialMethodInfo != null) {
|
||||||
valueParameters.take(specialMethodInfo.argumentsToCheck).forEach {
|
valueParameters.take(specialMethodInfo.argumentsToCheck).forEach {
|
||||||
addParameterTypeCheck(
|
addParameterTypeCheck(
|
||||||
it,
|
it,
|
||||||
maybeOrphanedTarget.valueParameters[it.index].type,
|
target.valueParameters[it.index].type,
|
||||||
specialMethodInfo.defaultValueGenerator,
|
specialMethodInfo.defaultValueGenerator,
|
||||||
this@createBridgeBody
|
this@createBridgeBody
|
||||||
)
|
)
|
||||||
@@ -341,17 +338,17 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass
|
|||||||
irImplicitCast(
|
irImplicitCast(
|
||||||
IrCallImpl(
|
IrCallImpl(
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||||
maybeOrphanedTarget.returnType,
|
target.returnType,
|
||||||
maybeOrphanedTarget.symbol, origin = IrStatementOrigin.BRIDGE_DELEGATION,
|
target.symbol, origin = IrStatementOrigin.BRIDGE_DELEGATION,
|
||||||
superQualifierSymbol = if (invokeStatically) maybeOrphanedTarget.parentAsClass.symbol else null
|
superQualifierSymbol = if (invokeStatically) target.parentAsClass.symbol else null
|
||||||
).apply {
|
).apply {
|
||||||
passTypeArgumentsFrom(this@createBridgeBody)
|
passTypeArgumentsFrom(this@createBridgeBody)
|
||||||
dispatchReceiver = irGet(dispatchReceiverParameter!!)
|
dispatchReceiver = irGet(dispatchReceiverParameter!!)
|
||||||
extensionReceiverParameter?.let {
|
extensionReceiverParameter?.let {
|
||||||
extensionReceiver = irImplicitCast(irGet(it), maybeOrphanedTarget.extensionReceiverParameter!!.type)
|
extensionReceiver = irImplicitCast(irGet(it), target.extensionReceiverParameter!!.type)
|
||||||
}
|
}
|
||||||
valueParameters.forEach {
|
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
|
returnType
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
|
|
||||||
// FILE: J.java
|
// FILE: J.java
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
// FILE: J.java
|
// FILE: J.java
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
private object NotEmptyMap : MutableMap<Any, Int> {
|
private object NotEmptyMap : MutableMap<Any, Int> {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
// KJS_WITH_FULL_RUNTIME
|
// KJS_WITH_FULL_RUNTIME
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// IGNORE_BACKEND: NATIVE
|
// IGNORE_BACKEND: NATIVE
|
||||||
|
|
||||||
interface A0 {
|
interface A0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user