From 002804941f09c18af48a27285ef1deac7f12080b Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Sat, 19 Sep 2020 16:26:23 +0300 Subject: [PATCH] Replace Lambda state with KFunctionState --- .../kotlin/ir/interpreter/IrInterpreter.kt | 30 +++---- .../jetbrains/kotlin/ir/interpreter/Utils.kt | 2 + .../intrinsics/IntrinsicImplementations.kt | 3 +- .../ir/interpreter/proxy/LambdaProxy.kt | 62 -------------- .../kotlin/ir/interpreter/proxy/Proxy.kt | 2 - .../reflection/AbstractKPropertyProxy.kt | 8 +- .../reflection/FunctionWithAllInvokes.kt | 65 +++++++++++++++ .../proxy/reflection/KFunctionProxy.kt | 81 +++++++++++++++++++ .../proxy/reflection/KProperty0Proxy.kt | 42 +++------- .../proxy/reflection/KProperty1Proxy.kt | 51 +++++------- .../proxy/reflection/KProperty2Proxy.kt | 48 ++++------- .../proxy/reflection/ReflectionProxy.kt | 11 +-- .../kotlin/ir/interpreter/stack/Variable.kt | 5 ++ .../kotlin/ir/interpreter/state/Lambda.kt | 46 ----------- .../ir/interpreter/state/ReflectionState.kt | 38 +++++++++ .../kotlin/ir/interpreter/state/State.kt | 8 -- .../kotlin/ir/interpreter/state/Wrapper.kt | 17 ++++ 17 files changed, 281 insertions(+), 238 deletions(-) delete mode 100644 compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/LambdaProxy.kt create mode 100644 compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/FunctionWithAllInvokes.kt create mode 100644 compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KFunctionProxy.kt delete mode 100644 compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Lambda.kt diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt index e3f78fadf6f..a415bcce63e 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt @@ -94,13 +94,13 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map } internal fun IrFunction.interpret(valueArguments: List, expectedResultClass: Class<*> = Any::class.java): Any? { - val returnLabel = stack.newFrame(initPool = valueArguments) { + val returnLabel = stack.newFrame(asSubFrame = this.isLocal, initPool = valueArguments) { this@interpret.interpret() } return when (returnLabel.returnLabel) { ReturnLabel.REGULAR -> stack.popReturnValue().wrap(this@IrInterpreter, expectedResultClass) ReturnLabel.EXCEPTION -> throw stack.popReturnValue() as ExceptionState - else -> TODO("$returnLabel not supported as result of interpretation") + else -> TODO("${returnLabel::class} not supported as result of interpretation") } } @@ -319,10 +319,8 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map return@newFrame when { dispatchReceiver is Wrapper && !isInlineOnly -> dispatchReceiver.getMethod(irFunction).invokeMethod(irFunction) irFunction.hasAnnotation(evaluateIntrinsicAnnotation) -> Wrapper.getStaticMethod(irFunction).invokeMethod(irFunction) - dispatchReceiver is ReflectionState -> { - stack.pushReturnValue((dispatchReceiver.wrap(this) as ReflectionProxy).evaluate(expression, stack.getAll())) - Next - } + dispatchReceiver is KFunctionState && expression.symbol.owner.name.asString() == "invoke" -> irFunction.interpret() + dispatchReceiver is ReflectionState -> Wrapper.getReflectionMethod(irFunction).invokeMethod(irFunction) dispatchReceiver is Primitive<*> -> calculateBuiltIns(irFunction) // 'is Primitive' check for js char and js long irFunction.body == null -> irFunction.trySubstituteFunctionBody() ?: irFunction.tryCalculateLazyConst() ?: calculateBuiltIns(irFunction) @@ -490,7 +488,6 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map } private fun interpretStatements(statements: List): ExecutionResult { - if (statements.isEmpty()) return getOrCreateObjectValue(irBuiltIns.unitClass.owner) var executionResult: ExecutionResult = Next for (statement in statements) { when (statement) { @@ -507,7 +504,13 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map } private fun interpretBody(body: IrBody): ExecutionResult { - return stack.newFrame(asSubFrame = true) { interpretStatements(body.statements) } + return stack.newFrame(asSubFrame = true) { + val executionResult = interpretStatements(body.statements).check { return@newFrame it } + when { + !stack.hasReturnValue() -> getOrCreateObjectValue(irBuiltIns.unitClass.owner) + else -> executionResult + } + } } private fun interpretReturn(expression: IrReturn): ExecutionResult { @@ -853,22 +856,21 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map toStringFun.body?.let { toStringFun.interpret() } ?: calculateBuiltIns(toStringFun) } } - is Lambda -> state.toString() - else -> throw InterpreterError("${state::class.java} cannot be used in StringConcatenation expression") + else -> state.toString() } stack.pushReturnValue(result.toState(irBuiltIns.stringType)) return Next } private fun interpretFunctionExpression(expression: IrFunctionExpression): ExecutionResult { - val lambda = Lambda(expression.function, expression.type.classOrNull!!.owner) - if (expression.function.isLocal) lambda.fields.addAll(stack.getAll()) // TODO save only necessary declarations - stack.pushReturnValue(lambda) + val function = KFunctionState(expression.function, expression.type.classOrNull!!.owner) + if (expression.function.isLocal) function.fields.addAll(stack.getAll()) // TODO save only necessary declarations + stack.pushReturnValue(function) return Next } private fun interpretFunctionReference(reference: IrFunctionReference): ExecutionResult { - stack.pushReturnValue(Lambda(reference.symbol.owner, reference.type.classOrNull!!.owner)) + stack.pushReturnValue(KFunctionState(reference)) return Next } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt index 776ee9a286c..d05d50fb482 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt @@ -38,6 +38,8 @@ internal fun IrFunctionAccessExpression.getBody(): IrBody? = this.symbol.owner.b internal fun IrFunctionAccessExpression.getThisReceiver(): IrValueSymbol = this.symbol.owner.parentAsClass.thisReceiver!!.symbol +internal fun IrCall.isInvokeFun(): Boolean = this.origin == IrStatementOrigin.INVOKE || this.symbol.owner.name.asString() == "invoke" + internal fun State.toIrExpression(expression: IrExpression): IrExpression { val start = expression.startOffset val end = expression.endOffset diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicImplementations.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicImplementations.kt index f73d82f5864..822097c6db0 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicImplementations.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicImplementations.kt @@ -14,7 +14,6 @@ import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrEnumEntry import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.interpreter.exceptions.throwAsUserException -import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.isCharArray import org.jetbrains.kotlin.ir.util.* @@ -153,7 +152,7 @@ internal object ArrayConstructor : IntrinsicBase() { if (irFunction.valueParameters.size == 2) { val initDescriptor = irFunction.valueParameters[1].symbol - val initLambda = stack.getVariable(initDescriptor).state as Lambda + val initLambda = stack.getVariable(initDescriptor).state as KFunctionState val index = initLambda.irFunction.valueParameters.single() val nonLocalDeclarations = initLambda.extractNonLocalDeclarations() for (i in 0 until size) { diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/LambdaProxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/LambdaProxy.kt deleted file mode 100644 index e779d36c7cd..00000000000 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/LambdaProxy.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.ir.interpreter.proxy - -import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor -import org.jetbrains.kotlin.ir.interpreter.IrInterpreter -import org.jetbrains.kotlin.ir.interpreter.stack.Variable -import org.jetbrains.kotlin.ir.interpreter.state.Lambda -import org.jetbrains.kotlin.ir.interpreter.toState - -internal class LambdaProxy private constructor( - override val state: Lambda, override val interpreter: IrInterpreter -) : Proxy { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is Proxy) return false - - return state == other.state - } - - override fun hashCode(): Int { - return state.hashCode() - } - - override fun toString(): String { - return state.toString() - } - - companion object { - fun Lambda.asProxy(interpreter: IrInterpreter): Any { - val lambdaProxy = LambdaProxy(this, interpreter) - val arity = this.getArity() - val hasBigArity = arity == null || arity >= FunctionInvokeDescriptor.BIG_ARITY - - val functionClass = when { - !hasBigArity && this.isFunction -> Class.forName("kotlin.jvm.functions." + this.irClass.name) - hasBigArity && this.isFunction -> Class.forName("kotlin.jvm.functions.FunctionN") - this.isKFunction -> Class.forName("kotlin.reflect.KFunction") - else -> throw InternalError("Cannot handle lambda $this as proxy") - } - return java.lang.reflect.Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), arrayOf(functionClass, Proxy::class.java)) - { proxy, method, args -> - when { - method.declaringClass == Proxy::class.java && method.name == "getState" -> lambdaProxy.state - method.declaringClass == Proxy::class.java && method.name == "getInterpreter" -> lambdaProxy.interpreter - method.name == "equals" && method.parameterTypes.single().isObject() -> lambdaProxy.equals(args.single()) - method.name == "hashCode" && method.parameterTypes.isEmpty() -> lambdaProxy.hashCode() - method.name == "toString" && method.parameterTypes.isEmpty() -> lambdaProxy.toString() - method.name == "invoke" && method.parameterTypes.single().isObject() -> { - val valueArguments = this.irFunction.valueParameters - .mapIndexed { index, parameter -> Variable(parameter.symbol, args[index].toState(parameter.type)) } - with(interpreter) { lambdaProxy.state.irFunction.interpret(valueArguments, method.returnType) } - } - else -> throw InternalError("Cannot invoke method ${method.name} from lambda $this") - } - } - } - } -} \ No newline at end of file diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/Proxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/Proxy.kt index dd660280c78..909559c8474 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/Proxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/Proxy.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.interpreter.proxy import org.jetbrains.kotlin.ir.interpreter.IrInterpreter import org.jetbrains.kotlin.ir.interpreter.proxy.CommonProxy.Companion.asProxy -import org.jetbrains.kotlin.ir.interpreter.proxy.LambdaProxy.Companion.asProxy import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.ReflectionProxy.Companion.asProxy import org.jetbrains.kotlin.ir.interpreter.state.* @@ -29,7 +28,6 @@ internal fun State.wrap(interpreter: IrInterpreter, extendFrom: Class<*>? = null is Wrapper -> this.value is Primitive<*> -> this.value is Common -> this.asProxy(interpreter, extendFrom, calledFromBuiltIns) - is Lambda -> this.asProxy(interpreter) is ReflectionState -> this.asProxy(interpreter) else -> throw AssertionError("${this::class} is unsupported as argument for wrap function") } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/AbstractKPropertyProxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/AbstractKPropertyProxy.kt index 8efdad67c0c..51504488817 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/AbstractKPropertyProxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/AbstractKPropertyProxy.kt @@ -9,14 +9,18 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.interpreter.IrInterpreter import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState -import org.jetbrains.kotlin.ir.interpreter.state.State +import org.jetbrains.kotlin.ir.types.IrType import kotlin.reflect.KProperty import kotlin.reflect.KType import kotlin.reflect.KVisibility internal abstract class AbstractKPropertyProxy( override val state: KPropertyState, override val interpreter: IrInterpreter -) : ReflectionProxy, KProperty { +) : ReflectionProxy, KProperty { + + protected val propertyType: IrType + get() = state.propertyReference.getter!!.owner.returnType + private val propertyOwner: IrProperty get() = state.propertyReference.symbol.owner diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/FunctionWithAllInvokes.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/FunctionWithAllInvokes.kt new file mode 100644 index 00000000000..fc67292f765 --- /dev/null +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/FunctionWithAllInvokes.kt @@ -0,0 +1,65 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.ir.interpreter.proxy.reflection + +import kotlin.jvm.functions.FunctionN +import kotlin.reflect.KCallable + +// copied from core/reflection.jvm/src/kotlin/reflect/jvm/internal/FunctionWithAllInvokes.kt +// additionally added FunctionN +internal interface FunctionWithAllInvokes : + // (0..22).forEach { n -> println("Function$n<" + (0..n).joinToString { "Any?" } + ">,") } + Function0, + Function1, + Function2, + Function3, + Function4, + Function5, + Function6, + Function7, + Function8, + Function9, + Function10, + Function11, + Function12, + Function13, + Function14, + Function15, + Function16, + Function17, + Function18, + Function19, + Function20, + Function21, + Function22, + KCallable, FunctionN +{ + // (0..22).forEach { n -> println("override fun invoke(" + (1..n).joinToString { "p$it: Any?" } + "): Any? = call(" + (1..n).joinToString { "p$it" } + ")") } + override fun invoke(): Any? = call() + override fun invoke(p1: Any?): Any? = call(p1) + override fun invoke(p1: Any?, p2: Any?): Any? = call(p1, p2) + override fun invoke(p1: Any?, p2: Any?, p3: Any?): Any? = call(p1, p2, p3) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?): Any? = call(p1, p2, p3, p4) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?): Any? = call(p1, p2, p3, p4, p5) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?): Any? = call(p1, p2, p3, p4, p5, p6) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?, p19: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?, p19: Any?, p20: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?, p19: Any?, p20: Any?, p21: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21) + override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?, p19: Any?, p20: Any?, p21: Any?, p22: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22) + override fun invoke(vararg args: Any?): Any? = call(*args) +} diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KFunctionProxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KFunctionProxy.kt new file mode 100644 index 00000000000..125020dd497 --- /dev/null +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KFunctionProxy.kt @@ -0,0 +1,81 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.ir.interpreter.proxy.reflection + +import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.interpreter.IrInterpreter +import org.jetbrains.kotlin.ir.interpreter.stack.Variable +import org.jetbrains.kotlin.ir.interpreter.state.KFunctionState +import org.jetbrains.kotlin.ir.interpreter.toState +import org.jetbrains.kotlin.ir.util.isSuspend +import kotlin.reflect.* + +internal class KFunctionProxy( + override val state: KFunctionState, override val interpreter: IrInterpreter +) : ReflectionProxy, KFunction, FunctionWithAllInvokes { + override val arity: Int = state.getArity() ?: BuiltInFunctionArity.BIG_ARITY + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is ReflectionProxy) return false + + return state == other.state + } + + override fun hashCode(): Int { + return state.hashCode() + } + + override fun toString(): String { + return state.toString() + } + + override val annotations: List + get() = TODO("Not yet implemented") + override val isAbstract: Boolean + get() = state.irFunction is IrSimpleFunction && state.irFunction.modality == Modality.ABSTRACT + override val isExternal: Boolean + get() = state.irFunction.isExternal + override val isFinal: Boolean + get() = state.irFunction is IrSimpleFunction && state.irFunction.modality == Modality.FINAL + override val isInfix: Boolean + get() = state.irFunction is IrSimpleFunction && state.irFunction.isInfix + override val isInline: Boolean + get() = state.irFunction.isInline + override val isOpen: Boolean + get() = state.irFunction is IrSimpleFunction && state.irFunction.modality == Modality.OPEN + override val isOperator: Boolean + get() = state.irFunction is IrSimpleFunction && state.irFunction.isOperator + override val isSuspend: Boolean + get() = state.irFunction.isSuspend + override val name: String + get() = state.irFunction.name.asString() + + override val parameters: List + get() = TODO("Not yet implemented") + override val returnType: KType + get() = TODO("Not yet implemented") + override val typeParameters: List + get() = TODO("Not yet implemented") + override val visibility: KVisibility? + get() = TODO("Not yet implemented") + + override fun call(vararg args: Any?): Any? { + 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)) } + return with(interpreter) { state.irFunction.interpret(valueArguments) } + } + + override fun callBy(args: Map): Any? { + TODO("Not yet implemented") + } +} + diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty0Proxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty0Proxy.kt index 38823bc3c97..5061d5c0d53 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty0Proxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty0Proxy.kt @@ -5,27 +5,19 @@ package org.jetbrains.kotlin.ir.interpreter.proxy.reflection -import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.interpreter.IrInterpreter import org.jetbrains.kotlin.ir.interpreter.stack.Variable import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState import org.jetbrains.kotlin.ir.interpreter.state.State import org.jetbrains.kotlin.ir.interpreter.toState -import kotlin.reflect.* +import kotlin.reflect.KMutableProperty0 +import kotlin.reflect.KParameter +import kotlin.reflect.KProperty0 +import kotlin.reflect.KTypeParameter internal open class KProperty0Proxy( override val state: KPropertyState, override val interpreter: IrInterpreter -) : AbstractKPropertyProxy(state, interpreter), KProperty0 { - override fun evaluate(expression: IrCall, args: List): State { - val result: Any = when (expression.symbol.owner.name.asString()) { - "" -> name - "get" -> get() - "invoke" -> invoke() - else -> TODO("not supported expression for kProperty0") - } - - return result.toState(expression.type) - } +) : AbstractKPropertyProxy(state, interpreter), KProperty0 { override val getter: KProperty0.Getter get() = TODO("Not yet implemented") @@ -34,15 +26,15 @@ internal open class KProperty0Proxy( override val typeParameters: List get() = TODO("Not yet implemented") - override fun call(vararg args: Any?): State { + override fun call(vararg args: Any?): Any? { TODO("Not yet implemented") } - override fun callBy(args: Map): State { + override fun callBy(args: Map): Any? { TODO("Not yet implemented") } - override fun get(): State { + override fun get(): Any? { return state.dispatchReceiver!!.getState(state.propertyReference.symbol)!! } @@ -50,25 +42,17 @@ internal open class KProperty0Proxy( TODO("Not yet implemented") } - override fun invoke(): State = get() + override fun invoke(): Any? = get() } internal class KMutableProperty0Proxy( override val state: KPropertyState, override val interpreter: IrInterpreter -) : KProperty0Proxy(state, interpreter), KMutableProperty0 { - override fun evaluate(expression: IrCall, args: List): State { - val result: Any = when (expression.symbol.owner.name.asString()) { - "set" -> set(args[1].state) - else -> return super.evaluate(expression, args) - } +) : KProperty0Proxy(state, interpreter), KMutableProperty0 { - return result.toState(expression.type) - } - - override val setter: KMutableProperty0.Setter + override val setter: KMutableProperty0.Setter get() = TODO("Not yet implemented") - override fun set(value: State) { - state.dispatchReceiver!!.setField(Variable(state.propertyReference.symbol, value)) + override fun set(value: Any?) { + state.dispatchReceiver!!.setField(Variable(state.propertyReference.symbol, value.toState(propertyType))) } } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty1Proxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty1Proxy.kt index e41e09e7d95..f95ad6e5b15 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty1Proxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty1Proxy.kt @@ -5,70 +5,55 @@ package org.jetbrains.kotlin.ir.interpreter.proxy.reflection -import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.interpreter.IrInterpreter +import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy +import org.jetbrains.kotlin.ir.interpreter.proxy.wrap import org.jetbrains.kotlin.ir.interpreter.stack.Variable import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState -import org.jetbrains.kotlin.ir.interpreter.state.State import org.jetbrains.kotlin.ir.interpreter.toState -import kotlin.reflect.* +import kotlin.reflect.KMutableProperty1 +import kotlin.reflect.KParameter +import kotlin.reflect.KProperty1 +import kotlin.reflect.KTypeParameter internal open class KProperty1Proxy( override val state: KPropertyState, override val interpreter: IrInterpreter -) : AbstractKPropertyProxy(state, interpreter), KProperty1 { - override fun evaluate(expression: IrCall, args: List): State { - val result: Any = when (expression.symbol.owner.name.asString()) { - "" -> name - "get" -> get(args[1].state) - "invoke" -> invoke(args[1].state) - else -> TODO("not supported expression for kProperty0") - } +) : AbstractKPropertyProxy(state, interpreter), KProperty1 { - return result.toState(expression.type) - } - - override val getter: KProperty1.Getter + override val getter: KProperty1.Getter get() = TODO("Not yet implemented") override val parameters: List get() = TODO("Not yet implemented") override val typeParameters: List get() = TODO("Not yet implemented") - override fun call(vararg args: Any?): State { + override fun call(vararg args: Any?): Any? { TODO("Not yet implemented") } - override fun callBy(args: Map): State { + override fun callBy(args: Map): Any? { TODO("Not yet implemented") } - override fun get(receiver: State): State { - return receiver.getState(state.propertyReference.symbol)!! + override fun get(receiver: Proxy): Any? { + return receiver.state.getState(state.propertyReference.symbol)!!.wrap(interpreter) } - override fun getDelegate(receiver: State): Any? { + override fun getDelegate(receiver: Proxy): Any? { TODO("Not yet implemented") } - override fun invoke(p1: State): State = get(p1) + override fun invoke(p1: Proxy): Any? = get(p1) } internal class KMutableProperty1Proxy( override val state: KPropertyState, override val interpreter: IrInterpreter -) : KProperty1Proxy(state, interpreter), KMutableProperty1 { - override fun evaluate(expression: IrCall, args: List): State { - val result: Any = when (expression.symbol.owner.name.asString()) { - "set" -> set(args[1].state, args[2].state) - else -> return super.evaluate(expression, args) - } +) : KProperty1Proxy(state, interpreter), KMutableProperty1 { - return result.toState(expression.type) - } - - override val setter: KMutableProperty1.Setter + override val setter: KMutableProperty1.Setter get() = TODO("Not yet implemented") - override fun set(receiver: State, value: State) { - receiver.setField(Variable(state.propertyReference.symbol, value)) + override fun set(receiver: Proxy, value: Any?) { + receiver.state.setField(Variable(state.propertyReference.symbol, value.toState(propertyType))) } } \ No newline at end of file diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty2Proxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty2Proxy.kt index 0daf375cbe1..aed761b90e7 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty2Proxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty2Proxy.kt @@ -5,70 +5,52 @@ package org.jetbrains.kotlin.ir.interpreter.proxy.reflection -import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.interpreter.IrInterpreter -import org.jetbrains.kotlin.ir.interpreter.stack.Variable +import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState -import org.jetbrains.kotlin.ir.interpreter.state.State -import org.jetbrains.kotlin.ir.interpreter.toState -import kotlin.reflect.* +import kotlin.reflect.KMutableProperty2 +import kotlin.reflect.KParameter +import kotlin.reflect.KProperty2 +import kotlin.reflect.KTypeParameter internal open class KProperty2Proxy( override val state: KPropertyState, override val interpreter: IrInterpreter -) : AbstractKPropertyProxy(state, interpreter), KProperty2 { - override fun evaluate(expression: IrCall, args: List): State { - val result: Any = when (expression.symbol.owner.name.asString()) { - "" -> name - //"get" -> get() - //"invoke" -> invoke() - else -> TODO("not supported expression for kProperty0") - } +) : AbstractKPropertyProxy(state, interpreter), KProperty2 { - return result.toState(expression.type) - } - - override val getter: KProperty2.Getter + override val getter: KProperty2.Getter get() = TODO("Not yet implemented") override val parameters: List get() = TODO("Not yet implemented") override val typeParameters: List get() = TODO("Not yet implemented") - override fun call(vararg args: Any?): State { + override fun call(vararg args: Any?): Any? { TODO("Not yet implemented") } - override fun callBy(args: Map): State { + override fun callBy(args: Map): Any? { TODO("Not yet implemented") } - override fun get(receiver1: State, receiver2: State): State { + override fun get(receiver1: Proxy, receiver2: Proxy): Any? { TODO("Not yet implemented") } - override fun getDelegate(receiver1: State, receiver2: State): Any? { + override fun getDelegate(receiver1: Proxy, receiver2: Proxy): Any? { TODO("Not yet implemented") } - override fun invoke(p1: State, p2: State): State = get(p1, p2) + override fun invoke(p1: Proxy, p2: Proxy): Any? = get(p1, p2) } internal class KMutableProperty2Proxy( override val state: KPropertyState, override val interpreter: IrInterpreter -) : KProperty2Proxy(state, interpreter), KMutableProperty2 { - override fun evaluate(expression: IrCall, args: List): State { - val result: Any = when (expression.symbol.owner.name.asString()) { - //"set" -> set() - else -> return super.evaluate(expression, args) - } +) : KProperty2Proxy(state, interpreter), KMutableProperty2 { - return result.toState(expression.type) - } - - override val setter: KMutableProperty2.Setter + override val setter: KMutableProperty2.Setter get() = TODO("Not yet implemented") - override fun set(receiver1: State, receiver2: State, value: State) { + override fun set(receiver1: Proxy, receiver2: Proxy, value: Any?) { TODO("Not yet implemented") } } \ No newline at end of file diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/ReflectionProxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/ReflectionProxy.kt index 79818080be8..30cbf294762 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/ReflectionProxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/ReflectionProxy.kt @@ -5,21 +5,17 @@ package org.jetbrains.kotlin.ir.interpreter.proxy.reflection -import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.interpreter.IrInterpreter import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy -import org.jetbrains.kotlin.ir.interpreter.stack.Variable +import org.jetbrains.kotlin.ir.interpreter.state.KFunctionState import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState import org.jetbrains.kotlin.ir.interpreter.state.ReflectionState -import org.jetbrains.kotlin.ir.interpreter.state.State internal interface ReflectionProxy : Proxy { - fun evaluate(expression: IrCall, args: List): State - companion object { internal fun ReflectionState.asProxy(interpreter: IrInterpreter): ReflectionProxy { - return when { - this is KPropertyState -> when { + return when (this) { + is KPropertyState -> when { this.isKProperty0() -> KProperty0Proxy(this, interpreter) this.isKMutableProperty0() -> KMutableProperty0Proxy(this, interpreter) this.isKProperty1() -> KProperty1Proxy(this, interpreter) @@ -28,6 +24,7 @@ internal interface ReflectionProxy : Proxy { this.isKMutableProperty2() -> KMutableProperty2Proxy(this, interpreter) else -> TODO() } + is KFunctionState -> KFunctionProxy(this, interpreter) else -> TODO("not supported reference state") } } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/Variable.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/Variable.kt index 92d5745c411..6780cd20060 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/Variable.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/Variable.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.ir.interpreter.stack +import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName import org.jetbrains.kotlin.ir.interpreter.state.State import org.jetbrains.kotlin.ir.symbols.IrSymbol @@ -15,4 +16,8 @@ internal data class Variable(val symbol: IrSymbol) { constructor(symbol: IrSymbol, state: State) : this(symbol) { this.state = state } + + override fun toString(): String { + return "Variable(symbol=${(symbol.owner as? IrDeclarationWithName)?.name}, state=$state)" + } } \ No newline at end of file diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Lambda.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Lambda.kt deleted file mode 100644 index 26ac2b2be61..00000000000 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Lambda.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.ir.interpreter.state - -import org.jetbrains.kotlin.ir.interpreter.getLastOverridden -import org.jetbrains.kotlin.ir.interpreter.stack.Variable -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction -import org.jetbrains.kotlin.ir.expressions.IrCall -import org.jetbrains.kotlin.ir.interpreter.isFunction -import org.jetbrains.kotlin.ir.interpreter.isKFunction -import org.jetbrains.kotlin.ir.util.defaultType -import org.jetbrains.kotlin.ir.util.nameForIrSerialization -import org.jetbrains.kotlin.ir.util.render -import org.jetbrains.kotlin.utils.addToStdlib.cast - -internal class Lambda(val irFunction: IrFunction, override val irClass: IrClass) : State { - override val fields: MutableList = mutableListOf() - override val typeArguments: MutableList = mutableListOf() - val isKFunction = irClass.defaultType.isKFunction() - val isFunction = irClass.defaultType.isFunction() - - private val invokeSymbol = irClass.declarations - .single { it.nameForIrSerialization.asString() == "invoke" } - .cast() - .getLastOverridden().symbol - - fun getArity(): Int? { - return irClass.name.asString().removePrefix("Function").removePrefix("KFunction").toIntOrNull() - } - - override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? { - return if (invokeSymbol == expression.symbol) irFunction else null - } - - override fun toString(): String { - val receiver = (irFunction.dispatchReceiverParameter?.type ?: irFunction.extensionReceiverParameter?.type)?.render() - val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.render() } - val returnType = irFunction.returnType.render() - return ("$arguments -> $returnType").let { if (receiver != null) "$receiver.$it" else it } - } -} \ No newline at end of file diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/ReflectionState.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/ReflectionState.kt index aed9a1b8cd5..11189723fe7 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/ReflectionState.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/ReflectionState.kt @@ -7,11 +7,20 @@ package org.jetbrains.kotlin.ir.interpreter.state import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.IrCall +import org.jetbrains.kotlin.ir.expressions.IrFunctionReference import org.jetbrains.kotlin.ir.expressions.IrPropertyReference +import org.jetbrains.kotlin.ir.interpreter.getLastOverridden +import org.jetbrains.kotlin.ir.interpreter.isFunction +import org.jetbrains.kotlin.ir.interpreter.isKFunction import org.jetbrains.kotlin.ir.interpreter.stack.Variable import org.jetbrains.kotlin.ir.types.classOrNull +import org.jetbrains.kotlin.ir.util.defaultType +import org.jetbrains.kotlin.ir.util.nameForIrSerialization import org.jetbrains.kotlin.ir.util.parentAsClass +import org.jetbrains.kotlin.ir.util.render +import org.jetbrains.kotlin.utils.addToStdlib.cast internal abstract class ReflectionState(override val irClass: IrClass) : State { override val fields: MutableList = mutableListOf() @@ -49,3 +58,32 @@ internal class KPropertyState( return className == "KMutableProperty2" } } + +internal class KFunctionState(val irFunction: IrFunction, override val irClass: IrClass) : ReflectionState(irClass) { + override val fields: MutableList = mutableListOf() + override val typeArguments: MutableList = mutableListOf() + val isKFunction = irClass.defaultType.isKFunction() + val isFunction = irClass.defaultType.isFunction() + + constructor(functionReference: IrFunctionReference) : this(functionReference.symbol.owner, functionReference.type.classOrNull!!.owner) + + private val invokeSymbol = irClass.declarations + .single { it.nameForIrSerialization.asString() == "invoke" } + .cast() + .getLastOverridden().symbol + + fun getArity(): Int? { + return irClass.name.asString().removePrefix("Function").removePrefix("KFunction").toIntOrNull() + } + + override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? { + return if (invokeSymbol == expression.symbol) irFunction else null + } + + override fun toString(): String { + val receiver = (irFunction.dispatchReceiverParameter?.type ?: irFunction.extensionReceiverParameter?.type)?.render() + val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.render() } + val returnType = irFunction.returnType.render() + return ("$arguments -> $returnType").let { if (receiver != null) "$receiver.$it" else it } + } +} \ No newline at end of file diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/State.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/State.kt index 6dfe5cfbe9e..cdbbe4a9734 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/State.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/State.kt @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.interpreter.exceptions.throwAsUserException -import org.jetbrains.kotlin.ir.interpreter.isFunction import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.defaultType @@ -58,13 +57,6 @@ internal fun State.isSubtypeOf(other: IrType): Boolean { return otherArgument.typeOrNull?.classOrNull?.let { thisClass.isSubtypeOfClass(it) } ?: true } - if (this is Lambda) { - if (!other.isFunction()) return false - val typeArgumentsCount = (other as? IrSimpleType)?.arguments?.size ?: return false - val lambdaArgumentCount = this.irFunction.valueParameters.size + 1 // +1 for return type - return typeArgumentsCount == lambdaArgumentCount - } - return this.irClass.defaultType.isSubtypeOfClass(other.classOrNull!!) } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt index 651d80e936e..0d7c9e43845 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt @@ -66,6 +66,23 @@ internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex companion object { private val companionObjectValue = mapOf("kotlin.text.Regex\$Companion" to Regex.Companion) + fun getReflectionMethod(irFunction: IrFunction): MethodHandle { + val receiverClass = irFunction.dispatchReceiverParameter!!.type.getClass(asObject = true) + val methodType = irFunction.getMethodType() + val methodName = when (irFunction) { + is IrSimpleFunction -> { + val property = irFunction.correspondingPropertySymbol?.owner + when { + property?.getter == irFunction -> "get${property.name.asString().capitalizeAsciiOnly()}" + property?.setter == irFunction -> "set${property.name.asString().capitalizeAsciiOnly()}" + else -> irFunction.name.asString() + } + } + else -> irFunction.name.asString() + } + return MethodHandles.lookup().findVirtual(receiverClass, methodName, methodType) + } + fun getCompanionObject(irClass: IrClass): Wrapper { val objectName = irClass.getEvaluateIntrinsicValue()!! val objectValue = companionObjectValue[objectName] ?: throw InternalError("Companion object $objectName cannot be interpreted")