[K/JS] Fix autoboxing for inlined function ^KT-60785 Fixed

This commit is contained in:
Artem Kobzar
2023-08-11 09:19:51 +00:00
committed by Space Team
parent 7ae443ad7f
commit 4dc0d68288
7 changed files with 77 additions and 6 deletions
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineFunc
import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineLambdasLowering
import org.jetbrains.kotlin.backend.common.lower.loops.ForLoopsLowering
import org.jetbrains.kotlin.backend.common.phaser.*
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.ir.backend.js.lower.*
import org.jetbrains.kotlin.ir.backend.js.lower.calls.CallsLowering
import org.jetbrains.kotlin.ir.backend.js.lower.cleanup.CleanupLowering
@@ -23,7 +22,6 @@ import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.AddContinuationToFunc
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.JsSuspendArityStoreLowering
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.JsSuspendFunctionsLowering
import org.jetbrains.kotlin.ir.backend.js.lower.inline.*
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsGenerationGranularity
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration
@@ -738,7 +736,7 @@ private val inlineClassUsageLoweringPhase = makeBodyLoweringPhase(
)
private val autoboxingTransformerPhase = makeBodyLoweringPhase(
::AutoboxingTransformer,
{ AutoboxingTransformer(it, shouldCalculateActualTypeForInlinedFunction = true) },
name = "AutoboxingTransformer",
description = "Insert box/unbox intrinsics"
)
@@ -31,7 +31,10 @@ import org.jetbrains.kotlin.ir.util.render
// Copied and adapted from Kotlin/Native
abstract class AbstractValueUsageLowering(val context: JsCommonBackendContext) : AbstractValueUsageTransformer(context.irBuiltIns),
abstract class AbstractValueUsageLowering(
val context: JsCommonBackendContext,
private val shouldCalculateActualTypeForInlinedFunction: Boolean = false
) : AbstractValueUsageTransformer(context.irBuiltIns),
BodyLoweringPass {
val icUtils = context.inlineClassesUtils
@@ -52,11 +55,19 @@ abstract class AbstractValueUsageLowering(val context: JsCommonBackendContext) :
abstract fun IrExpression.useExpressionAsType(actualType: IrType, expectedType: IrType): IrExpression
protected fun IrExpression.getActualType() = when (this) {
protected fun IrExpression.getActualType(): IrType = when (this) {
is IrConstructorCall -> symbol.owner.returnType
is IrCall -> symbol.owner.realOverrideTarget.returnType
is IrGetField -> this.symbol.owner.type
is IrInlinedFunctionBlock -> {
if (shouldCalculateActualTypeForInlinedFunction) {
inlineCall.getActualType()
} else {
this.type
}
}
is IrTypeOperatorCall -> {
if (operator == IrTypeOperator.REINTERPRET_CAST) {
this.typeOperand
@@ -120,7 +131,10 @@ abstract class AbstractValueUsageLowering(val context: JsCommonBackendContext) :
)
}
class AutoboxingTransformer(context: JsCommonBackendContext) : AbstractValueUsageLowering(context) {
class AutoboxingTransformer(
context: JsCommonBackendContext,
shouldCalculateActualTypeForInlinedFunction: Boolean = false
) : AbstractValueUsageLowering(context, shouldCalculateActualTypeForInlinedFunction) {
private var processingReturnStack = mutableListOf<IrReturn>()
private fun IrExpression.useReturnableExpressionAsType(expectedType: IrType): IrExpression {
@@ -872,6 +872,12 @@ public class FirJsBoxTestGenerated extends AbstractFirJsBoxTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/coroutines"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("boxingUnboxingInsideTheSuspendFunction.kt")
public void testBoxingUnboxingInsideTheSuspendFunction() throws Exception {
runTest("js/js.translator/testData/box/coroutines/boxingUnboxingInsideTheSuspendFunction.kt");
}
@Test
@TestMetadata("debugStatement.kt")
public void testDebugStatement() throws Exception {
@@ -872,6 +872,12 @@ public class FirJsES6BoxTestGenerated extends AbstractFirJsES6BoxTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/coroutines"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
@Test
@TestMetadata("boxingUnboxingInsideTheSuspendFunction.kt")
public void testBoxingUnboxingInsideTheSuspendFunction() throws Exception {
runTest("js/js.translator/testData/box/coroutines/boxingUnboxingInsideTheSuspendFunction.kt");
}
@Test
@TestMetadata("debugStatement.kt")
public void testDebugStatement() throws Exception {
@@ -872,6 +872,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/coroutines"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
@Test
@TestMetadata("boxingUnboxingInsideTheSuspendFunction.kt")
public void testBoxingUnboxingInsideTheSuspendFunction() throws Exception {
runTest("js/js.translator/testData/box/coroutines/boxingUnboxingInsideTheSuspendFunction.kt");
}
@Test
@TestMetadata("debugStatement.kt")
public void testDebugStatement() throws Exception {
@@ -872,6 +872,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/coroutines"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("boxingUnboxingInsideTheSuspendFunction.kt")
public void testBoxingUnboxingInsideTheSuspendFunction() throws Exception {
runTest("js/js.translator/testData/box/coroutines/boxingUnboxingInsideTheSuspendFunction.kt");
}
@Test
@TestMetadata("debugStatement.kt")
public void testDebugStatement() throws Exception {
@@ -0,0 +1,35 @@
// WITH_STDLIB
// EXPECTED_REACHABLE_NODES: 1292
// KT-60785
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
value class SomeValue(val a: String) {
override fun toString() = when (a) {
"fa" -> "O"
"il" -> "K"
else -> ""
}
}
suspend fun foo() = mapOf(SomeValue("fa") to SomeValue("il"))
fun builder(c: suspend () -> Unit) {
c.startCoroutine(object : Continuation<Unit> {
override val context = EmptyCoroutineContext
override fun resumeWith(result: Result<Unit>) {}
})
}
fun box(): String {
var result = ""
builder {
for ((k, v) in foo()) {
result += "$k$v"
}
}
return result
}