KT-43286 use JVM 1.8 intrinsics for coercible unsigned values only
This commit is contained in:
Generated
+10
@@ -32036,6 +32036,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286.kt")
|
||||
public void testKt43286() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286a.kt")
|
||||
public void testKt43286a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||
|
||||
+26
-18
@@ -35,8 +35,8 @@ class JvmStandardLibraryBuiltInsLowering(val context: JvmBackendContext) : FileL
|
||||
|
||||
val parentClass = expression.symbol.owner.parent.fqNameForIrSerialization.asString()
|
||||
val functionName = expression.symbol.owner.name.asString()
|
||||
Jvm8builtInReplacements[parentClass to functionName]?.let {
|
||||
return expression.replaceWithCallTo(it)
|
||||
jvm8builtInReplacements[parentClass to functionName]?.let { replacement ->
|
||||
return expression.replaceWithCallTo(replacement)
|
||||
}
|
||||
|
||||
return expression
|
||||
@@ -46,7 +46,7 @@ class JvmStandardLibraryBuiltInsLowering(val context: JvmBackendContext) : FileL
|
||||
irFile.transformChildren(transformer, null)
|
||||
}
|
||||
|
||||
private val Jvm8builtInReplacements = mapOf(
|
||||
private val jvm8builtInReplacements = mapOf(
|
||||
("kotlin.UInt" to "compareTo") to context.ir.symbols.compareUnsignedInt,
|
||||
("kotlin.UInt" to "div") to context.ir.symbols.divideUnsignedInt,
|
||||
("kotlin.UInt" to "rem") to context.ir.symbols.remainderUnsignedInt,
|
||||
@@ -59,7 +59,8 @@ class JvmStandardLibraryBuiltInsLowering(val context: JvmBackendContext) : FileL
|
||||
|
||||
// Originals are so far only instance methods, and the replacements are
|
||||
// statics, so we copy dispatch receivers to a value argument if needed.
|
||||
private fun IrCall.replaceWithCallTo(replacement: IrSimpleFunctionSymbol) =
|
||||
// If we can't coerce arguments to required types, keep original expression (see below).
|
||||
private fun IrCall.replaceWithCallTo(replacement: IrSimpleFunctionSymbol): IrCall =
|
||||
IrCallImpl.fromSymbolOwner(
|
||||
startOffset,
|
||||
endOffset,
|
||||
@@ -68,23 +69,30 @@ class JvmStandardLibraryBuiltInsLowering(val context: JvmBackendContext) : FileL
|
||||
).also { newCall ->
|
||||
var valueArgumentOffset = 0
|
||||
this.dispatchReceiver?.let {
|
||||
newCall.putValueArgument(valueArgumentOffset, it.coerceTo(replacement.owner.valueParameters[valueArgumentOffset].type))
|
||||
val coercedDispatchReceiver = it.coerceIfPossible(replacement.owner.valueParameters[valueArgumentOffset].type)
|
||||
?: return this@replaceWithCallTo
|
||||
newCall.putValueArgument(valueArgumentOffset, coercedDispatchReceiver)
|
||||
valueArgumentOffset++
|
||||
}
|
||||
(0 until valueArgumentsCount).forEach {
|
||||
newCall.putValueArgument(it + valueArgumentOffset, getValueArgument(it)!!.coerceTo(replacement.owner.valueParameters[it].type))
|
||||
for (index in 0 until valueArgumentsCount) {
|
||||
val coercedValueArgument = getValueArgument(index)!!.coerceIfPossible(replacement.owner.valueParameters[index].type)
|
||||
?: return this@replaceWithCallTo
|
||||
newCall.putValueArgument(index + valueArgumentOffset, coercedValueArgument)
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrExpression.coerceTo(target: IrType): IrExpression =
|
||||
IrCallImpl.fromSymbolOwner(
|
||||
startOffset,
|
||||
endOffset,
|
||||
target,
|
||||
context.ir.symbols.unsafeCoerceIntrinsic
|
||||
).also { call ->
|
||||
call.putTypeArgument(0, type)
|
||||
call.putTypeArgument(1, target)
|
||||
call.putValueArgument(0, this)
|
||||
}
|
||||
private fun IrExpression.coerceIfPossible(toType: IrType): IrExpression? {
|
||||
// TODO maybe UnsafeCoerce could handle types with different, but coercible underlying representations.
|
||||
// See KT-43286 and related tests for details.
|
||||
val fromJvmType = context.typeMapper.mapType(type)
|
||||
val toJvmType = context.typeMapper.mapType(toType)
|
||||
return if (fromJvmType != toJvmType)
|
||||
null
|
||||
else
|
||||
IrCallImpl.fromSymbolOwner(startOffset, endOffset, toType, context.ir.symbols.unsafeCoerceIntrinsic).also { call ->
|
||||
call.putTypeArgument(0, type)
|
||||
call.putTypeArgument(1, toType)
|
||||
call.putValueArgument(0, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// JVM_TARGET: 1.8
|
||||
// WITH_RUNTIME
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
|
||||
class D(val x: UInt?)
|
||||
|
||||
class E(val x: Any)
|
||||
|
||||
fun f(d: D): String {
|
||||
return d.x?.let { d.x.toString() } ?: ""
|
||||
}
|
||||
|
||||
fun g(e: E): String {
|
||||
if (e.x is UInt) return e.x.toString()
|
||||
return ""
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val test1 = f(D(42u))
|
||||
if (test1 != "42") throw Exception(test1)
|
||||
|
||||
val test2 = g(E(42u))
|
||||
if (test2 != "42") throw Exception(test2)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// JVM_TARGET: 1.8
|
||||
// WITH_RUNTIME
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
|
||||
fun box(): String {
|
||||
val x = 3UL % 2U
|
||||
return if (x == 1UL) "OK" else "Fail: $x"
|
||||
}
|
||||
+10
@@ -33807,6 +33807,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286.kt")
|
||||
public void testKt43286() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286a.kt")
|
||||
public void testKt43286a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||
|
||||
+10
@@ -31441,6 +31441,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286.kt")
|
||||
public void testKt43286() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286a.kt")
|
||||
public void testKt43286a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||
|
||||
+10
@@ -32036,6 +32036,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286.kt")
|
||||
public void testKt43286() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286a.kt")
|
||||
public void testKt43286a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||
|
||||
Generated
+10
@@ -26002,6 +26002,16 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286.kt")
|
||||
public void testKt43286() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286a.kt")
|
||||
public void testKt43286a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||
|
||||
Generated
+10
@@ -26002,6 +26002,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286.kt")
|
||||
public void testKt43286() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286a.kt")
|
||||
public void testKt43286a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||
|
||||
+10
@@ -26017,6 +26017,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286.kt")
|
||||
public void testKt43286() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286a.kt")
|
||||
public void testKt43286a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||
|
||||
Generated
+10
@@ -14305,6 +14305,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverListOfBoxedUnsignedValues.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286.kt")
|
||||
public void testKt43286() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43286a.kt")
|
||||
public void testKt43286a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||
|
||||
Reference in New Issue
Block a user