Add support in interpreter for jvm static fields in primitive classes
This commit is contained in:
+15
-7
@@ -14,11 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
|
||||||
import org.jetbrains.kotlin.ir.util.isLocal
|
|
||||||
import org.jetbrains.kotlin.ir.util.isObject
|
|
||||||
import org.jetbrains.kotlin.ir.util.statements
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
@@ -159,8 +155,20 @@ class IrCompileTimeChecker(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitGetField(expression: IrGetField, data: Nothing?): Boolean {
|
override fun visitGetField(expression: IrGetField, data: Nothing?): Boolean {
|
||||||
val parent = expression.symbol.owner.parent as IrSymbolOwner
|
val owner = expression.symbol.owner
|
||||||
return callStack.contains(parent.symbol)
|
val parent = owner.parent as IrSymbolOwner
|
||||||
|
val isJavaPrimitiveStatic = owner.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && owner.isStatic &&
|
||||||
|
owner.parentAsClass.fqNameWhenAvailable.isJavaPrimitive()
|
||||||
|
return callStack.contains(parent.symbol) || isJavaPrimitiveStatic
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO find similar method in utils
|
||||||
|
private fun FqName?.isJavaPrimitive(): Boolean {
|
||||||
|
this ?: return false
|
||||||
|
return this.toString() in setOf(
|
||||||
|
"java.lang.Byte", "java.lang.Short", "java.lang.Integer", "java.lang.Long",
|
||||||
|
"java.lang.Float", "java.lang.Double", "java.lang.Boolean", "java.lang.Character"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitSetField(expression: IrSetField, data: Nothing?): Boolean {
|
override fun visitSetField(expression: IrSetField, data: Nothing?): Boolean {
|
||||||
|
|||||||
+7
-2
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.backend.common.interpreter.exceptions.InterpreterTim
|
|||||||
import org.jetbrains.kotlin.backend.common.interpreter.intrinsics.IntrinsicEvaluator
|
import org.jetbrains.kotlin.backend.common.interpreter.intrinsics.IntrinsicEvaluator
|
||||||
import org.jetbrains.kotlin.backend.common.interpreter.stack.*
|
import org.jetbrains.kotlin.backend.common.interpreter.stack.*
|
||||||
import org.jetbrains.kotlin.backend.common.interpreter.state.*
|
import org.jetbrains.kotlin.backend.common.interpreter.state.*
|
||||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
|
||||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
@@ -389,7 +388,7 @@ class IrInterpreter(irModule: IrModuleFragment, private val bodyMap: Map<IdSigna
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun interpretDelegatedConstructorCall(delegatingConstructorCall: IrDelegatingConstructorCall): ExecutionResult {
|
private suspend fun interpretDelegatedConstructorCall(delegatingConstructorCall: IrDelegatingConstructorCall): ExecutionResult {
|
||||||
if (delegatingConstructorCall.symbol.descriptor.containingDeclaration.defaultType == DefaultBuiltIns.Instance.anyType) {
|
if (delegatingConstructorCall.symbol.owner.parent == irBuiltIns.anyClass.owner) {
|
||||||
val anyAsStateObject = Common(irBuiltIns.anyClass.owner)
|
val anyAsStateObject = Common(irBuiltIns.anyClass.owner)
|
||||||
stack.pushReturnValue(anyAsStateObject)
|
stack.pushReturnValue(anyAsStateObject)
|
||||||
return Next
|
return Next
|
||||||
@@ -506,6 +505,12 @@ class IrInterpreter(irModule: IrModuleFragment, private val bodyMap: Map<IdSigna
|
|||||||
|
|
||||||
private suspend fun interpretGetField(expression: IrGetField): ExecutionResult {
|
private suspend fun interpretGetField(expression: IrGetField): ExecutionResult {
|
||||||
val receiver = (expression.receiver as? IrDeclarationReference)?.symbol?.descriptor
|
val receiver = (expression.receiver as? IrDeclarationReference)?.symbol?.descriptor
|
||||||
|
val field = expression.symbol.owner
|
||||||
|
// for java static variables
|
||||||
|
if (field.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && field.isStatic) {
|
||||||
|
stack.pushReturnValue(Wrapper.getStaticGetter(field)!!.invokeWithArguments().toState(field.type))
|
||||||
|
return Next
|
||||||
|
}
|
||||||
// receiver is null, for example, for top level fields
|
// receiver is null, for example, for top level fields
|
||||||
val result = receiver?.let { stack.getVariable(receiver).state.getState(expression.symbol.descriptor) }
|
val result = receiver?.let { stack.getVariable(receiver).state.getState(expression.symbol.descriptor) }
|
||||||
?: return (expression.symbol.owner.initializer?.expression?.interpret() ?: Next)
|
?: return (expression.symbol.owner.initializer?.expression?.interpret() ?: Next)
|
||||||
|
|||||||
+8
-4
@@ -14,15 +14,13 @@ import org.jetbrains.kotlin.backend.common.interpreter.stack.Variable
|
|||||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
|
||||||
import org.jetbrains.kotlin.ir.util.isTypeParameter
|
|
||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
|
||||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithDifferentJvmName
|
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithDifferentJvmName
|
||||||
import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties
|
import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
@@ -97,6 +95,12 @@ class Wrapper(val value: Any, override val irClass: IrClass) : Complex(irClass,
|
|||||||
return MethodHandles.lookup().findStatic(jvmClassName, irFunction.name.asString(), methodType)
|
return MethodHandles.lookup().findStatic(jvmClassName, irFunction.name.asString(), methodType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getStaticGetter(field: IrField): MethodHandle? {
|
||||||
|
val jvmClass = field.parentAsClass.defaultType.getClass(true)
|
||||||
|
val returnType = field.type.getClass(false)
|
||||||
|
return MethodHandles.lookup().findStaticGetter(jvmClass, field.name.asString(), returnType)
|
||||||
|
}
|
||||||
|
|
||||||
fun getEnumEntry(enumClass: IrClass): MethodHandle? {
|
fun getEnumEntry(enumClass: IrClass): MethodHandle? {
|
||||||
val intrinsicName = enumClass.getEvaluateIntrinsicValue()
|
val intrinsicName = enumClass.getEvaluateIntrinsicValue()
|
||||||
if (intrinsicName?.isEmpty() == true) return null
|
if (intrinsicName?.isEmpty() == true) return null
|
||||||
|
|||||||
Reference in New Issue
Block a user