diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicFunction.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicFunction.kt index 7257c7fc096..f08f16eb075 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicFunction.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicFunction.kt @@ -19,16 +19,39 @@ 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.AsmUtil import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.resolve.calls.components.isVararg import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature +import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import java.util.* +private class IrEmptyVarargExpression( + override val type: KotlinType, + override val startOffset: Int, + override val endOffset: Int +) : IrExpression { + override fun accept(visitor: IrElementVisitor, data: D): R { + TODO("not implemented") + } + + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + TODO("not implemented") + } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + TODO("not implemented") + } +} open class IrIntrinsicFunction( val expression: IrMemberAccessExpression, @@ -60,12 +83,26 @@ open class IrIntrinsicFunction( } open fun invoke(v: InstructionAdapter, codegen: ExpressionCodegen, data: BlockInfo):StackValue { - val args = mutableListOf(expression.dispatchReceiver, expression.extensionReceiver) - args.addAll(expression.descriptor.valueParameters.mapIndexed { - i, _ -> - expression.getValueArgument(i) - }) - args.filterNotNull().forEachIndexed { i, irExpression -> genArg(irExpression, codegen, i, data) } + val args = listOfNotNull(expression.dispatchReceiver, expression.extensionReceiver) + + expression.descriptor.valueParameters.mapIndexed { i, descriptor -> + expression.getValueArgument(i) ?: + if (descriptor.isVararg) + IrEmptyVarargExpression(descriptor.type, UNDEFINED_OFFSET, UNDEFINED_OFFSET) + else error("Unknown parameter: $descriptor in $expression") + } + + args.forEachIndexed { i, irExpression -> + if (irExpression is IrEmptyVarargExpression) { + val parameterType = codegen.typeMapper.mapType(irExpression.type) + StackValue.operation(parameterType) { + it.aconst(0) + it.newarray(AsmUtil.correctElementType(parameterType)) + }.put(parameterType, codegen.mv) + } + else { + genArg(irExpression, codegen, i, data) + } + } genInvokeInstruction(v) return StackValue.onStack(returnType) }