Implement interpretation for unsigned numbers
This commit is contained in:
+22
-2
@@ -9,6 +9,7 @@ import kotlinx.coroutines.*
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.builtins.*
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.stack.*
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||
import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
@@ -540,8 +541,27 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
||||
}
|
||||
|
||||
private suspend fun interpretConst(expression: IrConst<*>, data: Frame): Code {
|
||||
data.pushReturnValue(expression.toPrimitive())
|
||||
return Code.NEXT
|
||||
fun getSignedType(unsignedClassName: String): IrType {
|
||||
return when (unsignedClassName) {
|
||||
"UByte" -> irBuiltIns.byteType
|
||||
"UShort" -> irBuiltIns.shortType
|
||||
"UInt" -> irBuiltIns.intType
|
||||
"ULong" -> irBuiltIns.longType
|
||||
else -> throw AssertionError("")
|
||||
}
|
||||
}
|
||||
|
||||
return if (UnsignedTypes.isUnsignedType(expression.type.toKotlinType())) {
|
||||
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(unsignedClass.owner.name.asString())))
|
||||
|
||||
constructorCall.interpret(data)
|
||||
} else {
|
||||
data.pushReturnValue(expression.toPrimitive())
|
||||
Code.NEXT
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun interpretStatements(statements: List<IrStatement>, data: Frame): Code {
|
||||
|
||||
+14
-2
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.common.interpreter
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.builtins.evaluateIntrinsicAnnotation
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.stack.*
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
@@ -15,6 +16,7 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||
import org.jetbrains.kotlin.ir.util.isFakeOverride
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -81,15 +83,25 @@ fun IrFunction.isFakeOverridden(): Boolean {
|
||||
}
|
||||
|
||||
fun State.toIrExpression(expression: IrExpression): IrExpression {
|
||||
val start = expression.startOffset
|
||||
val end = expression.endOffset
|
||||
return when (this) {
|
||||
is Primitive<*> ->
|
||||
when (this.value) {
|
||||
// toIrConst call is necessary to replace ir offsets
|
||||
is Boolean, is Char, is Byte, is Short, is Int, is Long, is String, is Float, is Double ->
|
||||
this.value.toIrConst(this.type, expression.startOffset, expression.endOffset)
|
||||
null -> this.value.toIrConst(this.type, expression.startOffset, expression.endOffset)
|
||||
this.value.toIrConst(this.type, start, end)
|
||||
null -> this.value.toIrConst(this.type, start, end)
|
||||
else -> expression // TODO support for arrays
|
||||
}
|
||||
is Complex -> {
|
||||
val type = this.irClass.defaultType.toKotlinType()
|
||||
when {
|
||||
UnsignedTypes.isUnsignedType(type) ->
|
||||
(this.fields.single().state as Primitive<*>).value.toIrConst(this.irClass.defaultType, start, end)
|
||||
else -> expression
|
||||
}
|
||||
}
|
||||
else -> expression // TODO support
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user