Fix for KT-9064

#KT-9064 Fixed
This commit is contained in:
Michael Bogdanov
2015-09-09 14:52:54 +03:00
parent e03e9bb1a3
commit a5f7df3ebf
10 changed files with 106 additions and 13 deletions
@@ -237,7 +237,7 @@ public class AnonymousObjectTransformer {
RegeneratedLambdaFieldRemapper remapper =
new RegeneratedLambdaFieldRemapper(oldObjectType.getInternalName(), newLambdaType.getInternalName(),
parameters, anonymousObjectGen.getCapturedLambdasToInline(),
parentRemapper);
parentRemapper, false);
MethodInliner inliner = new MethodInliner(sourceNode, parameters, inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
remapper, isSameModule, "Transformer for " + anonymousObjectGen.getOwnerInternalName(),
@@ -325,7 +325,7 @@ public class AnonymousObjectTransformer {
RegeneratedLambdaFieldRemapper remapper =
new RegeneratedLambdaFieldRemapper(oldObjectType.getInternalName(), newLambdaType.getInternalName(),
constructorParameters, anonymousObjectGen.getCapturedLambdasToInline(),
parentRemapper);
parentRemapper, true);
MethodInliner inliner = new MethodInliner(constructor, constructorParameters, inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
remapper, isSameModule, "Transformer for constructor of " + anonymousObjectGen.getOwnerInternalName(),
@@ -60,6 +60,11 @@ public class FieldRemapper {
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;
}
@Nullable
private AbstractInsnNode foldFieldAccessChainIfNeeded(
@NotNull List<AbstractInsnNode> capturedFieldAccess,
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.codegen.inline;
import com.google.common.collect.Lists;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.ClosureCodegen;
@@ -25,11 +24,6 @@ import org.jetbrains.kotlin.codegen.StackValue;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.kotlin.codegen.optimization.MandatoryMethodTransformer;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass;
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache;
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass;
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Opcodes;
@@ -551,9 +545,7 @@ public class MethodInliner {
public LambdaInfo getLambdaIfExists(AbstractInsnNode insnNode) {
if (insnNode.getOpcode() == Opcodes.ALOAD) {
int varIndex = ((VarInsnNode) insnNode).var;
if (varIndex < parameters.totalSize()) {
return parameters.get(varIndex).getLambda();
}
return getLambdaIfExists(varIndex);
}
else if (insnNode instanceof FieldInsnNode) {
FieldInsnNode fieldInsnNode = (FieldInsnNode) insnNode;
@@ -565,6 +557,13 @@ public class MethodInliner {
return null;
}
private LambdaInfo getLambdaIfExists(int varIndex) {
if (varIndex < parameters.totalSize()) {
return parameters.get(varIndex).getLambda();
}
return null;
}
private static void removeClosureAssertions(MethodNode node) {
AbstractInsnNode cur = node.instructions.getFirst();
while (cur != null && cur.getNext() != null) {
@@ -598,7 +597,8 @@ public class MethodInliner {
AbstractInsnNode cur = node.instructions.getFirst();
while (cur != null) {
if (cur instanceof VarInsnNode && cur.getOpcode() == Opcodes.ALOAD) {
if (((VarInsnNode) cur).var == 0) {
int varIndex = ((VarInsnNode) cur).var;
if (varIndex == 0 || nodeRemapper.processNonAload0FieldAccessChains(getLambdaIfExists(varIndex) != null)) {
List<AbstractInsnNode> accessChain = getCapturedFieldAccessChain((VarInsnNode) cur);
AbstractInsnNode insnNode = nodeRemapper.foldFieldAccessChainIfNeeded(accessChain, node);
if (insnNode != null) {
@@ -31,19 +31,22 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
private final String newOwnerType;
private final Parameters parameters;
private final Map<String, LambdaInfo> recapturedLambdas;
private final boolean isConstructor;
public RegeneratedLambdaFieldRemapper(
String oldOwnerType,
String newOwnerType,
Parameters parameters,
Map<String, LambdaInfo> recapturedLambdas,
FieldRemapper remapper
FieldRemapper remapper,
boolean isConstructor
) {
super(oldOwnerType, remapper, parameters);
this.oldOwnerType = oldOwnerType;
this.newOwnerType = newOwnerType;
this.parameters = parameters;
this.recapturedLambdas = recapturedLambdas;
this.isConstructor = isConstructor;
}
@Override
@@ -66,6 +69,11 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
}
}
@Override
public boolean processNonAload0FieldAccessChains(boolean isInlinedLambda) {
return isInlinedLambda && isConstructor;
}
@Nullable
public CapturedParamInfo findFieldInMyCaptured(@NotNull FieldInsnNode fieldInsnNode) {
return super.findField(fieldInsnNode, parameters.getCaptured());