diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/FieldRemapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/FieldRemapper.java index 2071017ef1d..43d0c462b78 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/FieldRemapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/FieldRemapper.java @@ -41,8 +41,10 @@ public class FieldRemapper { params = methodParams; } - public boolean canProcess(@NotNull String fieldOwner, boolean isFolding) { - return fieldOwner.equals(getLambdaInternalName()); + protected boolean canProcess(@NotNull String fieldOwner, String fieldName, boolean isFolding) { + return fieldOwner.equals(getLambdaInternalName()) && + //don't process general field of anonymous objects + InlineCodegenUtil.isCapturedFieldName(fieldName); } @Nullable @@ -73,7 +75,7 @@ public class FieldRemapper { if (transformed == null) { //if parent couldn't transform FieldInsnNode insnNode = (FieldInsnNode) capturedFieldAccess.get(currentInstruction); - if (canProcess(insnNode.owner, true)) { + if (canProcess(insnNode.owner, insnNode.name, true)) { insnNode.name = "$$$" + insnNode.name; insnNode.setOpcode(Opcodes.GETSTATIC); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegenUtil.java index 39ba14ea618..cc9bd7f65fd 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegenUtil.java @@ -56,6 +56,12 @@ public class InlineCodegenUtil { public static final String INVOKE = "invoke"; public static final boolean DEFAULT_INLINE_FLAG = true; + public static final String CAPTURED_FIELD_PREFIX = "$"; + + public static final String THIS$0 = "this$0"; + + public static final String RECEIVER$0 = "receiver$0"; + @Nullable public static MethodNode getMethodNode( InputStream classData, @@ -259,4 +265,8 @@ public class InlineCodegenUtil { return true; } + + public static boolean isCapturedFieldName(@NotNull String fieldName) { + return fieldName.startsWith(CAPTURED_FIELD_PREFIX) || THIS$0.equals(fieldName) || RECEIVER$0.equals(fieldName); + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlinedLambdaRemapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlinedLambdaRemapper.java index 68a56869de4..5440e72f578 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlinedLambdaRemapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlinedLambdaRemapper.java @@ -34,8 +34,8 @@ public class InlinedLambdaRemapper extends FieldRemapper { @Override - public boolean canProcess(@NotNull String fieldOwner, boolean isFolding) { - return isFolding ? super.canProcess(fieldOwner, isFolding) : false; + public boolean canProcess(@NotNull String fieldOwner, String fieldName, boolean isFolding) { + return isFolding ? super.canProcess(fieldOwner, fieldName, isFolding) : false; } @Override diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaTransformer.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaTransformer.java index bb1bf8736cb..98350d56204 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaTransformer.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaTransformer.java @@ -244,7 +244,7 @@ public class LambdaTransformer { AbstractInsnNode cur = constructor.instructions.getFirst(); //load captured parameters (NB: there is also could be object fields) while (cur != null) { - if (cur.getType() == AbstractInsnNode.FIELD_INSN) { + if (cur instanceof FieldInsnNode && cur.getOpcode() == Opcodes.PUTFIELD && InlineCodegenUtil.isCapturedFieldName(((FieldInsnNode) cur).name)) { FieldInsnNode fieldNode = (FieldInsnNode) cur; CapturedParamInfo info = builder.addCapturedParam(owner, fieldNode.name, Type.getType(fieldNode.desc), false, null); @@ -290,7 +290,7 @@ public class LambdaTransformer { @NotNull public String getNewFieldName(@NotNull String oldName) { - if (oldName.equals("this$0")) { + if (InlineCodegenUtil.THIS$0.equals(oldName)) { //"this$0" couldn't clash and we should keep this name invariant for further transformations return oldName; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/RegeneratedLambdaFieldRemapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/RegeneratedLambdaFieldRemapper.java index 4dcc8725368..696ab74dcec 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/RegeneratedLambdaFieldRemapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/RegeneratedLambdaFieldRemapper.java @@ -51,8 +51,8 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper { } @Override - public boolean canProcess(@NotNull String fieldOwner, boolean isFolding) { - return super.canProcess(fieldOwner, isFolding) || isRecapturedLambdaType(fieldOwner); + public boolean canProcess(@NotNull String fieldOwner, String fieldName, boolean isFolding) { + return super.canProcess(fieldOwner, fieldName, isFolding) || isRecapturedLambdaType(fieldOwner); } private boolean isRecapturedLambdaType(String owner) { @@ -62,7 +62,7 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper { @Nullable @Override public CapturedParamInfo findField(@NotNull FieldInsnNode fieldInsnNode, @NotNull Collection captured) { - boolean searchInParent = !canProcess(fieldInsnNode.owner, false); + boolean searchInParent = !canProcess(fieldInsnNode.owner, fieldInsnNode.name, false); if (searchInParent) { return parent.findField(fieldInsnNode); } else { @@ -87,7 +87,7 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper { field = findFieldInMyCaptured(new FieldInsnNode(Opcodes.GETSTATIC, oldOwnerType, "this$0", Type.getObjectType(parent.getLambdaInternalName()).getDescriptor())); searchInParent = true; if (field == null) { - throw new IllegalStateException("Could find captured this " + getLambdaInternalName()); + throw new IllegalStateException("Couldn't find captured this " + getLambdaInternalName() + " for " + node.name); } }