IR: add isUnsignedType/getUnsignedType
This commit is contained in:
+4
-4
@@ -5,13 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter
|
||||
|
||||
import org.jetbrains.kotlin.ir.interpreter.builtins.compileTimeAnnotation
|
||||
import org.jetbrains.kotlin.ir.interpreter.builtins.contractsDslAnnotation
|
||||
import org.jetbrains.kotlin.ir.interpreter.builtins.evaluateIntrinsicAnnotation
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.interpreter.builtins.compileTimeAnnotation
|
||||
import org.jetbrains.kotlin.ir.interpreter.builtins.contractsDslAnnotation
|
||||
import org.jetbrains.kotlin.ir.interpreter.builtins.evaluateIntrinsicAnnotation
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
@@ -45,7 +45,7 @@ class IrCompileTimeChecker(
|
||||
parentType?.isPrimitiveType() == true -> (this as IrFunction).name.asString() !in setOf("inc", "dec", "rangeTo", "hashCode")
|
||||
parentType?.isString() == true -> (this as IrDeclarationWithName).name.asString() !in setOf("subSequence", "hashCode")
|
||||
parentType?.isAny() == true -> (this as IrFunction).name.asString() == "toString" && expression?.dispatchReceiver !is IrGetObjectValue
|
||||
parent?.isObject == true -> parent.parentClassOrNull?.defaultType?.let { it.isPrimitiveType() || it.isUnsigned() } == true
|
||||
parent?.isObject == true -> parent.parentClassOrNull?.defaultType?.let { it.isPrimitiveType() || it.isUnsignedType() } == true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter
|
||||
|
||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -417,21 +418,20 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
}
|
||||
|
||||
private fun interpretConst(expression: IrConst<*>): ExecutionResult {
|
||||
fun getSignedType(unsignedType: IrType): IrType {
|
||||
return when {
|
||||
unsignedType.isUByte() -> irBuiltIns.byteType
|
||||
unsignedType.isUShort() -> irBuiltIns.shortType
|
||||
unsignedType.isUInt() -> irBuiltIns.intType
|
||||
unsignedType.isULong() -> irBuiltIns.longType
|
||||
else -> throw InterpreterException("Unsupported unsigned class ${unsignedType.render()}")
|
||||
}
|
||||
fun getSignedType(unsignedType: IrType): IrType? = when (unsignedType.getUnsignedType()) {
|
||||
UnsignedType.UBYTE -> irBuiltIns.byteType
|
||||
UnsignedType.USHORT -> irBuiltIns.shortType
|
||||
UnsignedType.UINT -> irBuiltIns.intType
|
||||
UnsignedType.ULONG -> irBuiltIns.longType
|
||||
else -> null
|
||||
}
|
||||
|
||||
return if (expression.type.isUnsigned()) {
|
||||
val signedType = getSignedType(expression.type)
|
||||
return if (signedType != null) {
|
||||
val unsignedClass = expression.type.classOrNull!!
|
||||
val constructor = unsignedClass.constructors.single().owner
|
||||
val constructorCall = IrConstructorCallImpl.fromSymbolOwner(constructor.returnType, constructor.symbol)
|
||||
constructorCall.putValueArgument(0, expression.value.toIrConst(getSignedType(expression.type)))
|
||||
constructorCall.putValueArgument(0, expression.value.toIrConst(signedType))
|
||||
|
||||
constructorCall.interpret()
|
||||
} else {
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.interpreter
|
||||
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -48,7 +49,7 @@ internal fun State.toIrExpression(expression: IrExpression): IrExpression {
|
||||
is Complex -> {
|
||||
val stateType = this.irClass.defaultType
|
||||
when {
|
||||
stateType.isUnsigned() -> (this.fields.single().state as Primitive<*>).value.toIrConst(type, start, end)
|
||||
stateType.isUnsignedType() -> (this.fields.single().state as Primitive<*>).value.toIrConst(type, start, end)
|
||||
else -> expression
|
||||
}
|
||||
}
|
||||
@@ -79,13 +80,15 @@ fun Any?.toIrConst(irType: IrType, startOffset: Int = UNDEFINED_OFFSET, endOffse
|
||||
PrimitiveType.FLOAT -> IrConstImpl.float(startOffset, endOffset, constType, (this as Number).toFloat())
|
||||
PrimitiveType.LONG -> IrConstImpl.long(startOffset, endOffset, constType, (this as Number).toLong())
|
||||
PrimitiveType.DOUBLE -> IrConstImpl.double(startOffset, endOffset, constType, (this as Number).toDouble())
|
||||
else -> when {
|
||||
constType.isString() -> IrConstImpl.string(startOffset, endOffset, constType, this as String)
|
||||
constType.isUByte() -> IrConstImpl.byte(startOffset, endOffset, constType, (this as Number).toByte())
|
||||
constType.isUShort() -> IrConstImpl.short(startOffset, endOffset, constType, (this as Number).toShort())
|
||||
constType.isUInt() -> IrConstImpl.int(startOffset, endOffset, constType, (this as Number).toInt())
|
||||
constType.isULong() -> IrConstImpl.long(startOffset, endOffset, constType, (this as Number).toLong())
|
||||
else -> throw UnsupportedOperationException("Unsupported const element type ${constType.render()}")
|
||||
null -> when (constType.getUnsignedType()) {
|
||||
UnsignedType.UBYTE -> IrConstImpl.byte(startOffset, endOffset, constType, (this as Number).toByte())
|
||||
UnsignedType.USHORT -> IrConstImpl.short(startOffset, endOffset, constType, (this as Number).toShort())
|
||||
UnsignedType.UINT -> IrConstImpl.int(startOffset, endOffset, constType, (this as Number).toInt())
|
||||
UnsignedType.ULONG -> IrConstImpl.long(startOffset, endOffset, constType, (this as Number).toLong())
|
||||
null -> when {
|
||||
constType.isString() -> IrConstImpl.string(startOffset, endOffset, constType, this as String)
|
||||
else -> throw UnsupportedOperationException("Unsupported const element type ${constType.render()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,8 +216,6 @@ internal fun State?.getCorrectReceiverByFunction(irFunction: IrFunction): State?
|
||||
|
||||
internal fun IrFunction.getCapitalizedFileName() = this.file.name.replace(".kt", "Kt").capitalizeAsciiOnly()
|
||||
|
||||
internal fun IrType.isUnsigned() = this.isUByte() || this.isUShort() || this.isUInt() || this.isULong()
|
||||
|
||||
internal fun IrType.isPrimitiveArray(): Boolean {
|
||||
return this.getClass()?.fqNameWhenAvailable?.toUnsafe()?.let { StandardNames.isPrimitiveArray(it) } ?: false
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.types
|
||||
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
@@ -100,6 +101,20 @@ fun IrType.getPrimitiveType(): PrimitiveType? =
|
||||
idSignatureToPrimitiveType[classifier.signature]
|
||||
else null
|
||||
|
||||
fun IrType.isUnsignedType(hasQuestionMark: Boolean = false): Boolean =
|
||||
this is IrSimpleType && hasQuestionMark == this.hasQuestionMark && getUnsignedType() != null
|
||||
|
||||
fun IrType.getUnsignedType(): UnsignedType? =
|
||||
if (this is IrSimpleType && classifier is IrClassSymbol)
|
||||
when (classifier.signature) {
|
||||
IdSignatureValues.uByte -> UnsignedType.UBYTE
|
||||
IdSignatureValues.uShort -> UnsignedType.USHORT
|
||||
IdSignatureValues.uInt -> UnsignedType.UINT
|
||||
IdSignatureValues.uLong -> UnsignedType.ULONG
|
||||
else -> null
|
||||
}
|
||||
else null
|
||||
|
||||
fun IrType.isMarkedNullable() = (this as? IrSimpleType)?.hasQuestionMark ?: false
|
||||
|
||||
fun IrType.isUnit() = isNotNullClassType(IdSignatureValues.unit)
|
||||
|
||||
Reference in New Issue
Block a user