Convert FieldRemapper to Kotlin
This commit is contained in:
+3
-3
@@ -391,7 +391,7 @@ class AnonymousObjectTransformer(
|
||||
//TODO: some of such parameters could be skipped - we should perform additional analysis
|
||||
val capturedLambdasToInline = HashMap<String, LambdaInfo>() //captured var of inlined parameter
|
||||
val allRecapturedParameters = ArrayList<CapturedParamDesc>()
|
||||
val addCapturedNotAddOuter = parentFieldRemapper.isRoot || parentFieldRemapper is InlinedLambdaRemapper && parentFieldRemapper.getParent().isRoot
|
||||
val addCapturedNotAddOuter = parentFieldRemapper.isRoot || parentFieldRemapper is InlinedLambdaRemapper && parentFieldRemapper.parent!!.isRoot
|
||||
val alreadyAdded = HashMap<String, CapturedParamInfo>()
|
||||
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)
|
||||
|
||||
@@ -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<AbstractInsnNode> capturedFieldAccess, @NotNull MethodNode node) {
|
||||
if (capturedFieldAccess.size() == 1) {
|
||||
fun foldFieldAccessChainIfNeeded(capturedFieldAccess: List<AbstractInsnNode>, 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<AbstractInsnNode> capturedFieldAccess,
|
||||
int currentInstruction,
|
||||
@NotNull MethodNode node
|
||||
) {
|
||||
boolean checkParent = !isRoot() && currentInstruction < capturedFieldAccess.size() - 1;
|
||||
private fun foldFieldAccessChainIfNeeded(
|
||||
capturedFieldAccess: List<AbstractInsnNode>,
|
||||
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<CapturedParamInfo> 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>): 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
|
||||
}
|
||||
|
||||
@@ -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<CapturedParamInfo>) =
|
||||
parent.findField(fieldInsnNode, captured)
|
||||
override fun findField(fieldInsnNode: FieldInsnNode, captured: Collection<CapturedParamInfo>): 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)
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CapturedParamInfo findField(@NotNull FieldInsnNode fieldInsnNode, @NotNull Collection<CapturedParamInfo> captured) {
|
||||
public CapturedParamInfo findField(@NotNull FieldInsnNode fieldInsnNode, @NotNull Collection<? extends CapturedParamInfo> captured) {
|
||||
boolean searchInParent = !canProcess(fieldInsnNode.owner, fieldInsnNode.name, false);
|
||||
if (searchInParent) {
|
||||
return parent.findField(fieldInsnNode);
|
||||
|
||||
Reference in New Issue
Block a user