Obtain reification marker on default lambda extraction.
Add reification tests.
This commit is contained in:
@@ -522,7 +522,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
private void generateClosuresBodies() {
|
||||
for (LambdaInfo info : expressionMap.values()) {
|
||||
info.generateLambdaBody(codegen);
|
||||
info.generateLambdaBody(codegen, reifiedTypeInliner);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean, @JvmField val is
|
||||
|
||||
lateinit var node: SMAPAndMethodNode
|
||||
|
||||
abstract fun generateLambdaBody(codegen: ExpressionCodegen)
|
||||
abstract fun generateLambdaBody(codegen: ExpressionCodegen, reifiedTypeInliner: ReifiedTypeInliner)
|
||||
|
||||
fun addAllParameters(remapper: FieldRemapper): Parameters {
|
||||
val builder = ParametersBuilder.initializeBuilderFrom(AsmTypes.OBJECT_TYPE, invokeMethod.descriptor, this)
|
||||
@@ -81,7 +81,8 @@ class DefaultLambda(
|
||||
override val lambdaClassType: Type,
|
||||
val capturedArgs: Array<Type>,
|
||||
val parameterDescriptor: ValueParameterDescriptor,
|
||||
val offset: Int
|
||||
val offset: Int,
|
||||
val needReification: Boolean
|
||||
) : LambdaInfo(parameterDescriptor.isCrossinline, false) {
|
||||
|
||||
val parameterOffsetsInDefault: MutableList<Int> = arrayListOf()
|
||||
@@ -99,7 +100,7 @@ class DefaultLambda(
|
||||
|
||||
override fun isMyLabel(name: String): Boolean = false
|
||||
|
||||
override fun generateLambdaBody(codegen: ExpressionCodegen) {
|
||||
override fun generateLambdaBody(codegen: ExpressionCodegen, reifiedTypeInliner: ReifiedTypeInliner) {
|
||||
val classReader = InlineCodegenUtil.buildClassReaderByInternalName(codegen.state, lambdaClassType.internalName)
|
||||
|
||||
val descriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *capturedArgs)
|
||||
@@ -129,6 +130,11 @@ class DefaultLambda(
|
||||
invokeMethod.name,
|
||||
invokeMethod.descriptor,
|
||||
lambdaClassType.internalName)!!
|
||||
|
||||
if (needReification) {
|
||||
//nested classes could also require reification
|
||||
reifiedTypeInliner.reifyInstructions(node.node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +229,7 @@ class ExpressionLambda(
|
||||
val isPropertyReference: Boolean
|
||||
get() = propertyReferenceInfo != null
|
||||
|
||||
override fun generateLambdaBody(codegen: ExpressionCodegen) {
|
||||
override fun generateLambdaBody(codegen: ExpressionCodegen, reifiedTypeInliner: ReifiedTypeInliner) {
|
||||
val closureContext =
|
||||
if (isPropertyReference)
|
||||
codegen.getContext().intoAnonymousClass(classDescriptor, codegen, OwnerKind.IMPLEMENTATION)
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.DEFAULT_LAMBDA_FAKE_CALL
|
||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.getConstant
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.isNeedClassReificationMarker
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.insnText
|
||||
@@ -153,7 +154,7 @@ private fun extractDefaultLambdasInfo(
|
||||
instanceInstuction = instanceInstuction.previous
|
||||
}
|
||||
|
||||
val (owner, argTypes) = when (instanceInstuction) {
|
||||
val (owner, argTypes, needReification) = when (instanceInstuction) {
|
||||
is MethodInsnNode -> {
|
||||
assert(instanceInstuction.name == "<init>") { "Expected constructor call for default lambda, but $instanceInstuction" }
|
||||
val ownerInternalName = instanceInstuction.owner
|
||||
@@ -170,20 +171,23 @@ private fun extractDefaultLambdasInfo(
|
||||
addAll(InsnSequence(instanceInstuction, varAssignmentInstruction.next).toList())
|
||||
}
|
||||
|
||||
Type.getObjectType(instanceInstuction.owner) to Type.getArgumentTypes(instanceInstuction.desc)
|
||||
val needReification = instanceCreation.previous.takeIf { isNeedClassReificationMarker(it) }?.let { toDelete.add(it) } != null
|
||||
Triple(Type.getObjectType(instanceInstuction.owner), Type.getArgumentTypes(instanceInstuction.desc), needReification)
|
||||
}
|
||||
|
||||
is FieldInsnNode -> {
|
||||
toDelete.addAll(InsnSequence(instanceInstuction, varAssignmentInstruction.next).toList())
|
||||
|
||||
Type.getObjectType(instanceInstuction.owner) to emptyArray<Type>()
|
||||
val needReification = instanceInstuction.previous.takeIf { isNeedClassReificationMarker(it) }?.let { toDelete.add(it) } != null
|
||||
|
||||
Triple(Type.getObjectType(instanceInstuction.owner), emptyArray<Type>(), needReification)
|
||||
}
|
||||
else -> throw RuntimeException("Can't extract default lambda info $it.\n Unknown instruction: ${instanceInstuction.insnText}")
|
||||
}
|
||||
|
||||
toInsert.add(varAssignmentInstruction to defaultLambdaFakeCallStub(argTypes, it.varIndex))
|
||||
|
||||
DefaultLambda(owner, argTypes, defaultLambdas[it.varIndex]!!, it.varIndex)
|
||||
DefaultLambda(owner, argTypes, defaultLambdas[it.varIndex]!!, it.varIndex, needReification)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user