Move all coroutine-related declarations from built-ins to stdlib

Also move internal declarations from runtime.jvm module into new package
kotlin.coroutines.jvm.internal in stdlib

The necessity of these declarations being in built-ins is controversial,
but also it will complicate the migration of current coroutine runtime
to a separate jar if we ever need this
This commit is contained in:
Denis Zharkov
2017-01-26 12:24:02 +03:00
parent b61c152b4e
commit 0e132b9857
32 changed files with 212 additions and 150 deletions
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
import org.jetbrains.kotlin.codegen.context.ClosureContext;
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
@@ -429,7 +430,8 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
iv.load(0, superClassAsmType);
String superClassConstructorDescriptor;
if (superClassAsmType.equals(LAMBDA) || superClassAsmType.equals(FUNCTION_REFERENCE) || superClassAsmType.equals(COROUTINE_IMPL)) {
if (superClassAsmType.equals(LAMBDA) || superClassAsmType.equals(FUNCTION_REFERENCE) ||
superClassAsmType.equals(CoroutineCodegenUtilKt.COROUTINE_IMPL_ASM_TYPE)) {
int arity = calculateArity();
iv.iconst(arity);
if (shouldHaveBoundReferenceReceiver) {
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.MutableClassDescriptor
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.isBuiltinWithSpecialDescriptorInJvm
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
@@ -17,11 +17,13 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.builtins.createFunctionType
import org.jetbrains.kotlin.codegen.coroutines.COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME
import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView
import org.jetbrains.kotlin.coroutines.isSuspendLambda
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.descriptors.impl.MutableClassDescriptor
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -31,6 +33,8 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
class JvmRuntimeTypes(module: ModuleDescriptor) {
private val kotlinJvmInternalPackage = MutablePackageFragmentDescriptor(module, FqName("kotlin.jvm.internal"))
private val kotlinCoroutinesJvmInternalPackage =
MutablePackageFragmentDescriptor(module, COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME)
private fun klass(name: String) = lazy { createClass(kotlinJvmInternalPackage, name) }
@@ -38,7 +42,7 @@ class JvmRuntimeTypes(module: ModuleDescriptor) {
private val functionReference: ClassDescriptor by klass("FunctionReference")
private val localVariableReference: ClassDescriptor by klass("LocalVariableReference")
private val mutableLocalVariableReference: ClassDescriptor by klass("MutableLocalVariableReference")
private val coroutineImplClass by klass("CoroutineImpl")
private val coroutineImplClass by lazy { createClass(kotlinCoroutinesJvmInternalPackage, "CoroutineImpl") }
private val propertyReferences: List<ClassDescriptor> by lazy {
(0..2).map { i -> createClass(kotlinJvmInternalPackage, "PropertyReference$i") }
@@ -1,194 +0,0 @@
/*
* 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;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase;
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorImpl;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
import org.jetbrains.kotlin.types.ClassTypeConstructorImpl;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeConstructor;
import org.jetbrains.kotlin.types.TypeUtils;
import java.util.*;
public class MutableClassDescriptor extends ClassDescriptorBase {
private final ClassKind kind;
private final boolean isInner;
private Modality modality;
private Visibility visibility;
private TypeConstructor typeConstructor;
private List<TypeParameterDescriptor> typeParameters;
private final Collection<KotlinType> supertypes = new ArrayList<KotlinType>();
public MutableClassDescriptor(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull ClassKind kind,
boolean isInner,
boolean isExternal,
@NotNull Name name,
@NotNull SourceElement source
) {
super(LockBasedStorageManager.NO_LOCKS, containingDeclaration, name, source, isExternal);
assert kind != ClassKind.OBJECT : "Fix isCompanionObject()";
this.kind = kind;
this.isInner = isInner;
}
@Nullable
@Override
public ClassDescriptor getCompanionObjectDescriptor() {
return null;
}
@NotNull
@Override
public Annotations getAnnotations() {
return Annotations.Companion.getEMPTY();
}
public void setModality(@NotNull Modality modality) {
assert modality != Modality.SEALED : "Implement getSealedSubclasses() for this class: " + getClass();
this.modality = modality;
}
@Override
@NotNull
public Modality getModality() {
return modality;
}
@NotNull
@Override
public ClassKind getKind() {
return kind;
}
public void setVisibility(@NotNull Visibility visibility) {
this.visibility = visibility;
}
@NotNull
@Override
public Visibility getVisibility() {
return visibility;
}
@Override
public boolean isInner() {
return isInner;
}
@Override
public boolean isData() {
return false;
}
@Override
public boolean isCompanionObject() {
return false;
}
@Override
public boolean isHeader() {
return false;
}
@Override
public boolean isImpl() {
return false;
}
@NotNull
@Override
public TypeConstructor getTypeConstructor() {
return typeConstructor;
}
public void addSupertype(@NotNull KotlinType supertype) {
assert !supertype.isError() : "Error types must be filtered out in DescriptorResolver";
if (TypeUtils.getClassDescriptor(supertype) != null) {
// See the Errors.SUPERTYPE_NOT_A_CLASS_OR_INTERFACE
supertypes.add(supertype);
}
}
@NotNull
@Override
public Set<ClassConstructorDescriptor> getConstructors() {
return Collections.emptySet();
}
@Override
@Nullable
public ClassConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
return null;
}
public void setTypeParameterDescriptors(@NotNull List<TypeParameterDescriptor> typeParameters) {
if (this.typeParameters != null) {
throw new IllegalStateException("Type parameters are already set for " + getName());
}
this.typeParameters = new ArrayList<TypeParameterDescriptor>(typeParameters);
}
@NotNull
@Override
public List<TypeParameterDescriptor> getDeclaredTypeParameters() {
return typeParameters;
}
public void createTypeConstructor() {
assert typeConstructor == null : typeConstructor;
this.typeConstructor = new ClassTypeConstructorImpl(this, ModalityKt.isFinalClass(this), typeParameters, supertypes);
for (FunctionDescriptor functionDescriptor : getConstructors()) {
((ClassConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType());
}
}
@Override
@NotNull
public MemberScope getUnsubstitutedMemberScope() {
return MemberScope.Empty.INSTANCE; // used for getDefaultType
}
@NotNull
@Override
public MemberScope getStaticScope() {
return MemberScope.Empty.INSTANCE;
}
@NotNull
@Override
public Collection<ClassDescriptor> getSealedSubclasses() {
return Collections.emptyList();
}
@Override
public String toString() {
return DeclarationDescriptorImpl.toString(this);
}
}
@@ -31,6 +31,8 @@ import org.jetbrains.kotlin.diagnostics.rendering.RenderingContext
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtObjectDeclaration
@@ -43,6 +45,7 @@ import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.serialization.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
@@ -339,3 +342,6 @@ fun MemberDescriptor.isToArrayFromCollection(): Boolean {
return isGenericToArray() || isNonGenericToArray()
}
fun FqName.topLevelClassInternalName() = JvmClassName.byClassId(ClassId(parent(), shortName())).internalName
fun FqName.topLevelClassAsmType(): Type = Type.getObjectType(topLevelClassInternalName())
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
@@ -34,6 +35,7 @@ import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtFunctionLiteral
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
@@ -106,11 +108,7 @@ class CoroutineCodegen private constructor(
funDescriptor.createCustomCopy {
setName(Name.identifier(SUSPEND_FUNCTION_CREATE_METHOD_NAME))
setReturnType(
KotlinTypeFactory.simpleNotNullType(
Annotations.EMPTY,
builtIns.continuationClassDescriptor,
listOf(builtIns.unitType.asTypeProjection())
)
funDescriptor.module.getContinuationOfTypeOrAny(builtIns.unitType)
)
setVisibility(Visibilities.PUBLIC)
}
@@ -178,7 +176,7 @@ class CoroutineCodegen private constructor(
v.thisName,
createCoroutineDescriptor.name.identifier,
Type.getMethodDescriptor(
AsmTypes.CONTINUATION,
CONTINUATION_ASM_TYPE,
*parameterTypes.toTypedArray()
),
false
@@ -192,7 +190,7 @@ class CoroutineCodegen private constructor(
override fun generateConstructor(): Method {
val args = calculateConstructorParameters(typeMapper, closure, asmType)
val argTypes = args.map { it.fieldType }.plus(AsmTypes.CONTINUATION).toTypedArray()
val argTypes = args.map { it.fieldType }.plus(CONTINUATION_ASM_TYPE).toTypedArray()
val constructor = Method("<init>", Type.VOID_TYPE, argTypes)
val mv = v.newMethod(
@@ -212,7 +210,7 @@ class CoroutineCodegen private constructor(
iv.iconst(calculateArity())
iv.load(argTypes.map { it.size }.sum(), AsmTypes.OBJECT_TYPE)
val superClassConstructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, AsmTypes.CONTINUATION)
val superClassConstructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, CONTINUATION_ASM_TYPE)
iv.invokespecial(superClassAsmType.internalName, "<init>", superClassConstructorDescriptor, false)
iv.visitInsn(Opcodes.RETURN)
@@ -107,7 +107,7 @@ class CoroutineTransformerMethodVisitor(
VarInsnNode(Opcodes.ALOAD, 0),
FieldInsnNode(
Opcodes.GETFIELD,
AsmTypes.COROUTINE_IMPL.internalName,
COROUTINE_IMPL_ASM_TYPE.internalName,
COROUTINE_LABEL_FIELD_NAME, Type.INT_TYPE.descriptor
),
TableSwitchInsnNode(0,
@@ -303,7 +303,7 @@ class CoroutineTransformerMethodVisitor(
VarInsnNode(Opcodes.ALOAD, 0),
*withInstructionAdapter { iconst(id) }.toArray(),
FieldInsnNode(
Opcodes.PUTFIELD, AsmTypes.COROUTINE_IMPL.internalName, COROUTINE_LABEL_FIELD_NAME,
Opcodes.PUTFIELD, COROUTINE_IMPL_ASM_TYPE.internalName, COROUTINE_LABEL_FIELD_NAME,
Type.INT_TYPE.descriptor
)
)
@@ -17,16 +17,20 @@
package org.jetbrains.kotlin.codegen.coroutines
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.backend.common.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME
import org.jetbrains.kotlin.backend.common.SUSPENDED_MARKER_NAME
import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineOrReturn
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.codegen.topLevelClassAsmType
import org.jetbrains.kotlin.codegen.topLevelClassInternalName
import org.jetbrains.kotlin.coroutines.isSuspendLambda
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
@@ -35,7 +39,9 @@ import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.TypeConstructorSubstitution
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
@@ -58,7 +64,22 @@ const val COROUTINE_LABEL_FIELD_NAME = "label"
const val SUSPEND_FUNCTION_CREATE_METHOD_NAME = "create"
const val DO_RESUME_METHOD_NAME = "doResume"
private val INTERNAL_COROUTINE_INTRINSICS_OWNER = "kotlin/jvm/internal/CoroutineIntrinsics"
@JvmField
val COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME =
DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("jvm")).child(Name.identifier("internal"))
@JvmField
val CONTINUATION_ASM_TYPE = DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME.topLevelClassAsmType()
@JvmField
val COROUTINE_IMPL_ASM_TYPE = COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineImpl")).topLevelClassAsmType()
private val COROUTINES_INTRINSICS_FILE_FACADE_INTERNAL_NAME =
COROUTINES_INTRINSICS_PACKAGE_FQ_NAME.child(Name.identifier("IntrinsicsKt")).topLevelClassAsmType()
private val INTERNAL_COROUTINE_INTRINSICS_OWNER_INTERNAL_NAME =
COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineIntrinsics")).topLevelClassInternalName()
private val NORMALIZE_CONTINUATION_METHOD_NAME = "normalizeContinuation"
data class ResolvedCallWithRealDescriptor(val resolvedCall: ResolvedCall<*>, val fakeContinuationExpression: KtExpression)
@@ -206,10 +227,16 @@ fun <D : FunctionDescriptor> D.createCustomCopy(
}
private fun FunctionDescriptor.getContinuationParameterTypeOfSuspendFunction() =
KotlinTypeFactory.simpleType(
builtIns.continuationClassDescriptor.defaultType,
arguments = listOf(returnType!!.asTypeProjection())
)
module.getContinuationOfTypeOrAny(returnType!!)
fun ModuleDescriptor.getContinuationOfTypeOrAny(kotlinType: KotlinType) =
module.findContinuationClassDescriptorOrNull(NoLookupLocation.FROM_BACKEND)?.defaultType?.let {
KotlinTypeFactory.simpleType(
it,
arguments = listOf(kotlinType.asTypeProjection())
)
} ?: module.builtIns.nullableAnyType
fun FunctionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm() =
getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)?.isBuiltInSuspendCoroutineOrReturn() == true
@@ -235,9 +262,9 @@ fun createMethodNodeForSuspendCoroutineOrReturn(
node.visitMethodInsn(
Opcodes.INVOKESTATIC,
INTERNAL_COROUTINE_INTRINSICS_OWNER,
INTERNAL_COROUTINE_INTRINSICS_OWNER_INTERNAL_NAME,
NORMALIZE_CONTINUATION_METHOD_NAME,
Type.getMethodDescriptor(AsmTypes.CONTINUATION, AsmTypes.CONTINUATION),
Type.getMethodDescriptor(CONTINUATION_ASM_TYPE, CONTINUATION_ASM_TYPE),
false
)
@@ -260,7 +287,7 @@ fun <D : CallableDescriptor?> D.unwrapInitialDescriptorForSuspendFunction(): D =
fun InstructionAdapter.loadSuspendMarker() {
invokestatic(
AsmTypes.COROUTINES_INTRINSICS_FILE_FACADE.internalName,
COROUTINES_INTRINSICS_FILE_FACADE_INTERNAL_NAME.internalName,
"get$SUSPENDED_MARKER_NAME",
Type.getMethodDescriptor(AsmTypes.OBJECT_TYPE),
false
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.codegen.AsmUtil;
import org.jetbrains.kotlin.codegen.ClassBuilder;
import org.jetbrains.kotlin.codegen.FieldInfo;
import org.jetbrains.kotlin.codegen.StackValue;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
@@ -68,7 +68,7 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
InlineCodegenUtil.assertVersionNotGreaterThanGeneratedOne(version, name, inliningContext.state);
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces);
if(AsmTypes.COROUTINE_IMPL.getInternalName().equals(superName)) {
if(CoroutineCodegenUtilKt.COROUTINE_IMPL_ASM_TYPE.getInternalName().equals(superName)) {
inliningContext.setContinuation(true);
}
}