Move object initialization from <init> to <clinit>
Codegen generates static backing fields for object properties. They are initialized in class constructor but some of them are final static and such access is prohibited in specification but it's allowed in java bytecode <= 1.8. Such access in 1.9 bytecode cause "IllegalAccessError: Update to static final field Object.INSTANCE attempted from a different method (<init>) than the initializer method <clinit>" Added additional hidden field in interface companion to pass out companion instance from <clinit>. #KT-15894 Fixed
This commit is contained in:
committed by
Ilya Gorbunov
parent
de004337a2
commit
b73be50e5b
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.util.capitalizeDecapitalize.CapitalizeDecapitalizeKt
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isClassOrEnumClass;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
|
||||
|
||||
public final class JvmAbi {
|
||||
public static final String DEFAULT_IMPLS_CLASS_NAME = "DefaultImpls";
|
||||
@@ -54,6 +55,7 @@ public final class JvmAbi {
|
||||
private static final String ANNOTATED_TYPEALIAS_METHOD_NAME_SUFFIX = ANNOTATIONS_SUFFIX;
|
||||
|
||||
public static final String INSTANCE_FIELD = "INSTANCE";
|
||||
public static final String HIDDEN_INSTANCE_FIELD = "$$" + INSTANCE_FIELD;
|
||||
|
||||
public static final String DEFAULT_MODULE_NAME = "main";
|
||||
public static final ClassId REFLECTION_FACTORY_IMPL = ClassId.topLevel(new FqName("kotlin.reflect.jvm.internal.ReflectionFactoryImpl"));
|
||||
@@ -110,6 +112,16 @@ public final class JvmAbi {
|
||||
public static boolean isCompanionObjectWithBackingFieldsInOuter(@NotNull DeclarationDescriptor companionObject) {
|
||||
return isCompanionObject(companionObject) &&
|
||||
isClassOrEnumClass(companionObject.getContainingDeclaration()) &&
|
||||
!CompanionObjectMapping.INSTANCE.isMappedIntrinsicCompanionObject((ClassDescriptor) companionObject);
|
||||
!isMappedIntrinsicCompanionObject((ClassDescriptor) companionObject);
|
||||
}
|
||||
|
||||
public static boolean isMappedIntrinsicCompanionObject(@NotNull ClassDescriptor companionObject) {
|
||||
return CompanionObjectMapping.INSTANCE.isMappedIntrinsicCompanionObject(companionObject);
|
||||
}
|
||||
|
||||
public static boolean isCompanionObjectInInterfaceNotIntrinsic(@NotNull DeclarationDescriptor companionObject) {
|
||||
return isCompanionObject(companionObject) &&
|
||||
isInterface(companionObject.getContainingDeclaration()) &&
|
||||
!isMappedIntrinsicCompanionObject((ClassDescriptor) companionObject);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user