From b0e61ab470d895fb44ccbd8be323d390bd693d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Thu, 9 Jan 2020 15:01:05 +0100 Subject: [PATCH] JVM IR: Remove IrEnumValueOf intrinsic --- .../kotlin/backend/jvm/JvmSymbols.kt | 13 +++++ .../backend/jvm/intrinsics/IrEnumValueOf.kt | 44 -------------- .../jvm/intrinsics/IrIntrinsicMethods.kt | 1 - .../backend/jvm/lower/EnumClassLowering.kt | 41 +++++-------- .../kotlin/ir/descriptors/IrBuiltIns.kt | 58 ------------------- 5 files changed, 26 insertions(+), 131 deletions(-) delete mode 100644 compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrEnumValueOf.kt diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt index 8c709b9c91a..be47024ea06 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt @@ -586,6 +586,19 @@ class JvmSymbols( fun typeToStringValueOfFunction(type: IrType): IrSimpleFunctionSymbol = valueOfFunctions[type] ?: defaultValueOfFunction + + private val javaLangEnum: IrClassSymbol = + createClass(FqName("java.lang.Enum")) { klass -> + // The declaration of Enum.valueOf is: `public static > T valueOf(Class enumType, String name)` + // But we only need the following type-erased version to generate correct calls. + klass.addFunction("valueOf", klass.defaultType, isStatic = true).apply { + addValueParameter("enumType", javaLangClass.starProjectedType) + addValueParameter("name", irBuiltIns.stringType) + } + } + + val enumValueOfFunction: IrSimpleFunctionSymbol = + javaLangEnum.functionByName("valueOf") } private fun IrClassSymbol.functionByName(name: String): IrSimpleFunctionSymbol = diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrEnumValueOf.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrEnumValueOf.kt deleted file mode 100644 index b76e6c9cd16..00000000000 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrEnumValueOf.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2010-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.backend.jvm.intrinsics - -import org.jetbrains.kotlin.backend.jvm.JvmBackendContext -import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo -import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen -import org.jetbrains.kotlin.codegen.StackValue -import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression -import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE -import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature -import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter - -object IrEnumValueOf : IntrinsicMethod() { - override fun toCallable( - expression: IrFunctionAccessExpression, - signature: JvmMethodSignature, - context: JvmBackendContext - ): IrIntrinsicFunction = - object : IrIntrinsicFunction(expression, signature, context, listOf(JAVA_STRING_TYPE)) { - override fun invoke(v: InstructionAdapter, codegen: ExpressionCodegen, data: BlockInfo): StackValue { - val enumType = context.typeMapper.mapType(expression.type) - v.tconst(enumType) - codegen.gen(expression.getValueArgument(0)!!, JAVA_STRING_TYPE, context.irBuiltIns.stringType, data) - v.invokestatic("java/lang/Enum", "valueOf", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;", false) - v.checkcast(enumType) - return StackValue.onStack(enumType) - } - } -} diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt index e9193a70add..f64c59f5d2a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt @@ -95,7 +95,6 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) { irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.floatClass]!!.toKey()!! to Ieee754Equals(Type.FLOAT_TYPE), irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.doubleClass]!!.toKey()!! to Ieee754Equals(Type.DOUBLE_TYPE), irBuiltIns.booleanNotSymbol.toKey()!! to Not, - irBuiltIns.enumValueOfSymbol.toKey()!! to IrEnumValueOf, irBuiltIns.noWhenBranchMatchedExceptionSymbol.toKey()!! to IrNoWhenBranchMatchedException, irBuiltIns.illegalArgumentExceptionSymbol.toKey()!! to IrIllegalArgumentException, irBuiltIns.andandSymbol.toKey()!! to AndAnd, diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt index 624a8b42a84..8efe3b3b4a7 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt @@ -17,6 +17,9 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.builders.irCall +import org.jetbrains.kotlin.ir.builders.irExprBody +import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl @@ -466,35 +469,17 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP } } - private fun createEnumValueOfBody(): IrBody { - val enumValueOf = context.irBuiltIns.enumValueOfSymbol - - val irValueOfCall = - IrCallImpl( - UNDEFINED_OFFSET, - UNDEFINED_OFFSET, - irClass.defaultType, - enumValueOf, - enumValueOf.owner.typeParameters.size + private fun createEnumValueOfBody(): IrBody = + context.createJvmIrBuilder(valueOfFunction.symbol).run { + irExprBody( + irCall(backendContext.ir.symbols.enumValueOfFunction).apply { + putValueArgument(0, with(CallableReferenceLowering) { + javaClassReference(irClass.defaultType, backendContext) + }) + putValueArgument(1, irGet(valueOfFunction.valueParameters[0])) + } ) - irValueOfCall.putTypeArgument(0, irClass.defaultType) - irValueOfCall.putValueArgument( - 0, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueOfFunction.valueParameters[0].symbol) - ) - - return IrBlockBodyImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - listOf( - IrReturnImpl( - UNDEFINED_OFFSET, - UNDEFINED_OFFSET, - context.irBuiltIns.nothingType, - valueOfFunction.symbol, - irValueOfCall - ) - ) - ) - } + } private fun createEnumValuesBody(valuesField: IrField): IrBody { val cloneFun = context.irBuiltIns.arrayClass.owner.functions.find { it.name.asString() == "clone" }!! diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt index 4515466fc36..37bed4c186f 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt @@ -80,63 +80,6 @@ class IrBuiltIns( return symbol.symbol } - private fun defineEnumValueOfOperator(): IrSimpleFunctionSymbol { - val name = Name.identifier("enumValueOf") - val typeParameterDescriptor: TypeParameterDescriptor - val valueParameterDescriptor: ValueParameterDescriptor - val descriptor = SimpleFunctionDescriptorImpl.create( - packageFragmentDescriptor, - Annotations.EMPTY, - name, - CallableMemberDescriptor.Kind.SYNTHESIZED, - SourceElement.NO_SOURCE - ).apply { - typeParameterDescriptor = TypeParameterDescriptorImpl.createWithDefaultBound( - this, Annotations.EMPTY, true, Variance.INVARIANT, Name.identifier("T0"), 0, LockBasedStorageManager.NO_LOCKS - ) - - valueParameterDescriptor = ValueParameterDescriptorImpl( - this, null, 0, Annotations.EMPTY, Name.identifier("arg0"), string, - false, false, false, null, SourceElement.NO_SOURCE - ) - - val returnType = typeParameterDescriptor.typeConstructor.makeNonNullType() - - initialize(null, null, listOf(typeParameterDescriptor), listOf(valueParameterDescriptor), returnType, Modality.FINAL, Visibilities.PUBLIC) - } - - val returnKotlinType = descriptor.returnType - val typeParameterSymbol = IrTypeParameterSymbolImpl(typeParameterDescriptor) - val typeParameter = IrBuiltInOperatorTypeParameter(typeParameterSymbol, Variance.INVARIANT, 0, true).apply { - superTypes += anyNType - } - - val returnIrType = IrSimpleTypeBuilder().run { - classifier = typeParameterSymbol - kotlinType = returnKotlinType - buildSimpleType() - } - - return symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, descriptor) { - val operator = IrBuiltInOperator(it, name, returnIrType, ":enum") - operator.parent = packageFragment - packageFragment.declarations += operator - - val valueParameterSymbol = IrValueParameterSymbolImpl(valueParameterDescriptor) - val valueParameter = IrBuiltInOperatorValueParameter(valueParameterSymbol, 0, stringType) - - valueParameter.parent = operator - typeParameter.parent = operator - - operator.valueParameters += valueParameter - operator.typeParameters += typeParameter - - irBuiltInsSymbols += operator - - operator - }.symbol - } - private fun defineCheckNotNullOperator(): IrSimpleFunctionSymbol { val name = Name.identifier("CHECK_NOT_NULL") val typeParameterDescriptor: TypeParameterDescriptor @@ -342,7 +285,6 @@ class IrBuiltIns( val noWhenBranchMatchedExceptionSymbol = defineOperator(OperatorNames.NO_WHEN_BRANCH_MATCHED_EXCEPTION, nothingType, listOf()) val illegalArgumentExceptionSymbol = defineOperator(OperatorNames.ILLEGAL_ARGUMENT_EXCEPTION, nothingType, listOf(stringType)) - val enumValueOfSymbol = defineEnumValueOfOperator() val checkNotNullSymbol = defineCheckNotNullOperator() val checkNotNull = checkNotNullSymbol.descriptor