From accccdfb778846372acac01399c9021d5e24cc48 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 27 Jan 2014 14:25:36 +0400 Subject: [PATCH] Addded inline closure flag --- .../jet/codegen/ExpressionCodegen.java | 3 ++ .../jet/codegen/asm/InlineCodegen.java | 3 +- .../jet/codegen/context/MethodContext.java | 28 +++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index dd773771a05..0d7fef41b36 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1717,6 +1717,9 @@ public class ExpressionCodegen extends JetVisitor implem StackValue value = context.lookupInContext(descriptor, StackValue.local(0, OBJECT_TYPE), state, false); if (value != null) { + if (context.isSpecialStackValue(value) != null) { + return value; + } if (value instanceof StackValue.Composed) { StackValue.Composed composed = (StackValue.Composed) value; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegen.java index fab453b8a3a..a8b4e9d007d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegen.java @@ -212,6 +212,7 @@ public class InlineCodegen implements ParentCodegenAware, Inliner { MethodContext parentContext = codegen.getContext(); MethodContext context = parentContext.intoClosure(descriptor, codegen, typeMapper).intoFunction(descriptor); + context.setInlineClosure(true); JvmMethodSignature jvmMethodSignature = typeMapper.mapSignature(descriptor); Method asmMethod = jvmMethodSignature.getAsmMethod(); @@ -271,7 +272,7 @@ public class InlineCodegen implements ParentCodegenAware, Inliner { boolean shouldPut = false == (stackValue != null && stackValue instanceof StackValue.Local); if (shouldPut) { //we could recapture field of anonymous objects cause they couldn't change - if ((stackValue instanceof StackValue.Extension || stackValue instanceof StackValue.Field) && codegen.getContext().getContextDescriptor() instanceof AnonymousFunctionDescriptor) { + if ((stackValue instanceof StackValue.Composed || stackValue instanceof StackValue.Field) && codegen.getContext().getContextDescriptor() instanceof AnonymousFunctionDescriptor) { if (descriptor != null && !InlineUtil.hasNoinlineAnnotation(descriptor)) { //check type of context return false; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java index 1b53944bef5..890680bd5a9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java @@ -30,6 +30,16 @@ public class MethodContext extends CodegenContext { private Label methodStartLabel; + private boolean isInlineClosure; + + public MethodContext( + @NotNull FunctionDescriptor contextType, + @NotNull OwnerKind contextKind, + @NotNull CodegenContext parentContext + ) { + this(contextType, contextKind, parentContext, null); + } + protected MethodContext( @NotNull FunctionDescriptor contextDescriptor, @NotNull OwnerKind contextKind, @@ -85,4 +95,22 @@ public class MethodContext extends CodegenContext { } return false; } + + public void setInlineClosure(boolean isInlineClosure) { + this.isInlineClosure = isInlineClosure; + } + + public StackValue isSpecialStackValue(StackValue stackValue) { + if (isInlineClosure && stackValue instanceof StackValue.Composed) { + StackValue prefix = ((StackValue.Composed) stackValue).prefix; + StackValue suffix = ((StackValue.Composed) stackValue).suffix; + if (prefix instanceof StackValue.Local && ((StackValue.Local) prefix).index == 0) { + if (suffix instanceof StackValue.Field) { + StackValue.Field field = (StackValue.Field) suffix; + return StackValue.field(field.type, field.owner, field.name, true); + } + } + } + return null; + } }