JVM IR: Remove varargs from CallableReferenceLowering
This commit is contained in:
committed by
max-kammerer
parent
99f1329c14
commit
4d8d65abec
+16
-15
@@ -16,11 +16,12 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
|||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall
|
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
|
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.ir.irArray
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter
|
import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter
|
||||||
import org.jetbrains.kotlin.codegen.PropertyReferenceCodegen
|
import org.jetbrains.kotlin.codegen.PropertyReferenceCodegen
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
|
import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||||
@@ -30,7 +31,6 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
@@ -257,7 +257,7 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body = context.createIrBuilder(symbol).run {
|
body = context.createJvmIrBuilder(symbol).run {
|
||||||
var unboundIndex = 0
|
var unboundIndex = 0
|
||||||
irExprBody(irCall(callee).apply {
|
irExprBody(irCall(callee).apply {
|
||||||
for ((typeParameter, typeArgument) in typeArgumentsMap) {
|
for ((typeParameter, typeArgument) in typeArgumentsMap) {
|
||||||
@@ -273,25 +273,26 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
|
|||||||
boundReceiver.second.type
|
boundReceiver.second.type
|
||||||
)
|
)
|
||||||
|
|
||||||
unboundIndex >= argumentTypes.size ->
|
|
||||||
// Unbound, but out of range - empty vararg or default value.
|
|
||||||
// TODO For suspend functions the last argument is continuation and it is implicit:
|
|
||||||
// irCall(getContinuationSymbol, listOf(ourSymbol.descriptor.returnType!!))
|
|
||||||
null
|
|
||||||
|
|
||||||
// If a vararg parameter corresponds to exactly one KFunction argument, which is an array, that array
|
// If a vararg parameter corresponds to exactly one KFunction argument, which is an array, that array
|
||||||
// is forwarded as a spread. In all other cases, excess arguments are packed into a new array.
|
// is forwarded as is. In all other cases, excess arguments are packed into a new array.
|
||||||
//
|
//
|
||||||
// fun f(x: (Int, Array<String>) -> String) = x(0, arrayOf("OK", "FAIL"))
|
// fun f(x: (Int, Array<String>) -> String) = x(0, arrayOf("OK", "FAIL"))
|
||||||
// fun g(x: (Int, String, String) -> String) = x(0, "OK", "FAIL")
|
// fun g(x: (Int, String, String) -> String) = x(0, "OK", "FAIL")
|
||||||
// fun h(i: Int, vararg xs: String) = xs[i]
|
// fun h(i: Int, vararg xs: String) = xs[i]
|
||||||
// f(::h) == g(::h)
|
// f(::h) == g(::h)
|
||||||
//
|
//
|
||||||
parameter.isVararg && (unboundIndex < argumentTypes.size - 1 || argumentTypes.last() != parameter.type) ->
|
parameter.isVararg && unboundIndex < argumentTypes.size && parameter.type == valueParameters[unboundIndex].type ->
|
||||||
IrVarargImpl(
|
irArray(parameter.type) { addSpread(irGet(valueParameters[unboundIndex++])) }
|
||||||
startOffset, endOffset, parameter.type, parameter.varargElementType!!,
|
parameter.isVararg && (unboundIndex < argumentTypes.size || !parameter.hasDefaultValue()) ->
|
||||||
(unboundIndex until argumentTypes.size).map { irGet(valueParameters[unboundIndex++]) }
|
irArray(parameter.type) {
|
||||||
)
|
(unboundIndex until argumentTypes.size).forEach { +irGet(valueParameters[unboundIndex++]) }
|
||||||
|
}
|
||||||
|
|
||||||
|
unboundIndex >= argumentTypes.size ->
|
||||||
|
// Default value argument
|
||||||
|
// TODO For suspend functions the last argument is continuation and it is implicit:
|
||||||
|
// irCall(getContinuationSymbol, listOf(ourSymbol.descriptor.returnType!!))
|
||||||
|
null
|
||||||
|
|
||||||
else ->
|
else ->
|
||||||
irGet(valueParameters[unboundIndex++])
|
irGet(valueParameters[unboundIndex++])
|
||||||
|
|||||||
+11
-16
@@ -8,23 +8,23 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
|||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.at
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irIfThen
|
import org.jetbrains.kotlin.backend.common.lower.irIfThen
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.ir.irArray
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
@@ -52,19 +52,14 @@ private class FunctionNVarargBridgeLowering(val context: JvmBackendContext) :
|
|||||||
expression.symbol.owner.name.asString() != "invoke")
|
expression.symbol.owner.name.asString() != "invoke")
|
||||||
return super.visitFunctionAccess(expression)
|
return super.visitFunctionAccess(expression)
|
||||||
|
|
||||||
return IrCallImpl(
|
return context.createJvmIrBuilder(currentScope!!.scope.scopeOwnerSymbol).run {
|
||||||
expression.startOffset, expression.endOffset,
|
at(expression)
|
||||||
expression.type, functionNInvokeFun, functionNInvokeFun.descriptor,
|
irCall(functionNInvokeFun).apply {
|
||||||
1, expression.origin
|
dispatchReceiver = expression.dispatchReceiver
|
||||||
).apply {
|
putValueArgument(0, irArray(backendContext.ir.symbols.array.typeWith(context.irBuiltIns.anyNType)) {
|
||||||
putTypeArgument(0, expression.type)
|
(0 until expression.valueArgumentsCount).forEach { +expression.getValueArgument(it)!! }
|
||||||
dispatchReceiver = expression.dispatchReceiver
|
})
|
||||||
putValueArgument(0, IrVarargImpl(
|
}
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
|
||||||
context.ir.symbols.array.typeWith(context.irBuiltIns.anyNType),
|
|
||||||
context.irBuiltIns.anyNType,
|
|
||||||
(0 until expression.valueArgumentsCount).map { expression.getValueArgument(it)!! }
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user