JVM IR: Fix types in ArrayGet/Set intrinsics

This commit is contained in:
Steven Schäfer
2019-07-30 15:05:15 +02:00
committed by max-kammerer
parent a1c52f69f2
commit d61b276ebf
3 changed files with 29 additions and 21 deletions
@@ -16,19 +16,16 @@
package org.jetbrains.kotlin.backend.jvm.intrinsics package org.jetbrains.kotlin.backend.jvm.intrinsics
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.codegen.*
import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.org.objectweb.asm.Type
object ArrayGet : IntrinsicMethod() { object ArrayGet : IntrinsicMethod() {
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction { override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? {
val arrayType = calcReceiverType(expression, context) val receiver = expression.dispatchReceiver!!.accept(codegen, data).materialized
val elementType = AsmUtil.correctElementType(arrayType) val elementType = AsmUtil.correctElementType(receiver.type)
return IrIntrinsicFunction.create(expression, signature.newReturnType(elementType), context, listOf(arrayType, Type.INT_TYPE)) { expression.getValueArgument(0)!!.accept(codegen, data).materialize()
it.aload(elementType) codegen.mv.aload(elementType)
} return MaterialValue(codegen, elementType, expression.type)
} }
} }
@@ -16,20 +16,19 @@
package org.jetbrains.kotlin.backend.jvm.intrinsics package org.jetbrains.kotlin.backend.jvm.intrinsics
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.codegen.*
import org.jetbrains.kotlin.backend.jvm.ir.getArrayElementType
import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.org.objectweb.asm.Type
object ArraySet : IntrinsicMethod() { object ArraySet : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? {
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction { val receiver = expression.dispatchReceiver!!.accept(codegen, data).materialized
val arrayType = expressionType(expression.dispatchReceiver!!, context) val elementType = AsmUtil.correctElementType(receiver.type)
val elementType = AsmUtil.correctElementType(arrayType) val elementIrType = receiver.irType.getArrayElementType(codegen.context.irBuiltIns)
return IrIntrinsicFunction.create(expression, signature, context, listOf(arrayType, Type.INT_TYPE, elementType)) { expression.getValueArgument(0)!!.accept(codegen, data).materialize()
it.astore(elementType) expression.getValueArgument(1)!!.accept(codegen, data).coerce(elementType, elementIrType).materialize()
} codegen.mv.astore(elementType)
return codegen.immaterialUnitValue
} }
} }
@@ -6,12 +6,15 @@
package org.jetbrains.kotlin.backend.jvm.ir package org.jetbrains.kotlin.backend.jvm.ir
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.hasAnnotation import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.util.isFunction import org.jetbrains.kotlin.ir.util.isFunction
import org.jetbrains.kotlin.ir.util.isSuspendFunctionTypeOrSubtype import org.jetbrains.kotlin.ir.util.isSuspendFunctionTypeOrSubtype
@@ -79,3 +82,12 @@ fun IrFunction.hasJvmDefault(): Boolean = propertyIfAccessor.hasAnnotation(JVM_D
fun IrValueParameter.isInlineParameter() = fun IrValueParameter.isInlineParameter() =
index >= 0 && !isNoinline && !type.isNullable() && (type.isFunction() || type.isSuspendFunctionTypeOrSubtype()) index >= 0 && !isNoinline && !type.isNullable() && (type.isFunction() || type.isSuspendFunctionTypeOrSubtype())
val IrType.isBoxedArray: Boolean
get() = classOrNull?.owner?.fqNameWhenAvailable == KotlinBuiltIns.FQ_NAMES.array.toSafe()
fun IrType.getArrayElementType(irBuiltIns: IrBuiltIns): IrType =
if (isBoxedArray)
((this as IrSimpleType).arguments.single() as IrTypeProjection).type
else
irBuiltIns.primitiveArrayElementTypes.getValue(this.classOrNull!!)