JVM: remove more redundant properties from LambdaInfo
This commit is contained in:
+7
-5
@@ -421,11 +421,13 @@ class AnonymousObjectTransformer(
|
||||
}
|
||||
|
||||
private fun getMethodParametersWithCaptured(capturedBuilder: ParametersBuilder, sourceNode: MethodNode): Parameters {
|
||||
val builder = ParametersBuilder.initializeBuilderFrom(
|
||||
oldObjectType,
|
||||
sourceNode.desc,
|
||||
isStatic = sourceNode.access and Opcodes.ACC_STATIC != 0
|
||||
)
|
||||
val builder = ParametersBuilder.newBuilder()
|
||||
if (sourceNode.access and Opcodes.ACC_STATIC == 0) {
|
||||
builder.addThis(oldObjectType, skipped = false)
|
||||
}
|
||||
for (type in Type.getArgumentTypes(sourceNode.desc)) {
|
||||
builder.addNextParameter(type, false)
|
||||
}
|
||||
for (param in capturedBuilder.listCaptured()) {
|
||||
builder.addCapturedParamCopy(param)
|
||||
}
|
||||
|
||||
@@ -18,10 +18,6 @@ import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
|
||||
interface FunctionalArgument
|
||||
|
||||
abstract class LambdaInfo : FunctionalArgument {
|
||||
abstract val isBoundCallableReference: Boolean
|
||||
|
||||
abstract val isSuspend: Boolean
|
||||
|
||||
abstract val lambdaClassType: Type
|
||||
|
||||
abstract val invokeMethod: Method
|
||||
@@ -39,11 +35,17 @@ abstract class LambdaInfo : FunctionalArgument {
|
||||
|
||||
val reifiedTypeParametersUsages = ReifiedTypeParametersUsages()
|
||||
|
||||
open val hasDispatchReceiver = true
|
||||
open val hasDispatchReceiver
|
||||
get() = true
|
||||
|
||||
fun addAllParameters(remapper: FieldRemapper): Parameters {
|
||||
val builder = ParametersBuilder.initializeBuilderFrom(OBJECT_TYPE, invokeMethod.descriptor, this)
|
||||
|
||||
val builder = ParametersBuilder.newBuilder()
|
||||
if (hasDispatchReceiver) {
|
||||
builder.addThis(lambdaClassType, skipped = true).functionalArgument = this
|
||||
}
|
||||
for (type in Type.getArgumentTypes(invokeMethod.descriptor)) {
|
||||
builder.addNextParameter(type, skipped = false)
|
||||
}
|
||||
for (info in capturedVars) {
|
||||
val field = remapper.findField(FieldInsnNode(0, info.containingLambdaName, info.fieldName, ""))
|
||||
?: error("Captured field not found: " + info.containingLambdaName + "." + info.fieldName)
|
||||
@@ -75,9 +77,9 @@ abstract class ExpressionLambda : LambdaInfo() {
|
||||
}
|
||||
|
||||
class DefaultLambda(info: ExtractedDefaultLambda, sourceCompiler: SourceCompilerForInline) : LambdaInfo() {
|
||||
val isBoundCallableReference: Boolean
|
||||
|
||||
override val lambdaClassType: Type = info.type
|
||||
override val isSuspend: Boolean get() = false // TODO: it should probably be true sometimes, but it never was
|
||||
override val isBoundCallableReference: Boolean
|
||||
override val capturedVars: List<CapturedParamDesc>
|
||||
|
||||
override val invokeMethod: Method
|
||||
|
||||
@@ -228,7 +228,7 @@ class MethodInliner(
|
||||
val expectedParameters = info.invokeMethod.argumentTypes
|
||||
val expectedKotlinParameters = info.invokeMethodParameters
|
||||
val argumentCount = Type.getArgumentTypes(desc).size.let {
|
||||
if (!inliningContext.root.state.isIrBackend && info.isSuspend && it < expectedParameters.size) {
|
||||
if (info is PsiExpressionLambda && info.invokeMethodDescriptor.isSuspend && it < expectedParameters.size) {
|
||||
// Inlining suspend lambda into a function that takes a non-suspend lambda.
|
||||
// In the IR backend, this cannot happen as inline lambdas are not lowered.
|
||||
addFakeContinuationMarker(this)
|
||||
@@ -381,10 +381,7 @@ class MethodInliner(
|
||||
private fun getNewIndex(`var`: Int): Int {
|
||||
val lambdaInfo = inliningContext.lambdaInfo
|
||||
if (reorderIrLambdaParameters && lambdaInfo is IrExpressionLambda) {
|
||||
val extensionSize =
|
||||
if (lambdaInfo.isExtensionLambda && !lambdaInfo.isBoundCallableReference)
|
||||
lambdaInfo.invokeMethod.argumentTypes[0].size
|
||||
else 0
|
||||
val extensionSize = if (lambdaInfo.isExtensionLambda) lambdaInfo.invokeMethod.argumentTypes[0].size else 0
|
||||
return when {
|
||||
// v-- extensionSize v-- argsSizeOnStack
|
||||
// |- extension -|- captured -|- real -|- locals -| old descriptor
|
||||
@@ -637,9 +634,8 @@ class MethodInliner(
|
||||
private fun replaceContinuationAccessesWithFakeContinuationsIfNeeded(processingNode: MethodNode) {
|
||||
// in ir backend inline suspend lambdas do not use ALOAD 0 to get continuation, since they are generated as static functions
|
||||
// instead they get continuation from parameter.
|
||||
if (inliningContext.state.isIrBackend) return
|
||||
val lambdaInfo = inliningContext.lambdaInfo ?: return
|
||||
if (!lambdaInfo.isSuspend) return
|
||||
if (lambdaInfo !is PsiExpressionLambda || !lambdaInfo.invokeMethodDescriptor.isSuspend) return
|
||||
val sources = analyzeMethodNodeWithInterpreter(processingNode, Aload0Interpreter(processingNode))
|
||||
val cfg = ControlFlowGraph.build(processingNode)
|
||||
val aload0s = processingNode.instructions.asSequence().filter { it.opcode == Opcodes.ALOAD && it.safeAs<VarInsnNode>()?.`var` == 0 }
|
||||
|
||||
@@ -107,22 +107,5 @@ class ParametersBuilder private constructor() {
|
||||
fun newBuilder(): ParametersBuilder {
|
||||
return ParametersBuilder()
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
@JvmStatic
|
||||
fun initializeBuilderFrom(
|
||||
objectType: Type, descriptor: String, inlineLambda: LambdaInfo? = null, isStatic: Boolean = false
|
||||
): ParametersBuilder {
|
||||
val builder = newBuilder()
|
||||
if (inlineLambda?.hasDispatchReceiver != false && !isStatic) {
|
||||
//skipped this for inlined lambda cause it will be removed
|
||||
builder.addThis(objectType, inlineLambda != null).functionalArgument = inlineLambda
|
||||
}
|
||||
|
||||
for (type in Type.getArgumentTypes(descriptor)) {
|
||||
builder.addNextParameter(type, false)
|
||||
}
|
||||
return builder
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ class PsiExpressionLambda(
|
||||
expression: KtExpression,
|
||||
private val state: GenerationState,
|
||||
val isCrossInline: Boolean,
|
||||
override val isBoundCallableReference: Boolean
|
||||
val isBoundCallableReference: Boolean
|
||||
) : ExpressionLambda() {
|
||||
override val lambdaClassType: Type
|
||||
|
||||
@@ -204,7 +204,7 @@ class PsiExpressionLambda(
|
||||
|
||||
override val invokeMethodParameters: List<KotlinType?>
|
||||
get() {
|
||||
val actualInvokeDescriptor = if (isSuspend)
|
||||
val actualInvokeDescriptor = if (invokeMethodDescriptor.isSuspend)
|
||||
getOrCreateJvmSuspendFunctionView(invokeMethodDescriptor, state)
|
||||
else
|
||||
invokeMethodDescriptor
|
||||
@@ -222,8 +222,6 @@ class PsiExpressionLambda(
|
||||
|
||||
override val returnLabels: Map<String, Label?>
|
||||
|
||||
override val isSuspend: Boolean
|
||||
|
||||
val closure: CalculatedClosure
|
||||
|
||||
init {
|
||||
@@ -252,7 +250,6 @@ class PsiExpressionLambda(
|
||||
?: throw AssertionError("null closure for lambda ${expression.text}")
|
||||
returnLabels = getDeclarationLabels(expression, invokeMethodDescriptor).associateWith { null }
|
||||
invokeMethod = state.typeMapper.mapAsmMethod(invokeMethodDescriptor)
|
||||
isSuspend = invokeMethodDescriptor.isSuspend
|
||||
}
|
||||
|
||||
// This can only be computed after generating the body, hence `lazy`.
|
||||
|
||||
+6
-15
@@ -119,17 +119,11 @@ class IrExpressionLambdaImpl(
|
||||
val reference: IrFunctionReference,
|
||||
irValueParameter: IrValueParameter
|
||||
) : ExpressionLambda(), IrExpressionLambda {
|
||||
override val isExtensionLambda: Boolean = irValueParameter.type.isExtensionFunctionType
|
||||
override val isExtensionLambda: Boolean = irValueParameter.type.isExtensionFunctionType && reference.extensionReceiver == null
|
||||
|
||||
val function: IrFunction
|
||||
get() = reference.symbol.owner
|
||||
|
||||
override val isBoundCallableReference: Boolean
|
||||
get() = reference.extensionReceiver != null
|
||||
|
||||
override val isSuspend: Boolean
|
||||
get() = reference.symbol.owner.isSuspend
|
||||
|
||||
override val hasDispatchReceiver: Boolean
|
||||
get() = false
|
||||
|
||||
@@ -148,20 +142,17 @@ class IrExpressionLambdaImpl(
|
||||
init {
|
||||
val asmMethod = codegen.methodSignatureMapper.mapAsmMethod(function)
|
||||
val capturedParameters = reference.getArgumentsWithIr()
|
||||
val (startCapture, endCapture) = when {
|
||||
isBoundCallableReference -> 0 to 1 // (bound receiver, real parameters...)
|
||||
isExtensionLambda -> 1 to capturedParameters.size + 1 // (unbound receiver, captures..., real parameters...)
|
||||
else -> 0 to capturedParameters.size // (captures..., real parameters...)
|
||||
}
|
||||
val captureStart = if (isExtensionLambda) 1 else 0 // extension receiver comes before captures
|
||||
val captureEnd = captureStart + capturedParameters.size
|
||||
capturedVars = capturedParameters.mapIndexed { index, (parameter, _) ->
|
||||
val isSuspend = parameter.isInlineParameter() && parameter.type.isSuspendFunctionTypeOrSubtype()
|
||||
capturedParamDesc(parameter.name.asString(), asmMethod.argumentTypes[startCapture + index], isSuspend)
|
||||
capturedParamDesc(parameter.name.asString(), asmMethod.argumentTypes[captureStart + index], isSuspend)
|
||||
}
|
||||
// The parameter list should include the continuation if this is a suspend lambda. In the IR backend,
|
||||
// the lambda is suspend iff the inline function's parameter is marked suspend, so FunctionN.invoke call
|
||||
// inside the inline function already has a (real) continuation value as the last argument.
|
||||
val freeParameters = function.explicitParameters.let { it.take(startCapture) + it.drop(endCapture) }
|
||||
val freeAsmParameters = asmMethod.argumentTypes.let { it.take(startCapture) + it.drop(endCapture) }
|
||||
val freeParameters = function.explicitParameters.let { it.take(captureStart) + it.drop(captureEnd) }
|
||||
val freeAsmParameters = asmMethod.argumentTypes.let { it.take(captureStart) + it.drop(captureEnd) }
|
||||
// The return type, on the other hand, should be the original type if this is a suspend lambda that returns
|
||||
// an unboxed inline class value so that the inliner will box it (FunctionN.invoke should return a boxed value).
|
||||
val unboxedReturnType = function.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass()
|
||||
|
||||
Reference in New Issue
Block a user