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.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
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.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
@@ -159,8 +155,20 @@ class IrCompileTimeChecker(
|
||||
}
|
||||
|
||||
override fun visitGetField(expression: IrGetField, data: Nothing?): Boolean {
|
||||
val parent = expression.symbol.owner.parent as IrSymbolOwner
|
||||
return callStack.contains(parent.symbol)
|
||||
val owner = expression.symbol.owner
|
||||
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 {
|
||||
|
||||
+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.stack.*
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.state.*
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
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 {
|
||||
if (delegatingConstructorCall.symbol.descriptor.containingDeclaration.defaultType == DefaultBuiltIns.Instance.anyType) {
|
||||
if (delegatingConstructorCall.symbol.owner.parent == irBuiltIns.anyClass.owner) {
|
||||
val anyAsStateObject = Common(irBuiltIns.anyClass.owner)
|
||||
stack.pushReturnValue(anyAsStateObject)
|
||||
return Next
|
||||
@@ -506,6 +505,12 @@ class IrInterpreter(irModule: IrModuleFragment, private val bodyMap: Map<IdSigna
|
||||
|
||||
private suspend fun interpretGetField(expression: IrGetField): ExecutionResult {
|
||||
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
|
||||
val result = receiver?.let { stack.getVariable(receiver).state.getState(expression.symbol.descriptor) }
|
||||
?: 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.descriptors.SimpleFunctionDescriptor
|
||||
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.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
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.isTypeParameter
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithDifferentJvmName
|
||||
import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties
|
||||
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)
|
||||
}
|
||||
|
||||
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? {
|
||||
val intrinsicName = enumClass.getEvaluateIntrinsicValue()
|
||||
if (intrinsicName?.isEmpty() == true) return null
|
||||
|
||||
Reference in New Issue
Block a user