From e981b1f958b5ad259c8272b6a4717142c75ffaa2 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Fri, 3 Feb 2023 14:53:15 +0100 Subject: [PATCH] [Native] Support evaluation of const intrinsics for K2 #KT-56023 #KT-55469 Fixed --- .../kotlin/fir/backend/Fir2IrConverter.kt | 7 +- .../kotlin/ir/interpreter/CallInterceptor.kt | 9 +- .../kotlin/ir/interpreter/IrInterpreter.kt | 4 +- .../builtins/IrBuiltInsMapGenerated.kt | 40 +++++++-- .../ir/interpreter/checker/EvaluationMode.kt | 5 +- .../checker/IrCompileTimeChecker.kt | 7 ++ .../explicitEqualsOnDouble.kt | 3 - .../codegen/box/constants/comparisonFalse.kt | 2 - .../foldingBinaryOpsUnsignedConst.kt | 1 - .../codegen/box/ieee754/explicitEqualsCall.kt | 3 - .../dumpIrAndCheck/booleanOperations.kt | 3 + .../dumpIrAndCheck/byteOperations.kt | 3 +- .../dumpIrAndCheck/charOperations.kt | 3 + .../dumpIrAndCheck/doubleOperations.kt | 3 +- .../dumpIrAndCheck/enumRecursiveName.kt | 2 +- .../dumpIrAndCheck/floatOperations.kt | 3 +- .../dumpIrAndCheck/ifConstVal.kt | 3 +- .../dumpIrAndCheck/intOperations.kt | 3 +- .../dumpIrAndCheck/longOperations.kt | 3 +- .../dumpIrAndCheck/shortOperations.kt | 3 +- .../dumpIrAndCheck/stdlibConst.kt | 1 + .../dumpIrAndCheck/stringOperations.kt | 1 + .../dumpIrAndCheck/unsignedConst.kt | 1 + .../stringConcatenationWithObject.kt | 1 + .../involvesIrInterpreter/thisPlusString.kt | 1 + .../codegen/box/primitiveTypes/kt3517.kt | 2 - .../initializerOfConstValWithConst.kt | 5 -- .../initializerOfConstValWithConstExpr.kt | 4 - .../interpreter/GenerateInterpreterMap.kt | 15 +++- .../backend.native/tests/build.gradle | 10 +-- .../annotationArguments/primitiveArrays.kt | 2 - .../annotationArguments/primitives.kt | 3 - .../FirNativeCodegenBoxTestGenerated.java | 84 +++++++++++++++++++ .../K1NativeCodegenBoxTestGenerated.java | 84 +++++++++++++++++++ 34 files changed, 264 insertions(+), 60 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index 060e6a87328..c4a976eb209 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -417,9 +417,14 @@ class Fir2IrConverter( companion object { private fun evaluateConstants(irModuleFragment: IrModuleFragment) { + val firModuleDescriptor = irModuleFragment.descriptor as? FirModuleDescriptor + val languageVersionSettings = firModuleDescriptor?.session?.languageVersionSettings + val intrinsicConstEvaluation = languageVersionSettings?.supportsFeature(LanguageFeature.IntrinsicConstEvaluation) == true + val interpreter = IrInterpreter(irModuleFragment.irBuiltins) + val mode = if (intrinsicConstEvaluation) EvaluationMode.ONLY_INTRINSIC_CONST else EvaluationMode.ONLY_BUILTINS irModuleFragment.files.forEach { - it.transformChildren(IrConstTransformer(interpreter, it, mode = EvaluationMode.ONLY_BUILTINS), null) + it.transformChildren(IrConstTransformer(interpreter, it, mode = mode), null) } } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt index c57beebf158..304d8d1e39b 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt @@ -19,10 +19,7 @@ import org.jetbrains.kotlin.ir.interpreter.intrinsics.IntrinsicEvaluator import org.jetbrains.kotlin.ir.interpreter.proxy.wrap import org.jetbrains.kotlin.ir.interpreter.stack.CallStack import org.jetbrains.kotlin.ir.interpreter.state.* -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.classOrNull -import org.jetbrains.kotlin.ir.types.isArray -import org.jetbrains.kotlin.ir.types.isUnsignedType +import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.hasAnnotation import org.jetbrains.kotlin.name.FqName @@ -91,7 +88,9 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) : verify(handleIntrinsicMethods(irConstructor)) { "Unsupported intrinsic constructor: ${irConstructor.render()}" } } irClass.defaultType.isUnsignedType() -> { - val propertySymbol = irClass.declarations.single { it is IrProperty }.symbol + // Check for type is a hack needed for Native; + // in UInt, for example, we may have (after lowerings, I guess) additional property "$companion". + val propertySymbol = irClass.declarations.single { it is IrProperty && it.getter?.returnType?.isPrimitiveType() == true }.symbol callStack.pushState(receiver.apply { this.setField(propertySymbol, args.single()) }) } else -> defaultAction() diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt index 7986d5aca36..d6ff4abe204 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt @@ -23,7 +23,7 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.util.OperatorNameConventions -class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal val bodyMap: Map) { +class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal val bodyMap: Map = emptyMap()) { val irBuiltIns: IrBuiltIns get() = environment.irBuiltIns private val callStack: CallStack @@ -239,7 +239,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal constructor.valueParameters.forEachIndexed { i, param -> callStack.storeState(param.symbol, valueArguments[i]) } callStack.storeState(constructor.symbol, KTypeState(returnType, environment.kTypeClass.owner)) - val superReceiver = when (val irStatement = constructor.body?.statements?.get(0)) { + val superReceiver = when (val irStatement = constructor.body?.statements?.getOrNull(0)) { null -> null // for jvm is IrTypeOperatorCall -> (irStatement.argument as IrFunctionAccessExpression).getThisReceiver() // for enums is IrFunctionAccessExpression -> irStatement.getThisReceiver() diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/builtins/IrBuiltInsMapGenerated.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/builtins/IrBuiltInsMapGenerated.kt index 3421e96e003..4c0b9b363eb 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/builtins/IrBuiltInsMapGenerated.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/builtins/IrBuiltInsMapGenerated.kt @@ -255,14 +255,38 @@ internal fun interpretBinaryFunction(name: String, typeA: String, typeB: String, "Comparable" -> if (typeB == "T") return (a as Comparable).compareTo(b) } "equals" -> when (typeA) { - "Boolean" -> if (typeB == "Any?") return (a as Boolean).equals(b) - "Char" -> if (typeB == "Any?") return (a as Char).equals(b) - "Byte" -> if (typeB == "Any?") return (a as Byte).equals(b) - "Short" -> if (typeB == "Any?") return (a as Short).equals(b) - "Int" -> if (typeB == "Any?") return (a as Int).equals(b) - "Float" -> if (typeB == "Any?") return (a as Float).equals(b) - "Long" -> if (typeB == "Any?") return (a as Long).equals(b) - "Double" -> if (typeB == "Any?") return (a as Double).equals(b) + "Boolean" -> when (typeB) { + "Any?" -> return (a as Boolean).equals(b) + "Boolean" -> return (a as Boolean).equals(b as Boolean) + } + "Char" -> when (typeB) { + "Any?" -> return (a as Char).equals(b) + "Char" -> return (a as Char).equals(b as Char) + } + "Byte" -> when (typeB) { + "Any?" -> return (a as Byte).equals(b) + "Byte" -> return (a as Byte).equals(b as Byte) + } + "Short" -> when (typeB) { + "Any?" -> return (a as Short).equals(b) + "Short" -> return (a as Short).equals(b as Short) + } + "Int" -> when (typeB) { + "Any?" -> return (a as Int).equals(b) + "Int" -> return (a as Int).equals(b as Int) + } + "Float" -> when (typeB) { + "Any?" -> return (a as Float).equals(b) + "Float" -> return (a as Float).equals(b as Float) + } + "Long" -> when (typeB) { + "Any?" -> return (a as Long).equals(b) + "Long" -> return (a as Long).equals(b as Long) + } + "Double" -> when (typeB) { + "Any?" -> return (a as Double).equals(b) + "Double" -> return (a as Double).equals(b as Double) + } "String" -> if (typeB == "Any?") return (a as String).equals(b) "Any" -> if (typeB == "Any?") return (a as Any).equals(b) } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt index 087bc26c4fd..80bd513dde8 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt @@ -50,7 +50,10 @@ enum class EvaluationMode(protected val mustCheckBody: Boolean) { ONLY_BUILTINS(mustCheckBody = false) { private val forbiddenMethodsOnPrimitives = setOf("inc", "dec", "rangeTo", "rangeUntil", "hashCode") private val forbiddenMethodsOnStrings = setOf("subSequence", "hashCode", "") - private val allowedExtensionFunctions = setOf("kotlin.floorDiv", "kotlin.mod", "kotlin.NumbersKt.floorDiv", "kotlin.NumbersKt.mod") + private val allowedExtensionFunctions = setOf( + "kotlin.floorDiv", "kotlin.mod", "kotlin.NumbersKt.floorDiv", "kotlin.NumbersKt.mod", "kotlin.", + "kotlin.internal.ir.EQEQ", + ) override fun canEvaluateFunction(function: IrFunction, context: IrCall?): Boolean { if ((function as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.isConst == true) return true diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt index 5329f577001..be3f81aa3a2 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt @@ -99,6 +99,13 @@ class IrCompileTimeChecker( if (mode == EvaluationMode.ONLY_INTRINSIC_CONST && expression.origin == IrStatementOrigin.WHEN) { return expression.statements.all { it.accept(this, null) } } + + // `IrReturnableBlock` will be created from IrCall after inline. We should do basically the same check as for IrCall. + if (expression is IrReturnableBlock) { + // TODO after JVM inline MR 8122 will be pushed check original IrCall. + TODO("Interpretation of `IrReturnableBlock` is not implemented") + } + return visitStatements(expression.statements) } diff --git a/compiler/testData/codegen/box/boxingOptimization/explicitEqualsOnDouble.kt b/compiler/testData/codegen/box/boxingOptimization/explicitEqualsOnDouble.kt index 2d77299c77a..d8147a0df73 100644 --- a/compiler/testData/codegen/box/boxingOptimization/explicitEqualsOnDouble.kt +++ b/compiler/testData/codegen/box/boxingOptimization/explicitEqualsOnDouble.kt @@ -1,6 +1,3 @@ -// KT-55469 -// IGNORE_BACKEND_K2: NATIVE - fun equals1(a: Double, b: Double) = a.equals(b) fun box(): String { diff --git a/compiler/testData/codegen/box/constants/comparisonFalse.kt b/compiler/testData/codegen/box/constants/comparisonFalse.kt index a24dff0e0e9..a931ecb7c6c 100644 --- a/compiler/testData/codegen/box/constants/comparisonFalse.kt +++ b/compiler/testData/codegen/box/constants/comparisonFalse.kt @@ -1,5 +1,3 @@ -// KT-55469 -// IGNORE_BACKEND_K2: NATIVE // WITH_STDLIB fun foo(): Array { return arrayOf( diff --git a/compiler/testData/codegen/box/constants/foldingBinaryOpsUnsignedConst.kt b/compiler/testData/codegen/box/constants/foldingBinaryOpsUnsignedConst.kt index 73e3edac421..5070a7cd894 100644 --- a/compiler/testData/codegen/box/constants/foldingBinaryOpsUnsignedConst.kt +++ b/compiler/testData/codegen/box/constants/foldingBinaryOpsUnsignedConst.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_K2: NATIVE // WITH_STDLIB const val a = "INT " + 0x8fffffffU diff --git a/compiler/testData/codegen/box/ieee754/explicitEqualsCall.kt b/compiler/testData/codegen/box/ieee754/explicitEqualsCall.kt index 653ac9a1d57..51dfd696f72 100644 --- a/compiler/testData/codegen/box/ieee754/explicitEqualsCall.kt +++ b/compiler/testData/codegen/box/ieee754/explicitEqualsCall.kt @@ -1,6 +1,3 @@ -// KT-55469 -// IGNORE_BACKEND_K2: NATIVE - fun equals1(a: Double, b: Double) = a.equals(b) fun equals2(a: Double?, b: Double?) = a!!.equals(b!!) diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/booleanOperations.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/booleanOperations.kt index 8d2a5586589..b486d35ded3 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/booleanOperations.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/booleanOperations.kt @@ -1,4 +1,7 @@ // TARGET_BACKEND: JVM_IR +// TARGET_BACKEND: NATIVE +// `Boolean.equals(Boolean)` will not be evaluated in K1 +// IGNORE_BACKEND_K1: NATIVE const val trueVal = true const val falseVal = false diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/byteOperations.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/byteOperations.kt index 3cbbb11d586..5bd33b69f62 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/byteOperations.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/byteOperations.kt @@ -1,5 +1,6 @@ // TARGET_BACKEND: JVM_IR -// IGNORE_BACKEND_K1: JVM_IR +// TARGET_BACKEND: NATIVE +// IGNORE_BACKEND_K1: JVM_IR, NATIVE const val minusOneVal = (-1).toByte() const val oneVal = 1.toByte() diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/charOperations.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/charOperations.kt index 71e9298cd3e..0f99e3dd746 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/charOperations.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/charOperations.kt @@ -1,4 +1,7 @@ // TARGET_BACKEND: JVM_IR +// TARGET_BACKEND: NATIVE +// `Char.equals(Char)` will not be evaluated in K1 +// IGNORE_BACKEND_K1: NATIVE // WITH_STDLIB const val oneVal = '1' diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/doubleOperations.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/doubleOperations.kt index a05e8955e36..ea5be56b54a 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/doubleOperations.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/doubleOperations.kt @@ -1,5 +1,6 @@ // TARGET_BACKEND: JVM_IR -// IGNORE_BACKEND_K1: JVM_IR +// TARGET_BACKEND: NATIVE +// IGNORE_BACKEND_K1: JVM_IR, NATIVE const val minusOneVal = -1.0 const val oneVal = 1.0 diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/enumRecursiveName.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/enumRecursiveName.kt index 8fd8f10d98d..bf8070db8bd 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/enumRecursiveName.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/enumRecursiveName.kt @@ -1,6 +1,6 @@ // TARGET_BACKEND: JVM_IR -// IGNORE_BACKEND_K1: JVM_IR // IGNORE_FIR_DIAGNOSTICS +// IGNORE_BACKEND_K1: JVM_IR // !DIAGNOSTICS: -UNINITIALIZED_ENUM_ENTRY enum class TestEnum(val testNaming: String) { diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/floatOperations.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/floatOperations.kt index 7a2c51b3779..2540722351b 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/floatOperations.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/floatOperations.kt @@ -1,5 +1,6 @@ // TARGET_BACKEND: JVM_IR -// IGNORE_BACKEND_K1: JVM_IR +// TARGET_BACKEND: NATIVE +// IGNORE_BACKEND_K1: JVM_IR, NATIVE const val minusOneVal = -1.0f const val oneVal = 1.0f diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/ifConstVal.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/ifConstVal.kt index 6d499ddc406..2b73690d525 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/ifConstVal.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/ifConstVal.kt @@ -1,6 +1,7 @@ // !LANGUAGE: +IntrinsicConstEvaluation // TARGET_BACKEND: JVM_IR -// IGNORE_BACKEND_K1: JVM_IR +// TARGET_BACKEND: NATIVE +// IGNORE_BACKEND_K1: JVM_IR, NATIVE const val flag = true const val value = 10 diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/intOperations.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/intOperations.kt index 8ef60c13283..8ebcd285ebe 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/intOperations.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/intOperations.kt @@ -1,5 +1,6 @@ // TARGET_BACKEND: JVM_IR -// IGNORE_BACKEND_K1: JVM_IR +// TARGET_BACKEND: NATIVE +// IGNORE_BACKEND_K1: JVM_IR, NATIVE const val minusOneVal = -1 const val oneVal = 1 diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/longOperations.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/longOperations.kt index c9f4875e36e..5ea0b802a04 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/longOperations.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/longOperations.kt @@ -1,5 +1,6 @@ // TARGET_BACKEND: JVM_IR -// IGNORE_BACKEND_K1: JVM_IR +// TARGET_BACKEND: NATIVE +// IGNORE_BACKEND_K1: JVM_IR, NATIVE const val minusOneVal = -1L const val oneVal = 1L diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/shortOperations.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/shortOperations.kt index 33c893dd854..454d41d2648 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/shortOperations.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/shortOperations.kt @@ -1,5 +1,6 @@ // TARGET_BACKEND: JVM_IR -// IGNORE_BACKEND_K1: JVM_IR +// TARGET_BACKEND: NATIVE +// IGNORE_BACKEND_K1: JVM_IR, NATIVE const val minusOneVal = (-1).toShort() const val oneVal = 1.toShort() diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stdlibConst.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stdlibConst.kt index 3d949cac206..60d6da2daba 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stdlibConst.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stdlibConst.kt @@ -1,4 +1,5 @@ // TARGET_BACKEND: JVM_IR +// TARGET_BACKEND: NATIVE // WITH_STDLIB const val code = '1'.code diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stringOperations.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stringOperations.kt index 3d089be304b..a7460328581 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stringOperations.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stringOperations.kt @@ -1,4 +1,5 @@ // TARGET_BACKEND: JVM_IR +// TARGET_BACKEND: NATIVE const val someStr = "123" const val otherStr = "other" diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt index 7029989fce2..1271934a5dd 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt @@ -1,4 +1,5 @@ // TARGET_BACKEND: JVM_IR +// TARGET_BACKEND: NATIVE // WITH_STDLIB const val byteVal: UByte = 1u diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/stringConcatenationWithObject.kt b/compiler/testData/codegen/box/involvesIrInterpreter/stringConcatenationWithObject.kt index d8fac86057c..c838e3c8561 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/stringConcatenationWithObject.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/stringConcatenationWithObject.kt @@ -1,4 +1,5 @@ // TARGET_BACKEND: JVM_IR +// TARGET_BACKEND: NATIVE object K : Code("K") diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/thisPlusString.kt b/compiler/testData/codegen/box/involvesIrInterpreter/thisPlusString.kt index 96254ecfdfc..503054cbe19 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/thisPlusString.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/thisPlusString.kt @@ -1,4 +1,5 @@ // TARGET_BACKEND: JVM_IR +// TARGET_BACKEND: NATIVE // WITH_STDLIB object Test { diff --git a/compiler/testData/codegen/box/primitiveTypes/kt3517.kt b/compiler/testData/codegen/box/primitiveTypes/kt3517.kt index e3effec94af..535f32308cd 100644 --- a/compiler/testData/codegen/box/primitiveTypes/kt3517.kt +++ b/compiler/testData/codegen/box/primitiveTypes/kt3517.kt @@ -1,6 +1,4 @@ // KT-3517 Can't call .equals() on a boolean -// KT-55469 -// IGNORE_BACKEND_K2: NATIVE fun box(): String { val a = false diff --git a/compiler/testData/codegen/box/properties/initializerOfConstValWithConst.kt b/compiler/testData/codegen/box/properties/initializerOfConstValWithConst.kt index 18957651554..0e77710f519 100644 --- a/compiler/testData/codegen/box/properties/initializerOfConstValWithConst.kt +++ b/compiler/testData/codegen/box/properties/initializerOfConstValWithConst.kt @@ -1,8 +1,3 @@ -// KT-56023 -// JS_IR: InterpreterError: Unsupported number of arguments for invocation as builtin function: four -// NATIVE: in mode -Pkotlin.internal.native.test.mode=TWO_STAGE_MULTI_MODULE (default test mode), test fails as below -// InterpreterError: Unsupported number of arguments for invocation as builtin function: four -// in mode -Pkotlin.internal.native.test.mode=ONE_STAGE_MULTI_MODULE, test passes // IGNORE_BACKEND_K2: NATIVE, JS_IR // MODULE: lib diff --git a/compiler/testData/codegen/box/properties/initializerOfConstValWithConstExpr.kt b/compiler/testData/codegen/box/properties/initializerOfConstValWithConstExpr.kt index 6e80b804713..c6c7b745d43 100644 --- a/compiler/testData/codegen/box/properties/initializerOfConstValWithConstExpr.kt +++ b/compiler/testData/codegen/box/properties/initializerOfConstValWithConstExpr.kt @@ -1,7 +1,3 @@ -// KT-56023 -// JS_IR: IllegalStateException: CONST_VAL_WITH_NON_CONST_INITIALIZER: Const 'val' initializer should be a constant value at (7,18) in /lib.kt -// NATIVE: test fails as below in both modes -Pkotlin.internal.native.test.mode=TWO_STAGE_MULTI_MODULE, -Pkotlin.internal.native.test.mode=ONE_STAGE_MULTI_MODULE -// error: const 'val' initializer should be a constant value // IGNORE_BACKEND_K2: NATIVE, JS_IR // MODULE: lib diff --git a/generators/interpreter/GenerateInterpreterMap.kt b/generators/interpreter/GenerateInterpreterMap.kt index bc1ac10fa9e..9345d186709 100644 --- a/generators/interpreter/GenerateInterpreterMap.kt +++ b/generators/interpreter/GenerateInterpreterMap.kt @@ -61,7 +61,10 @@ fun generateMap(): String { this += Operation("toString", listOf("Unit"), customExpression = "Unit.toString()") }) - generateInterpretBinaryFunction(p, getOperationMap(2) + getBinaryIrOperationMap(irBuiltIns) + getExtensionOperationMap()) + generateInterpretBinaryFunction( + p, + getOperationMap(2) + getBinaryIrOperationMap(irBuiltIns) + getExtensionOperationMap() + getAdditionalEqualsOperationMap() + ) generateInterpretTernaryFunction(p, getOperationMap(3)) @@ -274,6 +277,16 @@ private fun getExtensionOperationMap(): List { return operationMap } +// We need this additional list to properly interpret functions like `Boolean.equals(Boolean) in Native` +// Probably can be dropped after KT-57344 fix +private fun getAdditionalEqualsOperationMap(): List { + val builtIns = DefaultBuiltIns.Instance + return PrimitiveType.values().map { builtIns.getBuiltInClassByFqName(it.typeFqName) }.map { + val type = it.defaultType.constructor.toString() + Operation("equals", listOf(type, type), isFunction = true) + } +} + private fun getIrMethodSymbolByName(methodName: String): String { return when (methodName) { BuiltInOperatorNames.LESS -> "<" diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index 8f88235da95..9b8ac841aa0 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -1420,8 +1420,7 @@ task localClass_localHierarchy(type: KonanLocalTest) { } standaloneTest("objectDeclaration_globalConstants") { - disabled = (cacheTesting != null) || // Cache is not compatible with -opt. - isK2(project) // KT-56189 + disabled = (cacheTesting != null) // Cache is not compatible with -opt. flags = ["-opt", "-opt-in=kotlin.native.internal.InternalForKotlinNative", "-tr"] source = "codegen/objectDeclaration/globalConstants.kt" } @@ -2846,7 +2845,6 @@ standaloneTest("runtime_math_exceptions") { } standaloneTest("runtime_math") { - disabled = isK2(project) // KT-56189 source = "stdlib_external/numbers/MathTest.kt" flags = ['-tr'] } @@ -3095,7 +3093,6 @@ task concatenation(type: KonanLocalTest) { } task const_infinity(type: KonanLocalTest) { - disabled = isK2(project) // KT-56189 source = "codegen/basics/const_infinity.kt" } @@ -3217,7 +3214,6 @@ task initializers3(type: KonanLocalTest) { } task initializers4(type: KonanLocalTest) { - disabled = isK2(project) // KT-56189 useGoldenData = true source = "runtime/basic/initializers4.kt" } @@ -6147,10 +6143,6 @@ task buildKonanTests { t -> // These tests should not be built into the TestRunner's test executable def excludeList = [ "codegen/inline/returnLocalClassFromBlock.kt" ] - if (isK2(project)) { - excludeList += "codegen/basics/const_infinity.kt" // KT-56189 - excludeList += "runtime/basic/initializers4.kt" // KT-56189 - } project.tasks .withType(KonanStandaloneTest.class) .each { diff --git a/native/native.tests/testData/klibContents/builtinsSerializer/annotationArguments/primitiveArrays.kt b/native/native.tests/testData/klibContents/builtinsSerializer/annotationArguments/primitiveArrays.kt index 48ca87933c5..e37614c667c 100644 --- a/native/native.tests/testData/klibContents/builtinsSerializer/annotationArguments/primitiveArrays.kt +++ b/native/native.tests/testData/klibContents/builtinsSerializer/annotationArguments/primitiveArrays.kt @@ -1,5 +1,3 @@ -// KT-56189 -3.14 is not constant -// MUTED_WHEN: K2 package test annotation class PrimitiveArrays( diff --git a/native/native.tests/testData/klibContents/builtinsSerializer/annotationArguments/primitives.kt b/native/native.tests/testData/klibContents/builtinsSerializer/annotationArguments/primitives.kt index 76dcbde09e4..a593202fb29 100644 --- a/native/native.tests/testData/klibContents/builtinsSerializer/annotationArguments/primitives.kt +++ b/native/native.tests/testData/klibContents/builtinsSerializer/annotationArguments/primitives.kt @@ -1,6 +1,3 @@ -// KT-56189 error: an annotation argument must be a compile-time constant -// -3.14 is not constant -// MUTED_WHEN: K2 package test annotation class Primitives( diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestGenerated.java index 113879ee094..bd887d5f053 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestGenerated.java @@ -24247,6 +24247,18 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); } + @Test + @TestMetadata("stringConcatenationWithObject.kt") + public void testStringConcatenationWithObject() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/stringConcatenationWithObject.kt"); + } + + @Test + @TestMetadata("thisPlusString.kt") + public void testThisPlusString() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/thisPlusString.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck") @TestDataPath("$PROJECT_ROOT") @@ -24259,6 +24271,78 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe public void testAllFilesPresentInDumpIrAndCheck() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true); } + + @Test + @TestMetadata("booleanOperations.kt") + public void testBooleanOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/booleanOperations.kt"); + } + + @Test + @TestMetadata("byteOperations.kt") + public void testByteOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/byteOperations.kt"); + } + + @Test + @TestMetadata("charOperations.kt") + public void testCharOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/charOperations.kt"); + } + + @Test + @TestMetadata("doubleOperations.kt") + public void testDoubleOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/doubleOperations.kt"); + } + + @Test + @TestMetadata("floatOperations.kt") + public void testFloatOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/floatOperations.kt"); + } + + @Test + @TestMetadata("ifConstVal.kt") + public void testIfConstVal() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/ifConstVal.kt"); + } + + @Test + @TestMetadata("intOperations.kt") + public void testIntOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/intOperations.kt"); + } + + @Test + @TestMetadata("longOperations.kt") + public void testLongOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/longOperations.kt"); + } + + @Test + @TestMetadata("shortOperations.kt") + public void testShortOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/shortOperations.kt"); + } + + @Test + @TestMetadata("stdlibConst.kt") + public void testStdlibConst() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stdlibConst.kt"); + } + + @Test + @TestMetadata("stringOperations.kt") + public void testStringOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stringOperations.kt"); + } + + @Test + @TestMetadata("unsignedConst.kt") + public void testUnsignedConst() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt"); + } } } diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K1NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K1NativeCodegenBoxTestGenerated.java index 1e9c1be7014..172a9be533e 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K1NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K1NativeCodegenBoxTestGenerated.java @@ -24013,6 +24013,18 @@ public class K1NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTes runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); } + @Test + @TestMetadata("stringConcatenationWithObject.kt") + public void testStringConcatenationWithObject() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/stringConcatenationWithObject.kt"); + } + + @Test + @TestMetadata("thisPlusString.kt") + public void testThisPlusString() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/thisPlusString.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck") @TestDataPath("$PROJECT_ROOT") @@ -24024,6 +24036,78 @@ public class K1NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTes public void testAllFilesPresentInDumpIrAndCheck() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true); } + + @Test + @TestMetadata("booleanOperations.kt") + public void testBooleanOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/booleanOperations.kt"); + } + + @Test + @TestMetadata("byteOperations.kt") + public void testByteOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/byteOperations.kt"); + } + + @Test + @TestMetadata("charOperations.kt") + public void testCharOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/charOperations.kt"); + } + + @Test + @TestMetadata("doubleOperations.kt") + public void testDoubleOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/doubleOperations.kt"); + } + + @Test + @TestMetadata("floatOperations.kt") + public void testFloatOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/floatOperations.kt"); + } + + @Test + @TestMetadata("ifConstVal.kt") + public void testIfConstVal() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/ifConstVal.kt"); + } + + @Test + @TestMetadata("intOperations.kt") + public void testIntOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/intOperations.kt"); + } + + @Test + @TestMetadata("longOperations.kt") + public void testLongOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/longOperations.kt"); + } + + @Test + @TestMetadata("shortOperations.kt") + public void testShortOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/shortOperations.kt"); + } + + @Test + @TestMetadata("stdlibConst.kt") + public void testStdlibConst() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stdlibConst.kt"); + } + + @Test + @TestMetadata("stringOperations.kt") + public void testStringOperations() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stringOperations.kt"); + } + + @Test + @TestMetadata("unsignedConst.kt") + public void testUnsignedConst() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt"); + } } }