Replace Lambda state with KFunctionState

This commit is contained in:
Ivan Kylchik
2020-09-19 16:26:23 +03:00
committed by TeamCityServer
parent 749200d518
commit 002804941f
17 changed files with 281 additions and 238 deletions
@@ -94,13 +94,13 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
}
internal fun IrFunction.interpret(valueArguments: List<Variable>, 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<IrStatement>): 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
}
@@ -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
@@ -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) {
@@ -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")
}
}
}
}
}
@@ -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")
}
@@ -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<State> {
) : ReflectionProxy, KProperty<Any?> {
protected val propertyType: IrType
get() = state.propertyReference.getter!!.owner.returnType
private val propertyOwner: IrProperty
get() = state.propertyReference.symbol.owner
@@ -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<Any?>,
Function1<Any?, Any?>,
Function2<Any?, Any?, Any?>,
Function3<Any?, Any?, Any?, Any?>,
Function4<Any?, Any?, Any?, Any?, Any?>,
Function5<Any?, Any?, Any?, Any?, Any?, Any?>,
Function6<Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function7<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function8<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function9<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function10<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function11<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function12<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function13<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function14<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function15<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function16<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function17<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function18<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function19<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function20<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function21<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function22<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
KCallable<Any?>, FunctionN<Any?>
{
// (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)
}
@@ -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<Any?>, 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<Annotation>
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<KParameter>
get() = TODO("Not yet implemented")
override val returnType: KType
get() = TODO("Not yet implemented")
override val typeParameters: List<KTypeParameter>
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<KParameter, Any?>): Any? {
TODO("Not yet implemented")
}
}
@@ -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<State> {
override fun evaluate(expression: IrCall, args: List<Variable>): State {
val result: Any = when (expression.symbol.owner.name.asString()) {
"<get-name>" -> name
"get" -> get()
"invoke" -> invoke()
else -> TODO("not supported expression for kProperty0")
}
return result.toState(expression.type)
}
) : AbstractKPropertyProxy(state, interpreter), KProperty0<Any?> {
override val getter: KProperty0.Getter<State>
get() = TODO("Not yet implemented")
@@ -34,15 +26,15 @@ internal open class KProperty0Proxy(
override val typeParameters: List<KTypeParameter>
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<KParameter, Any?>): State {
override fun callBy(args: Map<KParameter, Any?>): 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<State> {
override fun evaluate(expression: IrCall, args: List<Variable>): 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<Any?> {
return result.toState(expression.type)
}
override val setter: KMutableProperty0.Setter<State>
override val setter: KMutableProperty0.Setter<Any?>
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)))
}
}
@@ -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<State, State> {
override fun evaluate(expression: IrCall, args: List<Variable>): State {
val result: Any = when (expression.symbol.owner.name.asString()) {
"<get-name>" -> name
"get" -> get(args[1].state)
"invoke" -> invoke(args[1].state)
else -> TODO("not supported expression for kProperty0")
}
) : AbstractKPropertyProxy(state, interpreter), KProperty1<Proxy, Any?> {
return result.toState(expression.type)
}
override val getter: KProperty1.Getter<State, State>
override val getter: KProperty1.Getter<Proxy, Any?>
get() = TODO("Not yet implemented")
override val parameters: List<KParameter>
get() = TODO("Not yet implemented")
override val typeParameters: List<KTypeParameter>
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<KParameter, Any?>): State {
override fun callBy(args: Map<KParameter, Any?>): 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<State, State> {
override fun evaluate(expression: IrCall, args: List<Variable>): 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<Proxy, Any?> {
return result.toState(expression.type)
}
override val setter: KMutableProperty1.Setter<State, State>
override val setter: KMutableProperty1.Setter<Proxy, Any?>
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)))
}
}
@@ -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<State, State, State> {
override fun evaluate(expression: IrCall, args: List<Variable>): State {
val result: Any = when (expression.symbol.owner.name.asString()) {
"<get-name>" -> name
//"get" -> get()
//"invoke" -> invoke()
else -> TODO("not supported expression for kProperty0")
}
) : AbstractKPropertyProxy(state, interpreter), KProperty2<Proxy, Proxy, Any?> {
return result.toState(expression.type)
}
override val getter: KProperty2.Getter<State, State, State>
override val getter: KProperty2.Getter<Proxy, Proxy, Any?>
get() = TODO("Not yet implemented")
override val parameters: List<KParameter>
get() = TODO("Not yet implemented")
override val typeParameters: List<KTypeParameter>
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<KParameter, Any?>): State {
override fun callBy(args: Map<KParameter, Any?>): 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<State, State, State> {
override fun evaluate(expression: IrCall, args: List<Variable>): State {
val result: Any = when (expression.symbol.owner.name.asString()) {
//"set" -> set()
else -> return super.evaluate(expression, args)
}
) : KProperty2Proxy(state, interpreter), KMutableProperty2<Proxy, Proxy, Any?> {
return result.toState(expression.type)
}
override val setter: KMutableProperty2.Setter<State, State, State>
override val setter: KMutableProperty2.Setter<Proxy, Proxy, Any?>
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")
}
}
@@ -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<Variable>): 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")
}
}
@@ -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)"
}
}
@@ -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<Variable> = mutableListOf()
override val typeArguments: MutableList<Variable> = mutableListOf()
val isKFunction = irClass.defaultType.isKFunction()
val isFunction = irClass.defaultType.isFunction()
private val invokeSymbol = irClass.declarations
.single { it.nameForIrSerialization.asString() == "invoke" }
.cast<IrSimpleFunction>()
.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 }
}
}
@@ -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<Variable> = 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<Variable> = mutableListOf()
override val typeArguments: MutableList<Variable> = 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<IrSimpleFunction>()
.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 }
}
}
@@ -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!!)
}
@@ -66,6 +66,23 @@ 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)
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")