From 5b947ac27e615208160106b74b8127c410bef6d5 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 15 May 2017 20:53:32 +0200 Subject: [PATCH] Convert FieldRemapper to Kotlin --- .../inline/AnonymousObjectTransformer.kt | 6 +- .../kotlin/codegen/inline/FieldRemapper.kt | 131 +++++++----------- .../codegen/inline/InlinedLambdaRemapper.kt | 9 +- .../RegeneratedLambdaFieldRemapper.java | 2 +- 4 files changed, 59 insertions(+), 89 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 b12187d13fc..44c2bd44c4b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt @@ -391,7 +391,7 @@ class AnonymousObjectTransformer( //TODO: some of such parameters could be skipped - we should perform additional analysis val capturedLambdasToInline = HashMap() //captured var of inlined parameter val allRecapturedParameters = ArrayList() - val addCapturedNotAddOuter = parentFieldRemapper.isRoot || parentFieldRemapper is InlinedLambdaRemapper && parentFieldRemapper.getParent().isRoot + val addCapturedNotAddOuter = parentFieldRemapper.isRoot || parentFieldRemapper is InlinedLambdaRemapper && parentFieldRemapper.parent!!.isRoot val alreadyAdded = HashMap() for (info in capturedLambdas) { if (addCapturedNotAddOuter) { @@ -426,8 +426,8 @@ class AnonymousObjectTransformer( if (parentFieldRemapper is InlinedLambdaRemapper && !capturedLambdas.isEmpty() && !addCapturedNotAddOuter) { //lambda with non InlinedLambdaRemapper already have outer - val parent = parentFieldRemapper.getParent() - assert(parent is RegeneratedLambdaFieldRemapper) + val parent = parentFieldRemapper.parent as? RegeneratedLambdaFieldRemapper ?: + throw AssertionError("Expecting RegeneratedLambdaFieldRemapper, but ${parentFieldRemapper.parent}") val ownerType = Type.getObjectType(parent.lambdaInternalName) val desc = CapturedParamDesc(ownerType, InlineCodegenUtil.THIS, ownerType) val recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, InlineCodegenUtil.`THIS$0`/*outer lambda/object*/, false) 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 f9055cb5255..ba8503f90aa 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt @@ -14,122 +14,91 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.inline; +package org.jetbrains.kotlin.codegen.inline -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.codegen.StackValue; -import org.jetbrains.org.objectweb.asm.Opcodes; -import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode; -import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode; -import org.jetbrains.org.objectweb.asm.tree.MethodNode; +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.org.objectweb.asm.Opcodes +import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode +import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode +import org.jetbrains.org.objectweb.asm.tree.MethodNode -import java.util.Collection; -import java.util.List; +open class FieldRemapper(val lambdaInternalName: String?, @JvmField val parent: FieldRemapper?, private val params: Parameters) { -public class FieldRemapper { - protected FieldRemapper parent; - private final String lambdaInternalName; - private final Parameters params; - - public FieldRemapper(@Nullable String lambdaInternalName, @Nullable FieldRemapper parent, @NotNull Parameters methodParams) { - this.lambdaInternalName = lambdaInternalName; - this.parent = parent; - this.params = methodParams; - } - - protected boolean canProcess(@NotNull String fieldOwner, @NotNull String fieldName, boolean isFolding) { - return fieldOwner.equals(getLambdaInternalName()) && + protected open fun canProcess(fieldOwner: String, fieldName: String, isFolding: Boolean): Boolean { + return fieldOwner == lambdaInternalName && //don't process general field of anonymous objects - InlineCodegenUtil.isCapturedFieldName(fieldName); + InlineCodegenUtil.isCapturedFieldName(fieldName) } - @Nullable - public AbstractInsnNode foldFieldAccessChainIfNeeded(@NotNull List capturedFieldAccess, @NotNull MethodNode node) { - if (capturedFieldAccess.size() == 1) { + fun foldFieldAccessChainIfNeeded(capturedFieldAccess: List, node: MethodNode): AbstractInsnNode? { + if (capturedFieldAccess.size == 1) { //just aload - return null; + return null } - return foldFieldAccessChainIfNeeded(capturedFieldAccess, 1, node); + return foldFieldAccessChainIfNeeded(capturedFieldAccess, 1, node) } //TODO: seems that this method is redundant but it added from safety purposes before new milestone - public boolean processNonAload0FieldAccessChains(boolean isInlinedLambda) { - return false; + open fun processNonAload0FieldAccessChains(isInlinedLambda: Boolean): Boolean { + return false } - @Nullable - private AbstractInsnNode foldFieldAccessChainIfNeeded( - @NotNull List capturedFieldAccess, - int currentInstruction, - @NotNull MethodNode node - ) { - boolean checkParent = !isRoot() && currentInstruction < capturedFieldAccess.size() - 1; + private fun foldFieldAccessChainIfNeeded( + capturedFieldAccess: List, + currentInstruction: Int, + node: MethodNode + ): AbstractInsnNode? { + val checkParent = !isRoot && currentInstruction < capturedFieldAccess.size - 1 if (checkParent) { - AbstractInsnNode transformed = parent.foldFieldAccessChainIfNeeded(capturedFieldAccess, currentInstruction + 1, node); + val transformed = parent!!.foldFieldAccessChainIfNeeded(capturedFieldAccess, currentInstruction + 1, node) if (transformed != null) { - return transformed; + return transformed } } - FieldInsnNode insnNode = (FieldInsnNode) capturedFieldAccess.get(currentInstruction); + val insnNode = capturedFieldAccess[currentInstruction] as FieldInsnNode if (canProcess(insnNode.owner, insnNode.name, true)) { - insnNode.name = "$$$" + insnNode.name; - insnNode.setOpcode(Opcodes.GETSTATIC); + insnNode.name = "$$$" + insnNode.name + insnNode.opcode = Opcodes.GETSTATIC - AbstractInsnNode next = capturedFieldAccess.get(0); - while (next != insnNode) { - AbstractInsnNode toDelete = next; - next = next.getNext(); - node.instructions.remove(toDelete); + var next = capturedFieldAccess[0] + while (next !== insnNode) { + val toDelete = next + next = next.next + node.instructions.remove(toDelete) } - return capturedFieldAccess.get(capturedFieldAccess.size() - 1); + return capturedFieldAccess[capturedFieldAccess.size - 1] } - return null; + return null } - @Nullable - public CapturedParamInfo findField(@NotNull FieldInsnNode fieldInsnNode) { - return findField(fieldInsnNode, params.getCaptured()); + fun findField(fieldInsnNode: FieldInsnNode): CapturedParamInfo? { + return findField(fieldInsnNode, params.captured) } - @Nullable - protected CapturedParamInfo findField(@NotNull FieldInsnNode fieldInsnNode, @NotNull Collection captured) { - for (CapturedParamInfo valueDescriptor : captured) { - if (valueDescriptor.getOriginalFieldName().equals(fieldInsnNode.name) && - valueDescriptor.getContainingLambdaName().equals(fieldInsnNode.owner)) { - return valueDescriptor; + open fun findField(fieldInsnNode: FieldInsnNode, captured: Collection): CapturedParamInfo? { + for (valueDescriptor in captured) { + if (valueDescriptor.originalFieldName == fieldInsnNode.name && valueDescriptor.containingLambdaName == fieldInsnNode.owner) { + return valueDescriptor } } - return null; + return null } - @NotNull - public FieldRemapper getParent() { - return parent; + open fun getNewLambdaInternalName(): String { + return lambdaInternalName!! } - public String getLambdaInternalName() { - return lambdaInternalName; + val isRoot: Boolean + get() = parent == null + + open fun getFieldForInline(node: FieldInsnNode, prefix: StackValue?): StackValue? { + return MethodInliner.findCapturedField(node, this).remapValue } - public String getNewLambdaInternalName() { - return lambdaInternalName; - } - - public boolean isRoot() { - return parent == null; - } - - @Nullable - public StackValue getFieldForInline(@NotNull FieldInsnNode node, @Nullable StackValue prefix) { - return MethodInliner.findCapturedField(node, this).getRemapValue(); - } - - public boolean isInsideInliningLambda() { - return !isRoot() && parent.isInsideInliningLambda(); - } + open val isInsideInliningLambda: Boolean + get() = !isRoot && parent!!.isInsideInliningLambda } 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 4c859501d5d..c7677908904 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlinedLambdaRemapper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlinedLambdaRemapper.kt @@ -28,13 +28,14 @@ class InlinedLambdaRemapper( public override fun canProcess(fieldOwner: String, fieldName: String, isFolding: Boolean) = isFolding && super.canProcess(fieldOwner, fieldName, true) - public override fun findField(fieldInsnNode: FieldInsnNode, captured: Collection) = - parent.findField(fieldInsnNode, captured) + override fun findField(fieldInsnNode: FieldInsnNode, captured: Collection): CapturedParamInfo? { + return parent!!.findField(fieldInsnNode, captured) + } - override fun isInsideInliningLambda() = true + override val isInsideInliningLambda: Boolean = true override fun getFieldForInline(node: FieldInsnNode, prefix: StackValue?) = - if (parent.isRoot) + if (parent!!.isRoot) super.getFieldForInline(node, prefix) else parent.getFieldForInline(node, prefix) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.java index cbc37154f5c..93315aae0e6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.java @@ -60,7 +60,7 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper { @Nullable @Override - public CapturedParamInfo findField(@NotNull FieldInsnNode fieldInsnNode, @NotNull Collection captured) { + public CapturedParamInfo findField(@NotNull FieldInsnNode fieldInsnNode, @NotNull Collection captured) { boolean searchInParent = !canProcess(fieldInsnNode.owner, fieldInsnNode.name, false); if (searchInParent) { return parent.findField(fieldInsnNode);