diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 60de2b892de..e3734c2f4c8 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -349,7 +349,7 @@ private val jvmFilePhases = listOf( remapObjectFieldAccesses, anonymousObjectSuperConstructorPhase, - jvmStandardLibraryBuiltInsPhase, + jvmBuiltInsPhase, rangeContainsLoweringPhase, forLoopsPhase, diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStandardLibraryBuiltInsLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmBuiltInsLowering.kt similarity index 74% rename from compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStandardLibraryBuiltInsLowering.kt rename to compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmBuiltInsLowering.kt index 487693fb370..4915fd91b50 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStandardLibraryBuiltInsLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmBuiltInsLowering.kt @@ -6,8 +6,11 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder +import org.jetbrains.kotlin.backend.jvm.ir.irArrayOf import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.expressions.IrCall @@ -15,32 +18,45 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization import org.jetbrains.kotlin.ir.util.render -import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid -internal val jvmStandardLibraryBuiltInsPhase = makeIrFilePhase( - ::JvmStandardLibraryBuiltInsLowering, - name = "JvmStandardLibraryBuiltInsLowering", - description = "Use Java Standard Library implementations of built-ins" +internal val jvmBuiltInsPhase = makeIrFilePhase( + ::JvmBuiltInsLowering, + name = "JvmBuiltInsLowering", + description = "JVM-specific implementations of some built-ins" ) -class JvmStandardLibraryBuiltInsLowering(val context: JvmBackendContext) : FileLoweringPass { +class JvmBuiltInsLowering(val context: JvmBackendContext) : FileLoweringPass { override fun lower(irFile: IrFile) { - if (context.state.target < JvmTarget.JVM_1_8) return - - val transformer = object : IrElementTransformerVoid() { + val transformer = object : IrElementTransformerVoidWithContext() { override fun visitCall(expression: IrCall): IrExpression { expression.transformChildren(this, null) - val parentClass = expression.symbol.owner.parent.fqNameForIrSerialization.asString() - val functionName = expression.symbol.owner.name.asString() - jvm8builtInReplacements[parentClass to functionName]?.let { replacement -> - return expression.replaceWithCallTo(replacement) + val callee = expression.symbol.owner + + if (context.state.target >= JvmTarget.JVM_1_8) { + val parentClassName = callee.parent.fqNameForIrSerialization.asString() + val functionName = callee.name.asString() + val jvm8Replacement = jvm8builtInReplacements[parentClassName to functionName] + if (jvm8Replacement != null) { + return expression.replaceWithCallTo(jvm8Replacement) + } } - return expression + return when { + callee.isArrayOf() -> + expression.getValueArgument(0) + ?: throw AssertionError("Argument #0 expected: ${expression.dump()}") + + callee.isEmptyArray() -> + context.createJvmIrBuilder(currentScope!!, expression).irArrayOf(expression.type) + + else -> + expression + } } } diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/VarargLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/VarargLowering.kt index 15d1a58201c..7667f287fa5 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/VarargLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/VarargLowering.kt @@ -13,8 +13,8 @@ import org.jetbrains.kotlin.backend.jvm.ir.IrArrayBuilder import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder import org.jetbrains.kotlin.backend.jvm.ir.irArray import org.jetbrains.kotlin.backend.jvm.ir.irArrayOf -import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.PrimitiveType +import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.UnsignedType import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.IrClass @@ -22,7 +22,6 @@ import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrPackageFragment import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.types.makeNotNull import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly @@ -62,16 +61,7 @@ internal class VarargLowering(val context: JvmBackendContext) : FileLoweringPass } } - return when { - // Lower `arrayOf` calls. When `isArrayOf` returns true we know that the function has exactly one - // vararg parameter. Meanwhile, the code above ensures that the corresponding argument is not null. - function.owner.isArrayOf() -> - expression.getValueArgument(0)!! - function.isEmptyArray -> - createBuilder(expression.startOffset, expression.endOffset).irArrayOf(expression.type) - else -> - expression - } + return expression } override fun visitVararg(expression: IrVararg): IrExpression = @@ -99,11 +89,8 @@ internal class VarargLowering(val context: JvmBackendContext) : FileLoweringPass } private fun createBuilder(startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET) = - context.createJvmIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset) + context.createJvmIrBuilder(currentScope!!, startOffset, endOffset) - private val IrFunctionSymbol.isEmptyArray: Boolean - get() = owner.name.asString() == "emptyArray" && - (owner.parent as? IrPackageFragment)?.fqName == StandardNames.BUILT_INS_PACKAGE_FQ_NAME } internal val PRIMITIVE_ARRAY_OF_NAMES: Set = @@ -126,3 +113,6 @@ internal fun IrFunction.isArrayOf(): Boolean { valueParameters[0].isVararg } +internal fun IrFunction.isEmptyArray(): Boolean = + name.asString() == "emptyArray" && + (parent as? IrPackageFragment)?.fqName == StandardNames.BUILT_INS_PACKAGE_FQ_NAME \ No newline at end of file