JVM IR: Remove vararg handling from ExpressionCodegen
This commit is contained in:
committed by
max-kammerer
parent
4d8d65abec
commit
1543accf40
+13
-130
@@ -352,27 +352,27 @@ class ExpressionCodegen(
|
||||
}
|
||||
expression.descriptor is ConstructorDescriptor ->
|
||||
throw AssertionError("IrCall with ConstructorDescriptor: ${expression.javaClass.simpleName}")
|
||||
callee.isSuspend && !irFunction.isInvokeSuspendInContinuation() -> addInlineMarker(mv, isStartNotEnd = true)
|
||||
callee.isSuspend && !irFunction.isInvokeSuspendInContinuation() ->
|
||||
addInlineMarker(mv, isStartNotEnd = true)
|
||||
}
|
||||
|
||||
val receiver = expression.dispatchReceiver
|
||||
receiver?.apply {
|
||||
expression.dispatchReceiver?.let { receiver ->
|
||||
callGenerator.genValueAndPut(
|
||||
callee.dispatchReceiverParameter!!,
|
||||
this,
|
||||
receiver,
|
||||
if (isSuperCall) receiver.asmType else callable.dispatchReceiverType
|
||||
?: throw AssertionError("No dispatch receiver type: ${expression.render()}"),
|
||||
this@ExpressionCodegen,
|
||||
this,
|
||||
data
|
||||
)
|
||||
}
|
||||
|
||||
expression.extensionReceiver?.apply {
|
||||
expression.extensionReceiver?.let { receiver ->
|
||||
callGenerator.genValueAndPut(
|
||||
callee.extensionReceiverParameter!!,
|
||||
this,
|
||||
receiver,
|
||||
callable.extensionReceiverType!!,
|
||||
this@ExpressionCodegen,
|
||||
this,
|
||||
data
|
||||
)
|
||||
}
|
||||
@@ -381,25 +381,8 @@ class ExpressionCodegen(
|
||||
expression.symbol.owner.valueParameters.forEachIndexed { i, irParameter ->
|
||||
val arg = expression.getValueArgument(i)
|
||||
val parameterType = callable.valueParameterTypes[i]
|
||||
when {
|
||||
arg != null -> {
|
||||
callGenerator.genValueAndPut(irParameter, arg, parameterType, this@ExpressionCodegen, data)
|
||||
}
|
||||
else -> {
|
||||
assert(irParameter.varargElementType != null)
|
||||
val type = typeMapper.mapType(
|
||||
irParameter.type.substitute(typeSubstitutionMap)
|
||||
)
|
||||
callGenerator.putValueIfNeeded(
|
||||
parameterType,
|
||||
StackValue.operation(type) {
|
||||
it.aconst(0)
|
||||
it.newarray(correctElementType(type))
|
||||
},
|
||||
ValueKind.GENERAL_VARARG, i, this@ExpressionCodegen
|
||||
)
|
||||
}
|
||||
}
|
||||
require(arg != null) { "Null argument in ExpressionCodegen for parameter ${irParameter.render()}" }
|
||||
callGenerator.genValueAndPut(irParameter, arg, parameterType, this, data)
|
||||
}
|
||||
|
||||
expression.markLineNumber(true)
|
||||
@@ -409,19 +392,14 @@ class ExpressionCodegen(
|
||||
addSuspendMarker(mv, isStartNotEnd = true)
|
||||
}
|
||||
|
||||
callGenerator.genCall(
|
||||
callable,
|
||||
this,
|
||||
expression
|
||||
)
|
||||
|
||||
val returnType = callee.returnType
|
||||
callGenerator.genCall(callable, this, expression)
|
||||
|
||||
if (callee.isSuspend && !irFunction.isInvokeSuspendInContinuation()) {
|
||||
addSuspendMarker(mv, isStartNotEnd = false)
|
||||
addInlineMarker(mv, isStartNotEnd = false)
|
||||
}
|
||||
|
||||
val returnType = callee.returnType
|
||||
return when {
|
||||
returnType.substitute(expression.typeSubstitutionMap).isNothing() -> {
|
||||
mv.aconst(null)
|
||||
@@ -581,101 +559,6 @@ class ExpressionCodegen(
|
||||
return immaterialUnitValue
|
||||
}
|
||||
|
||||
override fun visitVararg(expression: IrVararg, data: BlockInfo): PromisedValue {
|
||||
expression.markLineNumber(startOffset = true)
|
||||
val outType = expression.type
|
||||
val type = expression.asmType
|
||||
assert(type.sort == Type.ARRAY)
|
||||
val elementType = correctElementType(type)
|
||||
val arguments = expression.elements
|
||||
val size = arguments.size
|
||||
|
||||
val hasSpread = arguments.firstIsInstanceOrNull<IrSpreadElement>() != null
|
||||
|
||||
if (hasSpread) {
|
||||
val arrayOfReferences = outType.makeNotNull().isArray()
|
||||
if (size == 1) {
|
||||
// Arrays.copyOf(receiverValue, newLength)
|
||||
val argument = (arguments[0] as IrSpreadElement).expression
|
||||
val arrayType = if (arrayOfReferences)
|
||||
Type.getType("[Ljava/lang/Object;")
|
||||
else
|
||||
Type.getType("[" + elementType.descriptor)
|
||||
argument.accept(this, data).coerce(type, argument.type).materialize()
|
||||
mv.dup()
|
||||
mv.arraylength()
|
||||
mv.invokestatic("java/util/Arrays", "copyOf", Type.getMethodDescriptor(arrayType, arrayType, Type.INT_TYPE), false)
|
||||
if (arrayOfReferences) {
|
||||
mv.checkcast(type)
|
||||
}
|
||||
} else {
|
||||
val owner: String
|
||||
val addDescriptor: String
|
||||
val toArrayDescriptor: String
|
||||
if (arrayOfReferences) {
|
||||
owner = "kotlin/jvm/internal/SpreadBuilder"
|
||||
addDescriptor = "(Ljava/lang/Object;)V"
|
||||
toArrayDescriptor = "([Ljava/lang/Object;)[Ljava/lang/Object;"
|
||||
} else {
|
||||
val spreadBuilderClassName =
|
||||
asmPrimitiveTypeToLangPrimitiveType(elementType)!!.typeName.identifier + "SpreadBuilder"
|
||||
owner = "kotlin/jvm/internal/$spreadBuilderClassName"
|
||||
addDescriptor = "(" + elementType.descriptor + ")V"
|
||||
toArrayDescriptor = "()" + type.descriptor
|
||||
}
|
||||
mv.anew(Type.getObjectType(owner))
|
||||
mv.dup()
|
||||
mv.iconst(size)
|
||||
mv.invokespecial(owner, "<init>", "(I)V", false)
|
||||
for (i in 0 until size) {
|
||||
mv.dup()
|
||||
val argument = arguments[i]
|
||||
if (argument is IrSpreadElement) {
|
||||
argument.expression.accept(this, data).coerce(OBJECT_TYPE, argument.expression.type).materialize()
|
||||
mv.invokevirtual(owner, "addSpread", "(Ljava/lang/Object;)V", false)
|
||||
} else {
|
||||
argument.accept(this, data).coerce(elementType, expression.varargElementType).materialize()
|
||||
mv.invokevirtual(owner, "add", addDescriptor, false)
|
||||
}
|
||||
}
|
||||
if (arrayOfReferences) {
|
||||
mv.dup()
|
||||
mv.invokevirtual(owner, "size", "()I", false)
|
||||
newArrayInstruction(outType)
|
||||
mv.invokevirtual(owner, "toArray", toArrayDescriptor, false)
|
||||
mv.checkcast(type)
|
||||
} else {
|
||||
mv.invokevirtual(owner, "toArray", toArrayDescriptor, false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mv.iconst(size)
|
||||
newArrayInstruction(expression.type)
|
||||
for ((i, element) in expression.elements.withIndex()) {
|
||||
mv.dup()
|
||||
mv.iconst(i)
|
||||
element.accept(this, data).coerce(elementType, expression.varargElementType).materialize()
|
||||
mv.astore(elementType)
|
||||
}
|
||||
}
|
||||
return expression.onStack
|
||||
}
|
||||
|
||||
fun newArrayInstruction(arrayType: IrType) {
|
||||
if (arrayType.isArray()) {
|
||||
val elementIrType = arrayType.safeAs<IrSimpleType>()!!.arguments[0].safeAs<IrTypeProjection>()!!.type
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
elementIrType,
|
||||
ReifiedTypeInliner.OperationKind.NEW_ARRAY,
|
||||
mv,
|
||||
this
|
||||
)
|
||||
mv.newarray(typeMapper.boxType(elementIrType))
|
||||
} else {
|
||||
mv.newarray(correctElementType(arrayType.asmType))
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitReturn(expression: IrReturn, data: BlockInfo): PromisedValue {
|
||||
val returnTarget = expression.returnTargetSymbol.owner
|
||||
val owner =
|
||||
@@ -1224,7 +1107,7 @@ class ExpressionCodegen(
|
||||
}
|
||||
|
||||
/* From ExpressionCodegen.java */
|
||||
private fun putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
fun putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
type: IrType, operationKind: ReifiedTypeInliner.OperationKind, v: InstructionAdapter,
|
||||
codegen: ExpressionCodegen?
|
||||
) {
|
||||
|
||||
@@ -1,29 +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.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
object ArrayOf : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context, signature.returnType) {
|
||||
//do nothing all generated as vararg
|
||||
}
|
||||
}
|
||||
}
|
||||
-2
@@ -70,7 +70,6 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
|
||||
"isArrayOf",
|
||||
emptyList()
|
||||
) to IsArrayOf,
|
||||
symbols.arrayOf.toKey() to ArrayOf,
|
||||
Key(
|
||||
KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME,
|
||||
KotlinBuiltIns.FQ_NAMES.any.toSafe(),
|
||||
@@ -113,7 +112,6 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
|
||||
unaryFunForPrimitives("hashCode", HashCode) +
|
||||
unaryFunForPrimitives("toString", ToString) +
|
||||
binaryFunForPrimitives("equals", EQUALS, irBuiltIns.anyClass) +
|
||||
symbols.primitiveArrayOfByType.values.map { it.toKey() to ArrayOf } +
|
||||
binaryFunForPrimitivesAcrossPrimitives("rangeTo", RangeTo) +
|
||||
binaryOp("plus", IADD) +
|
||||
binaryOp("minus", ISUB) +
|
||||
|
||||
+15
-2
@@ -8,13 +8,26 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.PromisedValue
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getArrayElementType
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.types.isArray
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
object NewArray : IntrinsicMethod() {
|
||||
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? {
|
||||
codegen.gen(expression.getValueArgument(0)!!, Type.INT_TYPE, codegen.context.irBuiltIns.intType, data)
|
||||
codegen.newArrayInstruction(expression.type)
|
||||
return with(codegen) { expression.onStack }
|
||||
return with(codegen) {
|
||||
val elementIrType = expression.type.getArrayElementType(context.irBuiltIns)
|
||||
if (expression.type.isArray()) {
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
elementIrType, ReifiedTypeInliner.OperationKind.NEW_ARRAY, mv, this
|
||||
)
|
||||
mv.newarray(typeMapper.boxType(elementIrType))
|
||||
} else {
|
||||
mv.newarray(typeMapper.mapType(elementIrType))
|
||||
}
|
||||
expression.onStack
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user