Properly process primitive receiver on inlining bound callable references
#KT-18728 Fixed
This commit is contained in:
@@ -20,8 +20,7 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.builtins.BuiltInsPackageFragment
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.getMethodAsmFlags
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.*
|
||||
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForSuspendCoroutineOrReturn
|
||||
import org.jetbrains.kotlin.codegen.coroutines.isBuiltInSuspendCoroutineOrReturnInJvm
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.bytecode
|
||||
@@ -657,7 +656,8 @@ class PsiInlineCodegen(
|
||||
|
||||
val receiver = getBoundCallableReferenceReceiver(argumentExpression)
|
||||
if (receiver != null) {
|
||||
putClosureParametersOnStack(lambdaInfo, codegen.gen(receiver))
|
||||
val receiverValue = codegen.gen(receiver)
|
||||
putClosureParametersOnStack(lambdaInfo, StackValue.coercion(receiverValue, receiverValue.type.boxReceiverForBoundReference()))
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -105,6 +105,9 @@ class DefaultLambda(
|
||||
|
||||
override fun isMyLabel(name: String): Boolean = false
|
||||
|
||||
var originalBoundReceiverType: Type? = null
|
||||
private set
|
||||
|
||||
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner) {
|
||||
val classReader = buildClassReaderByInternalName(sourceCompiler.state, lambdaClassType.internalName)
|
||||
var isPropertyReference = false
|
||||
@@ -141,7 +144,8 @@ class DefaultLambda(
|
||||
capturedVars =
|
||||
if (isFunctionReference || isPropertyReference)
|
||||
constructor?.desc?.let { Type.getArgumentTypes(it) }?.singleOrNull()?.let {
|
||||
listOf(capturedParamDesc(AsmUtil.RECEIVER_NAME, it))
|
||||
originalBoundReceiverType = it
|
||||
listOf(capturedParamDesc(AsmUtil.RECEIVER_NAME, it.boxReceiverForBoundReference()))
|
||||
} ?: emptyList()
|
||||
else
|
||||
constructor?.findCapturedFieldAssignmentInstructions()?.map {
|
||||
@@ -169,6 +173,9 @@ class DefaultLambda(
|
||||
}
|
||||
}
|
||||
|
||||
fun Type.boxReceiverForBoundReference() = AsmUtil.boxType(this)
|
||||
|
||||
|
||||
class ExpressionLambda(
|
||||
expression: KtExpression,
|
||||
private val typeMapper: KotlinTypeMapper,
|
||||
@@ -237,7 +244,9 @@ class ExpressionLambda(
|
||||
}
|
||||
|
||||
if (closure.captureReceiverType != null) {
|
||||
val type = typeMapper.mapType(closure.captureReceiverType!!)
|
||||
val type = typeMapper.mapType(closure.captureReceiverType!!).let {
|
||||
if (isBoundCallableReference) it.boxReceiverForBoundReference() else it
|
||||
}
|
||||
val descriptor = EnclosedValueDescriptor(
|
||||
AsmUtil.CAPTURED_RECEIVER_FIELD, null,
|
||||
StackValue.field(type, lambdaClassType, AsmUtil.CAPTURED_RECEIVER_FIELD, false, StackValue.LOCAL_0),
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.ClosureCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
@@ -347,6 +348,10 @@ class MethodInliner(
|
||||
val lambda = getLambdaIfExists(index) as DefaultLambda
|
||||
lambda.parameterOffsetsInDefault.zip(lambda.capturedVars).asReversed().forEach {
|
||||
(_, captured) ->
|
||||
val originalBoundReceiverType = lambda.originalBoundReceiverType
|
||||
if (lambda.isBoundCallableReference && AsmUtil.isPrimitive(originalBoundReceiverType)) {
|
||||
StackValue.onStack(originalBoundReceiverType!!).put(captured.type, InstructionAdapter(this))
|
||||
}
|
||||
super.visitFieldInsn(
|
||||
Opcodes.PUTSTATIC, captured.containingLambdaName, CAPTURED_FIELD_FOLD_PREFIX + captured.fieldName, captured.type.descriptor
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user