Use java.lang.Long.divideUnsigned/remainderUnsigned in Java 1.8+
#KT-24876
This commit is contained in:
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.codegen.Callable;
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod;
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
@@ -36,6 +37,10 @@ public abstract class IntrinsicMethod {
|
||||
return toCallable(codegen.getState().getTypeMapper().mapToCallableMethod(fd, false), isSuper, resolvedCall);
|
||||
}
|
||||
|
||||
public boolean isApplicableToOverload(@NotNull CallableMemberDescriptor descriptor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Callable toCallable(@NotNull CallableMethod method, boolean isSuper, @NotNull ResolvedCall resolvedCall) {
|
||||
return toCallable(method, isSuper);
|
||||
|
||||
@@ -41,6 +41,8 @@ public class IntrinsicMethods {
|
||||
private static final FqName KOTLIN_JVM = new FqName("kotlin.jvm");
|
||||
/* package */ static final FqNameUnsafe RECEIVER_PARAMETER_FQ_NAME = new FqNameUnsafe("T");
|
||||
|
||||
private static final FqNameUnsafe KOTLIN_ULONG = new FqNameUnsafe("kotlin.ULong");
|
||||
|
||||
private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus();
|
||||
private static final IntrinsicMethod UNARY_PLUS = new UnaryPlus();
|
||||
private static final IntrinsicMethod NUMBER_CAST = new NumberCast();
|
||||
@@ -153,6 +155,16 @@ public class IntrinsicMethods {
|
||||
}
|
||||
|
||||
declareArrayMethods();
|
||||
|
||||
if (jvmTarget.compareTo(JvmTarget.JVM_1_8) >= 0) {
|
||||
Java8ULongDivide java8ULongDivide = new Java8ULongDivide();
|
||||
Java8ULongRemainder java8ULongRemainder = new Java8ULongRemainder();
|
||||
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_ULONG.toSafe(), null, "div", 1, java8ULongDivide);
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_ULONG.toSafe(), null, "rem", 1, java8ULongRemainder);
|
||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "ulongDivide", 2, java8ULongDivide);
|
||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "ulongRemainder", 2, java8ULongRemainder);
|
||||
}
|
||||
}
|
||||
|
||||
private void declareArrayMethods() {
|
||||
|
||||
@@ -56,12 +56,15 @@ internal class IntrinsicsMap {
|
||||
}
|
||||
|
||||
fun getIntrinsic(descriptor: CallableMemberDescriptor): IntrinsicMethod? =
|
||||
intrinsicsMap[Key(
|
||||
intrinsicsMap[getKey(descriptor)]?.takeIf { it.isApplicableToOverload(descriptor.original) }
|
||||
|
||||
private fun getKey(descriptor: CallableMemberDescriptor): Key =
|
||||
Key(
|
||||
DescriptorUtils.getFqName(descriptor.containingDeclaration),
|
||||
getReceiverParameterFqName(descriptor),
|
||||
descriptor.name.asString(),
|
||||
valueParameterCountForKey(descriptor)
|
||||
)]
|
||||
)
|
||||
|
||||
private fun getReceiverParameterFqName(descriptor: CallableMemberDescriptor): FqNameUnsafe? {
|
||||
val receiverParameter = descriptor.extensionReceiverParameter ?: return null
|
||||
@@ -72,4 +75,6 @@ internal class IntrinsicsMap {
|
||||
else
|
||||
DescriptorUtils.getFqName(classifier)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
|
||||
abstract class UnsignedLongDivisionIntrinsic : IntrinsicMethod() {
|
||||
override fun isApplicableToOverload(descriptor: CallableMemberDescriptor): Boolean {
|
||||
if (descriptor.containingDeclaration is PackageFragmentDescriptor) return true
|
||||
val singleValueParameterTypeDescriptor = descriptor.valueParameters.single().type.constructor.declarationDescriptor
|
||||
?: throw AssertionError("Unexpected descriptor for unsigned long division intrinsic: $descriptor")
|
||||
return singleValueParameterTypeDescriptor.name.asString() == "ULong"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Java8ULongDivide : UnsignedLongDivisionIntrinsic() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createIntrinsicCallable(method) {
|
||||
it.invokestatic("java/lang/Long", "divideUnsigned", "(JJ)J", false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Java8ULongRemainder : UnsignedLongDivisionIntrinsic() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createIntrinsicCallable(method) {
|
||||
it.invokestatic("java/lang/Long", "remainderUnsigned", "(JJ)J", false)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user