Added InliningLambdaContext
This commit is contained in:
@@ -375,7 +375,7 @@ public class FunctionCodegen {
|
|||||||
functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.isInliningLambda()) {
|
if (context instanceof InlineLambdaContext) {
|
||||||
lambdaFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
lambdaFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,7 +404,7 @@ public class FunctionCodegen {
|
|||||||
functionFakeIndex);
|
functionFakeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.isInliningLambda() && thisType != null && lambdaFakeIndex != -1) {
|
if (context instanceof InlineLambdaContext && thisType != null && lambdaFakeIndex != -1) {
|
||||||
String name = thisType.getClassName();
|
String name = thisType.getClassName();
|
||||||
int indexOfLambdaOrdinal = name.lastIndexOf("$");
|
int indexOfLambdaOrdinal = name.lastIndexOf("$");
|
||||||
if (indexOfLambdaOrdinal > 0) {
|
if (indexOfLambdaOrdinal > 0) {
|
||||||
|
|||||||
@@ -279,7 +279,8 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
|||||||
|
|
||||||
protected void writeOuterClassAndEnclosingMethod() {
|
protected void writeOuterClassAndEnclosingMethod() {
|
||||||
CodegenContext context = this.context.getParentContext();
|
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
|
// If this is a lambda which will be inlined, skip its MethodContext and enclosing ClosureContext
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
context = context.getParentContext().getParentContext();
|
context = context.getParentContext().getParentContext();
|
||||||
|
|||||||
@@ -298,12 +298,12 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public MethodContext intoFunction(FunctionDescriptor descriptor) {
|
public MethodContext intoFunction(FunctionDescriptor descriptor) {
|
||||||
return new MethodContext(descriptor, getContextKind(), this, null, false, false);
|
return new MethodContext(descriptor, getContextKind(), this, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public MethodContext intoInlinedLambda(FunctionDescriptor descriptor, boolean isCrossInline) {
|
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
|
@NotNull
|
||||||
@@ -654,19 +654,6 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public CodegenContext getFirstCrossInlineOrNonInlineContext() {
|
public CodegenContext getFirstCrossInlineOrNonInlineContext() {
|
||||||
if (!(this instanceof MethodContext)) {
|
return this;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class ConstructorContext extends MethodContext {
|
|||||||
@NotNull CodegenContext parent,
|
@NotNull CodegenContext parent,
|
||||||
@Nullable MutableClosure closure
|
@Nullable MutableClosure closure
|
||||||
) {
|
) {
|
||||||
super(contextDescriptor, kind, parent, closure, false, false);
|
super(contextDescriptor, kind, parent, closure);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
|
||||||
public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
|
public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
|
||||||
private final boolean isInliningLambda;
|
|
||||||
private Label methodStartLabel;
|
private Label methodStartLabel;
|
||||||
private Label methodEndLabel;
|
private Label methodEndLabel;
|
||||||
|
|
||||||
// Note: in case of code inside property accessors, functionDescriptor will be that accessor,
|
// Note: in case of code inside property accessors, functionDescriptor will be that accessor,
|
||||||
// but CodegenContext#contextDescriptor will be the corresponding property
|
// but CodegenContext#contextDescriptor will be the corresponding property
|
||||||
private final FunctionDescriptor functionDescriptor;
|
private final FunctionDescriptor functionDescriptor;
|
||||||
public final boolean isCrossInline;
|
|
||||||
|
|
||||||
protected MethodContext(
|
protected MethodContext(
|
||||||
@NotNull FunctionDescriptor functionDescriptor,
|
@NotNull FunctionDescriptor functionDescriptor,
|
||||||
@NotNull OwnerKind contextKind,
|
@NotNull OwnerKind contextKind,
|
||||||
@NotNull CodegenContext parentContext,
|
@NotNull CodegenContext parentContext,
|
||||||
@Nullable MutableClosure closure,
|
@Nullable MutableClosure closure
|
||||||
boolean isInliningLambda,
|
|
||||||
boolean isCrossInline
|
|
||||||
) {
|
) {
|
||||||
super(JvmCodegenUtil.getDirectMember(functionDescriptor), contextKind, parentContext, closure,
|
super(JvmCodegenUtil.getDirectMember(functionDescriptor), contextKind, parentContext, closure,
|
||||||
parentContext.hasThisDescriptor() ? parentContext.getThisDescriptor() : null, null);
|
parentContext.hasThisDescriptor() ? parentContext.getThisDescriptor() : null, null);
|
||||||
this.isInliningLambda = isInliningLambda;
|
|
||||||
this.functionDescriptor = functionDescriptor;
|
this.functionDescriptor = functionDescriptor;
|
||||||
this.isCrossInline = isCrossInline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -124,10 +118,6 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
|
|||||||
return InlineUtil.isInline(getContextDescriptor());
|
return InlineUtil.isInline(getContextDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInliningLambda() {
|
|
||||||
return isInliningLambda;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public FunctionDescriptor getFunctionDescriptor() {
|
public FunctionDescriptor getFunctionDescriptor() {
|
||||||
return functionDescriptor;
|
return functionDescriptor;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.codegen.MemberCodegen;
|
|||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||||
import org.jetbrains.kotlin.codegen.context.CodegenContextUtil;
|
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.context.MethodContext;
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.UtilKt;
|
import org.jetbrains.kotlin.codegen.optimization.common.UtilKt;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
@@ -398,7 +399,7 @@ public class InlineCodegenUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isFinallyMarkerRequired(@NotNull MethodContext context) {
|
public static boolean isFinallyMarkerRequired(@NotNull MethodContext context) {
|
||||||
return context.isInlineMethodContext() || context.isInliningLambda();
|
return context.isInlineMethodContext() || context instanceof InlineLambdaContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getConstant(AbstractInsnNode ins) {
|
public static int getConstant(AbstractInsnNode ins) {
|
||||||
|
|||||||
Reference in New Issue
Block a user