Generate special bridges for builtins with same name but different JVM descriptor

This commit is contained in:
Denis Zharkov
2015-10-15 21:00:49 +03:00
parent 07d8754adb
commit d335f71dfe
5 changed files with 52 additions and 7 deletions
@@ -516,7 +516,7 @@ public class FunctionCodegen {
// If the function doesn't have a physical declaration among super-functions, it's a SAM adapter or alike and doesn't need bridges
if (CallResolverUtilKt.isOrOverridesSynthesized(descriptor)) return;
boolean isSpecial = SpecialBuiltinMembers.doesOverrideBuiltinWithDifferentJvmName(descriptor);
boolean isSpecial = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(descriptor) != null;
Set<Bridge<Method>> bridgesToGenerate;
if (!isSpecial) {
@@ -560,7 +560,7 @@ public class FunctionCodegen {
}
if (!descriptor.getKind().isReal() && isAbstractMethod(descriptor, OwnerKind.IMPLEMENTATION)) {
CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmName(descriptor);
CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(descriptor);
assert overridden != null;
Method method = typeMapper.mapSignature(descriptor).getAsmMethod();
@@ -852,6 +852,8 @@ public class FunctionCodegen {
assert descriptor.getValueParameters().size() == 1 : "Should be descriptor with one value parameter, but found: " + descriptor;
if (bridge.getArgumentTypes()[0].getSort() != Type.OBJECT) return;
iv.load(1, OBJECT_TYPE);
JetType jetType = descriptor.getValueParameters().get(0).getType();
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.backend.common.bridges.*
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.load.java.getOverriddenBuiltinWithDifferentJvmName
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.getOverriddenBuiltinWithDifferentJvmDescriptor
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
@@ -41,16 +41,18 @@ object BuiltinSpecialBridgesUtil {
val functionHandle = DescriptorBasedFunctionHandle(function)
val fake = !functionHandle.isDeclaration
val overriddenBuiltin = function.getOverriddenBuiltinWithDifferentJvmName()!!
val overriddenBuiltin = function.getOverriddenBuiltinWithDifferentJvmDescriptor()!!
val reachableDeclarations = findAllReachableDeclarations(function)
val needGenerateSpecialBridge = needGenerateSpecialBridge(function, reachableDeclarations, overriddenBuiltin)
// e.g. `getSize()I`
val methodItself = signatureByDescriptor(function)
// e.g. `size()I`
val overriddenBuiltinSignature = signatureByDescriptor(overriddenBuiltin)
val needGenerateSpecialBridge = needGenerateSpecialBridge(function, reachableDeclarations, overriddenBuiltin)
&& methodItself != overriddenBuiltinSignature
val specialBridge = if (needGenerateSpecialBridge)
BridgeForBuiltinSpecial(overriddenBuiltinSignature, methodItself, isSpecial = true)
else null
@@ -3,6 +3,7 @@
public method contains(p0: java.lang.Object): boolean
public method containsAll(@org.jetbrains.annotations.NotNull p0: java.util.Collection): boolean
public abstract method getSize(): int
public abstract method remove(p0: java.lang.Object): boolean
public final method size(): int
public method toArray(): java.lang.Object[]
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
@@ -14,6 +15,8 @@
public final method contains(p0: java.lang.Object): boolean
public method containsAll(@org.jetbrains.annotations.NotNull p0: java.util.Collection): boolean
public abstract method getSize(): int
public final method remove(p0: java.lang.Object): boolean
public abstract method remove(p0: java.lang.String): boolean
public final method size(): int
public method toArray(): java.lang.Object[]
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
@@ -21,8 +24,12 @@
@kotlin.jvm.internal.KotlinClass A3 {
public method <init>(): void
public synthetic method contains(p0: java.lang.Object): boolean
public abstract method getSize(): int
public synthetic method indexOf(p0: java.lang.Object): int
public synthetic method lastIndexOf(p0: java.lang.Object): int
public final method remove(p0: int): java.lang.Object
public synthetic method remove(p0: java.lang.Object): boolean
public synthetic method removeAt(p0: int): java.lang.Object
public final method size(): int
}
@@ -32,15 +39,26 @@
public method contains(p0: java.lang.Object): boolean
public method containsAll(@org.jetbrains.annotations.NotNull p0: java.util.Collection): boolean
public abstract method getSize(): int
public synthetic method indexOf(p0: java.lang.Object): int
public synthetic method lastIndexOf(p0: java.lang.Object): int
public final method remove(p0: int): java.lang.Object
public synthetic method remove(p0: java.lang.Object): boolean
public synthetic method removeAt(p0: int): java.lang.Object
public final method size(): int
}
@kotlin.jvm.internal.KotlinClass A5 {
public method <init>(): void
public final method contains(p0: java.lang.Object): boolean
public synthetic method contains(p0: java.lang.String): boolean
public abstract method getSize(): int
public final method indexOf(p0: java.lang.Object): int
public synthetic method indexOf(p0: java.lang.String): int
public final method lastIndexOf(p0: java.lang.Object): int
public synthetic method lastIndexOf(p0: java.lang.String): int
public final method remove(p0: int): java.lang.String
public final method remove(p0: java.lang.Object): boolean
public synthetic method remove(p0: java.lang.String): boolean
public synthetic method removeAt(p0: int): java.lang.String
public final method size(): int
}
@@ -51,7 +69,13 @@
public final method contains(p0: java.lang.Object): boolean
public method containsAll(@org.jetbrains.annotations.NotNull p0: java.util.Collection): boolean
public abstract method getSize(): int
public final method indexOf(p0: java.lang.Object): int
public synthetic method indexOf(p0: java.lang.String): int
public final method lastIndexOf(p0: java.lang.Object): int
public synthetic method lastIndexOf(p0: java.lang.String): int
public final method remove(p0: int): java.lang.String
public final method remove(p0: java.lang.Object): boolean
public synthetic method remove(p0: java.lang.String): boolean
public synthetic method removeAt(p0: int): java.lang.String
public final method size(): int
}
@@ -61,6 +85,8 @@
public method contains(p0: int): boolean
public final method contains(p0: java.lang.Object): boolean
public abstract method getSize(): int
public abstract method remove(p0: java.lang.Integer): boolean
public final method remove(p0: java.lang.Object): boolean
public final method size(): int
public method toArray(): java.lang.Object[]
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
@@ -70,6 +96,7 @@
public method <init>(): void
public method contains(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public abstract method getSize(): int
public abstract method remove(p0: java.lang.Object): boolean
public final method size(): int
public method toArray(): java.lang.Object[]
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
@@ -101,7 +101,7 @@ fun foo(
// 0 signature \(TW;\)Z
// 0 signature \(TR;\)Z
// 6 signature \(Ljava/util/Collection<\+Ljava/lang/Object;>;\)Z
// 3 public final bridge contains\(Ljava/lang/Object;\)Z
// 4 public final bridge contains\(Ljava/lang/Object;\)Z
// 4 INVOKEVIRTUAL A[0-9]\.contains \(Ljava/lang/String;\)Z
// 4 INVOKEVIRTUAL A[0-9]\.contains \(Ljava/lang/Object;\)Z
// 2 INVOKEVIRTUAL A7\.contains \(I\)Z
@@ -29,6 +29,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.addToStdlib.check
import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties.getBuiltinSpecialPropertyGetterName
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.sameAsBuiltinMethodWithErasedValueParameters
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
object BuiltinSpecialProperties {
@@ -47,7 +49,7 @@ object BuiltinSpecialProperties {
PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP.getInversedShortNamesMap()
private val FQ_NAMES = PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP.keySet()
private val SHORT_NAMES = FQ_NAMES.map { it.shortName() }.toSet()
internal val SHORT_NAMES = FQ_NAMES.map { it.shortName() }.toSet()
fun hasBuiltinSpecialPropertyFqName(callableMemberDescriptor: CallableMemberDescriptor): Boolean {
if (callableMemberDescriptor.name !in SHORT_NAMES) return false
@@ -183,6 +185,18 @@ fun <T : CallableMemberDescriptor> T.getOverriddenBuiltinWithDifferentJvmName():
fun CallableMemberDescriptor.doesOverrideBuiltinWithDifferentJvmName(): Boolean = getOverriddenBuiltinWithDifferentJvmName() != null
@Suppress("UNCHECKED_CAST")
fun <T : CallableMemberDescriptor> T.getOverriddenBuiltinWithDifferentJvmDescriptor(): T? {
getOverriddenBuiltinWithDifferentJvmName()?.let { return it }
if (!name.sameAsBuiltinMethodWithErasedValueParameters) return null
return firstOverridden {
it.isFromBuiltins()
&& it.getSpecialSignatureInfo() == BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo.GENERIC_PARAMETER
}?.original as T?
}
fun getJvmMethodNameIfSpecial(callableMemberDescriptor: CallableMemberDescriptor): String? {
val builtinOverridden = getBuiltinOverriddenThatAffectsJvmName(callableMemberDescriptor)?.propertyIfAccessor
?: return null