Add MutableMap.remove(K, V) as built-in declaration

Use PlatformDependent annotation to guarantee it's only be available for JDK8
Also adjust type-safe bridges and mutable collection stubs generation
This commit is contained in:
Denis Zharkov
2016-04-28 09:09:25 +03:00
parent 55c4f875c8
commit d259b91143
41 changed files with 875 additions and 77 deletions
@@ -19,14 +19,16 @@ package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.codegen.state.GenerationState
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.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.isBuiltinWithSpecialDescriptorInJvm
import org.jetbrains.kotlin.load.java.isFromBuiltins
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy
import org.jetbrains.kotlin.resolve.OverrideResolver
import org.jetbrains.kotlin.resolve.OverridingStrategy
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeUniqueAsSequence
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
@@ -80,7 +82,7 @@ class CollectionStubMethodGenerator(
// Bind fake overrides and for each fake override originated from the MutableCollection, save its signature to generate a stub
// or save its descriptor to generate all the needed bridges
for (method in findFakeOverridesForMethodsFromMutableCollection(child, mutableClass)) {
if (method.modality == Modality.ABSTRACT) {
if (method.modality == Modality.ABSTRACT || isDefaultInJdk(method)) {
// If the fake override is abstract and it's _declared_ as abstract in the class, skip it because the method is already
// present in the bytecode (abstract) and we don't want a duplicate signature error
if (method.findOverriddenFromDirectSuperClass(descriptor)?.kind == DECLARATION) continue
@@ -149,6 +151,12 @@ class CollectionStubMethodGenerator(
}
}
private fun isDefaultInJdk(method: FunctionDescriptor) =
method.modality != Modality.ABSTRACT &&
method.original.overriddenTreeUniqueAsSequence(useOriginal = true).all {
(it as FunctionDescriptor).kind == FAKE_OVERRIDE || it.isFromBuiltins()
}
private data class CollectionClassPair(
val readOnlyClass: ClassDescriptor,
val mutableClass: ClassDescriptor
@@ -344,7 +344,7 @@ public class FunctionCodegen {
KotlinTypeMapper typeMapper = parentCodegen.typeMapper;
if (BuiltinSpecialBridgesUtil.shouldHaveTypeSafeBarrier(functionDescriptor, getSignatureMapper(typeMapper))) {
generateTypeCheckBarrierIfNeeded(
new InstructionAdapter(mv), functionDescriptor, signature.getReturnType(), /* delegateParameterType = */null);
new InstructionAdapter(mv), functionDescriptor, signature.getReturnType(), /* delegateParameterTypes = */null);
}
Label methodEnd;
@@ -890,8 +890,8 @@ public class FunctionCodegen {
InstructionAdapter iv = new InstructionAdapter(mv);
MemberCodegen.markLineNumberForDescriptor(owner.getThisDescriptor(), iv);
if (delegateTo.getArgumentTypes().length == 1 && isSpecialBridge) {
generateTypeCheckBarrierIfNeeded(iv, descriptor, bridge.getReturnType(), delegateTo.getArgumentTypes()[0]);
if (delegateTo.getArgumentTypes().length > 0 && isSpecialBridge) {
generateTypeCheckBarrierIfNeeded(iv, descriptor, bridge.getReturnType(), delegateTo.getArgumentTypes());
}
iv.load(0, OBJECT_TYPE);
@@ -921,37 +921,42 @@ public class FunctionCodegen {
@NotNull InstructionAdapter iv,
@NotNull FunctionDescriptor descriptor,
@NotNull Type returnType,
@Nullable final Type delegateParameterType
@Nullable Type[] delegateParameterTypes
) {
BuiltinMethodsWithSpecialGenericSignature.DefaultValue defaultValue =
BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(descriptor);
if (defaultValue == null) return;
assert descriptor.getValueParameters().size() == 1 : "Should be descriptor with one value parameter, but found: " + descriptor;
Label defaultBranch = new Label();
boolean isCheckForAny = delegateParameterType == null || OBJECT_TYPE.equals(delegateParameterType);
for (int i = 0; i < descriptor.getValueParameters().size(); i++) {
boolean isCheckForAny = delegateParameterTypes == null || OBJECT_TYPE.equals(delegateParameterTypes[i]);
final KotlinType kotlinType = descriptor.getValueParameters().get(0).getType();
KotlinType kotlinType = descriptor.getValueParameters().get(i).getType();
if (isCheckForAny && TypeUtils.isNullableType(kotlinType)) return;
if (isCheckForAny && TypeUtils.isNullableType(kotlinType)) continue;
iv.load(1, OBJECT_TYPE);
iv.load(1 + i, OBJECT_TYPE);
Label afterBarrier = new Label();
if (isCheckForAny) {
assert !TypeUtils.isNullableType(kotlinType) : "Only bridges for not-nullable types are necessary";
iv.ifnonnull(afterBarrier);
}
else {
CodegenUtilKt.generateIsCheck(iv, kotlinType, boxType(delegateParameterType));
iv.ifne(afterBarrier);
if (isCheckForAny) {
assert !TypeUtils.isNullableType(kotlinType) : "Only bridges for not-nullable types are necessary";
iv.ifnull(defaultBranch);
}
else {
CodegenUtilKt.generateIsCheck(iv, kotlinType, boxType(delegateParameterTypes[i]));
iv.ifeq(defaultBranch);
}
}
Label afterDefaultBranch = new Label();
iv.goTo(afterDefaultBranch);
iv.visitLabel(defaultBranch);
StackValue.constant(defaultValue.getValue(), returnType).put(returnType, iv);
iv.areturn(returnType);
iv.visitLabel(afterBarrier);
iv.visitLabel(afterDefaultBranch);
}
public void genSamDelegate(@NotNull FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenDescriptor, StackValue field) {