Add ULong.compareTo and UInt.div/rem/compareTo intrinsics for Java 8

This commit is contained in:
Jake Wharton
2019-04-18 22:56:53 -04:00
committed by max-kammerer
parent e6362661d1
commit 373424f430
25 changed files with 587 additions and 9 deletions
@@ -41,6 +41,7 @@ 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_UINT = new FqNameUnsafe("kotlin.UInt");
private static final FqNameUnsafe KOTLIN_ULONG = new FqNameUnsafe("kotlin.ULong");
private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus();
@@ -162,13 +163,29 @@ public class IntrinsicMethods {
declareArrayMethods();
if (jvmTarget.compareTo(JvmTarget.JVM_1_8) >= 0) {
Java8ULongDivide java8ULongDivide = new Java8ULongDivide();
Java8ULongRemainder java8ULongRemainder = new Java8ULongRemainder();
Java8UIntDivide java8UIntDivide = new Java8UIntDivide();
intrinsicsMap.registerIntrinsic(KOTLIN_UINT.toSafe(), null, "div", 1, java8UIntDivide);
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "uintDivide", 2, java8UIntDivide);
Java8UIntRemainder java8UIntRemainder = new Java8UIntRemainder();
intrinsicsMap.registerIntrinsic(KOTLIN_UINT.toSafe(), null, "rem", 1, java8UIntRemainder);
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "uintRemainder", 2, java8UIntRemainder);
Java8UIntCompare java8UIntCompare = new Java8UIntCompare();
intrinsicsMap.registerIntrinsic(KOTLIN_UINT.toSafe(), null, "compareTo", 1, java8UIntCompare);
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "uintCompare", 2, java8UIntCompare);
Java8ULongDivide java8ULongDivide = new Java8ULongDivide();
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);
Java8ULongRemainder java8ULongRemainder = new Java8ULongRemainder();
intrinsicsMap.registerIntrinsic(KOTLIN_ULONG.toSafe(), null, "rem", 1, java8ULongRemainder);
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "ulongRemainder", 2, java8ULongRemainder);
Java8ULongCompare java8ULongCompare = new Java8ULongCompare();
intrinsicsMap.registerIntrinsic(KOTLIN_ULONG.toSafe(), null, "compareTo", 1, java8ULongCompare);
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "ulongCompare", 2, java8ULongCompare);
}
}
@@ -10,28 +10,53 @@ import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
abstract class UnsignedLongDivisionIntrinsic : IntrinsicMethod() {
abstract class UnsignedIntrinsic(private val targetDescriptor: String) : 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"
?: throw AssertionError("Unexpected descriptor for unsigned intrinsic: $descriptor")
return singleValueParameterTypeDescriptor.name.asString() == targetDescriptor
}
}
class Java8UIntDivide : UnsignedIntrinsic("UInt") {
override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) {
it.invokestatic("java/lang/Integer", "divideUnsigned", "(II)I", false)
}
}
class Java8ULongDivide : UnsignedLongDivisionIntrinsic() {
class Java8UIntRemainder : UnsignedIntrinsic("UInt") {
override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) {
it.invokestatic("java/lang/Integer", "remainderUnsigned", "(II)I", false)
}
}
class Java8UIntCompare : UnsignedIntrinsic("UInt") {
override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) {
it.invokestatic("java/lang/Integer", "compareUnsigned", "(II)I", false)
}
}
class Java8ULongDivide : UnsignedIntrinsic("ULong") {
override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) {
it.invokestatic("java/lang/Long", "divideUnsigned", "(JJ)J", false)
}
}
class Java8ULongRemainder : UnsignedLongDivisionIntrinsic() {
class Java8ULongRemainder : UnsignedIntrinsic("ULong") {
override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) {
it.invokestatic("java/lang/Long", "remainderUnsigned", "(JJ)J", false)
}
}
class Java8ULongCompare : UnsignedIntrinsic("ULong") {
override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) {
it.invokestatic("java/lang/Long", "compareUnsigned", "(JJ)I", false)
}
}