From 8a083a41d516bec38e9c2cfd9c48386018848067 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Tue, 16 May 2017 10:13:46 +0200 Subject: [PATCH] Clean code after transformation --- .../inline/AnonymousObjectTransformer.kt | 2 +- .../kotlin/codegen/inline/FieldRemapper.kt | 10 ++--- .../codegen/inline/InlineCodegenUtil.java | 3 +- .../codegen/inline/InlinedLambdaRemapper.kt | 5 +-- .../kotlin/codegen/inline/MethodInliner.kt | 2 +- .../inline/RegeneratedLambdaFieldRemapper.kt | 43 +++++++++---------- 6 files changed, 32 insertions(+), 33 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt index 44c2bd44c4b..840d2f34845 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt @@ -428,7 +428,7 @@ class AnonymousObjectTransformer( //lambda with non InlinedLambdaRemapper already have outer val parent = parentFieldRemapper.parent as? RegeneratedLambdaFieldRemapper ?: throw AssertionError("Expecting RegeneratedLambdaFieldRemapper, but ${parentFieldRemapper.parent}") - val ownerType = Type.getObjectType(parent.lambdaInternalName) + val ownerType = Type.getObjectType(parent.originalLambdaInternalName) val desc = CapturedParamDesc(ownerType, InlineCodegenUtil.THIS, ownerType) val recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, InlineCodegenUtil.`THIS$0`/*outer lambda/object*/, false) val composed = StackValue.LOCAL_0 diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt index 08ea117dc06..29903bdb5d8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt @@ -24,16 +24,16 @@ import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode import org.jetbrains.org.objectweb.asm.tree.MethodNode open class FieldRemapper( - val lambdaInternalName: String?, + val originalLambdaInternalName: String?, @JvmField val parent: FieldRemapper?, - private val params: Parameters + protected val parameters: Parameters ) { val isRoot = parent == null open val isInsideInliningLambda: Boolean = parent?.isInsideInliningLambda ?: false protected open fun canProcess(fieldOwner: String, fieldName: String, isFolding: Boolean): Boolean { - return fieldOwner == lambdaInternalName && + return fieldOwner == originalLambdaInternalName && //don't process general field of anonymous objects InlineCodegenUtil.isCapturedFieldName(fieldName) } @@ -72,7 +72,7 @@ open class FieldRemapper( } @JvmOverloads - open fun findField(fieldInsnNode: FieldInsnNode, captured: Collection = params.captured): CapturedParamInfo? { + open fun findField(fieldInsnNode: FieldInsnNode, captured: Collection = parameters.captured): CapturedParamInfo? { for (valueDescriptor in captured) { if (valueDescriptor.originalFieldName == fieldInsnNode.name && valueDescriptor.containingLambdaName == fieldInsnNode.owner) { return valueDescriptor @@ -82,7 +82,7 @@ open class FieldRemapper( } open val newLambdaInternalName: String - get() = lambdaInternalName!! + get() = originalLambdaInternalName!! open fun getFieldForInline(node: FieldInsnNode, prefix: StackValue?): StackValue? = MethodInliner.findCapturedField(node, this).remapValue diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java index cda41e2bdaf..88636dda40e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java @@ -89,7 +89,8 @@ public class InlineCodegenUtil { public static final String INLINE_FUN_VAR_SUFFIX = "$iv"; public static final String DEFAULT_LAMBDA_FAKE_CALL = "$$$DEFAULT_LAMBDA_FAKE_CALL$$$"; - + public static final String CAPTURED_FIELD_FOLD_PREFIX = "$$$"; + @Nullable public static SMAPAndMethodNode getMethodNode( byte[] classData, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlinedLambdaRemapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlinedLambdaRemapper.kt index c7677908904..3757965f97e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlinedLambdaRemapper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlinedLambdaRemapper.kt @@ -28,9 +28,8 @@ class InlinedLambdaRemapper( public override fun canProcess(fieldOwner: String, fieldName: String, isFolding: Boolean) = isFolding && super.canProcess(fieldOwner, fieldName, true) - override fun findField(fieldInsnNode: FieldInsnNode, captured: Collection): CapturedParamInfo? { - return parent!!.findField(fieldInsnNode, captured) - } + override fun findField(fieldInsnNode: FieldInsnNode, captured: Collection) = + parent!!.findField(fieldInsnNode, captured) override val isInsideInliningLambda: Boolean = true diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt index 0c03d874bab..94aff872696 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt @@ -709,7 +709,7 @@ class MethodInliner( assert(node.name.startsWith("$$$")) { "Captured field template should start with $$$ prefix" } val fin = FieldInsnNode(node.opcode, node.owner, node.name.substring(3), node.desc) val field = fieldRemapper.findField(fin) ?: throw IllegalStateException( - "Couldn't find captured field " + node.owner + "." + node.name + " in " + fieldRemapper.lambdaInternalName + "Couldn't find captured field ${node.owner}.${node.name} in ${fieldRemapper.originalLambdaInternalName}" ) return field } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.kt index c5410dc3df6..279b44750c6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.kt @@ -17,18 +17,20 @@ package org.jetbrains.kotlin.codegen.inline import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.CAPTURED_FIELD_FOLD_PREFIX +import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.THIS import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode class RegeneratedLambdaFieldRemapper( - val oldOwnerType: String, + originalLambdaInternalName: String, override val newLambdaInternalName: String, - private val parameters: Parameters, + parameters: Parameters, private val recapturedLambdas: Map, remapper: FieldRemapper, private val isConstructor: Boolean -) : FieldRemapper(oldOwnerType, remapper, parameters) { +) : FieldRemapper(originalLambdaInternalName, remapper, parameters) { public override fun canProcess(fieldOwner: String, fieldName: String, isFolding: Boolean) = super.canProcess(fieldOwner, fieldName, isFolding) || isRecapturedLambdaType(fieldOwner, isFolding) @@ -41,38 +43,35 @@ class RegeneratedLambdaFieldRemapper( if (searchInParent) { return parent!!.findField(fieldInsnNode) } - return findFieldInMyCaptured(fieldInsnNode) + return findFieldInSuper(fieldInsnNode) } override fun processNonAload0FieldAccessChains(isInlinedLambda: Boolean): Boolean { return isInlinedLambda && isConstructor } - private fun findFieldInMyCaptured(fieldInsnNode: FieldInsnNode): CapturedParamInfo? { + private fun findFieldInSuper(fieldInsnNode: FieldInsnNode): CapturedParamInfo? { return super.findField(fieldInsnNode, parameters.captured) } override fun getFieldForInline(node: FieldInsnNode, prefix: StackValue?): StackValue? { - assert(node.name.startsWith("$$$")) { "Captured field template should start with $$$ prefix" } - if (node.name == "$$$" + InlineCodegenUtil.THIS) { - assert(oldOwnerType == node.owner) { "Can't unfold '$$\$THIS' parameter" } + val fieldName = node.name + assert(fieldName.startsWith(CAPTURED_FIELD_FOLD_PREFIX)) { "Captured field template should start with $CAPTURED_FIELD_FOLD_PREFIX prefix" } + if (fieldName == CAPTURED_FIELD_FOLD_PREFIX + THIS) { + assert(originalLambdaInternalName == node.owner) { "Can't unfold '$CAPTURED_FIELD_FOLD_PREFIX$THIS' parameter" } return StackValue.LOCAL_0 } - val fin = FieldInsnNode(node.opcode, node.owner, node.name.substring(3), node.desc) - var field = findFieldInMyCaptured(fin) + val fin = FieldInsnNode(node.opcode, node.owner, fieldName.substringAfter(CAPTURED_FIELD_FOLD_PREFIX), node.desc) + var fromParent = false + val field = findFieldInSuper(fin) ?: + //search in parent + findFieldInSuper(FieldInsnNode( + Opcodes.GETSTATIC, originalLambdaInternalName, InlineCodegenUtil.`THIS$0`, + Type.getObjectType(parent!!.originalLambdaInternalName!!).descriptor + ))?.also { fromParent = true } ?: + throw AssertionError("Couldn't find captured this $originalLambdaInternalName for $fieldName") - var searchInParent = false - if (field == null) { - field = findFieldInMyCaptured(FieldInsnNode( - Opcodes.GETSTATIC, oldOwnerType, InlineCodegenUtil.`THIS$0`, - Type.getObjectType(parent!!.lambdaInternalName!!).descriptor - )) - searchInParent = true - if (field == null) { - throw IllegalStateException("Couldn't find captured this " + lambdaInternalName + " for " + node.name) - } - } val result = StackValue.field( if (field.isSkipped) @@ -84,6 +83,6 @@ class RegeneratedLambdaFieldRemapper( prefix ?: StackValue.LOCAL_0 ) - return if (searchInParent) parent!!.getFieldForInline(node, result) else result + return if (fromParent) parent!!.getFieldForInline(node, result) else result } }