JVM IR: Remove IrEnumValueOf intrinsic

This commit is contained in:
Steven Schäfer
2020-01-09 15:01:05 +01:00
committed by max-kammerer
parent f8779ddf9d
commit b0e61ab470
5 changed files with 26 additions and 131 deletions
@@ -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 extends Enum<T>> T valueOf(Class<T> 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 =
@@ -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)
}
}
}
@@ -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,
@@ -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" }!!
@@ -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