JVM_IR: Fix bug in suspend function with many default arguments.
This commit is contained in:
@@ -197,7 +197,7 @@ fun IrFunction.copyValueParametersInsertingContinuationFrom(from: IrFunction, in
|
|||||||
var additionalShift = 0
|
var additionalShift = 0
|
||||||
from.valueParameters.forEach {
|
from.valueParameters.forEach {
|
||||||
// The continuation parameter goes before the default argument mask and handler.
|
// The continuation parameter goes before the default argument mask and handler.
|
||||||
if (it.origin == IrDeclarationOrigin.MASK_FOR_DEFAULT_FUNCTION) {
|
if (it.origin == IrDeclarationOrigin.MASK_FOR_DEFAULT_FUNCTION && additionalShift == 0) {
|
||||||
insertContinuation()
|
insertContinuation()
|
||||||
additionalShift = 1
|
additionalShift = 1
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-10
@@ -167,7 +167,7 @@ private fun IrFunction.suspendFunctionView(context: JvmBackendContext): IrFuncti
|
|||||||
it.copyTypeParametersFrom(this)
|
it.copyTypeParametersFrom(this)
|
||||||
|
|
||||||
// Copy the value parameters and insert the continuation parameter. The continuation parameter
|
// Copy the value parameters and insert the continuation parameter. The continuation parameter
|
||||||
// goes before the default argument mask and handler for default argument stubs.
|
// goes before the default argument mask(s) and handler for default argument stubs.
|
||||||
// TODO: It would be nice if AddContinuationLowering could insert the continuation argument before default stub generation.
|
// TODO: It would be nice if AddContinuationLowering could insert the continuation argument before default stub generation.
|
||||||
// That would avoid the reshuffling both here and in createSuspendFunctionClassViewIfNeeded.
|
// That would avoid the reshuffling both here and in createSuspendFunctionClassViewIfNeeded.
|
||||||
var continuationValueParam: IrValueParameter? = null
|
var continuationValueParam: IrValueParameter? = null
|
||||||
@@ -203,9 +203,9 @@ internal fun IrCall.createSuspendFunctionCallViewIfNeeded(
|
|||||||
it.copyTypeArgumentsFrom(this)
|
it.copyTypeArgumentsFrom(this)
|
||||||
it.dispatchReceiver = dispatchReceiver
|
it.dispatchReceiver = dispatchReceiver
|
||||||
it.extensionReceiver = extensionReceiver
|
it.extensionReceiver = extensionReceiver
|
||||||
// Locate the caller continuation parameter. The continuation parameter is before default argument mask and handler params.
|
// Locate the caller continuation parameter. The continuation parameter is before default argument mask(s) and handler params.
|
||||||
val callerHasDefaultMask = caller.valueParameters.lastOrNull()?.origin == IrDeclarationOrigin.METHOD_HANDLER_IN_DEFAULT_FUNCTION
|
val callerNumberOfMasks = caller.valueParameters.count { it.origin == IrDeclarationOrigin.MASK_FOR_DEFAULT_FUNCTION }
|
||||||
val callerContinuationIndex = caller.valueParameters.size - 1 - (if (callerHasDefaultMask) 2 else 0)
|
val callerContinuationIndex = caller.valueParameters.size - 1 - (if (callerNumberOfMasks != 0) callerNumberOfMasks + 1 else 0)
|
||||||
val continuationParameter =
|
val continuationParameter =
|
||||||
when {
|
when {
|
||||||
caller.isInvokeSuspendOfLambda() || caller.isInvokeSuspendOfContinuation() ||
|
caller.isInvokeSuspendOfLambda() || caller.isInvokeSuspendOfContinuation() ||
|
||||||
@@ -215,16 +215,17 @@ internal fun IrCall.createSuspendFunctionCallViewIfNeeded(
|
|||||||
else -> IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, caller.valueParameters[callerContinuationIndex].symbol)
|
else -> IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, caller.valueParameters[callerContinuationIndex].symbol)
|
||||||
}
|
}
|
||||||
// If the suspend function view that we are calling has default parameters, we need to make sure to pass the
|
// If the suspend function view that we are calling has default parameters, we need to make sure to pass the
|
||||||
// continuation before the default parameter mask and handler.
|
// continuation before the default parameter mask(s) and handler.
|
||||||
val hasDefaultMask = view.valueParameters.last().origin == IrDeclarationOrigin.METHOD_HANDLER_IN_DEFAULT_FUNCTION
|
val numberOfMasks = view.valueParameters.count { it.origin == IrDeclarationOrigin.MASK_FOR_DEFAULT_FUNCTION }
|
||||||
val continuationIndex = valueArgumentsCount - (if (hasDefaultMask) 2 else 0)
|
val continuationIndex = valueArgumentsCount - (if (numberOfMasks != 0) numberOfMasks + 1 else 0)
|
||||||
for (i in 0 until continuationIndex) {
|
for (i in 0 until continuationIndex) {
|
||||||
it.putValueArgument(i, getValueArgument(i))
|
it.putValueArgument(i, getValueArgument(i))
|
||||||
}
|
}
|
||||||
it.putValueArgument(continuationIndex, continuationParameter)
|
it.putValueArgument(continuationIndex, continuationParameter)
|
||||||
if (hasDefaultMask) {
|
if (numberOfMasks != 0) {
|
||||||
it.putValueArgument(valueArgumentsCount - 1, getValueArgument(continuationIndex))
|
for (i in 0 until numberOfMasks + 1) {
|
||||||
it.putValueArgument(valueArgumentsCount, getValueArgument(continuationIndex + 1))
|
it.putValueArgument(valueArgumentsCount + i - 1, getValueArgument(continuationIndex + i))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,43 @@ fun ordinary() = "OK"
|
|||||||
|
|
||||||
suspend fun withDefault(s: String = "OK") = s
|
suspend fun withDefault(s: String = "OK") = s
|
||||||
|
|
||||||
|
suspend fun withManyDefault(
|
||||||
|
s0: String = "NOT OK 0",
|
||||||
|
s1: String = "NOT OK 1",
|
||||||
|
s2: String = "NOT OK 2",
|
||||||
|
s3: String = "NOT OK 3",
|
||||||
|
s4: String = "NOT OK 4",
|
||||||
|
s5: String = "NOT OK 5",
|
||||||
|
s6: String = "NOT OK 6",
|
||||||
|
s7: String = "NOT OK 7",
|
||||||
|
s8: String = "NOT OK 8",
|
||||||
|
s9: String = "NOT OK 9",
|
||||||
|
s10: String = "NOT OK 10",
|
||||||
|
s11: String = "NOT OK 11",
|
||||||
|
s12: String = "NOT OK 12",
|
||||||
|
s13: String = "NOT OK 13",
|
||||||
|
s14: String = "NOT OK 14",
|
||||||
|
s15: String = "NOT OK 15",
|
||||||
|
s16: String = "NOT OK 16",
|
||||||
|
s17: String = "NOT OK 17",
|
||||||
|
s18: String = "NOT OK 18",
|
||||||
|
s19: String = "NOT OK 19",
|
||||||
|
s20: String = "NOT OK 20",
|
||||||
|
s21: String = "NOT OK 21",
|
||||||
|
s22: String = "NOT OK 22",
|
||||||
|
s23: String = "NOT OK 23",
|
||||||
|
s24: String = "NOT OK 24",
|
||||||
|
s25: String = "NOT OK 25",
|
||||||
|
s26: String = "NOT OK 26",
|
||||||
|
s27: String = "NOT OK 27",
|
||||||
|
s28: String = "NOT OK 28",
|
||||||
|
s29: String = "NOT OK 29",
|
||||||
|
s30: String = "NOT OK 30",
|
||||||
|
s31: String = "NOT OK 31",
|
||||||
|
s32: String = "NOT OK 32",
|
||||||
|
ok: String = "OK"
|
||||||
|
) = ok
|
||||||
|
|
||||||
var log = ""
|
var log = ""
|
||||||
|
|
||||||
var proceed = {}
|
var proceed = {}
|
||||||
@@ -64,6 +101,10 @@ fun box(): String {
|
|||||||
builder {
|
builder {
|
||||||
res = ::withDefault.callSuspendBy(emptyMap()) as String?
|
res = ::withDefault.callSuspendBy(emptyMap()) as String?
|
||||||
}
|
}
|
||||||
|
if (res != "OK") return res ?: "FAIL 5"
|
||||||
|
builder {
|
||||||
|
res = ::withManyDefault.callSuspendBy(emptyMap()) as String?
|
||||||
|
}
|
||||||
builder {
|
builder {
|
||||||
::suspending.callSuspendBy(emptyMap())
|
::suspending.callSuspendBy(emptyMap())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user