Remove typeArguments field in State interface
This commit is contained in:
committed by
TeamCityServer
parent
a10d88924f
commit
9d9ab498aa
+21
-29
@@ -22,10 +22,7 @@ import org.jetbrains.kotlin.ir.interpreter.proxy.wrap
|
|||||||
import org.jetbrains.kotlin.ir.interpreter.stack.StackImpl
|
import org.jetbrains.kotlin.ir.interpreter.stack.StackImpl
|
||||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.*
|
import org.jetbrains.kotlin.ir.interpreter.state.*
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KClassState
|
import org.jetbrains.kotlin.ir.interpreter.state.reflection.*
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KFunctionState
|
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KPropertyState
|
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.ReflectionState
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||||
@@ -67,10 +64,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
|
|||||||
is Float -> irBuiltIns.floatType
|
is Float -> irBuiltIns.floatType
|
||||||
is Double -> irBuiltIns.doubleType
|
is Double -> irBuiltIns.doubleType
|
||||||
null -> irBuiltIns.nothingNType
|
null -> irBuiltIns.nothingNType
|
||||||
else -> when (defaultType.classifierOrNull?.owner) {
|
else -> defaultType
|
||||||
is IrTypeParameter -> stack.getVariable(defaultType.classifierOrFail).state.irClass.defaultType
|
|
||||||
else -> defaultType
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,8 +222,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
|
|||||||
else -> throw InterpreterError("Unsupported number of arguments for invocation as builtin functions")
|
else -> throw InterpreterError("Unsupported number of arguments for invocation as builtin functions")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val typeArguments = if (methodName == "CHECK_NOT_NULL") args.single().typeArguments else listOf()
|
stack.pushReturnValue(result.toState(result.getType(irFunction.returnType)))
|
||||||
stack.pushReturnValue(result.toState(result.getType(irFunction.returnType)).apply { addTypeArguments(typeArguments) })
|
|
||||||
return Next
|
return Next
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,9 +298,15 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
|
|||||||
|
|
||||||
interpretValueParameters(expression, irFunction, valueArguments).check { return it }
|
interpretValueParameters(expression, irFunction, valueArguments).check { return it }
|
||||||
|
|
||||||
valueArguments.addAll(getTypeArguments(irFunction, expression) { stack.getVariable(it).state })
|
irFunction.typeParameters
|
||||||
if (dispatchReceiver is Complex) valueArguments.addAll(dispatchReceiver.typeArguments)
|
.filter {
|
||||||
if (extensionReceiver is Complex) valueArguments.addAll(extensionReceiver.typeArguments)
|
it.isReified || irFunction.fqNameWhenAvailable.toString().let { it == "kotlin.emptyArray" || it == "kotlin.ArrayIntrinsicsKt.emptyArray" }
|
||||||
|
}
|
||||||
|
.forEach {
|
||||||
|
// TODO: emptyArray check is a hack for js, because in js-ir its type parameter isn't marked as reified
|
||||||
|
// TODO: if using KTypeState then it's class must be corresponding
|
||||||
|
valueArguments.add(Variable(it.symbol, KTypeState(expression.getTypeArgument(it.index)!!, irBuiltIns.anyClass.owner)))
|
||||||
|
}
|
||||||
|
|
||||||
if (dispatchReceiver?.irClass?.isLocal == true || irFunction.isLocal) {
|
if (dispatchReceiver?.irClass?.isLocal == true || irFunction.isLocal) {
|
||||||
valueArguments.addAll(dispatchReceiver.extractNonLocalDeclarations())
|
valueArguments.addAll(dispatchReceiver.extractNonLocalDeclarations())
|
||||||
@@ -382,16 +381,17 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
|
|||||||
interpretValueParameters(constructorCall, owner, valueArguments).check { return it }
|
interpretValueParameters(constructorCall, owner, valueArguments).check { return it }
|
||||||
|
|
||||||
val irClass = owner.parent as IrClass
|
val irClass = owner.parent as IrClass
|
||||||
val typeArguments = getTypeArguments(irClass, constructorCall) { stack.getVariable(it).state }
|
|
||||||
if (irClass.hasAnnotation(evaluateIntrinsicAnnotation) || irClass.fqNameWhenAvailable!!.startsWith(Name.identifier("java"))) {
|
if (irClass.hasAnnotation(evaluateIntrinsicAnnotation) || irClass.fqNameWhenAvailable!!.startsWith(Name.identifier("java"))) {
|
||||||
return stack.newFrame(initPool = valueArguments) { Wrapper.getConstructorMethod(owner).invokeMethod(owner) }
|
return stack.newFrame(initPool = valueArguments) { Wrapper.getConstructorMethod(owner).invokeMethod(owner) }
|
||||||
.apply { stack.peekReturnValue().addTypeArguments(typeArguments) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irClass.defaultType.isArray() || irClass.defaultType.isPrimitiveArray()) {
|
if (irClass.defaultType.isArray() || irClass.defaultType.isPrimitiveArray()) {
|
||||||
// array constructor doesn't have body so must be treated separately
|
// array constructor doesn't have body so must be treated separately
|
||||||
return stack.newFrame(initPool = valueArguments) { handleIntrinsicMethods(owner) }
|
return stack.newFrame(initPool = valueArguments) { handleIntrinsicMethods(owner) }
|
||||||
.apply { stack.peekReturnValue().addTypeArguments(typeArguments) }
|
.apply {
|
||||||
|
val array = stack.popReturnValue() as Primitive<*>
|
||||||
|
stack.pushReturnValue(Primitive(array.value, constructorCall.type))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irClass.defaultType.isUnsignedType() && valueArguments.size == 1 && owner.valueParameters.size == 1) {
|
if (irClass.defaultType.isUnsignedType() && valueArguments.size == 1 && owner.valueParameters.size == 1) {
|
||||||
@@ -402,7 +402,6 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
|
|||||||
}
|
}
|
||||||
|
|
||||||
val state = stack.getVariable(constructorCall.getThisReceiver()).state as Common
|
val state = stack.getVariable(constructorCall.getThisReceiver()).state as Common
|
||||||
state.addTypeArguments(typeArguments)
|
|
||||||
|
|
||||||
if (irClass.isLocal) {
|
if (irClass.isLocal) {
|
||||||
state.fields.addAll(stack.getAll()) // TODO save only necessary declarations
|
state.fields.addAll(stack.getAll()) // TODO save only necessary declarations
|
||||||
@@ -419,7 +418,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
|
|||||||
}
|
}
|
||||||
|
|
||||||
valueArguments.add(Variable(constructorCall.getThisReceiver(), state)) //used to set up fields in body
|
valueArguments.add(Variable(constructorCall.getThisReceiver(), state)) //used to set up fields in body
|
||||||
return stack.newFrame(initPool = valueArguments + state.typeArguments) {
|
return stack.newFrame(initPool = valueArguments) {
|
||||||
val statements = constructorCall.getBody()!!.statements
|
val statements = constructorCall.getBody()!!.statements
|
||||||
when (val irStatement = statements[0]) {
|
when (val irStatement = statements[0]) {
|
||||||
is IrTypeOperatorCall -> {
|
is IrTypeOperatorCall -> {
|
||||||
@@ -709,7 +708,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
|
|||||||
val typeClassifier = expression.typeOperand.classifierOrFail
|
val typeClassifier = expression.typeOperand.classifierOrFail
|
||||||
val isReified = (typeClassifier.owner as? IrTypeParameter)?.isReified == true
|
val isReified = (typeClassifier.owner as? IrTypeParameter)?.isReified == true
|
||||||
val isErased = typeClassifier.owner is IrTypeParameter && !isReified
|
val isErased = typeClassifier.owner is IrTypeParameter && !isReified
|
||||||
val typeOperand = if (isReified) stack.getVariable(typeClassifier).state.irClass.defaultType else expression.typeOperand
|
val typeOperand = if (isReified) (stack.getVariable(typeClassifier).state as KTypeState).irType else expression.typeOperand
|
||||||
|
|
||||||
when (expression.operator) {
|
when (expression.operator) {
|
||||||
// coercion to unit means that return value isn't used
|
// coercion to unit means that return value isn't used
|
||||||
@@ -758,18 +757,17 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val elementIrClass = expression.varargElementType.classOrNull
|
|
||||||
val args = expression.elements.flatMap {
|
val args = expression.elements.flatMap {
|
||||||
it.interpret().check { executionResult -> return executionResult }
|
it.interpret().check { executionResult -> return executionResult }
|
||||||
return@flatMap when (val result = stack.popReturnValue()) {
|
return@flatMap when (val result = stack.popReturnValue()) {
|
||||||
is Wrapper -> listOf(result.value)
|
is Wrapper -> listOf(result.value)
|
||||||
is Primitive<*> -> when {
|
is Primitive<*> -> when {
|
||||||
expression.varargElementType.isArray() -> listOf(result.value)
|
expression.varargElementType.isArray() -> listOf(result)
|
||||||
else -> arrayToList(result.value)
|
else -> arrayToList(result.value)
|
||||||
}
|
}
|
||||||
is Common -> when {
|
is Common -> when {
|
||||||
result.irClass.defaultType.isUnsignedArray() -> arrayToList((result.fields.single().state as Primitive<*>).value)
|
result.irClass.defaultType.isUnsignedArray() -> arrayToList((result.fields.single().state as Primitive<*>).value)
|
||||||
else -> listOf(result.asProxy(this, elementIrClass?.owner))
|
else -> listOf(result.asProxy(this))
|
||||||
}
|
}
|
||||||
else -> listOf(result)
|
else -> listOf(result)
|
||||||
}
|
}
|
||||||
@@ -788,13 +786,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
|
|||||||
val unsignedArray = primitiveArray.toPrimitiveStateArray(storageProperty.backingField!!.type)
|
val unsignedArray = primitiveArray.toPrimitiveStateArray(storageProperty.backingField!!.type)
|
||||||
Common(owner).apply { fields.add(Variable(storageProperty.symbol, unsignedArray)) }
|
Common(owner).apply { fields.add(Variable(storageProperty.symbol, unsignedArray)) }
|
||||||
}
|
}
|
||||||
else -> args.toPrimitiveStateArray(expression.type).apply {
|
else -> args.toPrimitiveStateArray(expression.type)
|
||||||
if (expression.type.isArray()) {
|
|
||||||
val arrayTypeArgument = elementIrClass?.let { Common(it.owner) }
|
|
||||||
?: stack.getVariable(expression.varargElementType.classifierOrFail).state
|
|
||||||
this.addTypeArguments(listOf(Variable(irBuiltIns.arrayClass.owner.typeParameters.single().symbol, arrayTypeArgument)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
stack.pushReturnValue(array)
|
stack.pushReturnValue(array)
|
||||||
return Next
|
return Next
|
||||||
|
|||||||
@@ -21,9 +21,12 @@ import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
|
|||||||
import org.jetbrains.kotlin.ir.interpreter.proxy.wrap
|
import org.jetbrains.kotlin.ir.interpreter.proxy.wrap
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import java.lang.invoke.MethodType
|
import java.lang.invoke.MethodType
|
||||||
@@ -71,7 +74,7 @@ internal fun Any?.toState(irType: IrType): State {
|
|||||||
is Boolean, is Char, is Byte, is Short, is Int, is Long, is String, is Float, is Double, is Array<*>, is ByteArray,
|
is Boolean, is Char, is Byte, is Short, is Int, is Long, is String, is Float, is Double, is Array<*>, is ByteArray,
|
||||||
is CharArray, is ShortArray, is IntArray, is LongArray, is FloatArray, is DoubleArray, is BooleanArray -> Primitive(this, irType)
|
is CharArray, is ShortArray, is IntArray, is LongArray, is FloatArray, is DoubleArray, is BooleanArray -> Primitive(this, irType)
|
||||||
null -> Primitive(this, irType)
|
null -> Primitive(this, irType)
|
||||||
else -> Wrapper(this, irType.classOrNull!!.owner)
|
else -> irType.classOrNull?.owner?.let { Wrapper(this, it) } ?: Wrapper(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,38 +166,11 @@ internal fun List<Any?>.toPrimitiveStateArray(type: IrType): Primitive<*> {
|
|||||||
fun IrFunctionAccessExpression.getVarargType(index: Int): IrType? {
|
fun IrFunctionAccessExpression.getVarargType(index: Int): IrType? {
|
||||||
val varargType = this.symbol.owner.valueParameters[index].varargElementType ?: return null
|
val varargType = this.symbol.owner.valueParameters[index].varargElementType ?: return null
|
||||||
varargType.classOrNull?.let { return this.symbol.owner.valueParameters[index].type }
|
varargType.classOrNull?.let { return this.symbol.owner.valueParameters[index].type }
|
||||||
val typeParameter = varargType.classifierOrFail.owner as IrTypeParameter
|
val type = this.symbol.owner.valueParameters[index].type as? IrSimpleType ?: return null
|
||||||
return this.getTypeArgument(typeParameter.index)
|
return type.buildSimpleType {
|
||||||
}
|
val typeParameter = varargType.classifierOrFail.owner as IrTypeParameter
|
||||||
|
arguments = listOf(makeTypeProjection(this@getVarargType.getTypeArgument(typeParameter.index)!!, Variance.OUT_VARIANCE))
|
||||||
internal fun getTypeArguments(
|
|
||||||
container: IrTypeParametersContainer, expression: IrFunctionAccessExpression, mapper: (IrTypeParameterSymbol) -> State
|
|
||||||
): List<Variable> {
|
|
||||||
fun IrType.getState(): State {
|
|
||||||
return this.classOrNull?.owner?.let { Common(it) } ?: mapper(this.classifierOrFail as IrTypeParameterSymbol)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val typeArguments = container.typeParameters.mapIndexed { index, typeParameter ->
|
|
||||||
val typeArgument = expression.getTypeArgument(index)!!
|
|
||||||
Variable(typeParameter.symbol, typeArgument.getState())
|
|
||||||
}.toMutableList()
|
|
||||||
|
|
||||||
if (container is IrSimpleFunction) {
|
|
||||||
container.returnType.classifierOrFail.owner.safeAs<IrTypeParameter>()
|
|
||||||
?.let { typeArguments.add(Variable(it.symbol, expression.type.getState())) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrSimpleType.getArgumentsRecursive() {
|
|
||||||
val typeParameters = this.classOrNull?.owner?.typeParameters ?: return
|
|
||||||
typeParameters.zip(this.arguments).forEach {
|
|
||||||
it.second.typeOrNull?.classOrNull?.owner?.let { owner -> typeArguments.add(Variable(it.first.symbol, Common(owner))) }
|
|
||||||
}
|
|
||||||
this.classOrNull!!.superTypes().forEach { (it as? IrSimpleType)?.getArgumentsRecursive() }
|
|
||||||
}
|
|
||||||
|
|
||||||
(container as? IrClass)?.superTypes?.forEach { (it as? IrSimpleType)?.getArgumentsRecursive() }
|
|
||||||
|
|
||||||
return typeArguments
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun State?.extractNonLocalDeclarations(): List<Variable> {
|
internal fun State?.extractNonLocalDeclarations(): List<Variable> {
|
||||||
|
|||||||
+34
-11
@@ -15,8 +15,15 @@ import org.jetbrains.kotlin.ir.declarations.IrEnumEntry
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.interpreter.exceptions.throwAsUserException
|
import org.jetbrains.kotlin.ir.interpreter.exceptions.throwAsUserException
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KFunctionState
|
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KFunctionState
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KTypeState
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||||
|
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||||
|
import org.jetbrains.kotlin.ir.types.isArray
|
||||||
import org.jetbrains.kotlin.ir.types.isCharArray
|
import org.jetbrains.kotlin.ir.types.isCharArray
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
internal sealed class IntrinsicBase {
|
internal sealed class IntrinsicBase {
|
||||||
abstract fun equalTo(irFunction: IrFunction): Boolean
|
abstract fun equalTo(irFunction: IrFunction): Boolean
|
||||||
@@ -30,8 +37,11 @@ internal object EmptyArray : IntrinsicBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
||||||
val typeArguments = irFunction.typeParameters.map { stack.getVariable(it.symbol) }
|
val typeArgument = irFunction.typeParameters.map { stack.getVariable(it.symbol) }.single().state as KTypeState
|
||||||
stack.pushReturnValue(emptyArray<Any?>().toState(irFunction.returnType).apply { addTypeArguments(typeArguments) })
|
val returnType = (irFunction.returnType as IrSimpleType).buildSimpleType {
|
||||||
|
arguments = listOf(makeTypeProjection(typeArgument.irType, Variance.INVARIANT))
|
||||||
|
}
|
||||||
|
stack.pushReturnValue(emptyArray<Any?>().toState(returnType))
|
||||||
return Next
|
return Next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,9 +54,7 @@ internal object ArrayOf : IntrinsicBase() {
|
|||||||
|
|
||||||
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
||||||
val elementsVariable = irFunction.valueParameters.single().symbol
|
val elementsVariable = irFunction.valueParameters.single().symbol
|
||||||
val array = (stack.getVariable(elementsVariable).state as Primitive<*>).value as Array<out Any?>
|
stack.pushReturnValue(stack.getVariable(elementsVariable).state)
|
||||||
val typeArguments = irFunction.typeParameters.map { stack.getVariable(it.symbol) }
|
|
||||||
stack.pushReturnValue(array.toState(irFunction.returnType).apply { addTypeArguments(typeArguments) })
|
|
||||||
return Next
|
return Next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,8 +68,11 @@ internal object ArrayOfNulls : IntrinsicBase() {
|
|||||||
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
||||||
val size = stack.getVariable(irFunction.valueParameters.first().symbol).state.asInt()
|
val size = stack.getVariable(irFunction.valueParameters.first().symbol).state.asInt()
|
||||||
val array = arrayOfNulls<Any?>(size)
|
val array = arrayOfNulls<Any?>(size)
|
||||||
val typeArguments = irFunction.typeParameters.map { stack.getVariable(it.symbol) }
|
val typeArgument = irFunction.typeParameters.map { stack.getVariable(it.symbol) }.single().state as KTypeState
|
||||||
stack.pushReturnValue(array.toState(irFunction.returnType).apply { addTypeArguments(typeArguments) })
|
val returnType = (irFunction.returnType as IrSimpleType).buildSimpleType {
|
||||||
|
arguments = listOf(makeTypeProjection(typeArgument.irType, Variance.INVARIANT))
|
||||||
|
}
|
||||||
|
stack.pushReturnValue(array.toState(returnType))
|
||||||
return Next
|
return Next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,7 +85,10 @@ internal object EnumValues : IntrinsicBase() {
|
|||||||
|
|
||||||
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
||||||
val enumClass = when (irFunction.fqNameWhenAvailable.toString()) {
|
val enumClass = when (irFunction.fqNameWhenAvailable.toString()) {
|
||||||
"kotlin.enumValues" -> stack.getVariable(irFunction.typeParameters.first().symbol).state.irClass
|
"kotlin.enumValues" -> {
|
||||||
|
val kType = stack.getVariable(irFunction.typeParameters.first().symbol).state as KTypeState
|
||||||
|
kType.irType.classOrNull!!.owner
|
||||||
|
}
|
||||||
else -> irFunction.parent as IrClass
|
else -> irFunction.parent as IrClass
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +107,10 @@ internal object EnumValueOf : IntrinsicBase() {
|
|||||||
|
|
||||||
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
||||||
val enumClass = when (irFunction.fqNameWhenAvailable.toString()) {
|
val enumClass = when (irFunction.fqNameWhenAvailable.toString()) {
|
||||||
"kotlin.enumValueOf" -> stack.getVariable(irFunction.typeParameters.first().symbol).state.irClass
|
"kotlin.enumValueOf" -> {
|
||||||
|
val kType = stack.getVariable(irFunction.typeParameters.first().symbol).state as KTypeState
|
||||||
|
kType.irType.classOrNull!!.owner
|
||||||
|
}
|
||||||
else -> irFunction.parent as IrClass
|
else -> irFunction.parent as IrClass
|
||||||
}
|
}
|
||||||
val enumEntryName = stack.getVariable(irFunction.valueParameters.first().symbol).state.asString()
|
val enumEntryName = stack.getVariable(irFunction.valueParameters.first().symbol).state.asString()
|
||||||
@@ -149,7 +166,7 @@ internal object ArrayConstructor : IntrinsicBase() {
|
|||||||
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
||||||
val sizeDescriptor = irFunction.valueParameters[0].symbol
|
val sizeDescriptor = irFunction.valueParameters[0].symbol
|
||||||
val size = stack.getVariable(sizeDescriptor).state.asInt()
|
val size = stack.getVariable(sizeDescriptor).state.asInt()
|
||||||
val arrayValue = MutableList<Any>(size) { if (irFunction.returnType.isCharArray()) 0.toChar() else 0 }
|
val arrayValue = MutableList<Any?>(size) { if (irFunction.returnType.isCharArray()) 0.toChar() else 0 }
|
||||||
|
|
||||||
if (irFunction.valueParameters.size == 2) {
|
if (irFunction.valueParameters.size == 2) {
|
||||||
val initDescriptor = irFunction.valueParameters[1].symbol
|
val initDescriptor = irFunction.valueParameters[1].symbol
|
||||||
@@ -163,7 +180,13 @@ internal object ArrayConstructor : IntrinsicBase() {
|
|||||||
asSubFrame = initLambda.irFunction.isLocal || initLambda.irFunction.isInline,
|
asSubFrame = initLambda.irFunction.isLocal || initLambda.irFunction.isInline,
|
||||||
initPool = nonLocalDeclarations + indexVar
|
initPool = nonLocalDeclarations + indexVar
|
||||||
) { initLambda.irFunction.body!!.interpret() }.check(ReturnLabel.RETURN) { return it }
|
) { initLambda.irFunction.body!!.interpret() }.check(ReturnLabel.RETURN) { return it }
|
||||||
arrayValue[i] = stack.popReturnValue().let { (it as? Wrapper)?.value ?: (it as? Primitive<*>)?.value ?: it }
|
arrayValue[i] = stack.popReturnValue().let {
|
||||||
|
when (it) {
|
||||||
|
is Wrapper -> it.value
|
||||||
|
is Primitive<*> -> if (it.type.isArray() || it.type.isPrimitiveArray()) it else it.value
|
||||||
|
else -> it
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-26
@@ -5,20 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.interpreter.proxy
|
package org.jetbrains.kotlin.ir.interpreter.proxy
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
|
|
||||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||||
import org.jetbrains.kotlin.ir.interpreter.getDispatchReceiver
|
import org.jetbrains.kotlin.ir.interpreter.getDispatchReceiver
|
||||||
import org.jetbrains.kotlin.ir.interpreter.internalName
|
import org.jetbrains.kotlin.ir.interpreter.internalName
|
||||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.Common
|
import org.jetbrains.kotlin.ir.interpreter.state.Common
|
||||||
import org.jetbrains.kotlin.ir.interpreter.toState
|
import org.jetbrains.kotlin.ir.interpreter.toState
|
||||||
import org.jetbrains.kotlin.ir.types.defaultType
|
|
||||||
import org.jetbrains.kotlin.ir.types.isAny
|
|
||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
|
||||||
import org.jetbrains.kotlin.ir.util.isFakeOverriddenFromAny
|
import org.jetbrains.kotlin.ir.util.isFakeOverriddenFromAny
|
||||||
import org.jetbrains.kotlin.ir.util.nameForIrSerialization
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calledFromBuiltIns - used to avoid cyclic calls. For example:
|
* calledFromBuiltIns - used to avoid cyclic calls. For example:
|
||||||
@@ -64,25 +57,6 @@ internal class CommonProxy private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
internal fun Common.asProxy(interpreter: IrInterpreter, extendFrom: IrClass?): Any {
|
|
||||||
val elementType = when {
|
|
||||||
extendFrom?.defaultType?.isAny() == false -> {
|
|
||||||
val fqName = extendFrom.fqNameForIrSerialization.asString()
|
|
||||||
if (fqName.startsWith("kotlin")) Class.forName(fqName) else null
|
|
||||||
}
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
return when (elementType) {
|
|
||||||
Pair::class.java -> {
|
|
||||||
val first = this.irClass.declarations.single { it.nameForIrSerialization.asString() == "first" } as IrSymbolOwner
|
|
||||||
val second = this.irClass.declarations.single { it.nameForIrSerialization.asString() == "second" } as IrSymbolOwner
|
|
||||||
Pair(this.getState(first.symbol), this.getState(second.symbol))
|
|
||||||
}
|
|
||||||
else -> this.asProxy(interpreter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun Common.asProxy(interpreter: IrInterpreter, extendFrom: Class<*>? = null, calledFromBuiltIns: Boolean = false): Any {
|
internal fun Common.asProxy(interpreter: IrInterpreter, extendFrom: Class<*>? = null, calledFromBuiltIns: Boolean = false): Any {
|
||||||
val commonProxy = CommonProxy(this, interpreter, calledFromBuiltIns)
|
val commonProxy = CommonProxy(this, interpreter, calledFromBuiltIns)
|
||||||
|
|
||||||
|
|||||||
@@ -8,15 +8,12 @@ package org.jetbrains.kotlin.ir.interpreter.state
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||||
import org.jetbrains.kotlin.ir.interpreter.getLastOverridden
|
|
||||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
|
||||||
import org.jetbrains.kotlin.ir.util.nameForIrSerialization
|
import org.jetbrains.kotlin.ir.util.nameForIrSerialization
|
||||||
|
|
||||||
internal class Common private constructor(override val irClass: IrClass, override val fields: MutableList<Variable>) : Complex {
|
internal class Common private constructor(override val irClass: IrClass, override val fields: MutableList<Variable>) : Complex {
|
||||||
override var superWrapperClass: Wrapper? = null
|
override var superWrapperClass: Wrapper? = null
|
||||||
override val typeArguments: MutableList<Variable> = mutableListOf()
|
|
||||||
override var outerClass: Variable? = null
|
override var outerClass: Variable? = null
|
||||||
|
|
||||||
constructor(irClass: IrClass) : this(irClass, mutableListOf())
|
constructor(irClass: IrClass) : this(irClass, mutableListOf())
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
|
|
||||||
internal interface Complex: State {
|
internal interface Complex: State {
|
||||||
var superWrapperClass: Wrapper?
|
var superWrapperClass: Wrapper?
|
||||||
override val typeArguments: MutableList<Variable>
|
|
||||||
var outerClass: Variable?
|
var outerClass: Variable?
|
||||||
|
|
||||||
fun irClassFqName(): String {
|
fun irClassFqName(): String {
|
||||||
|
|||||||
-1
@@ -20,7 +20,6 @@ internal class ExceptionState private constructor(
|
|||||||
) : Complex, Throwable() {
|
) : Complex, Throwable() {
|
||||||
|
|
||||||
override var superWrapperClass: Wrapper? = null
|
override var superWrapperClass: Wrapper? = null
|
||||||
override val typeArguments: MutableList<Variable> = mutableListOf()
|
|
||||||
override var outerClass: Variable? = null
|
override var outerClass: Variable? = null
|
||||||
|
|
||||||
override val message: String?
|
override val message: String?
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.ir.util.overrides
|
|||||||
|
|
||||||
internal class Primitive<T>(val value: T, val type: IrType) : State {
|
internal class Primitive<T>(val value: T, val type: IrType) : State {
|
||||||
override val fields: MutableList<Variable> = mutableListOf()
|
override val fields: MutableList<Variable> = mutableListOf()
|
||||||
override val typeArguments: MutableList<Variable> = mutableListOf()
|
|
||||||
override val irClass: IrClass = type.classOrNull!!.owner
|
override val irClass: IrClass = type.classOrNull!!.owner
|
||||||
|
|
||||||
override fun getState(symbol: IrSymbol): State {
|
override fun getState(symbol: IrSymbol): State {
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.ir.util.defaultType
|
|||||||
internal interface State {
|
internal interface State {
|
||||||
val fields: MutableList<Variable>
|
val fields: MutableList<Variable>
|
||||||
val irClass: IrClass
|
val irClass: IrClass
|
||||||
val typeArguments: MutableList<Variable>
|
|
||||||
|
|
||||||
fun getState(symbol: IrSymbol): State? {
|
fun getState(symbol: IrSymbol): State? {
|
||||||
return fields.firstOrNull { it.symbol == symbol }?.state
|
return fields.firstOrNull { it.symbol == symbol }?.state
|
||||||
@@ -30,10 +29,6 @@ internal interface State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addTypeArguments(typeArguments: List<Variable>) {
|
|
||||||
this.typeArguments.addAll(typeArguments)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getIrFunctionByIrCall(expression: IrCall): IrFunction?
|
fun getIrFunctionByIrCall(expression: IrCall): IrFunction?
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,10 +46,15 @@ internal fun State.isSubtypeOf(other: IrType): Boolean {
|
|||||||
if (this is ExceptionState) return this.isSubtypeOf(other.classOrNull!!.owner)
|
if (this is ExceptionState) return this.isSubtypeOf(other.classOrNull!!.owner)
|
||||||
|
|
||||||
if (this is Primitive<*> && this.type.isArray() && other.isArray()) {
|
if (this is Primitive<*> && this.type.isArray() && other.isArray()) {
|
||||||
val thisClass = this.typeArguments.single().state.irClass.symbol
|
fun IrType.arraySubtypeCheck(other: IrType): Boolean {
|
||||||
val otherArgument = (other as IrSimpleType).arguments.single()
|
if (other !is IrSimpleType || this !is IrSimpleType) return false
|
||||||
if (otherArgument is IrStarProjection) return true
|
val thisArgument = this.arguments.single().typeOrNull ?: return false
|
||||||
return otherArgument.typeOrNull?.classOrNull?.let { thisClass.isSubtypeOfClass(it) } ?: true
|
val otherArgument = other.arguments.single().typeOrNull ?: return other.arguments.single() is IrStarProjection
|
||||||
|
if (thisArgument.isArray() && otherArgument.isArray()) return thisArgument.arraySubtypeCheck(otherArgument)
|
||||||
|
if (otherArgument.classOrNull == null) return false
|
||||||
|
return thisArgument.classOrNull?.isSubtypeOfClass(otherArgument.classOrNull!!) ?: false
|
||||||
|
}
|
||||||
|
return this.type.arraySubtypeCheck(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.irClass.defaultType.isSubtypeOfClass(other.classOrNull!!)
|
return this.irClass.defaultType.isSubtypeOfClass(other.classOrNull!!)
|
||||||
|
|||||||
+32
-1
@@ -18,21 +18,47 @@ 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.defaultType
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||||
|
import org.jetbrains.kotlin.ir.util.isInterface
|
||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
||||||
import java.lang.invoke.MethodHandle
|
import java.lang.invoke.MethodHandle
|
||||||
import java.lang.invoke.MethodHandles
|
import java.lang.invoke.MethodHandles
|
||||||
import java.lang.invoke.MethodType
|
import java.lang.invoke.MethodType
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.HashMap
|
||||||
|
import kotlin.collections.LinkedHashMap
|
||||||
|
|
||||||
internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex {
|
internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex {
|
||||||
override val fields: MutableList<Variable> = mutableListOf()
|
override val fields: MutableList<Variable> = mutableListOf()
|
||||||
|
|
||||||
override var superWrapperClass: Wrapper? = null
|
override var superWrapperClass: Wrapper? = null
|
||||||
override val typeArguments: MutableList<Variable> = mutableListOf()
|
|
||||||
override var outerClass: Variable? = null
|
override var outerClass: Variable? = null
|
||||||
|
|
||||||
private val receiverClass = irClass.defaultType.getClass(true)
|
private val receiverClass = irClass.defaultType.getClass(true)
|
||||||
|
|
||||||
|
init {
|
||||||
|
val javaClass = value::class.java
|
||||||
|
when {
|
||||||
|
javaClass == HashMap::class.java -> {
|
||||||
|
val nodeClass = javaClass.declaredClasses.single { it.name.contains("\$Node") }
|
||||||
|
val mutableMap = irClass.superTypes.mapNotNull { it.classOrNull?.owner }.single { it.isInterface }
|
||||||
|
javaClassToIrClass += nodeClass to mutableMap.declarations.filterIsInstance<IrClass>().single()
|
||||||
|
}
|
||||||
|
javaClass == LinkedHashMap::class.java -> {
|
||||||
|
val entryClass = javaClass.declaredClasses.single { it.name.contains("\$Entry") }
|
||||||
|
val mutableMap = irClass.superTypes.mapNotNull { it.classOrNull?.owner }.single { it.isInterface }
|
||||||
|
javaClassToIrClass += entryClass to mutableMap.declarations.filterIsInstance<IrClass>().single()
|
||||||
|
}
|
||||||
|
javaClass.canonicalName == "java.util.Collections.SingletonMap" -> {
|
||||||
|
javaClassToIrClass += AbstractMap.SimpleEntry::class.java to irClass.declarations.filterIsInstance<IrClass>().single()
|
||||||
|
javaClassToIrClass += AbstractMap.SimpleImmutableEntry::class.java to irClass.declarations.filterIsInstance<IrClass>().single()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
javaClassToIrClass += value::class.java to irClass
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(value: Any) : this(value, javaClassToIrClass[value::class.java]!!)
|
||||||
|
|
||||||
override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? = null
|
override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? = null
|
||||||
|
|
||||||
fun getMethod(irFunction: IrFunction): MethodHandle? {
|
fun getMethod(irFunction: IrFunction): MethodHandle? {
|
||||||
@@ -65,6 +91,11 @@ internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val companionObjectValue = mapOf<String, Any>("kotlin.text.Regex\$Companion" to Regex.Companion)
|
private val companionObjectValue = mapOf<String, Any>("kotlin.text.Regex\$Companion" to Regex.Companion)
|
||||||
|
private val javaClassToIrClass = mutableMapOf<Class<*>, IrClass>()
|
||||||
|
|
||||||
|
fun associateJavaClassWithIrClass(javaClass: Class<*>, irClass: IrClass) {
|
||||||
|
javaClassToIrClass += javaClass to irClass
|
||||||
|
}
|
||||||
|
|
||||||
fun getReflectionMethod(irFunction: IrFunction): MethodHandle {
|
fun getReflectionMethod(irFunction: IrFunction): MethodHandle {
|
||||||
val receiverClass = irFunction.dispatchReceiverParameter!!.type.getClass(asObject = true)
|
val receiverClass = irFunction.dispatchReceiverParameter!!.type.getClass(asObject = true)
|
||||||
|
|||||||
-1
@@ -27,7 +27,6 @@ import kotlin.reflect.KTypeParameter
|
|||||||
|
|
||||||
internal class KFunctionState(val irFunction: IrFunction, override val irClass: IrClass) : ReflectionState() {
|
internal class KFunctionState(val irFunction: IrFunction, override val irClass: IrClass) : ReflectionState() {
|
||||||
override val fields: MutableList<Variable> = mutableListOf()
|
override val fields: MutableList<Variable> = mutableListOf()
|
||||||
override val typeArguments: MutableList<Variable> = mutableListOf()
|
|
||||||
private var _parameters: List<KParameter>? = null
|
private var _parameters: List<KParameter>? = null
|
||||||
private var _returnType: KType? = null
|
private var _returnType: KType? = null
|
||||||
private var _typeParameters: List<KTypeParameter>? = null
|
private var _typeParameters: List<KTypeParameter>? = null
|
||||||
|
|||||||
+2
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KClassProxy
|
|||||||
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeParameterProxy
|
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeParameterProxy
|
||||||
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy
|
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy
|
||||||
import org.jetbrains.kotlin.ir.interpreter.renderType
|
import org.jetbrains.kotlin.ir.interpreter.renderType
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.state.Wrapper
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import kotlin.reflect.KClassifier
|
import kotlin.reflect.KClassifier
|
||||||
@@ -36,6 +37,7 @@ internal class KTypeState(val irType: IrType, override val irClass: IrClass) : R
|
|||||||
|
|
||||||
fun getArguments(interpreter: IrInterpreter): List<KTypeProjection> {
|
fun getArguments(interpreter: IrInterpreter): List<KTypeProjection> {
|
||||||
if (_arguments != null) return _arguments!!
|
if (_arguments != null) return _arguments!!
|
||||||
|
Wrapper.associateJavaClassWithIrClass(KTypeProjection::class.java, irClass.getIrClassOfReflectionFromList("arguments"))
|
||||||
_arguments = (irType as IrSimpleType).arguments
|
_arguments = (irType as IrSimpleType).arguments
|
||||||
.map {
|
.map {
|
||||||
when (it.getVariance()) {
|
when (it.getVariance()) {
|
||||||
|
|||||||
-1
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
|||||||
|
|
||||||
internal abstract class ReflectionState : State {
|
internal abstract class ReflectionState : State {
|
||||||
override val fields: MutableList<Variable> = mutableListOf()
|
override val fields: MutableList<Variable> = mutableListOf()
|
||||||
override val typeArguments: MutableList<Variable> = mutableListOf()
|
|
||||||
|
|
||||||
override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? = null
|
override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? = null
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user