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");
|
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")
|
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
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 parentClass = expression.symbol.owner.parent.fqNameForIrSerialization.asString()
|
||||||
val functionName = expression.symbol.owner.name.asString()
|
val functionName = expression.symbol.owner.name.asString()
|
||||||
Jvm8builtInReplacements[parentClass to functionName]?.let {
|
jvm8builtInReplacements[parentClass to functionName]?.let { replacement ->
|
||||||
return expression.replaceWithCallTo(it)
|
return expression.replaceWithCallTo(replacement)
|
||||||
}
|
}
|
||||||
|
|
||||||
return expression
|
return expression
|
||||||
@@ -46,7 +46,7 @@ class JvmStandardLibraryBuiltInsLowering(val context: JvmBackendContext) : FileL
|
|||||||
irFile.transformChildren(transformer, null)
|
irFile.transformChildren(transformer, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val Jvm8builtInReplacements = mapOf(
|
private val jvm8builtInReplacements = mapOf(
|
||||||
("kotlin.UInt" to "compareTo") to context.ir.symbols.compareUnsignedInt,
|
("kotlin.UInt" to "compareTo") to context.ir.symbols.compareUnsignedInt,
|
||||||
("kotlin.UInt" to "div") to context.ir.symbols.divideUnsignedInt,
|
("kotlin.UInt" to "div") to context.ir.symbols.divideUnsignedInt,
|
||||||
("kotlin.UInt" to "rem") to context.ir.symbols.remainderUnsignedInt,
|
("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
|
// Originals are so far only instance methods, and the replacements are
|
||||||
// statics, so we copy dispatch receivers to a value argument if needed.
|
// 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(
|
IrCallImpl.fromSymbolOwner(
|
||||||
startOffset,
|
startOffset,
|
||||||
endOffset,
|
endOffset,
|
||||||
@@ -68,23 +69,30 @@ class JvmStandardLibraryBuiltInsLowering(val context: JvmBackendContext) : FileL
|
|||||||
).also { newCall ->
|
).also { newCall ->
|
||||||
var valueArgumentOffset = 0
|
var valueArgumentOffset = 0
|
||||||
this.dispatchReceiver?.let {
|
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++
|
valueArgumentOffset++
|
||||||
}
|
}
|
||||||
(0 until valueArgumentsCount).forEach {
|
for (index in 0 until valueArgumentsCount) {
|
||||||
newCall.putValueArgument(it + valueArgumentOffset, getValueArgument(it)!!.coerceTo(replacement.owner.valueParameters[it].type))
|
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 =
|
private fun IrExpression.coerceIfPossible(toType: IrType): IrExpression? {
|
||||||
IrCallImpl.fromSymbolOwner(
|
// TODO maybe UnsafeCoerce could handle types with different, but coercible underlying representations.
|
||||||
startOffset,
|
// See KT-43286 and related tests for details.
|
||||||
endOffset,
|
val fromJvmType = context.typeMapper.mapType(type)
|
||||||
target,
|
val toJvmType = context.typeMapper.mapType(toType)
|
||||||
context.ir.symbols.unsafeCoerceIntrinsic
|
return if (fromJvmType != toJvmType)
|
||||||
).also { call ->
|
null
|
||||||
call.putTypeArgument(0, type)
|
else
|
||||||
call.putTypeArgument(1, target)
|
IrCallImpl.fromSymbolOwner(startOffset, endOffset, toType, context.ir.symbols.unsafeCoerceIntrinsic).also { call ->
|
||||||
call.putValueArgument(0, this)
|
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");
|
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")
|
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
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");
|
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")
|
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
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");
|
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")
|
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
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");
|
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")
|
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
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");
|
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")
|
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
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");
|
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")
|
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
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");
|
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")
|
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user