diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 36b145e24f1..da4b4137101 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -375,7 +375,7 @@ public class FunctionCodegen { functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE); } - if (context.isInliningLambda()) { + if (context instanceof InlineLambdaContext) { lambdaFakeIndex = frameMap.enterTemp(Type.INT_TYPE); } @@ -404,7 +404,7 @@ public class FunctionCodegen { functionFakeIndex); } - if (context.isInliningLambda() && thisType != null && lambdaFakeIndex != -1) { + if (context instanceof InlineLambdaContext && thisType != null && lambdaFakeIndex != -1) { String name = thisType.getClassName(); int indexOfLambdaOrdinal = name.lastIndexOf("$"); if (indexOfLambdaOrdinal > 0) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 461d0dabef3..d925d1a088e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -279,7 +279,8 @@ public abstract class MemberCodegen { @NotNull public MethodContext intoFunction(FunctionDescriptor descriptor) { - return new MethodContext(descriptor, getContextKind(), this, null, false, false); + return new MethodContext(descriptor, getContextKind(), this, null); } @NotNull public MethodContext intoInlinedLambda(FunctionDescriptor descriptor, boolean isCrossInline) { - return new MethodContext(descriptor, getContextKind(), this, null, true, isCrossInline); + return new InlineLambdaContext(descriptor, getContextKind(), this, null, isCrossInline); } @NotNull @@ -654,19 +654,6 @@ public abstract class CodegenContext { @NotNull public CodegenContext getFirstCrossInlineOrNonInlineContext() { - if (!(this instanceof MethodContext)) { - return this; - } - MethodContext context = (MethodContext) this; - if (!context.isInliningLambda() || context.isCrossInline) { - return this; - } - - CodegenContext parent = context.getParentContext(); - assert parent instanceof ClosureContext : "Parent of inlining lambda body should be ClosureContext, but: " + parent; - - parent = parent.getParentContext(); - assert parent != null : "Parent context of lambda class context should exist: " + this.contextDescriptor; - return parent.getFirstCrossInlineOrNonInlineContext(); + return this; } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/ConstructorContext.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/ConstructorContext.java index a1ece08d674..8d34ab09276 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/ConstructorContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/ConstructorContext.java @@ -34,7 +34,7 @@ public class ConstructorContext extends MethodContext { @NotNull CodegenContext parent, @Nullable MutableClosure closure ) { - super(contextDescriptor, kind, parent, closure, false, false); + super(contextDescriptor, kind, parent, closure); } @Override diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/InlineLambdaContext.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/InlineLambdaContext.kt new file mode 100644 index 00000000000..7f644b86338 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/InlineLambdaContext.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.codegen.context + +import org.jetbrains.kotlin.codegen.OwnerKind +import org.jetbrains.kotlin.codegen.binding.MutableClosure +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor + +class InlineLambdaContext( + functionDescriptor: FunctionDescriptor, + contextKind: OwnerKind, + parentContext: CodegenContext<*>, + closure: MutableClosure?, + val isCrossInline: Boolean +) : MethodContext(functionDescriptor, contextKind, parentContext, closure) { + + override fun getFirstCrossInlineOrNonInlineContext(): CodegenContext<*> { + if (isCrossInline) return this + + val parent = parentContext as? ClosureContext ?: + throw AssertionError("Parent of inlining lambda body should be ClosureContext, but: $parentContext") + + val grandParent = parent.parentContext ?: + throw AssertionError("Parent context of lambda class context should exist: $contextDescriptor") + return grandParent.firstCrossInlineOrNonInlineContext + } + +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/MethodContext.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/MethodContext.java index f6a4c8a233c..c67353948ba 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/MethodContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/MethodContext.java @@ -32,28 +32,22 @@ import org.jetbrains.org.objectweb.asm.Label; import org.jetbrains.org.objectweb.asm.Type; public class MethodContext extends CodegenContext { - private final boolean isInliningLambda; private Label methodStartLabel; private Label methodEndLabel; // Note: in case of code inside property accessors, functionDescriptor will be that accessor, // but CodegenContext#contextDescriptor will be the corresponding property private final FunctionDescriptor functionDescriptor; - public final boolean isCrossInline; protected MethodContext( @NotNull FunctionDescriptor functionDescriptor, @NotNull OwnerKind contextKind, @NotNull CodegenContext parentContext, - @Nullable MutableClosure closure, - boolean isInliningLambda, - boolean isCrossInline + @Nullable MutableClosure closure ) { super(JvmCodegenUtil.getDirectMember(functionDescriptor), contextKind, parentContext, closure, parentContext.hasThisDescriptor() ? parentContext.getThisDescriptor() : null, null); - this.isInliningLambda = isInliningLambda; this.functionDescriptor = functionDescriptor; - this.isCrossInline = isCrossInline; } @NotNull @@ -124,10 +118,6 @@ public class MethodContext extends CodegenContext { return InlineUtil.isInline(getContextDescriptor()); } - public boolean isInliningLambda() { - return isInliningLambda; - } - @NotNull public FunctionDescriptor getFunctionDescriptor() { return functionDescriptor; diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java index 753cde3f09e..30bc4c6a57a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.codegen.MemberCodegen; import org.jetbrains.kotlin.codegen.binding.CodegenBinding; import org.jetbrains.kotlin.codegen.context.CodegenContext; import org.jetbrains.kotlin.codegen.context.CodegenContextUtil; +import org.jetbrains.kotlin.codegen.context.InlineLambdaContext; import org.jetbrains.kotlin.codegen.context.MethodContext; import org.jetbrains.kotlin.codegen.optimization.common.UtilKt; import org.jetbrains.kotlin.codegen.state.GenerationState; @@ -398,7 +399,7 @@ public class InlineCodegenUtil { } public static boolean isFinallyMarkerRequired(@NotNull MethodContext context) { - return context.isInlineMethodContext() || context.isInliningLambda(); + return context.isInlineMethodContext() || context instanceof InlineLambdaContext; } public static int getConstant(AbstractInsnNode ins) {