IR: add isUnsignedType/getUnsignedType
This commit is contained in:
+4
-4
@@ -5,13 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.interpreter
|
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.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
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.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
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?.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?.isString() == true -> (this as IrDeclarationWithName).name.asString() !in setOf("subSequence", "hashCode")
|
||||||
parentType?.isAny() == true -> (this as IrFunction).name.asString() == "toString" && expression?.dispatchReceiver !is IrGetObjectValue
|
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
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.interpreter
|
package org.jetbrains.kotlin.ir.interpreter
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
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 {
|
private fun interpretConst(expression: IrConst<*>): ExecutionResult {
|
||||||
fun getSignedType(unsignedType: IrType): IrType {
|
fun getSignedType(unsignedType: IrType): IrType? = when (unsignedType.getUnsignedType()) {
|
||||||
return when {
|
UnsignedType.UBYTE -> irBuiltIns.byteType
|
||||||
unsignedType.isUByte() -> irBuiltIns.byteType
|
UnsignedType.USHORT -> irBuiltIns.shortType
|
||||||
unsignedType.isUShort() -> irBuiltIns.shortType
|
UnsignedType.UINT -> irBuiltIns.intType
|
||||||
unsignedType.isUInt() -> irBuiltIns.intType
|
UnsignedType.ULONG -> irBuiltIns.longType
|
||||||
unsignedType.isULong() -> irBuiltIns.longType
|
else -> null
|
||||||
else -> throw InterpreterException("Unsupported unsigned class ${unsignedType.render()}")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (expression.type.isUnsigned()) {
|
val signedType = getSignedType(expression.type)
|
||||||
|
return if (signedType != null) {
|
||||||
val unsignedClass = expression.type.classOrNull!!
|
val unsignedClass = expression.type.classOrNull!!
|
||||||
val constructor = unsignedClass.constructors.single().owner
|
val constructor = unsignedClass.constructors.single().owner
|
||||||
val constructorCall = IrConstructorCallImpl.fromSymbolOwner(constructor.returnType, constructor.symbol)
|
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()
|
constructorCall.interpret()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.interpreter
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
|
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -48,7 +49,7 @@ internal fun State.toIrExpression(expression: IrExpression): IrExpression {
|
|||||||
is Complex -> {
|
is Complex -> {
|
||||||
val stateType = this.irClass.defaultType
|
val stateType = this.irClass.defaultType
|
||||||
when {
|
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
|
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.FLOAT -> IrConstImpl.float(startOffset, endOffset, constType, (this as Number).toFloat())
|
||||||
PrimitiveType.LONG -> IrConstImpl.long(startOffset, endOffset, constType, (this as Number).toLong())
|
PrimitiveType.LONG -> IrConstImpl.long(startOffset, endOffset, constType, (this as Number).toLong())
|
||||||
PrimitiveType.DOUBLE -> IrConstImpl.double(startOffset, endOffset, constType, (this as Number).toDouble())
|
PrimitiveType.DOUBLE -> IrConstImpl.double(startOffset, endOffset, constType, (this as Number).toDouble())
|
||||||
else -> when {
|
null -> when (constType.getUnsignedType()) {
|
||||||
constType.isString() -> IrConstImpl.string(startOffset, endOffset, constType, this as String)
|
UnsignedType.UBYTE -> IrConstImpl.byte(startOffset, endOffset, constType, (this as Number).toByte())
|
||||||
constType.isUByte() -> IrConstImpl.byte(startOffset, endOffset, constType, (this as Number).toByte())
|
UnsignedType.USHORT -> IrConstImpl.short(startOffset, endOffset, constType, (this as Number).toShort())
|
||||||
constType.isUShort() -> IrConstImpl.short(startOffset, endOffset, constType, (this as Number).toShort())
|
UnsignedType.UINT -> IrConstImpl.int(startOffset, endOffset, constType, (this as Number).toInt())
|
||||||
constType.isUInt() -> IrConstImpl.int(startOffset, endOffset, constType, (this as Number).toInt())
|
UnsignedType.ULONG -> IrConstImpl.long(startOffset, endOffset, constType, (this as Number).toLong())
|
||||||
constType.isULong() -> IrConstImpl.long(startOffset, endOffset, constType, (this as Number).toLong())
|
null -> when {
|
||||||
else -> throw UnsupportedOperationException("Unsupported const element type ${constType.render()}")
|
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 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 {
|
internal fun IrType.isPrimitiveArray(): Boolean {
|
||||||
return this.getClass()?.fqNameWhenAvailable?.toUnsafe()?.let { StandardNames.isPrimitiveArray(it) } ?: false
|
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.PrimitiveType
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
|
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
@@ -100,6 +101,20 @@ fun IrType.getPrimitiveType(): PrimitiveType? =
|
|||||||
idSignatureToPrimitiveType[classifier.signature]
|
idSignatureToPrimitiveType[classifier.signature]
|
||||||
else null
|
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.isMarkedNullable() = (this as? IrSimpleType)?.hasQuestionMark ?: false
|
||||||
|
|
||||||
fun IrType.isUnit() = isNotNullClassType(IdSignatureValues.unit)
|
fun IrType.isUnit() = isNotNullClassType(IdSignatureValues.unit)
|
||||||
|
|||||||
Reference in New Issue
Block a user