Added InliningLambdaContext
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -279,7 +279,8 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
|
||||
protected void writeOuterClassAndEnclosingMethod() {
|
||||
CodegenContext context = this.context.getParentContext();
|
||||
while (context instanceof MethodContext && ((MethodContext) context).isInliningLambda()) {
|
||||
|
||||
while (context instanceof InlineLambdaContext) {
|
||||
// If this is a lambda which will be inlined, skip its MethodContext and enclosing ClosureContext
|
||||
//noinspection ConstantConditions
|
||||
context = context.getParentContext().getParentContext();
|
||||
|
||||
@@ -298,12 +298,12 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
|
||||
@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<T extends DeclarationDescriptor> {
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,28 +32,22 @@ import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
|
||||
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<CallableMemberDescriptor> {
|
||||
return InlineUtil.isInline(getContextDescriptor());
|
||||
}
|
||||
|
||||
public boolean isInliningLambda() {
|
||||
return isInliningLambda;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FunctionDescriptor getFunctionDescriptor() {
|
||||
return functionDescriptor;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user