diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Reporting.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Reporting.kt index dc6a4b4a9c6..ffe4e88be2f 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Reporting.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Reporting.kt @@ -14,7 +14,7 @@ internal fun CommonBackendContext.reportCompilationError(message: String, irFile throw KonanCompilationException() } -internal fun CommonBackendContext.reportCompilationError(message: String) { +internal fun CommonBackendContext.reportCompilationError(message: String): Nothing { report(null, null, message, true) throw KonanCompilationException() } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt index 5b830e13712..511507a928f 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.backend.konan.descriptors -import org.jetbrains.kotlin.backend.konan.binaryTypeIsReference import org.jetbrains.kotlin.backend.konan.irasdescriptors.* import org.jetbrains.kotlin.backend.konan.irasdescriptors.ClassDescriptor import org.jetbrains.kotlin.backend.konan.irasdescriptors.ConstructorDescriptor @@ -17,7 +16,6 @@ import org.jetbrains.kotlin.backend.konan.isInlined import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.types.isUnit -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.types.SimpleType /** @@ -81,6 +79,10 @@ internal fun IrSimpleFunction.resolveFakeOverride(): IrSimpleFunction { internal val FunctionDescriptor.isIntrinsic: Boolean get() = this.descriptor.isIntrinsic +// TODO: Merge with `isIntrinsic` +internal val FunctionDescriptor.isTypedIntrinsic: Boolean + get() = this.descriptor.isTypedIntrinsic + internal val DeclarationDescriptor.isFrozen: Boolean get() = this.descriptor.isFrozen diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/LegacyDescriptorUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/LegacyDescriptorUtils.kt index 43053516217..0f05f75d929 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/LegacyDescriptorUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/LegacyDescriptorUtils.kt @@ -239,6 +239,7 @@ fun CallableMemberDescriptor.findSourceFile(): SourceFile { } } +internal val TypedIntrinsic = FqName("kotlin.native.internal.TypedIntrinsic") private val intrinsicAnnotation = FqName("kotlin.native.internal.Intrinsic") private val symbolNameAnnotation = FqName("kotlin.native.SymbolName") private val objCMethodAnnotation = FqName("kotlinx.cinterop.ObjCMethod") @@ -253,6 +254,9 @@ internal val DeclarationDescriptor.isFrozen: Boolean internal val FunctionDescriptor.isIntrinsic: Boolean get() = this.annotations.hasAnnotation(intrinsicAnnotation) +internal val FunctionDescriptor.isTypedIntrinsic: Boolean + get() = this.annotations.hasAnnotation(TypedIntrinsic) + // TODO: coalesce all our annotation value getters into fewer functions. fun getAnnotationValue(annotation: AnnotationDescriptor): String? { return annotation.allValueArguments.values.ifNotEmpty { @@ -269,5 +273,7 @@ fun CallableMemberDescriptor.externalSymbolOrThrow(): String? { if (this.annotations.hasAnnotation(objCMethodAnnotation)) return null - throw Error("external function ${this} must have @SymbolName, @Intrinsic or @ObjCMethod annotation") + if (this.annotations.hasAnnotation(TypedIntrinsic)) return null + + throw Error("external function ${this} must have @TypedIntrinsic, @SymbolName, @Intrinsic or @ObjCMethod annotation") } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt index a1fbde5d92c..8498f51aecb 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt @@ -260,6 +260,9 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable, val override val areEqual get() = error("Must not be used") + val throwArithmeticException = symbolTable.referenceSimpleFunction( + context.getInternalFunctions("ThrowArithmeticException").single()) + override val ThrowNullPointerException = symbolTable.referenceSimpleFunction( context.getInternalFunctions("ThrowNullPointerException").single()) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index f3926a338db..5c8adc53f4a 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -481,6 +481,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, fun icmpLt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntSLT, arg0, arg1, name)!! fun icmpLe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntSLE, arg0, arg1, name)!! fun icmpNe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntNE, arg0, arg1, name)!! + fun icmpULt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntULT, arg0, arg1, name)!! fun icmpUGt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntUGT, arg0, arg1, name)!! /* floating-point comparisons */ @@ -490,6 +491,15 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, fun fcmpLt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFCmp(builder, LLVMRealPredicate.LLVMRealOLT, arg0, arg1, name)!! fun fcmpLe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFCmp(builder, LLVMRealPredicate.LLVMRealOLE, arg0, arg1, name)!! + fun sub(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildSub(builder, arg0, arg1, name)!! + fun add(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildAdd(builder, arg0, arg1, name)!! + + fun fsub(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFSub(builder, arg0, arg1, name)!! + fun fadd(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFAdd(builder, arg0, arg1, name)!! + + fun select(ifValue: LLVMValueRef, thenValue: LLVMValueRef, elseValue: LLVMValueRef, name: String = ""): LLVMValueRef = + LLVMBuildSelect(builder, ifValue, thenValue, elseValue, name)!! + fun bitcast(type: LLVMTypeRef?, value: LLVMValueRef, name: String = "") = LLVMBuildBitCast(builder, value, type, name)!! fun intToPtr(value: LLVMValueRef?, DestTy: LLVMTypeRef, Name: String = "") = LLVMBuildIntToPtr(builder, value, DestTy, Name)!! diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt new file mode 100644 index 00000000000..aa689d1f3e4 --- /dev/null +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt @@ -0,0 +1,300 @@ +package org.jetbrains.kotlin.backend.konan.llvm + +import llvm.* +import org.jetbrains.kotlin.backend.konan.descriptors.TypedIntrinsic +import org.jetbrains.kotlin.backend.konan.reportCompilationError +import org.jetbrains.kotlin.ir.expressions.IrCall +import org.jetbrains.kotlin.name.Name + +private enum class IntrinsicType { + PLUS, + MINUS, + TIMES, + SIGNED_DIV, + SIGNED_REM, + UNSIGNED_DIV, + UNSIGNED_REM, + INC, + DEC, + UNARY_PLUS, + UNARY_MINUS, + SHL, + SHR, + USHR, + AND, + OR, + XOR, + INV, + SIGN_EXTEND, + ZERO_EXTEND, + INT_TRUNCATE, + FLOAT_TRUNCATE, + FLOAT_EXTEND, + SIGNED_TO_FLOAT, + UNSIGNED_TO_FLOAT, + FLOAT_TO_SIGNED, + SIGNED_COMPARE_TO, + UNSIGNED_COMPARE_TO, + NOT, + TO_BITS, + FROM_BITS +} + +internal class IntrinsicGenerator(val codegen: CodeGenerator) { + + private val context = codegen.context + + private val IrCall.llvmReturnType: LLVMTypeRef + get() = LLVMGetReturnType(codegen.getLlvmFunctionType(symbol.owner))!! + + private fun getIntrinsicType(callSite: IrCall): IntrinsicType { + val function = callSite.symbol.owner + val annotation = function.descriptor.annotations.findAnnotation(TypedIntrinsic)!! + val value = annotation.allValueArguments[Name.identifier("kind")]!!.value as String + return IntrinsicType.valueOf(value) + } + + fun evaluateCall(callSite: IrCall, args: List, generationContext: FunctionGenerationContext, exceptionHandler: ExceptionHandler): LLVMValueRef = + generationContext.evaluateCall(callSite, args, exceptionHandler) + + // Assuming that we checked for `TypedIntrinsic` annotation presence. + private fun FunctionGenerationContext.evaluateCall(callSite: IrCall, args: List, exceptionHandler: ExceptionHandler): LLVMValueRef { + val result = when (getIntrinsicType(callSite)) { + IntrinsicType.PLUS -> emitPlus(args) + IntrinsicType.MINUS -> emitMinus(args) + IntrinsicType.TIMES -> emitTimes(args) + IntrinsicType.SIGNED_DIV -> emitSignedDiv(args, exceptionHandler) + IntrinsicType.SIGNED_REM -> emitSignedRem(args, exceptionHandler) + IntrinsicType.UNSIGNED_DIV -> emitUnsignedDiv(args, exceptionHandler) + IntrinsicType.UNSIGNED_REM -> emitUnsignedRem(args, exceptionHandler) + IntrinsicType.INC -> emitInc(args) + IntrinsicType.DEC -> emitDec(args) + IntrinsicType.UNARY_PLUS -> emitUnaryPlus(args) + IntrinsicType.UNARY_MINUS -> emitUnaryMinus(args) + IntrinsicType.SHL -> emitShl(args) + IntrinsicType.SHR -> emitShr(args) + IntrinsicType.USHR -> emitUshr(args) + IntrinsicType.AND -> emitAnd(args) + IntrinsicType.OR -> emitOr(args) + IntrinsicType.XOR -> emitXor(args) + IntrinsicType.INV -> emitInv(args) + IntrinsicType.SIGNED_COMPARE_TO -> emitSignedCompareTo(args) + IntrinsicType.UNSIGNED_COMPARE_TO -> emitUnsignedCompareTo(args) + IntrinsicType.NOT -> emitNot(args) + IntrinsicType.FROM_BITS -> emitReinterpret(callSite, args) + IntrinsicType.TO_BITS -> emitReinterpret(callSite, args) + IntrinsicType.SIGN_EXTEND -> emitSignExtend(callSite, args) + IntrinsicType.ZERO_EXTEND -> emitZeroExtend(callSite, args) + IntrinsicType.INT_TRUNCATE -> emitIntTruncate(callSite, args) + IntrinsicType.SIGNED_TO_FLOAT -> emitSignedToFloat(callSite, args) + IntrinsicType.UNSIGNED_TO_FLOAT -> emitUnsignedToFloat(callSite, args) + IntrinsicType.FLOAT_TO_SIGNED -> emitFloatToSigned(callSite, args) + IntrinsicType.FLOAT_EXTEND -> emitFloatExtend(callSite, args) + IntrinsicType.FLOAT_TRUNCATE -> emitFloatTruncate(callSite, args) + } + assert(result.type == callSite.llvmReturnType) { + "Substitution of ${callSite.symbol.owner.functionName} has wrong result type" + } + return result + } + + private fun FunctionGenerationContext.emitReinterpret(callSite: IrCall, args: List) = + bitcast(callSite.llvmReturnType, args[0]) + + private fun FunctionGenerationContext.emitNot(args: List) = + not(args[0]) + + private fun FunctionGenerationContext.emitPlus(args: List): LLVMValueRef { + val (first, second) = args + return if (first.type.isFloatingPoint()) { + fadd(first, second) + } else { + add(first, second) + } + } + + private fun FunctionGenerationContext.emitSignExtend(callSite: IrCall, args: List) = + sext(args[0], callSite.llvmReturnType) + + private fun FunctionGenerationContext.emitZeroExtend(callSite: IrCall, args: List) = + zext(args[0], callSite.llvmReturnType) + + private fun FunctionGenerationContext.emitIntTruncate(callSite: IrCall, args: List) = + trunc(args[0], callSite.llvmReturnType) + + private fun FunctionGenerationContext.emitSignedToFloat(callSite: IrCall, args: List) = + LLVMBuildSIToFP(builder, args[0], callSite.llvmReturnType, "")!! + + private fun FunctionGenerationContext.emitUnsignedToFloat(callSite: IrCall, args: List) = + LLVMBuildUIToFP(builder, args[0], callSite.llvmReturnType, "")!! + + private fun FunctionGenerationContext.emitFloatToSigned(callSite: IrCall, args: List) = + LLVMBuildFPToSI(builder, args[0], callSite.llvmReturnType, "")!! + + private fun FunctionGenerationContext.emitFloatExtend(callSite: IrCall, args: List) = + LLVMBuildFPExt(builder, args[0], callSite.llvmReturnType, "")!! + + private fun FunctionGenerationContext.emitFloatTruncate(callSite: IrCall, args: List) = + LLVMBuildFPTrunc(builder, args[0], callSite.llvmReturnType, "")!! + + private fun FunctionGenerationContext.emitShift(op: LLVMOpcode, args: List): LLVMValueRef { + val (first, second) = args + val shift = if (first.type == int64Type) { + val tmp = and(second, Int32(63).llvm) + zext(tmp, int64Type) + } else { + and(second, Int32(31).llvm) + } + return LLVMBuildBinOp(builder, op, first, shift, "")!! + } + + private fun FunctionGenerationContext.emitShl(args: List) = + emitShift(LLVMOpcode.LLVMShl, args) + + private fun FunctionGenerationContext.emitShr(args: List) = + emitShift(LLVMOpcode.LLVMAShr, args) + + private fun FunctionGenerationContext.emitUshr(args: List) = + emitShift(LLVMOpcode.LLVMLShr, args) + + private fun FunctionGenerationContext.emitAnd(args: List): LLVMValueRef { + val (first, second) = args + return and(first, second) + } + + private fun FunctionGenerationContext.emitOr(args: List): LLVMValueRef { + val (first, second) = args + return or(first, second) + } + + private fun FunctionGenerationContext.emitXor(args: List): LLVMValueRef { + val (first, second) = args + return xor(first, second) + } + + private fun FunctionGenerationContext.emitInv(args: List): LLVMValueRef { + val first = args[0] + val mask = makeConstOfType(first.type, -1) + return xor(first, mask) + } + + private fun FunctionGenerationContext.emitMinus(args: List): LLVMValueRef { + val (first, second) = args + return if (first.type.isFloatingPoint()) { + fsub(first, second) + } else { + sub(first, second) + } + } + + private fun FunctionGenerationContext.emitTimes(args: List): LLVMValueRef { + val (first, second) = args + return if (first.type.isFloatingPoint()) { + LLVMBuildFMul(builder, first, second, "") + } else { + LLVMBuildMul(builder, first, second, "") + }!! + } + + private fun FunctionGenerationContext.emitThrowIfZero(divider: LLVMValueRef, exceptionHandler: ExceptionHandler) { + ifThen(icmpEq(divider, Zero(divider.type).llvm)) { + val throwArithExc = codegen.llvmFunction(context.ir.symbols.throwArithmeticException.owner) + call(throwArithExc, emptyList(), Lifetime.GLOBAL, exceptionHandler) + unreachable() + } + } + + private fun FunctionGenerationContext.emitSignedDiv(args: List, exceptionHandler: ExceptionHandler): LLVMValueRef { + val (first, second) = args + if (!second.type.isFloatingPoint()) { + emitThrowIfZero(second, exceptionHandler) + } + return if (first.type.isFloatingPoint()) { + LLVMBuildFDiv(builder, first, second, "") + } else { + LLVMBuildSDiv(builder, first, second, "") + }!! + } + + private fun FunctionGenerationContext.emitSignedRem(args: List, exceptionHandler: ExceptionHandler): LLVMValueRef { + val (first, second) = args + if (!second.type.isFloatingPoint()) { + emitThrowIfZero(second, exceptionHandler) + } + return if (first.type.isFloatingPoint()) { + LLVMBuildFRem(builder, first, second, "") + } else { + LLVMBuildSRem(builder, first, second, "") + }!! + } + + private fun FunctionGenerationContext.emitUnsignedDiv(args: List, exceptionHandler: ExceptionHandler): LLVMValueRef { + val (first, second) = args + emitThrowIfZero(second, exceptionHandler) + return LLVMBuildUDiv(builder, first, second, "")!! + } + + private fun FunctionGenerationContext.emitUnsignedRem(args: List, exceptionHandler: ExceptionHandler): LLVMValueRef { + val (first, second) = args + emitThrowIfZero(second, exceptionHandler) + return LLVMBuildURem(builder, first, second, "")!! + } + + private fun FunctionGenerationContext.emitInc(args: List): LLVMValueRef { + val first = args[0] + val const1 = makeConstOfType(first.type, 1) + return if (first.type.isFloatingPoint()) { + fadd(first, const1) + } else { + add(first, const1) + } + } + + private fun FunctionGenerationContext.emitDec(args: List): LLVMValueRef { + val first = args[0] + val const1 = makeConstOfType(first.type, 1) + return if (first.type.isFloatingPoint()) { + fsub(first, const1) + } else { + sub(first, const1) + } + } + + private fun FunctionGenerationContext.emitUnaryPlus(args: List) = + args[0] + + private fun FunctionGenerationContext.emitUnaryMinus(args: List): LLVMValueRef { + val first = args[0] + val destTy = first.type + val const0 = makeConstOfType(destTy, 0) + return if (destTy.isFloatingPoint()) { + fsub(const0, first) + } else { + sub(const0, first) + } + } + + private fun FunctionGenerationContext.emitCompareTo(args: List, signed: Boolean): LLVMValueRef { + val (first, second) = args + val equal = icmpEq(first, second) + val less = if (signed) icmpLt(first, second) else icmpULt(first, second) + val tmp = select(less, Int32(-1).llvm, Int32(1).llvm) + return select(equal, Int32(0).llvm, tmp) + } + + private fun FunctionGenerationContext.emitSignedCompareTo(args: List) = + emitCompareTo(args, signed = true) + + private fun FunctionGenerationContext.emitUnsignedCompareTo(args: List) = + emitCompareTo(args, signed = false) + + private fun makeConstOfType(type: LLVMTypeRef, value: Int): LLVMValueRef = when (type) { + int8Type -> Int8(value.toByte()).llvm + int16Type -> Char16(value.toChar()).llvm + int32Type -> Int32(value).llvm + int64Type -> Int64(value.toLong()).llvm + floatType -> Float32(value.toFloat()).llvm + doubleType -> Float64(value.toDouble()).llvm + else -> context.reportCompilationError("Unexpected primitive type: $type") + } +} \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index f1757ee8b0d..c04a4c3f366 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -38,7 +38,6 @@ import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe -import org.jetbrains.kotlin.resolve.hasBackingField private val threadLocalAnnotationFqName = FqName("kotlin.native.ThreadLocal") private val sharedAnnotationFqName = FqName("kotlin.native.SharedImmutable") @@ -292,6 +291,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map - return delegatingConstructorCall(value.symbol.owner, args) - - else -> - return evaluateFunctionCall(value as IrCall, args, resultLifetime(value)) + return when (value) { + is IrDelegatingConstructorCall -> delegatingConstructorCall(value.symbol.owner, args) + else -> evaluateFunctionCall(value as IrCall, args, resultLifetime(value)) } } @@ -2092,23 +2091,17 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map, resultLifetime: Lifetime): LLVMValueRef { - val descriptor = callee.symbol.owner + val function = callee.symbol.owner - val argsWithContinuationIfNeeded = if (descriptor.isSuspend) + val argsWithContinuationIfNeeded = if (function.isSuspend) args + getContinuation() else args - if (descriptor.isIntrinsic) { - return evaluateIntrinsicCall(callee, argsWithContinuationIfNeeded) - } - - when { - descriptor.origin == IrDeclarationOrigin.IR_BUILTINS_STUB -> - return evaluateOperatorCall(callee, argsWithContinuationIfNeeded) - - descriptor is ConstructorDescriptor -> return evaluateConstructorCall(callee, argsWithContinuationIfNeeded) - - else -> return evaluateSimpleFunctionCall( - descriptor, argsWithContinuationIfNeeded, resultLifetime, callee.superQualifierSymbol?.owner) + return when { + function.isTypedIntrinsic -> intrinsicGenerator.evaluateCall(callee, args, functionGenerationContext, currentCodeContext.exceptionHandler) + function.isIntrinsic -> evaluateIntrinsicCall(callee, argsWithContinuationIfNeeded) + function.origin == IrDeclarationOrigin.IR_BUILTINS_STUB -> evaluateOperatorCall(callee, argsWithContinuationIfNeeded) + function is ConstructorDescriptor -> evaluateConstructorCall(callee, argsWithContinuationIfNeeded) + else -> evaluateSimpleFunctionCall(function, argsWithContinuationIfNeeded, resultLifetime, callee.superQualifierSymbol?.owner) } } @@ -2207,6 +2200,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map): LLVMValueRef { val descriptor = callee.descriptor.original val function = callee.symbol.owner diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt index 4eeac819b83..618b34166eb 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt @@ -398,7 +398,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : } val llvmFunction = if (descriptor.isExternal) { - if (descriptor.isIntrinsic || descriptor.isObjCBridgeBased()) { + if (descriptor.isTypedIntrinsic || descriptor.isIntrinsic || descriptor.isObjCBridgeBased()) { return } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt index 1c0ad17e1d4..0438ab6610a 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt @@ -91,6 +91,14 @@ internal class Int64(val value: Long) : ConstValue { override val llvm = LLVMConstInt(LLVMInt64Type(), value, 1)!! } +internal class Float32(val value: Float) : ConstValue { + override val llvm = LLVMConstReal(LLVMFloatType(), value.toDouble())!! +} + +internal class Float64(val value: Double) : ConstValue { + override val llvm = LLVMConstReal(LLVMDoubleType(), value)!! +} + internal class Zero(val type: LLVMTypeRef) : ConstValue { override val llvm = LLVMConstNull(type)!! } @@ -113,6 +121,8 @@ internal val int16Type = LLVMInt16Type()!! internal val int32Type = LLVMInt32Type()!! internal val int64Type = LLVMInt64Type()!! internal val int8TypePtr = pointerType(int8Type) +internal val floatType = LLVMFloatType()!! +internal val doubleType = LLVMDoubleType()!! internal val voidType = LLVMVoidType()!! diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index 863b91dfc03..8f1fdbbf08a 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -1048,6 +1048,19 @@ task initializers_correctOrder2(type: RunKonanTest) { source = "codegen/initializers/correctOrder2.kt" } +task arithmetic_basic(type: RunKonanTest) { + source = "codegen/arithmetic/basic.kt" +} + +task arithmetic_division(type: RunKonanTest) { + expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. + source = "codegen/arithmetic/division.kt" +} + +task arithmetic_github1856(type: RunKonanTest) { + source = "codegen/arithmetic/github1856.kt" +} + task bridges_test0(type: RunKonanTest) { goldValue = "42\n42\n" source = "codegen/bridges/test0.kt" diff --git a/backend.native/tests/codegen/arithmetic/basic.kt b/backend.native/tests/codegen/arithmetic/basic.kt new file mode 100644 index 00000000000..63adc4d176d --- /dev/null +++ b/backend.native/tests/codegen/arithmetic/basic.kt @@ -0,0 +1,90 @@ +package codegen.arithmetic.basic + +import kotlin.test.* + +// Check that compiler doesn't optimize it to `true` +fun selfCmp1(x: Int) = x + 1 > x + +fun selfCmp2(x: Int) = x - 1 < x + +@Test +fun selfComparison() { + assertFalse(selfCmp1(Int.MAX_VALUE)) + assertFalse(selfCmp2(Int.MIN_VALUE)) +} + +private fun charCornersMinus(): Int { + val a: Char = 0xFFFF.toChar() + val b: Char = 0.toChar() + return a - b +} + +private fun charCornersComparison(): Boolean { + val a = 0xFFFF.toChar() + val b = 0.toChar() + return a < b +} + +@Test +fun charCornerCases() { + assertEquals(65535, charCornersMinus()) + assertFalse(charCornersComparison()) +} + +@Test +fun shifts() { + assertEquals(-2147483648, 1 shl -1) + assertEquals(0, 1 shr -1) + assertEquals(1, 1 shl 32) + assertEquals(1073741823, -1 ushr 2) + assertEquals(-1, -1 shr 2) +} + +@Test +@kotlin.ExperimentalUnsignedTypes +fun uintTests() { + assertEquals(UInt.MAX_VALUE, UInt.MIN_VALUE - 1u) +} + +@Test +fun charConversions() { + assertEquals(97.0, 'a'.toDouble()) + assertEquals(-1, Char.MAX_VALUE.toShort()) + assertEquals(32768, Short.MIN_VALUE.toChar().toInt()) + assertEquals(-1, Char.MAX_VALUE.toByte()) + assertEquals(65408, Byte.MIN_VALUE.toChar().toInt()) + assertEquals(0, Float.MIN_VALUE.toChar().toInt()) +} + +@Test +fun doubleBasic() { + assertEquals(1, 0f.compareTo(-0f)) + assertEquals(1, 0.0.compareTo(-0.0)) + + assertEquals(1.0, Double.fromBits(1.0.toBits())) + assertEquals(1.0f, Float.fromBits(1.0f.toBits())) + + assertEquals(Double.NaN, Double.fromBits((0 / 0.0).toBits())) + assertEquals(Float.NaN, Float.fromBits((0 / 0f).toBits())) +} + +@Test +fun integralToFloat() { + assertEquals(9.223372E18f, Long.MAX_VALUE.toFloat()) + assertEquals(-9.223372E18f, Long.MIN_VALUE.toFloat()) + + assertEquals(-2.147483648E9, Int.MIN_VALUE.toDouble()) + assertEquals(2.147483647E9, Int.MAX_VALUE.toDouble()) + + assertEquals(2147483647, Double.MAX_VALUE.toInt()) + assertEquals(0, Float.MIN_VALUE.toLong()) + + assertEquals(9223372036854775807, Float.MAX_VALUE.toLong()) + assertEquals(0, Double.MIN_VALUE.toInt()) +} + +@Test +fun compareIntToFloat() { + assertEquals(1, 0.compareTo(-0.0f)) + assertEquals(0, 0.compareTo(+0.0f)) +} \ No newline at end of file diff --git a/backend.native/tests/codegen/arithmetic/division.kt b/backend.native/tests/codegen/arithmetic/division.kt new file mode 100644 index 00000000000..9a8a8188cc3 --- /dev/null +++ b/backend.native/tests/codegen/arithmetic/division.kt @@ -0,0 +1,11 @@ +package codegen.arithmetic.division + +import kotlin.test.* + +@Test +fun divisionByZero() { + assertFailsWith(ArithmeticException::class, { 5 / 0 }) + assertFailsWith(ArithmeticException::class, { 5 % 0 }) + assertEquals(1, 5 / try { 0 / 0; 1 } catch (e: ArithmeticException) { 5 }) + assertEquals(Double.NaN, 0.0 / 0.0) +} diff --git a/backend.native/tests/codegen/arithmetic/github1856.kt b/backend.native/tests/codegen/arithmetic/github1856.kt new file mode 100644 index 00000000000..667a0c11202 --- /dev/null +++ b/backend.native/tests/codegen/arithmetic/github1856.kt @@ -0,0 +1,26 @@ +package codegen.arithmetic.github1856 + +import kotlin.test.* + +object RGBA { + fun packFast(r: Int, g: Int, b: Int, a: Int) = (r shl 0) or (g shl 8) or (b shl 16) or (a shl 24) + + fun getFastR(v: Int): Int = (v ushr 0) and 0xFF + fun getFastG(v: Int): Int = (v ushr 8) and 0xFF + fun getFastB(v: Int): Int = (v ushr 16) and 0xFF + fun getFastA(v: Int): Int = (v ushr 24) and 0xFF + + fun premultiplyFastInt(v: Int): Int { + val A = getFastA(v) + 1 + val RB = (((v and 0x00FF00FF) * A) ushr 8) and 0x00FF00FF + val G = (((v and 0x0000FF00) * A) ushr 8) and 0x0000FF00 + return (v and 0x00FFFFFF.inv()) or RB or G + } +} + +@Test +fun main() { + val source = listOf(0xFFFFFFFF.toInt(), 0xFFFFFF77.toInt(), 0x777777FF.toInt(), 0x77777777.toInt()) + val expect = listOf(-1, -137, 2000107383, 2000107319) + assertEquals(expect, source.map { RGBA.premultiplyFastInt(it) }) +} \ No newline at end of file diff --git a/runtime/src/main/cpp/Operator.cpp b/runtime/src/main/cpp/Operator.cpp index 5d051712f20..5bfb2e5c0c9 100644 --- a/runtime/src/main/cpp/Operator.cpp +++ b/runtime/src/main/cpp/Operator.cpp @@ -19,431 +19,52 @@ #include "DoubleConversions.h" #include "Natives.h" -#include "Exceptions.h" #include "Common.h" -namespace { - -template R div(Ta a, Tb b) { - if (__builtin_expect(b == 0, false)) { - ThrowArithmeticException(); - } - return a / b; -} - -} - extern "C" { -//--- Boolean -----------------------------------------------------------------// - -ALWAYS_INLINE KBoolean Kotlin_Boolean_not (KBoolean a ) { return !a; } -ALWAYS_INLINE KBoolean Kotlin_Boolean_and_Boolean (KBoolean a, KBoolean b) { return a && b; } -ALWAYS_INLINE KBoolean Kotlin_Boolean_or_Boolean (KBoolean a, KBoolean b) { return a || b; } -ALWAYS_INLINE KBoolean Kotlin_Boolean_xor_Boolean (KBoolean a, KBoolean b) { return a != b; } -KInt Kotlin_Boolean_compareTo_Boolean(KBoolean a, KBoolean b) { if (a == b) return 0; return (a < b) ? -1 : 1; } - -//--- Char --------------------------------------------------------------------// - -KInt Kotlin_Char_compareTo_Char (KChar a, KChar b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -ALWAYS_INLINE KChar Kotlin_Char_plus_Int (KChar a, KInt b) { return a + b; } -ALWAYS_INLINE KInt Kotlin_Char_minus_Char (KChar a, KChar b) { return a - b; } -ALWAYS_INLINE KChar Kotlin_Char_minus_Int (KChar a, KInt b) { return a - b; } -ALWAYS_INLINE KChar Kotlin_Char_inc (KChar a ) { return a + 1; } -ALWAYS_INLINE KChar Kotlin_Char_dec (KChar a ) { return a - 1; } - -ALWAYS_INLINE KByte Kotlin_Char_toByte (KChar a ) { return a; } -ALWAYS_INLINE KChar Kotlin_Char_toChar (KChar a ) { return a; } -ALWAYS_INLINE KShort Kotlin_Char_toShort (KChar a ) { return a; } -ALWAYS_INLINE KInt Kotlin_Char_toInt (KChar a ) { return a; } -ALWAYS_INLINE KLong Kotlin_Char_toLong (KChar a ) { return a; } -ALWAYS_INLINE KFloat Kotlin_Char_toFloat (KChar a ) { return a; } -ALWAYS_INLINE KDouble Kotlin_Char_toDouble (KChar a ) { return a; } - -//--- Byte --------------------------------------------------------------------// - -KInt Kotlin_Byte_compareTo_Byte (KByte a, KByte b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Byte_compareTo_Short (KByte a, KShort b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Byte_compareTo_Int (KByte a, KInt b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Byte_compareTo_Long (KByte a, KLong b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Byte_compareTo_Float (KByte a, KFloat b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Byte_compareTo_Double (KByte a, KDouble b) { if (a == b) return 0; return (a < b) ? -1 : 1; } - -ALWAYS_INLINE KInt Kotlin_Byte_plus_Byte (KByte a, KByte b) { return a + b; } -ALWAYS_INLINE KInt Kotlin_Byte_plus_Short (KByte a, KShort b) { return a + b; } -ALWAYS_INLINE KInt Kotlin_Byte_plus_Int (KByte a, KInt b) { return a + b; } -ALWAYS_INLINE KLong Kotlin_Byte_plus_Long (KByte a, KLong b) { return a + b; } -ALWAYS_INLINE KFloat Kotlin_Byte_plus_Float (KByte a, KFloat b) { return a + b; } -ALWAYS_INLINE KDouble Kotlin_Byte_plus_Double (KByte a, KDouble b) { return a + b; } - -ALWAYS_INLINE KInt Kotlin_Byte_minus_Byte (KByte a, KByte b) { return a - b; } -ALWAYS_INLINE KInt Kotlin_Byte_minus_Short (KByte a, KShort b) { return a - b; } -ALWAYS_INLINE KInt Kotlin_Byte_minus_Int (KByte a, KInt b) { return a - b; } -ALWAYS_INLINE KLong Kotlin_Byte_minus_Long (KByte a, KLong b) { return a - b; } -ALWAYS_INLINE KFloat Kotlin_Byte_minus_Float (KByte a, KFloat b) { return a - b; } -ALWAYS_INLINE KDouble Kotlin_Byte_minus_Double (KByte a, KDouble b) { return a - b; } - -ALWAYS_INLINE KInt Kotlin_Byte_div_Byte (KByte a, KByte b) { return div(a, b); } -ALWAYS_INLINE KInt Kotlin_Byte_div_Short (KByte a, KShort b) { return div(a, b); } -ALWAYS_INLINE KInt Kotlin_Byte_div_Int (KByte a, KInt b) { return div(a, b); } -ALWAYS_INLINE KLong Kotlin_Byte_div_Long (KByte a, KLong b) { return div(a, b); } -ALWAYS_INLINE KFloat Kotlin_Byte_div_Float (KByte a, KFloat b) { return a / b; } -ALWAYS_INLINE KDouble Kotlin_Byte_div_Double (KByte a, KDouble b) { return a / b; } - -ALWAYS_INLINE KInt Kotlin_Byte_mod_Byte (KByte a, KByte b) { return a % b; } -ALWAYS_INLINE KInt Kotlin_Byte_mod_Short (KByte a, KShort b) { return a % b; } -ALWAYS_INLINE KInt Kotlin_Byte_mod_Int (KByte a, KInt b) { return a % b; } -ALWAYS_INLINE KLong Kotlin_Byte_mod_Long (KByte a, KLong b) { return a % b; } -ALWAYS_INLINE KFloat Kotlin_Byte_mod_Float (KByte a, KFloat b) { return fmodf(a, b); } -ALWAYS_INLINE KDouble Kotlin_Byte_mod_Double (KByte a, KDouble b) { return fmod (a, b); } - -ALWAYS_INLINE KInt Kotlin_Byte_times_Byte (KByte a, KByte b) { return a * b; } -ALWAYS_INLINE KInt Kotlin_Byte_times_Short (KByte a, KShort b) { return a * b; } -ALWAYS_INLINE KInt Kotlin_Byte_times_Int (KByte a, KInt b) { return a * b; } -ALWAYS_INLINE KLong Kotlin_Byte_times_Long (KByte a, KLong b) { return a * b; } -ALWAYS_INLINE KFloat Kotlin_Byte_times_Float (KByte a, KFloat b) { return a * b; } -ALWAYS_INLINE KDouble Kotlin_Byte_times_Double (KByte a, KDouble b) { return a * b; } - -ALWAYS_INLINE KByte Kotlin_Byte_inc (KByte a ) { return ++a; } -ALWAYS_INLINE KByte Kotlin_Byte_dec (KByte a ) { return --a; } -ALWAYS_INLINE KInt Kotlin_Byte_unaryPlus (KByte a ) { return +a; } -ALWAYS_INLINE KInt Kotlin_Byte_unaryMinus (KByte a ) { return -a; } - -ALWAYS_INLINE KByte Kotlin_Byte_toByte (KByte a ) { return a; } -ALWAYS_INLINE KChar Kotlin_Byte_toChar (KByte a ) { return a; } -ALWAYS_INLINE KShort Kotlin_Byte_toShort (KByte a ) { return a; } -ALWAYS_INLINE KInt Kotlin_Byte_toInt (KByte a ) { return a; } -ALWAYS_INLINE KLong Kotlin_Byte_toLong (KByte a ) { return a; } -ALWAYS_INLINE KFloat Kotlin_Byte_toFloat (KByte a ) { return a; } -ALWAYS_INLINE KDouble Kotlin_Byte_toDouble (KByte a ) { return a; } - -//--- Short -------------------------------------------------------------------// - -KInt Kotlin_Short_compareTo_Byte (KShort a, KByte b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Short_compareTo_Short (KShort a, KShort b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Short_compareTo_Int (KShort a, KInt b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Short_compareTo_Long (KShort a, KLong b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Short_compareTo_Float (KShort a, KFloat b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Short_compareTo_Double (KShort a, KDouble b) { if (a == b) return 0; return (a < b) ? -1 : 1; } - -ALWAYS_INLINE KInt Kotlin_Short_plus_Byte (KShort a, KByte b) { return a + b; } -ALWAYS_INLINE KInt Kotlin_Short_plus_Short (KShort a, KShort b) { return a + b; } -ALWAYS_INLINE KInt Kotlin_Short_plus_Int (KShort a, KInt b) { return a + b; } -ALWAYS_INLINE KLong Kotlin_Short_plus_Long (KShort a, KLong b) { return a + b; } -ALWAYS_INLINE KFloat Kotlin_Short_plus_Float (KShort a, KFloat b) { return a + b; } -ALWAYS_INLINE KDouble Kotlin_Short_plus_Double (KShort a, KDouble b) { return a + b; } - -ALWAYS_INLINE KInt Kotlin_Short_minus_Byte (KShort a, KByte b) { return a - b; } -ALWAYS_INLINE KInt Kotlin_Short_minus_Short (KShort a, KShort b) { return a - b; } -ALWAYS_INLINE KInt Kotlin_Short_minus_Int (KShort a, KInt b) { return a - b; } -ALWAYS_INLINE KLong Kotlin_Short_minus_Long (KShort a, KLong b) { return a - b; } -ALWAYS_INLINE KFloat Kotlin_Short_minus_Float (KShort a, KFloat b) { return a - b; } -ALWAYS_INLINE KDouble Kotlin_Short_minus_Double (KShort a, KDouble b) { return a - b; } - -ALWAYS_INLINE KInt Kotlin_Short_div_Byte (KShort a, KByte b) { return div(a, b); } -ALWAYS_INLINE KInt Kotlin_Short_div_Short (KShort a, KShort b) { return div(a, b); } -ALWAYS_INLINE KInt Kotlin_Short_div_Int (KShort a, KInt b) { return div(a, b); } -ALWAYS_INLINE KLong Kotlin_Short_div_Long (KShort a, KLong b) { return div(a, b); } -ALWAYS_INLINE KFloat Kotlin_Short_div_Float (KShort a, KFloat b) { return a / b; } -ALWAYS_INLINE KDouble Kotlin_Short_div_Double (KShort a, KDouble b) { return a / b; } - -ALWAYS_INLINE KInt Kotlin_Short_mod_Byte (KShort a, KByte b) { return a % b; } -ALWAYS_INLINE KInt Kotlin_Short_mod_Short (KShort a, KShort b) { return a % b; } -ALWAYS_INLINE KInt Kotlin_Short_mod_Int (KShort a, KInt b) { return a % b; } -ALWAYS_INLINE KLong Kotlin_Short_mod_Long (KShort a, KLong b) { return a % b; } -ALWAYS_INLINE KFloat Kotlin_Short_mod_Float (KShort a, KFloat b) { return fmodf(a, b); } -ALWAYS_INLINE KDouble Kotlin_Short_mod_Double (KShort a, KDouble b) { return fmod (a, b); } - -ALWAYS_INLINE KInt Kotlin_Short_times_Byte (KShort a, KByte b) { return a * b; } -ALWAYS_INLINE KInt Kotlin_Short_times_Short (KShort a, KShort b) { return a * b; } -ALWAYS_INLINE KInt Kotlin_Short_times_Int (KShort a, KInt b) { return a * b; } -ALWAYS_INLINE KLong Kotlin_Short_times_Long (KShort a, KLong b) { return a * b; } -ALWAYS_INLINE KFloat Kotlin_Short_times_Float (KShort a, KFloat b) { return a * b; } -ALWAYS_INLINE KDouble Kotlin_Short_times_Double (KShort a, KDouble b) { return a * b; } - -ALWAYS_INLINE KShort Kotlin_Short_inc (KShort a ) { return ++a; } -ALWAYS_INLINE KShort Kotlin_Short_dec (KShort a ) { return --a; } -ALWAYS_INLINE KInt Kotlin_Short_unaryPlus (KShort a ) { return +a; } -ALWAYS_INLINE KInt Kotlin_Short_unaryMinus (KShort a ) { return -a; } - -ALWAYS_INLINE KByte Kotlin_Short_toByte (KShort a ) { return a; } -ALWAYS_INLINE KChar Kotlin_Short_toChar (KShort a ) { return a; } -ALWAYS_INLINE KShort Kotlin_Short_toShort (KShort a ) { return a; } -ALWAYS_INLINE KInt Kotlin_Short_toInt (KShort a ) { return a; } -ALWAYS_INLINE KLong Kotlin_Short_toLong (KShort a ) { return a; } -ALWAYS_INLINE KFloat Kotlin_Short_toFloat (KShort a ) { return a; } -ALWAYS_INLINE KDouble Kotlin_Short_toDouble (KShort a ) { return a; } - -//--- Int ---------------------------------------------------------------------// - -KInt Kotlin_Int_compareTo_Byte (KInt a, KByte b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Int_compareTo_Short (KInt a, KShort b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Int_compareTo_Int (KInt a, KInt b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Int_compareTo_Long (KInt a, KLong b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Int_compareTo_Float (KInt a, KFloat b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Int_compareTo_Double (KInt a, KDouble b) { if (a == b) return 0; return (a < b) ? -1 : 1; } - -ALWAYS_INLINE KInt Kotlin_Int_plus_Byte (KInt a, KByte b) { return a + b; } -ALWAYS_INLINE KInt Kotlin_Int_plus_Short (KInt a, KShort b) { return a + b; } -ALWAYS_INLINE KInt Kotlin_Int_plus_Int (KInt a, KInt b) { return a + b; } -ALWAYS_INLINE KLong Kotlin_Int_plus_Long (KInt a, KLong b) { return a + b; } -ALWAYS_INLINE KFloat Kotlin_Int_plus_Float (KInt a, KFloat b) { return a + b; } -ALWAYS_INLINE KDouble Kotlin_Int_plus_Double (KInt a, KDouble b) { return a + b; } - -ALWAYS_INLINE KInt Kotlin_Int_minus_Byte (KInt a, KByte b) { return a - b; } -ALWAYS_INLINE KInt Kotlin_Int_minus_Short (KInt a, KShort b) { return a - b; } -ALWAYS_INLINE KInt Kotlin_Int_minus_Int (KInt a, KInt b) { return a - b; } -ALWAYS_INLINE KLong Kotlin_Int_minus_Long (KInt a, KLong b) { return a - b; } -ALWAYS_INLINE KFloat Kotlin_Int_minus_Float (KInt a, KFloat b) { return a - b; } -ALWAYS_INLINE KDouble Kotlin_Int_minus_Double (KInt a, KDouble b) { return a - b; } - -ALWAYS_INLINE KInt Kotlin_Int_div_Byte (KInt a, KByte b) { return div(a, b); } -ALWAYS_INLINE KInt Kotlin_Int_div_Short (KInt a, KShort b) { return div(a, b); } -ALWAYS_INLINE KInt Kotlin_Int_div_Int (KInt a, KInt b) { return div(a, b); } -ALWAYS_INLINE KLong Kotlin_Int_div_Long (KInt a, KLong b) { return div(a, b); } -ALWAYS_INLINE KFloat Kotlin_Int_div_Float (KInt a, KFloat b) { return a / b; } -ALWAYS_INLINE KDouble Kotlin_Int_div_Double (KInt a, KDouble b) { return a / b; } - -ALWAYS_INLINE KInt Kotlin_Int_mod_Byte (KInt a, KByte b) { return a % b; } -ALWAYS_INLINE KInt Kotlin_Int_mod_Short (KInt a, KShort b) { return a % b; } -ALWAYS_INLINE KInt Kotlin_Int_mod_Int (KInt a, KInt b) { return a % b; } -ALWAYS_INLINE KLong Kotlin_Int_mod_Long (KInt a, KLong b) { return a % b; } -ALWAYS_INLINE KFloat Kotlin_Int_mod_Float (KInt a, KFloat b) { return fmodf(a, b); } -ALWAYS_INLINE KDouble Kotlin_Int_mod_Double (KInt a, KDouble b) { return fmod (a, b); } - -ALWAYS_INLINE KInt Kotlin_Int_times_Byte (KInt a, KByte b) { return a * b; } -ALWAYS_INLINE KInt Kotlin_Int_times_Short (KInt a, KShort b) { return a * b; } -ALWAYS_INLINE KInt Kotlin_Int_times_Int (KInt a, KInt b) { return a * b; } -ALWAYS_INLINE KLong Kotlin_Int_times_Long (KInt a, KLong b) { return a * b; } -ALWAYS_INLINE KFloat Kotlin_Int_times_Float (KInt a, KFloat b) { return a * b; } -ALWAYS_INLINE KDouble Kotlin_Int_times_Double (KInt a, KDouble b) { return a * b; } - -ALWAYS_INLINE KInt Kotlin_Int_inc (KInt a ) { return ++a; } -ALWAYS_INLINE KInt Kotlin_Int_dec (KInt a ) { return --a; } -ALWAYS_INLINE KInt Kotlin_Int_unaryPlus (KInt a ) { return +a; } -ALWAYS_INLINE KInt Kotlin_Int_unaryMinus (KInt a ) { return -a; } - -ALWAYS_INLINE KInt Kotlin_Int_or_Int (KInt a, KInt b) { return a | b; } -ALWAYS_INLINE KInt Kotlin_Int_xor_Int (KInt a, KInt b) { return a ^ b; } -ALWAYS_INLINE KInt Kotlin_Int_and_Int (KInt a, KInt b) { return a & b; } -ALWAYS_INLINE KInt Kotlin_Int_inv (KInt a ) { return ~a; } - -// According to C++11 the result is undefined if the second operator is < 0 or >= . -// We avoid it by using only the least significant bits -ALWAYS_INLINE KInt Kotlin_Int_shl_Int (KInt a, KInt b) { return a << (b & 31); } -ALWAYS_INLINE KInt Kotlin_Int_shr_Int (KInt a, KInt b) { return a >> (b & 31); } -ALWAYS_INLINE KInt Kotlin_Int_ushr_Int (KInt a, KInt b) { - return static_cast(a) >> (b & 31); -} - -ALWAYS_INLINE KByte Kotlin_Int_toByte (KInt a ) { return a; } -ALWAYS_INLINE KChar Kotlin_Int_toChar (KInt a ) { return a; } -ALWAYS_INLINE KShort Kotlin_Int_toShort (KInt a ) { return a; } -ALWAYS_INLINE KInt Kotlin_Int_toInt (KInt a ) { return a; } -ALWAYS_INLINE KLong Kotlin_Int_toLong (KInt a ) { return a; } -ALWAYS_INLINE KFloat Kotlin_Int_toFloat (KInt a ) { return a; } -ALWAYS_INLINE KDouble Kotlin_Int_toDouble (KInt a ) { return a; } - -//--- Long --------------------------------------------------------------------// - -KInt Kotlin_Long_compareTo_Byte (KLong a, KByte b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Long_compareTo_Short (KLong a, KShort b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Long_compareTo_Int (KLong a, KInt b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Long_compareTo_Long (KLong a, KLong b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Long_compareTo_Float (KLong a, KFloat b) { if (a == b) return 0; return (a < b) ? -1 : 1; } -KInt Kotlin_Long_compareTo_Double (KLong a, KDouble b) { if (a == b) return 0; return (a < b) ? -1 : 1; } - -ALWAYS_INLINE KLong Kotlin_Long_plus_Byte (KLong a, KByte b) { return a + b; } -ALWAYS_INLINE KLong Kotlin_Long_plus_Short (KLong a, KShort b) { return a + b; } -ALWAYS_INLINE KLong Kotlin_Long_plus_Int (KLong a, KInt b) { return a + b; } -ALWAYS_INLINE KLong Kotlin_Long_plus_Long (KLong a, KLong b) { return a + b; } -ALWAYS_INLINE KFloat Kotlin_Long_plus_Float (KLong a, KFloat b) { return a + b; } -ALWAYS_INLINE KDouble Kotlin_Long_plus_Double (KLong a, KDouble b) { return a + b; } - -ALWAYS_INLINE KLong Kotlin_Long_minus_Byte (KLong a, KByte b) { return a - b; } -ALWAYS_INLINE KLong Kotlin_Long_minus_Short (KLong a, KShort b) { return a - b; } -ALWAYS_INLINE KLong Kotlin_Long_minus_Int (KLong a, KInt b) { return a - b; } -ALWAYS_INLINE KLong Kotlin_Long_minus_Long (KLong a, KLong b) { return a - b; } -ALWAYS_INLINE KFloat Kotlin_Long_minus_Float (KLong a, KFloat b) { return a - b; } -ALWAYS_INLINE KDouble Kotlin_Long_minus_Double (KLong a, KDouble b) { return a - b; } - -ALWAYS_INLINE KLong Kotlin_Long_div_Byte (KLong a, KByte b) { return div(a, b); } -ALWAYS_INLINE KLong Kotlin_Long_div_Short (KLong a, KShort b) { return div(a, b); } -ALWAYS_INLINE KLong Kotlin_Long_div_Int (KLong a, KInt b) { return div(a, b); } -ALWAYS_INLINE KLong Kotlin_Long_div_Long (KLong a, KLong b) { return div(a, b); } -ALWAYS_INLINE KFloat Kotlin_Long_div_Float (KLong a, KFloat b) { return a / b; } -ALWAYS_INLINE KDouble Kotlin_Long_div_Double (KLong a, KDouble b) { return a / b; } - -ALWAYS_INLINE KLong Kotlin_Long_mod_Byte (KLong a, KByte b) { return a % b; } -ALWAYS_INLINE KLong Kotlin_Long_mod_Short (KLong a, KShort b) { return a % b; } -ALWAYS_INLINE KLong Kotlin_Long_mod_Int (KLong a, KInt b) { return a % b; } -ALWAYS_INLINE KLong Kotlin_Long_mod_Long (KLong a, KLong b) { return a % b; } -ALWAYS_INLINE KFloat Kotlin_Long_mod_Float (KLong a, KFloat b) { return fmodf(a, b); } -ALWAYS_INLINE KDouble Kotlin_Long_mod_Double (KLong a, KDouble b) { return fmod (a, b); } - -ALWAYS_INLINE KLong Kotlin_Long_times_Byte (KLong a, KByte b) { return a * b; } -ALWAYS_INLINE KLong Kotlin_Long_times_Short (KLong a, KShort b) { return a * b; } -ALWAYS_INLINE KLong Kotlin_Long_times_Int (KLong a, KInt b) { return a * b; } -ALWAYS_INLINE KLong Kotlin_Long_times_Long (KLong a, KLong b) { return a * b; } -ALWAYS_INLINE KFloat Kotlin_Long_times_Float (KLong a, KFloat b) { return a * b; } -ALWAYS_INLINE KDouble Kotlin_Long_times_Double (KLong a, KDouble b) { return a * b; } - -ALWAYS_INLINE KLong Kotlin_Long_inc (KLong a ) { return ++a; } -ALWAYS_INLINE KLong Kotlin_Long_dec (KLong a ) { return --a; } -ALWAYS_INLINE KLong Kotlin_Long_unaryPlus (KLong a ) { return +a; } -ALWAYS_INLINE KLong Kotlin_Long_unaryMinus (KLong a ) { return -a; } - -ALWAYS_INLINE KLong Kotlin_Long_xor_Long (KLong a, KLong b) { return a ^ b; } -ALWAYS_INLINE KLong Kotlin_Long_or_Long (KLong a, KLong b) { return a | b; } -ALWAYS_INLINE KLong Kotlin_Long_and_Long (KLong a, KLong b) { return a & b; } -ALWAYS_INLINE KLong Kotlin_Long_inv (KLong a ) { return ~a; } - -// According to C++11 the result is undefined if the second operator is < 0 or >= . -// We avoid it by using only the least significant bits -ALWAYS_INLINE KLong Kotlin_Long_shl_Int (KLong a, KInt b) { return a << (b & 63); } -ALWAYS_INLINE KLong Kotlin_Long_shr_Int (KLong a, KInt b) { return a >> (b & 63); } -ALWAYS_INLINE KLong Kotlin_Long_ushr_Int (KLong a, KInt b) { - return static_cast(a) >> (b & 63); -} - -ALWAYS_INLINE KByte Kotlin_Long_toByte (KLong a ) { return a; } -ALWAYS_INLINE KChar Kotlin_Long_toChar (KLong a ) { return a; } -ALWAYS_INLINE KShort Kotlin_Long_toShort (KLong a ) { return a; } -ALWAYS_INLINE KInt Kotlin_Long_toInt (KLong a ) { return a; } -ALWAYS_INLINE KLong Kotlin_Long_toLong (KLong a ) { return a; } -ALWAYS_INLINE KFloat Kotlin_Long_toFloat (KLong a ) { return a; } -ALWAYS_INLINE KDouble Kotlin_Long_toDouble (KLong a ) { return a; } - //--- Float -------------------------------------------------------------------// -ALWAYS_INLINE KFloat Kotlin_Float_plus_Byte (KFloat a, KByte b) { return a + b; } -ALWAYS_INLINE KFloat Kotlin_Float_plus_Short (KFloat a, KShort b) { return a + b; } -ALWAYS_INLINE KFloat Kotlin_Float_plus_Int (KFloat a, KInt b) { return a + b; } -ALWAYS_INLINE KFloat Kotlin_Float_plus_Long (KFloat a, KLong b) { return a + b; } -ALWAYS_INLINE KFloat Kotlin_Float_plus_Float (KFloat a, KFloat b) { return a + b; } -ALWAYS_INLINE KDouble Kotlin_Float_plus_Double (KFloat a, KDouble b) { return a + b; } - -ALWAYS_INLINE KFloat Kotlin_Float_minus_Byte (KFloat a, KByte b) { return a - b; } -ALWAYS_INLINE KFloat Kotlin_Float_minus_Short (KFloat a, KShort b) { return a - b; } -ALWAYS_INLINE KFloat Kotlin_Float_minus_Int (KFloat a, KInt b) { return a - b; } -ALWAYS_INLINE KFloat Kotlin_Float_minus_Long (KFloat a, KLong b) { return a - b; } -ALWAYS_INLINE KFloat Kotlin_Float_minus_Float (KFloat a, KFloat b) { return a - b; } -ALWAYS_INLINE KDouble Kotlin_Float_minus_Double (KFloat a, KDouble b) { return a - b; } - -ALWAYS_INLINE KFloat Kotlin_Float_div_Byte (KFloat a, KByte b) { return a / b; } -ALWAYS_INLINE KFloat Kotlin_Float_div_Short (KFloat a, KShort b) { return a / b; } -ALWAYS_INLINE KFloat Kotlin_Float_div_Int (KFloat a, KInt b) { return a / b; } -ALWAYS_INLINE KFloat Kotlin_Float_div_Long (KFloat a, KLong b) { return a / b; } -ALWAYS_INLINE KFloat Kotlin_Float_div_Float (KFloat a, KFloat b) { return a / b; } -ALWAYS_INLINE KDouble Kotlin_Float_div_Double (KFloat a, KDouble b) { return a / b; } - -ALWAYS_INLINE KFloat Kotlin_Float_mod_Byte (KFloat a, KByte b) { return fmodf(a, b); } -ALWAYS_INLINE KFloat Kotlin_Float_mod_Short (KFloat a, KShort b) { return fmodf(a, b); } -ALWAYS_INLINE KFloat Kotlin_Float_mod_Int (KFloat a, KInt b) { return fmodf(a, b); } -ALWAYS_INLINE KFloat Kotlin_Float_mod_Long (KFloat a, KLong b) { return fmodf(a, b); } -ALWAYS_INLINE KFloat Kotlin_Float_mod_Float (KFloat a, KFloat b) { return fmodf(a, b); } -ALWAYS_INLINE KDouble Kotlin_Float_mod_Double (KFloat a, KDouble b) { return fmod (a, b); } - -ALWAYS_INLINE KFloat Kotlin_Float_times_Byte (KFloat a, KByte b) { return a * b; } -ALWAYS_INLINE KFloat Kotlin_Float_times_Short (KFloat a, KShort b) { return a * b; } -ALWAYS_INLINE KFloat Kotlin_Float_times_Int (KFloat a, KInt b) { return a * b; } -ALWAYS_INLINE KFloat Kotlin_Float_times_Long (KFloat a, KLong b) { return a * b; } -ALWAYS_INLINE KFloat Kotlin_Float_times_Float (KFloat a, KFloat b) { return a * b; } -ALWAYS_INLINE KDouble Kotlin_Float_times_Double (KFloat a, KDouble b) { return a * b; } - -ALWAYS_INLINE KFloat Kotlin_Float_inc (KFloat a ) { return ++a; } -ALWAYS_INLINE KFloat Kotlin_Float_dec (KFloat a ) { return --a; } -ALWAYS_INLINE KFloat Kotlin_Float_unaryPlus (KFloat a ) { return +a; } -ALWAYS_INLINE KFloat Kotlin_Float_unaryMinus (KFloat a ) { return -a; } - -KInt Kotlin_Float_toInt (KFloat a ) { +KInt Kotlin_Float_toInt(KFloat a) { if (isnan(a)) return 0; if (a >= (KFloat) INT32_MAX) return INT32_MAX; if (a <= (KFloat) INT32_MIN) return INT32_MIN; return a; } -KLong Kotlin_Float_toLong (KFloat a ) { + +KLong Kotlin_Float_toLong(KFloat a) { if (isnan(a)) return 0; if (a >= (KFloat) INT64_MAX) return INT64_MAX; if (a <= (KFloat) INT64_MIN) return INT64_MIN; return a; } -ALWAYS_INLINE KFloat Kotlin_Float_toFloat (KFloat a ) { return a; } -ALWAYS_INLINE KDouble Kotlin_Float_toDouble (KFloat a ) { return a; } -KByte Kotlin_Float_toByte (KFloat a ) { return (KByte) Kotlin_Float_toInt(a); } -KShort Kotlin_Float_toShort (KFloat a ) { return (KShort) Kotlin_Float_toInt(a); } -ALWAYS_INLINE KInt Kotlin_Float_bits (KFloat a ) { return floatToBits(a); } -ALWAYS_INLINE KFloat Kotlin_Float_fromBits (KInt a ) { return bitsToFloat(a); } +KByte Kotlin_Float_toByte(KFloat a) { return (KByte) Kotlin_Float_toInt(a); } +KShort Kotlin_Float_toShort(KFloat a) { return (KShort) Kotlin_Float_toInt(a); } -ALWAYS_INLINE KBoolean Kotlin_Float_isNaN (KFloat a) { return isnan(a); } -ALWAYS_INLINE KBoolean Kotlin_Float_isInfinite (KFloat a) { return isinf(a); } -ALWAYS_INLINE KBoolean Kotlin_Float_isFinite (KFloat a) { return isfinite(a); } +ALWAYS_INLINE KBoolean Kotlin_Float_isNaN(KFloat a) { return isnan(a); } +ALWAYS_INLINE KBoolean Kotlin_Float_isInfinite(KFloat a) { return isinf(a); } +ALWAYS_INLINE KBoolean Kotlin_Float_isFinite(KFloat a) { return isfinite(a); } - //--- Double ------------------------------------------------------------------// +//--- Double ------------------------------------------------------------------// -ALWAYS_INLINE KDouble Kotlin_Double_plus_Byte (KDouble a, KByte b) { return a + b; } -ALWAYS_INLINE KDouble Kotlin_Double_plus_Short (KDouble a, KShort b) { return a + b; } -ALWAYS_INLINE KDouble Kotlin_Double_plus_Int (KDouble a, KInt b) { return a + b; } -ALWAYS_INLINE KDouble Kotlin_Double_plus_Long (KDouble a, KLong b) { return a + b; } -ALWAYS_INLINE KDouble Kotlin_Double_plus_Float (KDouble a, KFloat b) { return a + b; } -ALWAYS_INLINE KDouble Kotlin_Double_plus_Double (KDouble a, KDouble b) { return a + b; } - -ALWAYS_INLINE KDouble Kotlin_Double_minus_Byte (KDouble a, KByte b) { return a - b; } -ALWAYS_INLINE KDouble Kotlin_Double_minus_Short (KDouble a, KShort b) { return a - b; } -ALWAYS_INLINE KDouble Kotlin_Double_minus_Int (KDouble a, KInt b) { return a - b; } -ALWAYS_INLINE KDouble Kotlin_Double_minus_Long (KDouble a, KLong b) { return a - b; } -ALWAYS_INLINE KDouble Kotlin_Double_minus_Float (KDouble a, KFloat b) { return a - b; } -ALWAYS_INLINE KDouble Kotlin_Double_minus_Double (KDouble a, KDouble b) { return a - b; } - -ALWAYS_INLINE KDouble Kotlin_Double_div_Byte (KDouble a, KByte b) { return a / b; } -ALWAYS_INLINE KDouble Kotlin_Double_div_Short (KDouble a, KShort b) { return a / b; } -ALWAYS_INLINE KDouble Kotlin_Double_div_Int (KDouble a, KInt b) { return a / b; } -ALWAYS_INLINE KDouble Kotlin_Double_div_Long (KDouble a, KLong b) { return a / b; } -ALWAYS_INLINE KDouble Kotlin_Double_div_Float (KDouble a, KFloat b) { return a / b; } -ALWAYS_INLINE KDouble Kotlin_Double_div_Double (KDouble a, KDouble b) { return a / b; } - -ALWAYS_INLINE KDouble Kotlin_Double_mod_Byte (KDouble a, KByte b) { return fmod(a, b); } -ALWAYS_INLINE KDouble Kotlin_Double_mod_Short (KDouble a, KShort b) { return fmod(a, b); } -ALWAYS_INLINE KDouble Kotlin_Double_mod_Int (KDouble a, KInt b) { return fmod(a, b); } -ALWAYS_INLINE KDouble Kotlin_Double_mod_Long (KDouble a, KLong b) { return fmod(a, b); } -ALWAYS_INLINE KDouble Kotlin_Double_mod_Float (KDouble a, KFloat b) { return fmod(a, b); } -ALWAYS_INLINE KDouble Kotlin_Double_mod_Double (KDouble a, KDouble b) { return fmod(a, b); } - -ALWAYS_INLINE KDouble Kotlin_Double_times_Byte (KDouble a, KByte b) { return a * b; } -ALWAYS_INLINE KDouble Kotlin_Double_times_Short (KDouble a, KShort b) { return a * b; } -ALWAYS_INLINE KDouble Kotlin_Double_times_Int (KDouble a, KInt b) { return a * b; } -ALWAYS_INLINE KDouble Kotlin_Double_times_Long (KDouble a, KLong b) { return a * b; } -ALWAYS_INLINE KDouble Kotlin_Double_times_Float (KDouble a, KFloat b) { return a * b; } -ALWAYS_INLINE KDouble Kotlin_Double_times_Double (KDouble a, KDouble b) { return a * b; } - -ALWAYS_INLINE KDouble Kotlin_Double_inc (KDouble a ) { return ++a; } -ALWAYS_INLINE KDouble Kotlin_Double_dec (KDouble a ) { return --a; } -ALWAYS_INLINE KDouble Kotlin_Double_unaryPlus (KDouble a ) { return +a; } -ALWAYS_INLINE KDouble Kotlin_Double_unaryMinus (KDouble a ) { return -a; } - -KInt Kotlin_Double_toInt (KDouble a ) { +KInt Kotlin_Double_toInt(KDouble a) { if (isnan(a)) return 0; if (a >= (KDouble) INT32_MAX) return INT32_MAX; if (a <= (KDouble) INT32_MIN) return INT32_MIN; return a; } -KLong Kotlin_Double_toLong (KDouble a ) { + +KLong Kotlin_Double_toLong(KDouble a) { if (isnan(a)) return 0; if (a >= (KDouble) INT64_MAX) return INT64_MAX; if (a <= (KDouble) INT64_MIN) return INT64_MIN; return a; } -ALWAYS_INLINE KFloat Kotlin_Double_toFloat (KDouble a ) { return a; } -ALWAYS_INLINE KDouble Kotlin_Double_toDouble (KDouble a ) { return a; } - -ALWAYS_INLINE KLong Kotlin_Double_bits (KDouble a ) { return doubleToBits(a); } -ALWAYS_INLINE KDouble Kotlin_Double_fromBits (KLong a ) { return bitsToDouble(a); } - -ALWAYS_INLINE KBoolean Kotlin_Double_isNaN (KDouble a) { return isnan(a); } -ALWAYS_INLINE KBoolean Kotlin_Double_isInfinite (KDouble a) { return isinf(a); } -ALWAYS_INLINE KBoolean Kotlin_Double_isFinite (KDouble a) { return isfinite(a); } +ALWAYS_INLINE KBoolean Kotlin_Double_isNaN(KDouble a) { return isnan(a); } +ALWAYS_INLINE KBoolean Kotlin_Double_isInfinite(KDouble a) { return isinf(a); } +ALWAYS_INLINE KBoolean Kotlin_Double_isFinite(KDouble a) { return isfinite(a); } } // extern "C" diff --git a/runtime/src/main/kotlin/kotlin/Boolean.kt b/runtime/src/main/kotlin/kotlin/Boolean.kt index 90f6e922fdc..58931d36799 100644 --- a/runtime/src/main/kotlin/kotlin/Boolean.kt +++ b/runtime/src/main/kotlin/kotlin/Boolean.kt @@ -5,6 +5,9 @@ package kotlin +import kotlin.native.internal.TypedIntrinsic +import kotlin.native.internal.IntrinsicType + /** * Represents a value which is either `true` or `false`. On the JVM, non-nullable values of this type are * represented as values of the primitive type `boolean`. @@ -18,30 +21,30 @@ public class Boolean private constructor( /** * Returns the inverse of this boolean. */ - @SymbolName("Kotlin_Boolean_not") + @TypedIntrinsic(IntrinsicType.NOT) external public operator fun not(): Boolean /** * Performs a logical `and` operation between this Boolean and the [other] one. Unlike the `&&` operator, * this function does not perform short-circuit evaluation. Both `this` and [other] will always be evaluated. */ - @SymbolName("Kotlin_Boolean_and_Boolean") + @TypedIntrinsic(IntrinsicType.AND) external public infix fun and(other: Boolean): Boolean /** * Performs a logical `or` operation between this Boolean and the [other] one. Unlike the `||` operator, * this function does not perform short-circuit evaluation. Both `this` and [other] will always be evaluated. */ - @SymbolName("Kotlin_Boolean_or_Boolean") + @TypedIntrinsic(IntrinsicType.OR) external public infix fun or(other: Boolean): Boolean /** * Performs a logical `xor` operation between this Boolean and the [other] one. */ - @SymbolName("Kotlin_Boolean_xor_Boolean") + @TypedIntrinsic(IntrinsicType.XOR) external public infix fun xor(other: Boolean): Boolean - @SymbolName("Kotlin_Boolean_compareTo_Boolean") + @TypedIntrinsic(IntrinsicType.SIGNED_COMPARE_TO) external public override fun compareTo(other: Boolean): Int public fun equals(other: Boolean): Boolean = kotlin.native.internal.areEqualByValue(this, other) diff --git a/runtime/src/main/kotlin/kotlin/Char.kt b/runtime/src/main/kotlin/kotlin/Char.kt index 6681aab8a5b..bc98e66a322 100644 --- a/runtime/src/main/kotlin/kotlin/Char.kt +++ b/runtime/src/main/kotlin/kotlin/Char.kt @@ -2,9 +2,13 @@ * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ +@file:Suppress("NOTHING_TO_INLINE") package kotlin +import kotlin.native.internal.TypedIntrinsic +import kotlin.native.internal.IntrinsicType + /** * Represents a 16-bit Unicode character. */ @@ -16,25 +20,24 @@ public class Char private constructor( * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Char_compareTo_Char") + @TypedIntrinsic(IntrinsicType.UNSIGNED_COMPARE_TO) external public override fun compareTo(other: Char): Int /** Adds the other Int value to this value resulting a Char. */ - @SymbolName("Kotlin_Char_plus_Int") - external public operator fun plus(other: Int): Char - + public inline operator fun plus(other: Int): Char = + (this.toInt() + other).toChar() /** Subtracts the other Char value from this value resulting an Int. */ - @SymbolName("Kotlin_Char_minus_Char") - external public operator fun minus(other: Char): Int + public inline operator fun minus(other: Char): Int = + this.toInt() - other.toInt() /** Subtracts the other Int value from this value resulting a Char. */ - @SymbolName("Kotlin_Char_minus_Int") - external public operator fun minus(other: Int): Char + public inline operator fun minus(other: Int): Char = + (this.toInt() - other).toChar() /** Increments this value. */ - @SymbolName("Kotlin_Char_inc") + @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Char /** Decrements this value. */ - @SymbolName("Kotlin_Char_dec") + @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Char /** Creates a range from this value to the specified [other] value. */ @@ -43,25 +46,24 @@ public class Char private constructor( } /** Returns the value of this character as a `Byte`. */ - @SymbolName("Kotlin_Char_toByte") + @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public fun toByte(): Byte /** Returns the value of this character as a `Char`. */ - @SymbolName("Kotlin_Char_toChar") - external public fun toChar(): Char + public inline fun toChar(): Char = this /** Returns the value of this character as a `Short`. */ - @SymbolName("Kotlin_Char_toShort") + @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) external public fun toShort(): Short /** Returns the value of this character as a `Int`. */ - @SymbolName("Kotlin_Char_toInt") + @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) external public fun toInt(): Int /** Returns the value of this character as a `Long`. */ - @SymbolName("Kotlin_Char_toLong") + @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) external public fun toLong(): Long /** Returns the value of this character as a `Float`. */ - @SymbolName("Kotlin_Char_toFloat") + @TypedIntrinsic(IntrinsicType.UNSIGNED_TO_FLOAT) external public fun toFloat(): Float /** Returns the value of this character as a `Double`. */ - @SymbolName("Kotlin_Char_toDouble") + @TypedIntrinsic(IntrinsicType.UNSIGNED_TO_FLOAT) external public fun toDouble(): Double companion object { diff --git a/runtime/src/main/kotlin/kotlin/Numbers.kt b/runtime/src/main/kotlin/kotlin/Numbers.kt index 1f94ec6e1ec..b9e4285568d 100644 --- a/runtime/src/main/kotlin/kotlin/Numbers.kt +++ b/runtime/src/main/kotlin/kotlin/Numbers.kt @@ -5,6 +5,9 @@ package kotlin +import kotlin.native.internal.TypedIntrinsic +import kotlin.native.internal.IntrinsicType + /** * Returns `true` if the specified number is a * Not-a-Number (NaN) value, `false` otherwise. @@ -68,7 +71,7 @@ public actual inline fun Double.toRawBits(): Long = bits() public actual inline fun Double.Companion.fromBits(bits: Long): Double = kotlin.fromBits(bits) @PublishedApi -@SymbolName("Kotlin_Double_fromBits") +@TypedIntrinsic(IntrinsicType.FROM_BITS) external internal fun fromBits(bits: Long): Double /** @@ -96,5 +99,5 @@ public actual inline fun Float.toRawBits(): Int = bits() public actual inline fun Float.Companion.fromBits(bits: Int): Float = kotlin.fromBits(bits) @PublishedApi -@SymbolName("Kotlin_Float_fromBits") +@TypedIntrinsic(IntrinsicType.FROM_BITS) external internal fun fromBits(bits: Int): Float diff --git a/runtime/src/main/kotlin/kotlin/Primitives.kt b/runtime/src/main/kotlin/kotlin/Primitives.kt index 81f4ca85b4e..da35a70d519 100644 --- a/runtime/src/main/kotlin/kotlin/Primitives.kt +++ b/runtime/src/main/kotlin/kotlin/Primitives.kt @@ -2,10 +2,14 @@ * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ +@file:Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") + package kotlin import kotlin.native.internal.NumberConverter +import kotlin.native.internal.TypedIntrinsic +import kotlin.native.internal.IntrinsicType /** * Represents a 8-bit signed integer. @@ -41,165 +45,165 @@ public final class Byte private constructor(private val value: kotlin.native.int * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Byte_compareTo_Byte") + @TypedIntrinsic(IntrinsicType.SIGNED_COMPARE_TO) external public override operator fun compareTo(other: Byte): Int /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Byte_compareTo_Short") - external public operator fun compareTo(other: Short): Int + public inline operator fun compareTo(other: Short): Int = + this.toShort().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Byte_compareTo_Int") - external public operator fun compareTo(other: Int): Int + public inline operator fun compareTo(other: Int): Int = + this.toInt().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Byte_compareTo_Long") - external public operator fun compareTo(other: Long): Int + public inline operator fun compareTo(other: Long): Int = + this.toLong().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Byte_compareTo_Float") - external public operator fun compareTo(other: Float): Int + public inline operator fun compareTo(other: Float): Int = + this.toFloat().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Byte_compareTo_Double") - external public operator fun compareTo(other: Double): Int + public inline operator fun compareTo(other: Double): Int = + this.toDouble().compareTo(other) /** Adds the other value to this value. */ - @SymbolName("Kotlin_Byte_plus_Byte") - external public operator fun plus(other: Byte): Int + public inline operator fun plus(other: Byte): Int = + this.toInt() + other.toInt() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Byte_plus_Short") - external public operator fun plus(other: Short): Int + public inline operator fun plus(other: Short): Int = + this.toInt() + other.toInt() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Byte_plus_Int") - external public operator fun plus(other: Int): Int + public inline operator fun plus(other: Int): Int = + this.toInt() + other /** Adds the other value to this value. */ - @SymbolName("Kotlin_Byte_plus_Long") - external public operator fun plus(other: Long): Long + public inline operator fun plus(other: Long): Long = + this.toLong() + other /** Adds the other value to this value. */ - @SymbolName("Kotlin_Byte_plus_Float") - external public operator fun plus(other: Float): Float + public inline operator fun plus(other: Float): Float = + this.toFloat() + other /** Adds the other value to this value. */ - @SymbolName("Kotlin_Byte_plus_Double") - external public operator fun plus(other: Double): Double + public inline operator fun plus(other: Double): Double = + this.toDouble() + other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Byte_minus_Byte") - external public operator fun minus(other: Byte): Int + public inline operator fun minus(other: Byte): Int = + this.toInt() - other.toInt() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Byte_minus_Short") - external public operator fun minus(other: Short): Int + public inline operator fun minus(other: Short): Int = + this.toInt() - other.toInt() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Byte_minus_Int") - external public operator fun minus(other: Int): Int + public inline operator fun minus(other: Int): Int = + this.toInt() - other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Byte_minus_Long") - external public operator fun minus(other: Long): Long + public inline operator fun minus(other: Long): Long = + this.toLong() - other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Byte_minus_Float") - external public operator fun minus(other: Float): Float + public inline operator fun minus(other: Float): Float = + this.toFloat() - other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Byte_minus_Double") - external public operator fun minus(other: Double): Double + public inline operator fun minus(other: Double): Double = + this.toDouble() - other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Byte_times_Byte") - external public operator fun times(other: Byte): Int + public inline operator fun times(other: Byte): Int = + this.toInt() * other.toInt() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Byte_times_Short") - external public operator fun times(other: Short): Int + public inline operator fun times(other: Short): Int = + this.toInt() * other.toInt() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Byte_times_Int") - external public operator fun times(other: Int): Int + public inline operator fun times(other: Int): Int = + this.toInt() * other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Byte_times_Long") - external public operator fun times(other: Long): Long + public inline operator fun times(other: Long): Long = + this.toLong() * other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Byte_times_Float") - external public operator fun times(other: Float): Float + public inline operator fun times(other: Float): Float = + this.toFloat() * other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Byte_times_Double") - external public operator fun times(other: Double): Double + public inline operator fun times(other: Double): Double = + this.toDouble() * other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Byte_div_Byte") - external public operator fun div(other: Byte): Int + public inline operator fun div(other: Byte): Int = + this.toInt() / other.toInt() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Byte_div_Short") - external public operator fun div(other: Short): Int + public inline operator fun div(other: Short): Int = + this.toInt() / other.toInt() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Byte_div_Int") - external public operator fun div(other: Int): Int + public inline operator fun div(other: Int): Int = + this.toInt() / other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Byte_div_Long") - external public operator fun div(other: Long): Long + public inline operator fun div(other: Long): Long = + this.toLong() / other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Byte_div_Float") - external public operator fun div(other: Float): Float + public inline operator fun div(other: Float): Float = + this.toFloat() / other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Byte_div_Double") - external public operator fun div(other: Double): Double + public inline operator fun div(other: Double): Double = + this.toDouble() / other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Byte_mod_Byte") - external public operator fun rem(other: Byte): Int + public inline operator fun rem(other: Byte): Int = + this.toInt() % other.toInt() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Byte_mod_Short") - external public operator fun rem(other: Short): Int + public inline operator fun rem(other: Short): Int = + this.toInt() % other.toInt() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Byte_mod_Int") - external public operator fun rem(other: Int): Int + public inline operator fun rem(other: Int): Int = + this.toInt() % other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Byte_mod_Long") - external public operator fun rem(other: Long): Long + public inline operator fun rem(other: Long): Long = + this.toLong() % other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Byte_mod_Float") - external public operator fun rem(other: Float): Float + public inline operator fun rem(other: Float): Float = + this.toFloat() % other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Byte_mod_Double") - external public operator fun rem(other: Double): Double + public inline operator fun rem(other: Double): Double = + this.toDouble() % other /** Increments this value. */ - @SymbolName("Kotlin_Byte_inc") + @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Byte /** Decrements this value. */ - @SymbolName("Kotlin_Byte_dec") + @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Byte /** Returns this value. */ - @SymbolName("Kotlin_Byte_unaryPlus") - external public operator fun unaryPlus(): Int + public inline operator fun unaryPlus(): Int = + this.toInt() /** Returns the negative of this value. */ - @SymbolName("Kotlin_Byte_unaryMinus") - external public operator fun unaryMinus(): Int + public inline operator fun unaryMinus(): Int = + -this.toInt() - @SymbolName("Kotlin_Byte_toByte") - external public override fun toByte(): Byte - @SymbolName("Kotlin_Byte_toChar") + public inline override fun toByte(): Byte = + this + @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toChar(): Char - @SymbolName("Kotlin_Byte_toShort") + @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toShort(): Short - @SymbolName("Kotlin_Byte_toInt") + @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toInt(): Int - @SymbolName("Kotlin_Byte_toLong") + @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toLong(): Long - @SymbolName("Kotlin_Byte_toFloat") + @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toFloat(): Float - @SymbolName("Kotlin_Byte_toDouble") + @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toDouble(): Double /** Creates a range from this value to the specified [other] value. */ @@ -266,151 +270,151 @@ public final class Short private constructor(private val value: kotlin.native.in * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Short_compareTo_Byte") - external public operator fun compareTo(other: Byte): Int + public inline operator fun compareTo(other: Byte): Int = + this.compareTo(other.toShort()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Short_compareTo_Short") + @TypedIntrinsic(IntrinsicType.SIGNED_COMPARE_TO) external public override operator fun compareTo(other: Short): Int /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Short_compareTo_Int") - external public operator fun compareTo(other: Int): Int + public inline operator fun compareTo(other: Int): Int = + this.toInt().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Short_compareTo_Long") - external public operator fun compareTo(other: Long): Int + public inline operator fun compareTo(other: Long): Int = + this.toLong().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Short_compareTo_Float") - external public operator fun compareTo(other: Float): Int + public inline operator fun compareTo(other: Float): Int = + this.toFloat().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Short_compareTo_Double") - external public operator fun compareTo(other: Double): Int + public inline operator fun compareTo(other: Double): Int = + this.toDouble().compareTo(other) /** Adds the other value to this value. */ - @SymbolName("Kotlin_Short_plus_Byte") - external public operator fun plus(other: Byte): Int + public inline operator fun plus(other: Byte): Int = + this.toInt() + other.toInt() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Short_plus_Short") - external public operator fun plus(other: Short): Int + public inline operator fun plus(other: Short): Int = + this.toInt() + other.toInt() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Short_plus_Int") - external public operator fun plus(other: Int): Int + public inline operator fun plus(other: Int): Int = + this.toInt() + other /** Adds the other value to this value. */ - @SymbolName("Kotlin_Short_plus_Long") - external public operator fun plus(other: Long): Long + public inline operator fun plus(other: Long): Long = + this.toLong() + other /** Adds the other value to this value. */ - @SymbolName("Kotlin_Short_plus_Float") - external public operator fun plus(other: Float): Float + public inline operator fun plus(other: Float): Float = + this.toFloat() + other /** Adds the other value to this value. */ - @SymbolName("Kotlin_Short_plus_Double") - external public operator fun plus(other: Double): Double + public inline operator fun plus(other: Double): Double = + this.toDouble() + other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Short_minus_Byte") - external public operator fun minus(other: Byte): Int + public inline operator fun minus(other: Byte): Int = + this.toInt() - other.toInt() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Short_minus_Short") - external public operator fun minus(other: Short): Int + public inline operator fun minus(other: Short): Int = + this.toInt() - other.toInt() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Short_minus_Int") - external public operator fun minus(other: Int): Int + public inline operator fun minus(other: Int): Int = + this.toInt() - other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Short_minus_Long") - external public operator fun minus(other: Long): Long + public inline operator fun minus(other: Long): Long = + this.toLong() - other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Short_minus_Float") - external public operator fun minus(other: Float): Float + public inline operator fun minus(other: Float): Float = + this.toFloat() - other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Short_minus_Double") - external public operator fun minus(other: Double): Double + public inline operator fun minus(other: Double): Double = + this.toDouble() - other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Short_times_Byte") - external public operator fun times(other: Byte): Int + public inline operator fun times(other: Byte): Int = + this.toInt() * other.toInt() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Short_times_Short") - external public operator fun times(other: Short): Int + public inline operator fun times(other: Short): Int = + this.toInt() * other.toInt() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Short_times_Int") - external public operator fun times(other: Int): Int + public inline operator fun times(other: Int): Int = + this.toInt() * other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Short_times_Long") - external public operator fun times(other: Long): Long + public inline operator fun times(other: Long): Long = + this.toLong() * other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Short_times_Float") - external public operator fun times(other: Float): Float + public inline operator fun times(other: Float): Float = + this.toFloat() * other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Short_times_Double") - external public operator fun times(other: Double): Double + public inline operator fun times(other: Double): Double = + this.toDouble() * other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Short_div_Byte") - external public operator fun div(other: Byte): Int + public inline operator fun div(other: Byte): Int = + this.toInt() / other.toInt() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Short_div_Short") - external public operator fun div(other: Short): Int + public inline operator fun div(other: Short): Int = + this.toInt() / other.toInt() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Short_div_Int") - external public operator fun div(other: Int): Int + public inline operator fun div(other: Int): Int = + this.toInt() / other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Short_div_Long") - external public operator fun div(other: Long): Long + public inline operator fun div(other: Long): Long = + this.toLong() / other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Short_div_Float") - external public operator fun div(other: Float): Float + public inline operator fun div(other: Float): Float = + this.toFloat() / other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Short_div_Double") - external public operator fun div(other: Double): Double + public inline operator fun div(other: Double): Double = + this.toDouble() / other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Short_mod_Byte") - external public operator fun rem(other: Byte): Int + public inline operator fun rem(other: Byte): Int = + this.toInt() % other.toInt() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Short_mod_Short") - external public operator fun rem(other: Short): Int + public inline operator fun rem(other: Short): Int = + this.toInt() % other.toInt() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Short_mod_Int") - external public operator fun rem(other: Int): Int + public inline operator fun rem(other: Int): Int = + this.toInt() % other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Short_mod_Long") - external public operator fun rem(other: Long): Long + public inline operator fun rem(other: Long): Long = + this.toLong() % other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Short_mod_Float") - external public operator fun rem(other: Float): Float + public inline operator fun rem(other: Float): Float = + this.toFloat() % other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Short_mod_Double") - external public operator fun rem(other: Double): Double + public inline operator fun rem(other: Double): Double = + this.toDouble() % other /** Increments this value. */ - @SymbolName("Kotlin_Short_inc") + @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Short /** Decrements this value. */ - @SymbolName("Kotlin_Short_dec") + @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Short /** Returns this value. */ - @SymbolName("Kotlin_Short_unaryPlus") - external public operator fun unaryPlus(): Int + public operator fun unaryPlus(): Int = + this.toInt() /** Returns the negative of this value. */ - @SymbolName("Kotlin_Short_unaryMinus") - external public operator fun unaryMinus(): Int + public inline operator fun unaryMinus(): Int = + -this.toInt() /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Byte): IntRange { @@ -429,19 +433,20 @@ public final class Short private constructor(private val value: kotlin.native.in return LongRange(this.toLong(), other.toLong()) } - @SymbolName("Kotlin_Short_toByte") + @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toByte(): Byte - @SymbolName("Kotlin_Short_toChar") + @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) external public override fun toChar(): Char - @SymbolName("Kotlin_Short_toShort") - external public override fun toShort(): Short - @SymbolName("Kotlin_Short_toInt") + + public inline override fun toShort(): Short = + this + @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toInt(): Int - @SymbolName("Kotlin_Short_toLong") + @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toLong(): Long - @SymbolName("Kotlin_Short_toFloat") + @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toFloat(): Float - @SymbolName("Kotlin_Short_toDouble") + @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toDouble(): Double // Konan-specific. @@ -491,172 +496,172 @@ public final class Int private constructor(private val value: kotlin.native.inte * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Int_compareTo_Byte") - external public operator fun compareTo(other: Byte): Int + public inline operator fun compareTo(other: Byte): Int = + this.compareTo(other.toInt()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Int_compareTo_Short") - external public operator fun compareTo(other: Short): Int + public inline operator fun compareTo(other: Short): Int = + this.compareTo(other.toInt()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Int_compareTo_Int") + @TypedIntrinsic(IntrinsicType.SIGNED_COMPARE_TO) external public override operator fun compareTo(other: Int): Int /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Int_compareTo_Long") - external public operator fun compareTo(other: Long): Int + public inline operator fun compareTo(other: Long): Int = + this.toLong().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Int_compareTo_Float") - external public operator fun compareTo(other: Float): Int + public inline operator fun compareTo(other: Float): Int = + this.toFloat().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Int_compareTo_Double") - external public operator fun compareTo(other: Double): Int + public inline operator fun compareTo(other: Double): Int = + this.toDouble().compareTo(other) /** Adds the other value to this value. */ - @SymbolName("Kotlin_Int_plus_Byte") - external public operator fun plus(other: Byte): Int + public inline operator fun plus(other: Byte): Int = + this + other.toInt() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Int_plus_Short") - external public operator fun plus(other: Short): Int + public inline operator fun plus(other: Short): Int = + this + other.toInt() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Int_plus_Int") + @TypedIntrinsic(IntrinsicType.PLUS) external public operator fun plus(other: Int): Int /** Adds the other value to this value. */ - @SymbolName("Kotlin_Int_plus_Long") - external public operator fun plus(other: Long): Long + public inline operator fun plus(other: Long): Long = + this.toLong() + other /** Adds the other value to this value. */ - @SymbolName("Kotlin_Int_plus_Float") - external public operator fun plus(other: Float): Float + public inline operator fun plus(other: Float): Float = + this.toFloat() + other /** Adds the other value to this value. */ - @SymbolName("Kotlin_Int_plus_Double") - external public operator fun plus(other: Double): Double + public inline operator fun plus(other: Double): Double = + this.toDouble() + other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Int_minus_Byte") - external public operator fun minus(other: Byte): Int + public inline operator fun minus(other: Byte): Int = + this - other.toInt() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Int_minus_Short") - external public operator fun minus(other: Short): Int + public inline operator fun minus(other: Short): Int = + this - other.toInt() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Int_minus_Int") + @TypedIntrinsic(IntrinsicType.MINUS) external public operator fun minus(other: Int): Int /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Int_minus_Long") - external public operator fun minus(other: Long): Long + public inline operator fun minus(other: Long): Long = + this.toLong() - other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Int_minus_Float") - external public operator fun minus(other: Float): Float + public inline operator fun minus(other: Float): Float = + this.toFloat() - other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Int_minus_Double") - external public operator fun minus(other: Double): Double + public inline operator fun minus(other: Double): Double = + this.toDouble() - other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Int_times_Byte") - external public operator fun times(other: Byte): Int + public inline operator fun times(other: Byte): Int = + this * other.toInt() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Int_times_Short") - external public operator fun times(other: Short): Int + public inline operator fun times(other: Short): Int = + this * other.toInt() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Int_times_Int") + @TypedIntrinsic(IntrinsicType.TIMES) external public operator fun times(other: Int): Int /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Int_times_Long") - external public operator fun times(other: Long): Long + public inline operator fun times(other: Long): Long = + this.toLong() * other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Int_times_Float") - external public operator fun times(other: Float): Float + public inline operator fun times(other: Float): Float = + this.toFloat() * other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Int_times_Double") - external public operator fun times(other: Double): Double + public inline operator fun times(other: Double): Double = + this.toDouble() * other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Int_div_Byte") - external public operator fun div(other: Byte): Int + public inline operator fun div(other: Byte): Int = + this / other.toInt() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Int_div_Short") - external public operator fun div(other: Short): Int + public inline operator fun div(other: Short): Int = + this / other.toInt() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Int_div_Int") + @TypedIntrinsic(IntrinsicType.SIGNED_DIV) external public operator fun div(other: Int): Int /** Divides this value by the other value. */ - @SymbolName("Kotlin_Int_div_Long") - external public operator fun div(other: Long): Long + public inline operator fun div(other: Long): Long = + this.toLong() / other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Int_div_Float") - external public operator fun div(other: Float): Float + public inline operator fun div(other: Float): Float = + this.toFloat() / other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Int_div_Double") - external public operator fun div(other: Double): Double + public inline operator fun div(other: Double): Double = + this.toDouble() / other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Int_mod_Byte") - external public operator fun rem(other: Byte): Int + public inline operator fun rem(other: Byte): Int = + this % other.toInt() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Int_mod_Short") - external public operator fun rem(other: Short): Int + public inline operator fun rem(other: Short): Int = + this % other.toInt() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Int_mod_Int") + @TypedIntrinsic(IntrinsicType.SIGNED_REM) external public operator fun rem(other: Int): Int /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Int_mod_Long") - external public operator fun rem(other: Long): Long + public inline operator fun rem(other: Long): Long = + this.toLong() % other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Int_mod_Float") - external public operator fun rem(other: Float): Float + public inline operator fun rem(other: Float): Float = + this.toFloat() % other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Int_mod_Double") - external public operator fun rem(other: Double): Double + public inline operator fun rem(other: Double): Double = + this.toDouble() % other /** Increments this value. */ - @SymbolName("Kotlin_Int_inc") + @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Int /** Decrements this value. */ - @SymbolName("Kotlin_Int_dec") + @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Int /** Returns this value. */ - @SymbolName("Kotlin_Int_unaryPlus") + @TypedIntrinsic(IntrinsicType.UNARY_PLUS) external public operator fun unaryPlus(): Int /** Returns the negative of this value. */ - @SymbolName("Kotlin_Int_unaryMinus") + @TypedIntrinsic(IntrinsicType.UNARY_MINUS) external public operator fun unaryMinus(): Int /** Shifts this value left by the [bitCount] number of bits. */ - @SymbolName("Kotlin_Int_shl_Int") + @TypedIntrinsic(IntrinsicType.SHL) external public infix fun shl(bitCount: Int): Int /** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit. */ - @SymbolName("Kotlin_Int_shr_Int") + @TypedIntrinsic(IntrinsicType.SHR) external public infix fun shr(bitCount: Int): Int /** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros. */ - @SymbolName("Kotlin_Int_ushr_Int") + @TypedIntrinsic(IntrinsicType.USHR) external public infix fun ushr(bitCount: Int): Int /** Performs a bitwise AND operation between the two values. */ - @SymbolName("Kotlin_Int_and_Int") + @TypedIntrinsic(IntrinsicType.AND) external public infix fun and(other: Int): Int /** Performs a bitwise OR operation between the two values. */ - @SymbolName("Kotlin_Int_or_Int") + @TypedIntrinsic(IntrinsicType.OR) external public infix fun or(other: Int): Int /** Performs a bitwise XOR operation between the two values. */ - @SymbolName("Kotlin_Int_xor_Int") + @TypedIntrinsic(IntrinsicType.XOR) external public infix fun xor(other: Int): Int /** Inverts the bits in this value. */ - @SymbolName("Kotlin_Int_inv") + @TypedIntrinsic(IntrinsicType.INV) external public fun inv(): Int /** Creates a range from this value to the specified [other] value. */ @@ -676,19 +681,20 @@ public final class Int private constructor(private val value: kotlin.native.inte return LongRange(this.toLong(), other.toLong()) } - @SymbolName("Kotlin_Int_toByte") + @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toByte(): Byte - @SymbolName("Kotlin_Int_toChar") + @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toChar(): Char - @SymbolName("Kotlin_Int_toShort") + @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toShort(): Short - @SymbolName("Kotlin_Int_toInt") - external public override fun toInt(): Int - @SymbolName("Kotlin_Int_toLong") + + public inline override fun toInt(): Int = + this + @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toLong(): Long - @SymbolName("Kotlin_Int_toFloat") + @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toFloat(): Float - @SymbolName("Kotlin_Int_toDouble") + @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toDouble(): Double // Konan-specific. @@ -738,150 +744,150 @@ public final class Long private constructor(private val value: kotlin.native.int * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Long_compareTo_Byte") - external public operator fun compareTo(other: Byte): Int + public inline operator fun compareTo(other: Byte): Int = + this.compareTo(other.toLong()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Long_compareTo_Short") - external public operator fun compareTo(other: Short): Int + public inline operator fun compareTo(other: Short): Int = + this.compareTo(other.toLong()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Long_compareTo_Int") - external public operator fun compareTo(other: Int): Int + public inline operator fun compareTo(other: Int): Int = + this.compareTo(other.toLong()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Long_compareTo_Long") + @TypedIntrinsic(IntrinsicType.SIGNED_COMPARE_TO) external public override operator fun compareTo(other: Long): Int /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Long_compareTo_Float") - external public operator fun compareTo(other: Float): Int + public inline operator fun compareTo(other: Float): Int = + this.toFloat().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @SymbolName("Kotlin_Long_compareTo_Double") - external public operator fun compareTo(other: Double): Int + public inline operator fun compareTo(other: Double): Int = + this.toDouble().compareTo(other) /** Adds the other value to this value. */ - @SymbolName("Kotlin_Long_plus_Byte") - external public operator fun plus(other: Byte): Long + public inline operator fun plus(other: Byte): Long = + this + other.toLong() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Long_plus_Short") - external public operator fun plus(other: Short): Long + public inline operator fun plus(other: Short): Long = + this + other.toLong() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Long_plus_Int") - external public operator fun plus(other: Int): Long + public inline operator fun plus(other: Int): Long = + this + other.toLong() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Long_plus_Long") + @TypedIntrinsic(IntrinsicType.PLUS) external public operator fun plus(other: Long): Long /** Adds the other value to this value. */ - @SymbolName("Kotlin_Long_plus_Float") - external public operator fun plus(other: Float): Float + public inline operator fun plus(other: Float): Float = + this.toFloat() + other /** Adds the other value to this value. */ - @SymbolName("Kotlin_Long_plus_Double") - external public operator fun plus(other: Double): Double + public inline operator fun plus(other: Double): Double = + this.toDouble() + other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Long_minus_Byte") - external public operator fun minus(other: Byte): Long + public inline operator fun minus(other: Byte): Long = + this - other.toLong() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Long_minus_Short") - external public operator fun minus(other: Short): Long + public inline operator fun minus(other: Short): Long = + this - other.toLong() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Long_minus_Int") - external public operator fun minus(other: Int): Long + public inline operator fun minus(other: Int): Long = + this - other.toLong() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Long_minus_Long") + @TypedIntrinsic(IntrinsicType.MINUS) external public operator fun minus(other: Long): Long /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Long_minus_Float") - external public operator fun minus(other: Float): Float + public inline operator fun minus(other: Float): Float = + this.toFloat() - other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Long_minus_Double") - external public operator fun minus(other: Double): Double + public inline operator fun minus(other: Double): Double = + this.toDouble() - other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Long_times_Byte") - external public operator fun times(other: Byte): Long + public inline operator fun times(other: Byte): Long = + this * other.toLong() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Long_times_Short") - external public operator fun times(other: Short): Long + public inline operator fun times(other: Short): Long = + this * other.toLong() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Long_times_Int") - external public operator fun times(other: Int): Long + public inline operator fun times(other: Int): Long = + this * other.toLong() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Long_times_Long") + @TypedIntrinsic(IntrinsicType.TIMES) external public operator fun times(other: Long): Long /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Long_times_Float") - external public operator fun times(other: Float): Float + public inline operator fun times(other: Float): Float = + this.toFloat() * other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Long_times_Double") - external public operator fun times(other: Double): Double + public inline operator fun times(other: Double): Double = + this.toDouble() * other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Long_div_Byte") - external public operator fun div(other: Byte): Long + public inline operator fun div(other: Byte): Long = + this / other.toLong() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Long_div_Short") - external public operator fun div(other: Short): Long + public inline operator fun div(other: Short): Long = + this / other.toLong() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Long_div_Int") - external public operator fun div(other: Int): Long + public inline operator fun div(other: Int): Long = + this / other.toLong() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Long_div_Long") + @TypedIntrinsic(IntrinsicType.SIGNED_DIV) external public operator fun div(other: Long): Long /** Divides this value by the other value. */ - @SymbolName("Kotlin_Long_div_Float") - external public operator fun div(other: Float): Float + public inline operator fun div(other: Float): Float = + this.toFloat() / other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Long_div_Double") - external public operator fun div(other: Double): Double + public inline operator fun div(other: Double): Double = + this.toDouble() / other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Long_mod_Byte") - external public operator fun rem(other: Byte): Long + public inline operator fun rem(other: Byte): Long = + this % other.toLong() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Long_mod_Short") - external public operator fun rem(other: Short): Long + public inline operator fun rem(other: Short): Long = + this % other.toLong() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Long_mod_Int") - external public operator fun rem(other: Int): Long + public inline operator fun rem(other: Int): Long = + this % other.toLong() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Long_mod_Long") + @TypedIntrinsic(IntrinsicType.SIGNED_REM) external public operator fun rem(other: Long): Long /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Long_mod_Float") - external public operator fun rem(other: Float): Float + public inline operator fun rem(other: Float): Float = + this.toFloat() % other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Long_mod_Double") - external public operator fun rem(other: Double): Double + public inline operator fun rem(other: Double): Double = + this.toDouble() % other /** Increments this value. */ - @SymbolName("Kotlin_Long_inc") + @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Long /** Decrements this value. */ - @SymbolName("Kotlin_Long_dec") + @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Long /** Returns this value. */ - @SymbolName("Kotlin_Long_unaryPlus") - external public operator fun unaryPlus(): Long + public inline operator fun unaryPlus(): Long = + this /** Returns the negative of this value. */ - @SymbolName("Kotlin_Long_unaryMinus") + @TypedIntrinsic(IntrinsicType.UNARY_MINUS) external public operator fun unaryMinus(): Long /** Creates a range from this value to the specified [other] value. */ @@ -902,40 +908,41 @@ public final class Long private constructor(private val value: kotlin.native.int } /** Shifts this value left by the [bitCount] number of bits. */ - @SymbolName("Kotlin_Long_shl_Int") + @TypedIntrinsic(IntrinsicType.SHL) external public infix fun shl(bitCount: Int): Long /** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit. */ - @SymbolName("Kotlin_Long_shr_Int") + @TypedIntrinsic(IntrinsicType.SHR) external public infix fun shr(bitCount: Int): Long /** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros. */ - @SymbolName("Kotlin_Long_ushr_Int") + @TypedIntrinsic(IntrinsicType.USHR) external public infix fun ushr(bitCount: Int): Long /** Performs a bitwise AND operation between the two values. */ - @SymbolName("Kotlin_Long_and_Long") + @TypedIntrinsic(IntrinsicType.AND) external public infix fun and(other: Long): Long /** Performs a bitwise OR operation between the two values. */ - @SymbolName("Kotlin_Long_or_Long") + @TypedIntrinsic(IntrinsicType.OR) external public infix fun or(other: Long): Long /** Performs a bitwise XOR operation between the two values. */ - @SymbolName("Kotlin_Long_xor_Long") + @TypedIntrinsic(IntrinsicType.XOR) external public infix fun xor(other: Long): Long /** Inverts the bits in this value. */ - @SymbolName("Kotlin_Long_inv") + @TypedIntrinsic(IntrinsicType.INV) external public fun inv(): Long - @SymbolName("Kotlin_Long_toByte") + @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toByte(): Byte - @SymbolName("Kotlin_Long_toChar") + @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toChar(): Char - @SymbolName("Kotlin_Long_toShort") + @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toShort(): Short - @SymbolName("Kotlin_Long_toInt") + @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toInt(): Int - @SymbolName("Kotlin_Long_toLong") - external public override fun toLong(): Long - @SymbolName("Kotlin_Long_toFloat") + + public inline override fun toLong(): Long = + this + @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toFloat(): Float - @SymbolName("Kotlin_Long_toDouble") + @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toDouble(): Double // Konan-specific. @@ -1034,111 +1041,111 @@ public final class Float private constructor(private val value: kotlin.native.in public operator fun compareTo(other: Double): Int = - other.compareTo(this) /** Adds the other value to this value. */ - @SymbolName("Kotlin_Float_plus_Byte") - external public operator fun plus(other: Byte): Float + public inline operator fun plus(other: Byte): Float = + this + other.toFloat() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Float_plus_Short") - external public operator fun plus(other: Short): Float + public inline operator fun plus(other: Short): Float = + this + other.toFloat() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Float_plus_Int") - external public operator fun plus(other: Int): Float + public inline operator fun plus(other: Int): Float = + this + other.toFloat() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Float_plus_Long") - external public operator fun plus(other: Long): Float + public inline operator fun plus(other: Long): Float = + this + other.toFloat() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Float_plus_Float") + @TypedIntrinsic(IntrinsicType.PLUS) external public operator fun plus(other: Float): Float /** Adds the other value to this value. */ - @SymbolName("Kotlin_Float_plus_Double") - external public operator fun plus(other: Double): Double + public inline operator fun plus(other: Double): Double = + this.toDouble() + other /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Float_minus_Byte") - external public operator fun minus(other: Byte): Float + public inline operator fun minus(other: Byte): Float = + this - other.toFloat() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Float_minus_Short") - external public operator fun minus(other: Short): Float + public inline operator fun minus(other: Short): Float = + this - other.toFloat() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Float_minus_Int") - external public operator fun minus(other: Int): Float + public inline operator fun minus(other: Int): Float = + this - other.toFloat() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Float_minus_Long") - external public operator fun minus(other: Long): Float + public inline operator fun minus(other: Long): Float = + this - other.toFloat() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Float_minus_Float") + @TypedIntrinsic(IntrinsicType.MINUS) external public operator fun minus(other: Float): Float /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Float_minus_Double") - external public operator fun minus(other: Double): Double + public inline operator fun minus(other: Double): Double = + this.toDouble() - other /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Float_times_Byte") - external public operator fun times(other: Byte): Float + public inline operator fun times(other: Byte): Float = + this * other.toFloat() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Float_times_Short") - external public operator fun times(other: Short): Float + public inline operator fun times(other: Short): Float = + this * other.toFloat() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Float_times_Int") - external public operator fun times(other: Int): Float + public inline operator fun times(other: Int): Float = + this * other.toFloat() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Float_times_Long") - external public operator fun times(other: Long): Float + public inline operator fun times(other: Long): Float = + this * other.toFloat() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Float_times_Float") + @TypedIntrinsic(IntrinsicType.TIMES) external public operator fun times(other: Float): Float /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Float_times_Double") - external public operator fun times(other: Double): Double + public inline operator fun times(other: Double): Double = + this.toDouble() * other /** Divides this value by the other value. */ - @SymbolName("Kotlin_Float_div_Byte") - external public operator fun div(other: Byte): Float + public inline operator fun div(other: Byte): Float = + this / other.toFloat() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Float_div_Short") - external public operator fun div(other: Short): Float + public inline operator fun div(other: Short): Float = + this / other.toFloat() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Float_div_Int") - external public operator fun div(other: Int): Float + public inline operator fun div(other: Int): Float = + this / other.toFloat() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Float_div_Long") - external public operator fun div(other: Long): Float + public inline operator fun div(other: Long): Float = + this / other.toFloat() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Float_div_Float") + @TypedIntrinsic(IntrinsicType.SIGNED_DIV) external public operator fun div(other: Float): Float /** Divides this value by the other value. */ - @SymbolName("Kotlin_Float_div_Double") - external public operator fun div(other: Double): Double + public inline operator fun div(other: Double): Double = + this.toDouble() / other /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Float_mod_Byte") - external public operator fun rem(other: Byte): Float + public inline operator fun rem(other: Byte): Float = + this % other.toFloat() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Float_mod_Short") - external public operator fun rem(other: Short): Float + public inline operator fun rem(other: Short): Float = + this % other.toFloat() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Float_mod_Int") - external public operator fun rem(other: Int): Float + public inline operator fun rem(other: Int): Float = + this % other.toFloat() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Float_mod_Long") - external public operator fun rem(other: Long): Float + public inline operator fun rem(other: Long): Float = + this % other.toFloat() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Float_mod_Float") + @TypedIntrinsic(IntrinsicType.SIGNED_REM) external public operator fun rem(other: Float): Float /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Float_mod_Double") - external public operator fun rem(other: Double): Double + public inline operator fun rem(other: Double): Double = + this.toDouble() % other /** Increments this value. */ - @SymbolName("Kotlin_Float_inc") + @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Float /** Decrements this value. */ - @SymbolName("Kotlin_Float_dec") + @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Float /** Returns this value. */ - @SymbolName("Kotlin_Float_unaryPlus") + @TypedIntrinsic(IntrinsicType.UNARY_PLUS) external public operator fun unaryPlus(): Float /** Returns the negative of this value. */ - @SymbolName("Kotlin_Float_unaryMinus") + @TypedIntrinsic(IntrinsicType.UNARY_MINUS) external public operator fun unaryMinus(): Float public override fun toByte(): Byte = this.toInt().toByte() @@ -1151,9 +1158,10 @@ public final class Float private constructor(private val value: kotlin.native.in external public override fun toInt(): Int @SymbolName("Kotlin_Float_toLong") external public override fun toLong(): Long - @SymbolName("Kotlin_Float_toFloat") - external public override fun toFloat(): Float - @SymbolName("Kotlin_Float_toDouble") + + public inline override fun toFloat(): Float = + this + @TypedIntrinsic(IntrinsicType.FLOAT_EXTEND) external public override fun toDouble(): Double public fun equals(other: Float): Boolean = toBits() == other.toBits() @@ -1166,7 +1174,7 @@ public final class Float private constructor(private val value: kotlin.native.in return bits() } - @SymbolName("Kotlin_Float_bits") + @TypedIntrinsic(IntrinsicType.TO_BITS) @PublishedApi external internal fun bits(): Int } @@ -1257,111 +1265,111 @@ public final class Double private constructor(private val value: kotlin.native.i } /** Adds the other value to this value. */ - @SymbolName("Kotlin_Double_plus_Byte") - external public operator fun plus(other: Byte): Double + public inline operator fun plus(other: Byte): Double = + this + other.toDouble() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Double_plus_Short") - external public operator fun plus(other: Short): Double + public inline operator fun plus(other: Short): Double = + this + other.toDouble() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Double_plus_Int") - external public operator fun plus(other: Int): Double + public inline operator fun plus(other: Int): Double = + this + other.toDouble() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Double_plus_Long") - external public operator fun plus(other: Long): Double + public inline operator fun plus(other: Long): Double = + this + other.toDouble() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Double_plus_Float") - external public operator fun plus(other: Float): Double + public inline operator fun plus(other: Float): Double = + this + other.toDouble() /** Adds the other value to this value. */ - @SymbolName("Kotlin_Double_plus_Double") + @TypedIntrinsic(IntrinsicType.PLUS) external public operator fun plus(other: Double): Double /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Double_minus_Byte") - external public operator fun minus(other: Byte): Double + public inline operator fun minus(other: Byte): Double = + this - other.toDouble() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Double_minus_Short") - external public operator fun minus(other: Short): Double + public inline operator fun minus(other: Short): Double = + this - other.toDouble() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Double_minus_Int") - external public operator fun minus(other: Int): Double + public inline operator fun minus(other: Int): Double = + this - other.toDouble() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Double_minus_Long") - external public operator fun minus(other: Long): Double + public inline operator fun minus(other: Long): Double = + this - other.toDouble() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Double_minus_Float") - external public operator fun minus(other: Float): Double + public inline operator fun minus(other: Float): Double = + this - other.toDouble() /** Subtracts the other value from this value. */ - @SymbolName("Kotlin_Double_minus_Double") + @TypedIntrinsic(IntrinsicType.MINUS) external public operator fun minus(other: Double): Double /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Double_times_Byte") - external public operator fun times(other: Byte): Double + public inline operator fun times(other: Byte): Double = + this * other.toDouble() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Double_times_Short") - external public operator fun times(other: Short): Double + public inline operator fun times(other: Short): Double = + this * other.toDouble() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Double_times_Int") - external public operator fun times(other: Int): Double + public inline operator fun times(other: Int): Double = + this * other.toDouble() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Double_times_Long") - external public operator fun times(other: Long): Double + public inline operator fun times(other: Long): Double = + this * other.toDouble() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Double_times_Float") - external public operator fun times(other: Float): Double + public inline operator fun times(other: Float): Double = + this * other.toDouble() /** Multiplies this value by the other value. */ - @SymbolName("Kotlin_Double_times_Double") + @TypedIntrinsic(IntrinsicType.TIMES) external public operator fun times(other: Double): Double /** Divides this value by the other value. */ - @SymbolName("Kotlin_Double_div_Byte") - external public operator fun div(other: Byte): Double + public inline operator fun div(other: Byte): Double = + this / other.toDouble() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Double_div_Short") - external public operator fun div(other: Short): Double + public inline operator fun div(other: Short): Double = + this / other.toDouble() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Double_div_Int") - external public operator fun div(other: Int): Double + public inline operator fun div(other: Int): Double = + this / other.toDouble() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Double_div_Long") - external public operator fun div(other: Long): Double + public inline operator fun div(other: Long): Double = + this / other.toDouble() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Double_div_Float") - external public operator fun div(other: Float): Double + public inline operator fun div(other: Float): Double = + this / other.toDouble() /** Divides this value by the other value. */ - @SymbolName("Kotlin_Double_div_Double") + @TypedIntrinsic(IntrinsicType.SIGNED_DIV) external public operator fun div(other: Double): Double /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Double_mod_Byte") - external public operator fun rem(other: Byte): Double + public inline operator fun rem(other: Byte): Double = + this % other.toDouble() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Double_mod_Short") - external public operator fun rem(other: Short): Double + public inline operator fun rem(other: Short): Double = + this % other.toDouble() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Double_mod_Int") - external public operator fun rem(other: Int): Double + public inline operator fun rem(other: Int): Double = + this % other.toDouble() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Double_mod_Long") - external public operator fun rem(other: Long): Double + public inline operator fun rem(other: Long): Double = + this % other.toDouble() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Double_mod_Float") - external public operator fun rem(other: Float): Double + public inline operator fun rem(other: Float): Double = + this % other.toDouble() /** Calculates the remainder of dividing this value by the other value. */ - @SymbolName("Kotlin_Double_mod_Double") + @TypedIntrinsic(IntrinsicType.SIGNED_REM) external public operator fun rem(other: Double): Double /** Increments this value. */ - @SymbolName("Kotlin_Double_inc") + @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Double /** Decrements this value. */ - @SymbolName("Kotlin_Double_dec") + @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Double /** Returns this value. */ - @SymbolName("Kotlin_Double_unaryPlus") + @TypedIntrinsic(IntrinsicType.UNARY_PLUS) external public operator fun unaryPlus(): Double /** Returns the negative of this value. */ - @SymbolName("Kotlin_Double_unaryMinus") + @TypedIntrinsic(IntrinsicType.UNARY_MINUS) external public operator fun unaryMinus(): Double public override fun toByte(): Byte = this.toInt().toByte() @@ -1374,10 +1382,11 @@ public final class Double private constructor(private val value: kotlin.native.i external public override fun toInt(): Int @SymbolName("Kotlin_Double_toLong") external public override fun toLong(): Long - @SymbolName("Kotlin_Double_toFloat") + @TypedIntrinsic(IntrinsicType.FLOAT_TRUNCATE) external public override fun toFloat(): Float - @SymbolName("Kotlin_Double_toDouble") - external public override fun toDouble(): Double + + public inline override fun toDouble(): Double = + this public fun equals(other: Double): Boolean = toBits() == other.toBits() @@ -1387,7 +1396,7 @@ public final class Double private constructor(private val value: kotlin.native.i public override fun hashCode(): Int = bits().hashCode() - @SymbolName("Kotlin_Double_bits") + @TypedIntrinsic(IntrinsicType.TO_BITS) @PublishedApi external internal fun bits(): Long } diff --git a/runtime/src/main/kotlin/kotlin/native/internal/Annotations.kt b/runtime/src/main/kotlin/kotlin/native/internal/Annotations.kt index 3b2cd453752..c600fbe42cb 100644 --- a/runtime/src/main/kotlin/kotlin/native/internal/Annotations.kt +++ b/runtime/src/main/kotlin/kotlin/native/internal/Annotations.kt @@ -95,3 +95,8 @@ internal annotation class Escapes(val who: Int) @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.BINARY) internal annotation class PointsTo(vararg val onWhom: Int) + + +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.BINARY) +internal annotation class TypedIntrinsic(val kind: String) \ No newline at end of file diff --git a/runtime/src/main/kotlin/kotlin/native/internal/IntrinsicType.kt b/runtime/src/main/kotlin/kotlin/native/internal/IntrinsicType.kt new file mode 100644 index 00000000000..247d77aa9c4 --- /dev/null +++ b/runtime/src/main/kotlin/kotlin/native/internal/IntrinsicType.kt @@ -0,0 +1,37 @@ +package kotlin.native.internal + +class IntrinsicType { + companion object { + const val PLUS = "PLUS" + const val MINUS = "MINUS" + const val TIMES = "TIMES" + const val SIGNED_DIV = "SIGNED_DIV" + const val SIGNED_REM = "SIGNED_REM" + const val UNSIGNED_DIV = "UNSIGNED_DIV" + const val UNSIGNED_REM = "UNSIGNED_REM" + const val INC = "INC" + const val DEC = "DEC" + const val UNARY_PLUS = "UNARY_PLUS" + const val UNARY_MINUS = "UNARY_MINUS" + const val SHL = "SHL" + const val SHR = "SHR" + const val USHR = "USHR" + const val AND = "AND" + const val OR = "OR" + const val XOR = "XOR" + const val INV = "INV" + const val SIGN_EXTEND = "SIGN_EXTEND" + const val ZERO_EXTEND = "ZERO_EXTEND" + const val INT_TRUNCATE = "INT_TRUNCATE" + const val FLOAT_TRUNCATE = "FLOAT_TRUNCATE" + const val FLOAT_EXTEND = "FLOAT_EXTEND" + const val SIGNED_TO_FLOAT = "SIGNED_TO_FLOAT" + const val UNSIGNED_TO_FLOAT = "UNSIGNED_TO_FLOAT" + const val FLOAT_TO_SIGNED = "FLOAT_TO_SIGNED" + const val SIGNED_COMPARE_TO = "SIGNED_COMPARE_TO" + const val UNSIGNED_COMPARE_TO = "UNSIGNED_COMPARE_TO" + const val NOT = "NOT" + const val TO_BITS = "TO_BITS" + const val FROM_BITS = "FROM_BITS" + } +} \ No newline at end of file diff --git a/runtime/src/main/kotlin/kotlin/native/internal/RuntimeUtils.kt b/runtime/src/main/kotlin/kotlin/native/internal/RuntimeUtils.kt index 168547af2fe..7515fce620e 100644 --- a/runtime/src/main/kotlin/kotlin/native/internal/RuntimeUtils.kt +++ b/runtime/src/main/kotlin/kotlin/native/internal/RuntimeUtils.kt @@ -32,7 +32,6 @@ fun ThrowInvalidReceiverTypeException(klass: KClass<*>): Nothing { throw RuntimeException("Unexpected receiver type: " + (klass.qualifiedName ?: "noname")) } -@ExportForCppRuntime internal fun ThrowArithmeticException() : Nothing { throw ArithmeticException() }