From 27ed0984673e5341c0fdc91fbac6ef705dac9cdb Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 20 May 2015 17:40:45 +0300 Subject: [PATCH] Introduce kotlin.jvm.internal.Lambda, superclass for all lambdas It has its arity precomputed, as opposed to the future KFunctionImpl inheriting from FunctionImpl, for which the computation of arity can take some time and so it shouldn't be passed in the constructor and saved as a field --- .../kotlin/codegen/ClosureCodegen.java | 10 +++++++- .../kotlin/codegen/JvmRuntimeTypes.java | 6 ++--- .../kotlin/resolve/jvm/AsmTypes.java | 2 ++ .../reflect/jvm/internal/KFunctionImpl.kt | 2 +- .../src/kotlin/jvm/internal/Lambda.kt | 23 +++++++++++++++++++ 5 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 core/runtime.jvm/src/kotlin/jvm/internal/Lambda.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java index d914a54d45a..22b86bbe97c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.psi.JetElement; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.DescriptorUtils; +import org.jetbrains.kotlin.resolve.jvm.AsmTypes; import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.expressions.OperatorConventions; import org.jetbrains.org.objectweb.asm.MethodVisitor; @@ -306,7 +307,14 @@ public class ClosureCodegen extends MemberCodegen { } iv.load(0, superClassAsmType); - iv.invokespecial(superClassAsmType.getInternalName(), "", "()V", false); + + if (superClassAsmType.equals(AsmTypes.LAMBDA)) { + iv.iconst(funDescriptor.getValueParameters().size()); + iv.invokespecial(superClassAsmType.getInternalName(), "", "(I)V", false); + } + else { + iv.invokespecial(superClassAsmType.getInternalName(), "", "()V", false); + } iv.visitInsn(RETURN); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.java index 8af56a136c8..83e2b343e0a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.java @@ -39,6 +39,7 @@ import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage. public class JvmRuntimeTypes { private final ReflectionTypes reflectionTypes; + private final ClassDescriptor lambda; private final ClassDescriptor functionImpl; private final ClassDescriptor memberFunctionImpl; private final ClassDescriptor extensionFunctionImpl; @@ -53,6 +54,7 @@ public class JvmRuntimeTypes { ); PackageFragmentDescriptor kotlinJvmInternal = new MutablePackageFragmentDescriptor(module, new FqName("kotlin.jvm.internal")); + this.lambda = createClass(kotlinJvmInternal, "Lambda"); this.functionImpl = createClass(kotlinJvmInternal, "FunctionImpl"); this.memberFunctionImpl = createClass(kotlinJvmInternal, "MemberFunctionImpl"); this.extensionFunctionImpl = createClass(kotlinJvmInternal, "ExtensionFunctionImpl"); @@ -76,8 +78,6 @@ public class JvmRuntimeTypes { public Collection getSupertypesForClosure(@NotNull FunctionDescriptor descriptor) { ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter(); - ClassDescriptor functionImplClass = receiverParameter != null ? extensionFunctionImpl : functionImpl; - //noinspection ConstantConditions JetType functionType = getBuiltIns(descriptor).getFunctionType( Annotations.EMPTY, @@ -86,7 +86,7 @@ public class JvmRuntimeTypes { descriptor.getReturnType() ); - return Arrays.asList(functionImplClass.getDefaultType(), functionType); + return Arrays.asList(lambda.getDefaultType(), functionType); } @NotNull diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/AsmTypes.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/AsmTypes.java index 99bdaacfe65..891973af0c1 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/AsmTypes.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/AsmTypes.java @@ -34,6 +34,8 @@ public class AsmTypes { public static final Type PROPERTY_METADATA_TYPE = Type.getObjectType("kotlin/PropertyMetadata"); public static final Type PROPERTY_METADATA_IMPL_TYPE = Type.getObjectType("kotlin/PropertyMetadataImpl"); + public static final Type LAMBDA = Type.getObjectType("kotlin/jvm/internal/Lambda"); + public static final Type K_CLASS_TYPE = reflect("KClass"); public static final Type K_CLASS_ARRAY_TYPE = Type.getObjectType("[" + K_CLASS_TYPE.getDescriptor()); public static final Type K_PACKAGE_TYPE = reflect("KPackage"); diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt index 563a4cab4a8..33ea57638c5 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt @@ -21,4 +21,4 @@ import kotlin.jvm.internal.FunctionImpl /** * @suppress */ -public abstract class KFunctionImpl : FunctionImpl() +public abstract class KFunctionImpl : FunctionImpl() diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/Lambda.kt b/core/runtime.jvm/src/kotlin/jvm/internal/Lambda.kt new file mode 100644 index 00000000000..59e857a5b10 --- /dev/null +++ b/core/runtime.jvm/src/kotlin/jvm/internal/Lambda.kt @@ -0,0 +1,23 @@ +/* + * 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 kotlin.jvm.internal + +public abstract class Lambda(private val arity: Int) : FunctionImpl() { + override fun getArity() = arity + + override fun toString() = "${(this as Object).getClass().getGenericInterfaces()[0]}" +}