Move static cache from Wrapper into non-static container in environment
By this change it is possible to run multiple test in parallel without running out of memory.
This commit is contained in:
committed by
TeamCityServer
parent
3932acf843
commit
44e1b61e6c
+5
-5
@@ -103,7 +103,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
||||
val objectClass = expression.symbol.owner
|
||||
when {
|
||||
Wrapper.mustBeHandledWithWrapper(objectClass) -> {
|
||||
val result = Wrapper.getCompanionObject(objectClass)
|
||||
val result = Wrapper.getCompanionObject(objectClass, environment)
|
||||
environment.mapOfObjects[expression.symbol] = result
|
||||
callStack.pushState(result)
|
||||
}
|
||||
@@ -115,7 +115,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
||||
val enumClass = enumEntry.symbol.owner.parentAsClass
|
||||
when {
|
||||
Wrapper.mustBeHandledWithWrapper(enumClass) -> {
|
||||
val enumEntryName = enumEntry.name.asString().toState(environment.irBuiltIns.stringType)
|
||||
val enumEntryName = environment.convertToState(enumEntry.name.asString(), environment.irBuiltIns.stringType)
|
||||
val valueOfFun = enumClass.declarations.single { it.nameForIrSerialization.asString() == "valueOf" } as IrFunction
|
||||
Wrapper.getEnumEntry(enumClass).invokeMethod(valueOfFun, listOf(enumEntryName))
|
||||
environment.mapOfEnums[enumEntry.symbol] = callStack.popState() as Complex
|
||||
@@ -128,7 +128,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
||||
val field = expression.symbol.owner
|
||||
verify(field.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && field.isStatic)
|
||||
verify(field.initializer?.expression !is IrConst<*>)
|
||||
callStack.pushState(Wrapper.getStaticGetter(field).invokeWithArguments().toState(field.type))
|
||||
callStack.pushState(environment.convertToState(Wrapper.getStaticGetter(field).invokeWithArguments(), field.type))
|
||||
}
|
||||
|
||||
private fun MethodHandle?.invokeMethod(irFunction: IrFunction, args: List<State>) {
|
||||
@@ -136,7 +136,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
||||
val argsForMethodInvocation = irFunction.getArgsForMethodInvocation(this@DefaultCallInterceptor, this.type(), args)
|
||||
withExceptionHandler(environment) {
|
||||
val result = this.invokeWithArguments(argsForMethodInvocation) // TODO if null return Unit
|
||||
callStack.pushState(result.toState(result.getType(irFunction.returnType)))
|
||||
callStack.pushState(environment.convertToState(result, result.getType(irFunction.returnType)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
||||
else -> throw InterpreterError("Unsupported number of arguments for invocation as builtin function: $methodName")
|
||||
}
|
||||
// TODO check "result is Unit"
|
||||
callStack.pushState(result.toState(result.getType(irFunction.returnType)))
|
||||
callStack.pushState(environment.convertToState(result, result.getType(irFunction.returnType)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -366,7 +366,7 @@ private fun unfoldStringConcatenation(expression: IrStringConcatenation, environ
|
||||
is Int -> value.toUInt().toString()
|
||||
else -> (value as Number).toLong().toULong().toString()
|
||||
}
|
||||
return callStack.pushState(result.toState(environment.irBuiltIns.stringType))
|
||||
return callStack.pushState(environment.convertToState(result, environment.irBuiltIns.stringType))
|
||||
}
|
||||
val toStringCall = state.createToStringIrCall()
|
||||
callStack.addInstruction(SimpleInstruction(toStringCall))
|
||||
|
||||
@@ -463,17 +463,18 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
||||
}
|
||||
IrTypeOperator.SAFE_CAST -> {
|
||||
when {
|
||||
!isErased && !state.isSubtypeOf(typeOperand) -> callStack.pushState(null.toState(irBuiltIns.nothingNType))
|
||||
!isErased && !state.isSubtypeOf(typeOperand) ->
|
||||
callStack.pushState(environment.convertToState(null, irBuiltIns.nothingNType))
|
||||
else -> callStack.pushState(state)
|
||||
}
|
||||
}
|
||||
IrTypeOperator.INSTANCEOF -> {
|
||||
val isInstance = isErased || state.isSubtypeOf(typeOperand)
|
||||
callStack.pushState(isInstance.toState(irBuiltIns.booleanType))
|
||||
callStack.pushState(environment.convertToState(isInstance, irBuiltIns.booleanType))
|
||||
}
|
||||
IrTypeOperator.NOT_INSTANCEOF -> {
|
||||
val isInstance = isErased || state.isSubtypeOf(typeOperand)
|
||||
callStack.pushState((!isInstance).toState(irBuiltIns.booleanType))
|
||||
callStack.pushState(environment.convertToState((!isInstance), irBuiltIns.booleanType))
|
||||
}
|
||||
IrTypeOperator.IMPLICIT_NOTNULL -> {
|
||||
when {
|
||||
@@ -564,7 +565,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
||||
}
|
||||
}
|
||||
|
||||
callStack.pushState(result.reversed().joinToString(separator = "").toState(expression.type))
|
||||
callStack.pushState(environment.convertToState(result.reversed().joinToString(separator = ""), expression.type))
|
||||
}
|
||||
|
||||
private fun interpretFunctionExpression(expression: IrFunctionExpression) {
|
||||
|
||||
+22
@@ -8,11 +8,17 @@ package org.jetbrains.kotlin.ir.interpreter
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.CallStack
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.Common
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.Complex
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.Primitive
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.State
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.Wrapper
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.util.isSubclassOf
|
||||
|
||||
class IrInterpreterEnvironment(
|
||||
@@ -23,6 +29,7 @@ class IrInterpreterEnvironment(
|
||||
internal val irExceptions = mutableListOf<IrClass>()
|
||||
internal var mapOfEnums = mutableMapOf<IrSymbol, Complex>()
|
||||
internal var mapOfObjects = mutableMapOf<IrSymbol, Complex>()
|
||||
internal var javaClassToIrClass = mutableMapOf<Class<*>, IrClass>()
|
||||
|
||||
private data class CacheFunctionSignature(
|
||||
val symbol: IrFunctionSymbol,
|
||||
@@ -80,4 +87,19 @@ class IrInterpreterEnvironment(
|
||||
functionCache[CacheFunctionSignature(symbol, hasDispatchReceiver, hasExtensionReceiver, fromDelegatingCall)] = newFunction
|
||||
return newFunction
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert object from outer world to state
|
||||
*/
|
||||
internal fun convertToState(value: Any?, irType: IrType): State {
|
||||
return when (value) {
|
||||
is Proxy -> value.state
|
||||
is State -> value
|
||||
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(value, irType)
|
||||
null -> Primitive.nullStateOfType(irType)
|
||||
else -> irType.classOrNull?.owner?.let { Wrapper(value, it, this) }
|
||||
?: Wrapper(value, this.javaClassToIrClass[value::class.java]!!, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.interpreter.exceptions.handleUserException
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.wrap
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.CallStack
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.*
|
||||
@@ -43,20 +42,6 @@ internal fun IrFunction.getReceiver(): IrSymbol? = this.getDispatchReceiver() ?:
|
||||
|
||||
internal fun IrFunctionAccessExpression.getThisReceiver(): IrValueSymbol = this.symbol.owner.parentAsClass.thisReceiver!!.symbol
|
||||
|
||||
/**
|
||||
* Convert object from outer world to state
|
||||
*/
|
||||
internal fun Any?.toState(irType: IrType): State {
|
||||
return when (this) {
|
||||
is Proxy -> this.state
|
||||
is State -> this
|
||||
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)
|
||||
null -> Primitive.nullStateOfType(irType)
|
||||
else -> irType.classOrNull?.owner?.let { Wrapper(this, it) } ?: Wrapper(this)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
internal fun <T> IrConst<T>.toPrimitive(): Primitive<T> = when {
|
||||
type.isByte() -> Primitive((value as Number).toByte() as T, type)
|
||||
|
||||
+10
-10
@@ -44,7 +44,7 @@ internal object EmptyArray : IntrinsicBase() {
|
||||
|
||||
override fun evaluate(irFunction: IrFunction, environment: IrInterpreterEnvironment) {
|
||||
val returnType = environment.callStack.getState(irFunction.symbol) as KTypeState
|
||||
environment.callStack.pushState(emptyArray<Any?>().toState(returnType.irType))
|
||||
environment.callStack.pushState(environment.convertToState(emptyArray<Any?>(), returnType.irType))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ internal object ArrayOfNulls : IntrinsicBase() {
|
||||
arguments = listOf(makeTypeProjection(typeArgument.irType, Variance.INVARIANT))
|
||||
}
|
||||
|
||||
environment.callStack.pushState(array.toState(returnType))
|
||||
environment.callStack.pushState(environment.convertToState(array, returnType))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ internal object EnumValues : IntrinsicBase() {
|
||||
val enumClass = getEnumClass(irFunction, environment)
|
||||
|
||||
val enumEntries = enumClass.declarations.filterIsInstance<IrEnumEntry>().map { environment.mapOfEnums[it.symbol] }
|
||||
environment.callStack.pushState(enumEntries.toTypedArray().toState(irFunction.returnType))
|
||||
environment.callStack.pushState(environment.convertToState(enumEntries.toTypedArray(), irFunction.returnType))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,14 +169,14 @@ internal object EnumIntrinsics : IntrinsicBase() {
|
||||
val ordinalSymbol = enumEntry.irClass.getOriginalPropertyByName("ordinal").symbol
|
||||
val other = callStack.getState(irFunction.valueParameters.single().symbol)
|
||||
val compareTo = enumEntry.getField(ordinalSymbol)!!.asInt().compareTo(other.getField(ordinalSymbol)!!.asInt())
|
||||
callStack.pushState(compareTo.toState(irFunction.returnType))
|
||||
callStack.pushState(environment.convertToState(compareTo, irFunction.returnType))
|
||||
}
|
||||
// TODO "clone" -> throw exception
|
||||
"equals" -> {
|
||||
val other = callStack.getState(irFunction.valueParameters.single().symbol)
|
||||
callStack.pushState((enumEntry === other).toState(irFunction.returnType))
|
||||
callStack.pushState(environment.convertToState((enumEntry === other), irFunction.returnType))
|
||||
}
|
||||
"hashCode" -> callStack.pushState(enumEntry.hashCode().toState(irFunction.returnType))
|
||||
"hashCode" -> callStack.pushState(environment.convertToState(enumEntry.hashCode(), irFunction.returnType))
|
||||
"toString" -> {
|
||||
val nameSymbol = enumEntry.irClass.getOriginalPropertyByName("name").symbol
|
||||
callStack.pushState(enumEntry.getField(nameSymbol)!!)
|
||||
@@ -197,11 +197,11 @@ internal object JsPrimitives : IntrinsicBase() {
|
||||
"kotlin.Long.<init>" -> {
|
||||
val low = environment.callStack.getState(irFunction.valueParameters[0].symbol).asInt()
|
||||
val high = environment.callStack.getState(irFunction.valueParameters[1].symbol).asInt()
|
||||
environment.callStack.pushState((high.toLong().shl(32) + low).toState(irFunction.returnType))
|
||||
environment.callStack.pushState(environment.convertToState((high.toLong().shl(32) + low), irFunction.returnType))
|
||||
}
|
||||
"kotlin.Char.<init>" -> {
|
||||
val value = environment.callStack.getState(irFunction.valueParameters[0].symbol).asInt()
|
||||
environment.callStack.pushState(value.toChar().toState(irFunction.returnType))
|
||||
environment.callStack.pushState(environment.convertToState(value.toChar(), irFunction.returnType))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,7 +276,7 @@ internal object SourceLocation : IntrinsicBase() {
|
||||
}
|
||||
|
||||
override fun evaluate(irFunction: IrFunction, environment: IrInterpreterEnvironment) {
|
||||
environment.callStack.pushState(environment.callStack.getFileAndPositionInfo().toState(irFunction.returnType))
|
||||
environment.callStack.pushState(environment.convertToState(environment.callStack.getFileAndPositionInfo(), irFunction.returnType))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,6 +329,6 @@ internal object DataClassArrayToString : IntrinsicBase() {
|
||||
|
||||
override fun evaluate(irFunction: IrFunction, environment: IrInterpreterEnvironment) {
|
||||
val array = environment.callStack.getState(irFunction.valueParameters.single().symbol) as Primitive<*>
|
||||
environment.callStack.pushState(arrayToString(array.value).toState(irFunction.returnType))
|
||||
environment.callStack.pushState(environment.convertToState(arrayToString(array.value), irFunction.returnType))
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.ir.interpreter.getDispatchReceiver
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.Common
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.State
|
||||
import org.jetbrains.kotlin.ir.interpreter.toState
|
||||
import org.jetbrains.kotlin.ir.util.isFakeOverriddenFromAny
|
||||
|
||||
internal class CommonProxy private constructor(override val state: Common, override val callInterceptor: CallInterceptor) : Proxy {
|
||||
@@ -84,8 +83,9 @@ internal class CommonProxy private constructor(override val state: Common, overr
|
||||
?: return@newProxyInstance commonProxy.fallbackIfMethodNotFound(method)
|
||||
val valueArguments = mutableListOf<Variable>()
|
||||
valueArguments += Variable(irFunction.getDispatchReceiver()!!, commonProxy.state)
|
||||
valueArguments += irFunction.valueParameters
|
||||
.mapIndexed { index, parameter -> Variable(parameter.symbol, args[index].toState(parameter.type)) }
|
||||
valueArguments += irFunction.valueParameters.mapIndexed { index, parameter ->
|
||||
Variable(parameter.symbol, callInterceptor.environment.convertToState(args[index], parameter.type))
|
||||
}
|
||||
callInterceptor.interceptProxy(irFunction, valueArguments, method.returnType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ import java.lang.invoke.MethodType
|
||||
internal interface Proxy {
|
||||
val state: State
|
||||
val callInterceptor: CallInterceptor
|
||||
val environment
|
||||
get() = callInterceptor.environment
|
||||
|
||||
override fun equals(other: Any?): Boolean
|
||||
override fun hashCode(): Int
|
||||
|
||||
+8
-5
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
|
||||
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KFunctionState
|
||||
import org.jetbrains.kotlin.ir.interpreter.toState
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.isSuspend
|
||||
import org.jetbrains.kotlin.ir.util.statements
|
||||
@@ -51,10 +50,14 @@ internal class KFunctionProxy(
|
||||
override fun call(vararg args: Any?): Any? {
|
||||
// TODO check arity
|
||||
var index = 0
|
||||
val dispatchReceiver = state.irFunction.dispatchReceiverParameter?.let { Variable(it.symbol, args[index++].toState(it.type)) }
|
||||
val extensionReceiver = state.irFunction.extensionReceiverParameter?.let { Variable(it.symbol, args[index++].toState(it.type)) }
|
||||
val valueArguments = listOfNotNull(dispatchReceiver, extensionReceiver) +
|
||||
state.irFunction.valueParameters.map { parameter -> Variable(parameter.symbol, args[index++].toState(parameter.type)) }
|
||||
val dispatchReceiver = state.irFunction.dispatchReceiverParameter
|
||||
?.let { Variable(it.symbol, environment.convertToState(args[index++], it.type)) }
|
||||
val extensionReceiver = state.irFunction.extensionReceiverParameter
|
||||
?.let { Variable(it.symbol, environment.convertToState(args[index++], it.type)) }
|
||||
val argsVariables = state.irFunction.valueParameters.map { parameter ->
|
||||
Variable(parameter.symbol, environment.convertToState(args[index++], parameter.type))
|
||||
}
|
||||
val valueArguments = listOfNotNull(dispatchReceiver, extensionReceiver) + argsVariables
|
||||
return callInterceptor.interceptProxy(state.irFunction, valueArguments)
|
||||
}
|
||||
|
||||
|
||||
+5
-6
@@ -5,20 +5,19 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
|
||||
|
||||
import org.jetbrains.kotlin.ir.interpreter.*
|
||||
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
|
||||
import org.jetbrains.kotlin.ir.interpreter.exceptions.verify
|
||||
import org.jetbrains.kotlin.ir.interpreter.getDispatchReceiver
|
||||
import org.jetbrains.kotlin.ir.interpreter.getExtensionReceiver
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.isNull
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KPropertyState
|
||||
import org.jetbrains.kotlin.ir.interpreter.toState
|
||||
import org.jetbrains.kotlin.ir.util.isObject
|
||||
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||
import kotlin.reflect.*
|
||||
|
||||
internal open class KProperty0Proxy(
|
||||
override val state: KPropertyState, override val callInterceptor: CallInterceptor
|
||||
state: KPropertyState, callInterceptor: CallInterceptor
|
||||
) : AbstractKPropertyProxy(state, callInterceptor), KProperty0<Any?> {
|
||||
override val getter: KProperty0.Getter<Any?>
|
||||
get() = object : Getter(state.property.getter!!), KProperty0.Getter<Any?> {
|
||||
@@ -34,7 +33,7 @@ internal open class KProperty0Proxy(
|
||||
return when {
|
||||
// null value <=> property is extension or Primitive; receiver.isNull() <=> nullable extension
|
||||
value == null || receiver.isNull() -> {
|
||||
val receiverSymbol = getter.getDispatchReceiver() ?: getter.getExtensionReceiver()
|
||||
val receiverSymbol = getter.getReceiver()
|
||||
val receiverVariable = receiverSymbol?.let { Variable(it, receiver) }
|
||||
callInterceptor.interceptProxy(getter, listOfNotNull(receiverVariable))
|
||||
}
|
||||
@@ -57,7 +56,7 @@ internal open class KProperty0Proxy(
|
||||
}
|
||||
|
||||
internal class KMutableProperty0Proxy(
|
||||
override val state: KPropertyState, override val callInterceptor: CallInterceptor
|
||||
state: KPropertyState, callInterceptor: CallInterceptor
|
||||
) : KProperty0Proxy(state, callInterceptor), KMutableProperty0<Any?> {
|
||||
override val setter: KMutableProperty0.Setter<Any?> =
|
||||
object : Setter(state.property.setter!!), KMutableProperty0.Setter<Any?> {
|
||||
@@ -69,7 +68,7 @@ internal class KMutableProperty0Proxy(
|
||||
verify(state.receiver != null) { "Cannot interpret set method on top level properties" }
|
||||
verify(state.receiver?.irClass?.isObject != true) { "Cannot interpret set method on property of object" }
|
||||
val receiver = state.receiver!!
|
||||
val newValue = args.single().toState(propertyType)
|
||||
val newValue = environment.convertToState(args.single(), propertyType)
|
||||
setter.getExtensionReceiver()
|
||||
?.let {
|
||||
val fieldSymbol = setter.valueParameters.single().symbol
|
||||
|
||||
+5
-6
@@ -10,14 +10,13 @@ import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KPropertyState
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KTypeState
|
||||
import org.jetbrains.kotlin.ir.interpreter.toState
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import kotlin.reflect.*
|
||||
|
||||
internal open class KProperty1Proxy(
|
||||
override val state: KPropertyState, override val callInterceptor: CallInterceptor
|
||||
state: KPropertyState, callInterceptor: CallInterceptor
|
||||
) : AbstractKPropertyProxy(state, callInterceptor), KProperty1<Any?, Any?> {
|
||||
protected fun IrValueParameter.getActualType(): IrType {
|
||||
return when (this.type.classOrNull) {
|
||||
@@ -33,7 +32,7 @@ internal open class KProperty1Proxy(
|
||||
override fun call(vararg args: Any?): Any? {
|
||||
checkArguments(1, args.size)
|
||||
val receiverParameter = (getter.dispatchReceiverParameter ?: getter.extensionReceiverParameter)!!
|
||||
val receiver = Variable(receiverParameter.symbol, args[0].toState(receiverParameter.getActualType()))
|
||||
val receiver = Variable(receiverParameter.symbol, environment.convertToState(args[0], receiverParameter.getActualType()))
|
||||
return callInterceptor.interceptProxy(getter, listOf(receiver))
|
||||
}
|
||||
|
||||
@@ -52,7 +51,7 @@ internal open class KProperty1Proxy(
|
||||
}
|
||||
|
||||
internal class KMutableProperty1Proxy(
|
||||
override val state: KPropertyState, override val callInterceptor: CallInterceptor
|
||||
state: KPropertyState, callInterceptor: CallInterceptor
|
||||
) : KProperty1Proxy(state, callInterceptor), KMutableProperty1<Any?, Any?> {
|
||||
override val setter: KMutableProperty1.Setter<Any?, Any?> =
|
||||
object : Setter(state.property.setter!!), KMutableProperty1.Setter<Any?, Any?> {
|
||||
@@ -61,9 +60,9 @@ internal class KMutableProperty1Proxy(
|
||||
override fun call(vararg args: Any?) {
|
||||
checkArguments(2, args.size)
|
||||
val receiverParameter = (setter.dispatchReceiverParameter ?: setter.extensionReceiverParameter)!!
|
||||
val receiver = Variable(receiverParameter.symbol, args[0].toState(receiverParameter.getActualType()))
|
||||
val receiver = Variable(receiverParameter.symbol, environment.convertToState(args[0], receiverParameter.getActualType()))
|
||||
val valueParameter = setter.valueParameters.single()
|
||||
val value = Variable(valueParameter.symbol, args[1].toState(valueParameter.getActualType()))
|
||||
val value = Variable(valueParameter.symbol, environment.convertToState(args[1], valueParameter.getActualType()))
|
||||
callInterceptor.interceptProxy(setter, listOf(receiver, value))
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -8,11 +8,10 @@ package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
|
||||
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KPropertyState
|
||||
import org.jetbrains.kotlin.ir.interpreter.toState
|
||||
import kotlin.reflect.*
|
||||
|
||||
internal open class KProperty2Proxy(
|
||||
override val state: KPropertyState, override val callInterceptor: CallInterceptor
|
||||
state: KPropertyState, callInterceptor: CallInterceptor
|
||||
) : AbstractKPropertyProxy(state, callInterceptor), KProperty2<Any?, Any?, Any?> {
|
||||
override val getter: KProperty2.Getter<Any?, Any?, Any?>
|
||||
get() = object : Getter(state.property.getter!!), KProperty2.Getter<Any?, Any?, Any?> {
|
||||
@@ -20,8 +19,10 @@ internal open class KProperty2Proxy(
|
||||
|
||||
override fun call(vararg args: Any?): Any? {
|
||||
checkArguments(2, args.size)
|
||||
val dispatch = Variable(getter.dispatchReceiverParameter!!.symbol, args[0].toState(getter.dispatchReceiverParameter!!.type))
|
||||
val extension = Variable(getter.extensionReceiverParameter!!.symbol, args[1].toState(getter.extensionReceiverParameter!!.type))
|
||||
val dispatchParameter = getter.dispatchReceiverParameter!!
|
||||
val extensionReceiverParameter = getter.extensionReceiverParameter!!
|
||||
val dispatch = Variable(dispatchParameter.symbol, environment.convertToState(args[0], dispatchParameter.type))
|
||||
val extension = Variable(extensionReceiverParameter.symbol, environment.convertToState(args[1], extensionReceiverParameter.type))
|
||||
return callInterceptor.interceptProxy(getter, listOf(dispatch, extension))
|
||||
}
|
||||
|
||||
@@ -40,7 +41,7 @@ internal open class KProperty2Proxy(
|
||||
}
|
||||
|
||||
internal class KMutableProperty2Proxy(
|
||||
override val state: KPropertyState, override val callInterceptor: CallInterceptor
|
||||
state: KPropertyState, callInterceptor: CallInterceptor
|
||||
) : KProperty2Proxy(state, callInterceptor), KMutableProperty2<Any?, Any?, Any?> {
|
||||
override val setter: KMutableProperty2.Setter<Any?, Any?, Any?>
|
||||
get() = object : Setter(state.property.setter!!), KMutableProperty2.Setter<Any?, Any?, Any?> {
|
||||
|
||||
+1
-2
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.ir.interpreter.state
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.interpreter.getOriginalPropertyByName
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.interpreter.toState
|
||||
import org.jetbrains.kotlin.ir.util.isSubclassOf
|
||||
import kotlin.math.min
|
||||
|
||||
@@ -104,7 +103,7 @@ internal class ExceptionState private constructor(
|
||||
val messageProperty = irClass.getOriginalPropertyByName("message")
|
||||
val causeProperty = irClass.getOriginalPropertyByName("cause")
|
||||
|
||||
val messageVar = Variable(messageProperty.symbol, exception.message.toState(messageProperty.getter!!.returnType))
|
||||
val messageVar = Variable(messageProperty.symbol, Primitive(exception.message, messageProperty.getter!!.returnType))
|
||||
val causeVar = exception.cause?.let {
|
||||
Variable(causeProperty.symbol, ExceptionState(it, irClass, stackTrace + it.stackTrace.reversed().map { "at $it" }))
|
||||
}
|
||||
|
||||
+10
-16
@@ -22,7 +22,7 @@ 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, environment: IrInterpreterEnvironment) : Complex {
|
||||
override val fields: MutableList<Variable> = mutableListOf()
|
||||
|
||||
override var superWrapperClass: Wrapper? = null
|
||||
@@ -37,29 +37,28 @@ internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex
|
||||
val nodeClass = javaClass.declaredClasses.single { it.name.contains("\$Node") }
|
||||
val mutableMap = irClass.superTypes.mapNotNull { it.classOrNull?.owner }
|
||||
.single { it.name == StandardNames.FqNames.mutableMap.shortName() }
|
||||
javaClassToIrClass += nodeClass to mutableMap.declarations.filterIsInstance<IrClass>().single()
|
||||
environment.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.name == StandardNames.FqNames.mutableMap.shortName() }
|
||||
javaClassToIrClass += entryClass to mutableMap.declarations.filterIsInstance<IrClass>().single()
|
||||
environment.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()
|
||||
val irClassMapEntry = irClass.declarations.filterIsInstance<IrClass>().single()
|
||||
environment.javaClassToIrClass += AbstractMap.SimpleEntry::class.java to irClassMapEntry
|
||||
environment.javaClassToIrClass += AbstractMap.SimpleImmutableEntry::class.java to irClassMapEntry
|
||||
}
|
||||
}
|
||||
if (javaClassToIrClass[value::class.java].let { it == null || irClass.isSubclassOf(it) }) {
|
||||
if (environment.javaClassToIrClass[value::class.java].let { it == null || irClass.isSubclassOf(it) }) {
|
||||
// second condition guarantees that implementation class will not be replaced with its interface
|
||||
// for example: map will store ArrayList instead of just List
|
||||
// this is needed for parallel calculations
|
||||
javaClassToIrClass[value::class.java] = irClass
|
||||
environment.javaClassToIrClass[value::class.java] = irClass
|
||||
}
|
||||
}
|
||||
|
||||
constructor(value: Any) : this(value, javaClassToIrClass[value::class.java]!!)
|
||||
|
||||
override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? = null
|
||||
|
||||
fun getMethod(irFunction: IrFunction): MethodHandle? {
|
||||
@@ -91,7 +90,6 @@ internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex
|
||||
|
||||
companion object {
|
||||
private val companionObjectValue = mapOf<String, Any>("kotlin.text.Regex\$Companion" to Regex.Companion)
|
||||
private val javaClassToIrClass = mutableMapOf<Class<*>, IrClass>()
|
||||
|
||||
// TODO remove later; used for tests only
|
||||
private val intrinsicClasses = setOf(
|
||||
@@ -110,10 +108,6 @@ internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex
|
||||
"Array.kotlin.collections.copyToArrayOfAny(Boolean)" to "kotlin.collections.CollectionsKt",
|
||||
)
|
||||
|
||||
fun associateJavaClassWithIrClass(javaClass: Class<*>, irClass: IrClass) {
|
||||
javaClassToIrClass += javaClass to irClass
|
||||
}
|
||||
|
||||
private fun IrDeclarationWithName.getSignature(): String {
|
||||
val fqName = this.fqName
|
||||
return when (this) {
|
||||
@@ -154,10 +148,10 @@ internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex
|
||||
return MethodHandles.lookup().findVirtual(receiverClass, methodName, methodType)
|
||||
}
|
||||
|
||||
fun getCompanionObject(irClass: IrClass): Wrapper {
|
||||
fun getCompanionObject(irClass: IrClass, environment: IrInterpreterEnvironment): Wrapper {
|
||||
val objectName = irClass.internalName()
|
||||
val objectValue = companionObjectValue[objectName] ?: throw InternalError("Companion object $objectName cannot be interpreted")
|
||||
return Wrapper(objectValue, irClass)
|
||||
return Wrapper(objectValue, irClass, environment)
|
||||
}
|
||||
|
||||
fun getConstructorMethod(irConstructor: IrFunction): MethodHandle? {
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ internal class KTypeState(val irType: IrType, override val irClass: IrClass) : R
|
||||
|
||||
fun getArguments(callInterceptor: CallInterceptor): List<KTypeProjection> {
|
||||
if (_arguments != null) return _arguments!!
|
||||
Wrapper.associateJavaClassWithIrClass(KTypeProjection::class.java, irClass.getIrClassOfReflectionFromList("arguments"))
|
||||
callInterceptor.environment.javaClassToIrClass += KTypeProjection::class.java to irClass.getIrClassOfReflectionFromList("arguments")
|
||||
_arguments = (irType as IrSimpleType).arguments
|
||||
.map {
|
||||
when (it.getVariance()) {
|
||||
|
||||
Reference in New Issue
Block a user