Implement basic proxy for Common state
For now proxy works only for Any class methods and only for Common state.
This commit is contained in:
committed by
TeamCityServer
parent
3c0c8d97cc
commit
4c75576414
+81
-33
@@ -89,6 +89,84 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class Proxy(val state: Common, val interpreter: IrInterpreter) {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as Proxy
|
||||||
|
|
||||||
|
val valueArguments = mutableListOf<Variable>()
|
||||||
|
val equalsFun = state.getEqualsFunction()
|
||||||
|
if (equalsFun.isFakeOverriddenFromAny()) return this.state.getOriginal() === other.state.getOriginal()
|
||||||
|
|
||||||
|
equalsFun.getDispatchReceiver()!!.let { valueArguments.add(Variable(it, state)) }
|
||||||
|
valueArguments.add(Variable(equalsFun.valueParameters.single().symbol, other.state))
|
||||||
|
|
||||||
|
return with(interpreter) {
|
||||||
|
stack.newFrame(initPool = valueArguments) {
|
||||||
|
equalsFun.interpret()
|
||||||
|
}
|
||||||
|
(stack.popReturnValue() as Primitive<*>).value as Boolean
|
||||||
|
} // TODO check
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
val valueArguments = mutableListOf<Variable>()
|
||||||
|
val hashCodeFun = state.getHashCodeFunction()
|
||||||
|
if (hashCodeFun.isFakeOverriddenFromAny()) return System.identityHashCode(state.getOriginal())
|
||||||
|
|
||||||
|
hashCodeFun.getDispatchReceiver()!!.let { valueArguments.add(Variable(it, state)) }
|
||||||
|
return with(interpreter) {
|
||||||
|
stack.newFrame(initPool = valueArguments) {
|
||||||
|
hashCodeFun.interpret()
|
||||||
|
}
|
||||||
|
(stack.popReturnValue() as Primitive<*>).value as Int
|
||||||
|
}// TODO check
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
val valueArguments = mutableListOf<Variable>()
|
||||||
|
val toStringFun = state.getToStringFunction()
|
||||||
|
if (toStringFun.isFakeOverriddenFromAny()) {
|
||||||
|
return "${state.getOriginal().irClass.internalName()}@" + System.identityHashCode(state).toString(16).padStart(8, '0')
|
||||||
|
}
|
||||||
|
|
||||||
|
toStringFun.getDispatchReceiver()!!.let { valueArguments.add(Variable(it, state)) }
|
||||||
|
return with(interpreter) {
|
||||||
|
stack.newFrame(initPool = valueArguments) {
|
||||||
|
toStringFun.interpret()
|
||||||
|
}
|
||||||
|
(stack.popReturnValue() as Primitive<*>).value as String
|
||||||
|
}// TODO check
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun State.wrapAsProxyIfNeeded(): Any? {
|
||||||
|
return when (this) {
|
||||||
|
is ExceptionState -> this.getThisAsCauseForException()
|
||||||
|
is Wrapper -> this.value
|
||||||
|
is Primitive<*> -> this.value
|
||||||
|
is Common -> Proxy(this, this@IrInterpreter)
|
||||||
|
is Lambda -> this // TODO as Proxy
|
||||||
|
else -> throw AssertionError("${this::class} is unsupported as argument for wrap function")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun IrFunction.getArgsForMethodInvocation(args: List<Variable>): List<Any?> {
|
||||||
|
val argsValues = args.map { it.state.wrapAsProxyIfNeeded() }.toMutableList()
|
||||||
|
|
||||||
|
// TODO if vararg isn't last parameter
|
||||||
|
// must convert vararg array into separated elements for correct invoke
|
||||||
|
if (this.valueParameters.lastOrNull()?.varargElementType != null) {
|
||||||
|
val varargValue = argsValues.last()
|
||||||
|
argsValues.removeAt(argsValues.size - 1)
|
||||||
|
argsValues.addAll(varargValue as Array<out Any?>)
|
||||||
|
}
|
||||||
|
|
||||||
|
return argsValues
|
||||||
|
}
|
||||||
|
|
||||||
private fun IrElement.interpret(): ExecutionResult {
|
private fun IrElement.interpret(): ExecutionResult {
|
||||||
try {
|
try {
|
||||||
incrementAndCheckCommands()
|
incrementAndCheckCommands()
|
||||||
@@ -172,19 +250,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
|||||||
|
|
||||||
val receiverType = irFunction.dispatchReceiverParameter?.type
|
val receiverType = irFunction.dispatchReceiverParameter?.type
|
||||||
val argsType = listOfNotNull(receiverType) + irFunction.valueParameters.map { it.type }
|
val argsType = listOfNotNull(receiverType) + irFunction.valueParameters.map { it.type }
|
||||||
val argsValues = args.map {
|
val argsValues = args.map { it.wrapAsProxyIfNeeded() }
|
||||||
when (it) {
|
|
||||||
is Wrapper -> it.value // wrapper can be used in built in calculation, for example, in null or equality checks
|
|
||||||
is Complex -> when (irFunction.fqNameWhenAvailable?.asString()) {
|
|
||||||
// must explicitly convert Common to String in String plus method or else will be taken default toString from Common
|
|
||||||
"kotlin.String.plus" -> stack.apply { interpretToString(it) }.popReturnValue().asString()
|
|
||||||
else -> it.getOriginal()
|
|
||||||
}
|
|
||||||
is Primitive<*> -> it.value
|
|
||||||
is Lambda -> it // lambda also can be used, for example, in null check or toString
|
|
||||||
else -> TODO("unsupported type of argument for builtins calculations: ${it::class.java}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrType.getOnlyName(): String {
|
fun IrType.getOnlyName(): String {
|
||||||
return when {
|
return when {
|
||||||
@@ -209,7 +275,6 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
|||||||
?: throw InterpreterMethodNotFoundError("For given function $signature there is no entry in binary map")
|
?: throw InterpreterMethodNotFoundError("For given function $signature there is no entry in binary map")
|
||||||
when (methodName) {
|
when (methodName) {
|
||||||
"rangeTo" -> return calculateRangeTo(irFunction.returnType)
|
"rangeTo" -> return calculateRangeTo(irFunction.returnType)
|
||||||
"EQEQ" -> return calculateEquals(argsValues[0], argsValues[1])
|
|
||||||
else -> function.invoke(argsValues[0], argsValues[1])
|
else -> function.invoke(argsValues[0], argsValues[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,24 +306,6 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calculateEquals(first: Any?, second: Any?): ExecutionResult {
|
|
||||||
if (first == null || second == null || first !is Common || second !is Common) {
|
|
||||||
return Next.apply { stack.pushReturnValue((first == second).toState(irBuiltIns.booleanType)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
val valueArguments = mutableListOf<Variable>()
|
|
||||||
val equalsFun = first.getEqualsFunction()
|
|
||||||
if (equalsFun.isFakeOverriddenFromAny()) {
|
|
||||||
return Next.apply { stack.pushReturnValue((first == second).toState(irBuiltIns.booleanType)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
equalsFun.getDispatchReceiver()!!.let { valueArguments.add(Variable(it, first)) }
|
|
||||||
valueArguments.add(Variable(equalsFun.valueParameters.single().symbol, second))
|
|
||||||
return stack.newFrame(initPool = valueArguments) {
|
|
||||||
equalsFun.interpret()
|
|
||||||
}.check { return it }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun interpretValueParameters(
|
private fun interpretValueParameters(
|
||||||
expression: IrFunctionAccessExpression, irFunction: IrFunction, pool: MutableList<Variable>
|
expression: IrFunctionAccessExpression, irFunction: IrFunction, pool: MutableList<Variable>
|
||||||
): ExecutionResult {
|
): ExecutionResult {
|
||||||
@@ -722,7 +769,8 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
|||||||
is Primitive<*> -> arrayToList(result.value)
|
is Primitive<*> -> arrayToList(result.value)
|
||||||
is Common -> when {
|
is Common -> when {
|
||||||
result.irClass.defaultType.isUnsignedArray() -> arrayToList((result.fields.single().state as Primitive<*>).value)
|
result.irClass.defaultType.isUnsignedArray() -> arrayToList((result.fields.single().state as Primitive<*>).value)
|
||||||
else -> listOf(result)
|
result.irClass.defaultType.isUnsigned() -> listOf(result)
|
||||||
|
else -> listOf(Proxy(result, this))
|
||||||
}
|
}
|
||||||
else -> listOf(result)
|
else -> listOf(result)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ internal fun State.toIrExpression(expression: IrExpression): IrExpression {
|
|||||||
|
|
||||||
internal fun Any?.toState(irType: IrType): State {
|
internal fun Any?.toState(irType: IrType): State {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
|
is IrInterpreter.Proxy -> this.state
|
||||||
is State -> this
|
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 Boolean, is Char, is Byte, is Short, is Int, is Long, is String, is Float, is Double, is Array<*>, is ByteArray,
|
||||||
is CharArray, is ShortArray, is IntArray, is LongArray, is FloatArray, is DoubleArray, is BooleanArray -> Primitive(this, irType)
|
is CharArray, is ShortArray, is IntArray, is LongArray, is FloatArray, is DoubleArray, is BooleanArray -> Primitive(this, irType)
|
||||||
@@ -130,27 +131,6 @@ internal fun getPrimitiveClass(irType: IrType, asObject: Boolean = false): Class
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrFunction.getArgsForMethodInvocation(args: List<Variable>): List<Any?> {
|
|
||||||
val argsValues = args.map {
|
|
||||||
when (val state = it.state) {
|
|
||||||
is ExceptionState -> state.getThisAsCauseForException()
|
|
||||||
is Wrapper -> state.value
|
|
||||||
is Primitive<*> -> state.value
|
|
||||||
else -> throw AssertionError("${state::class} is unsupported as argument for wrapper method invocation")
|
|
||||||
}
|
|
||||||
}.toMutableList()
|
|
||||||
|
|
||||||
// TODO if vararg isn't last parameter
|
|
||||||
// must convert vararg array into separated elements for correct invoke
|
|
||||||
if (this.valueParameters.lastOrNull()?.varargElementType != null) {
|
|
||||||
val varargValue = argsValues.last()
|
|
||||||
argsValues.removeAt(argsValues.size - 1)
|
|
||||||
argsValues.addAll(varargValue as Array<out Any?>)
|
|
||||||
}
|
|
||||||
|
|
||||||
return argsValues
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrFunction.getLastOverridden(): IrFunction {
|
fun IrFunction.getLastOverridden(): IrFunction {
|
||||||
if (this !is IrSimpleFunction) return this
|
if (this !is IrSimpleFunction) return this
|
||||||
|
|
||||||
|
|||||||
+3
-11
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.interpreter.builtins
|
package org.jetbrains.kotlin.ir.interpreter.builtins
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.interpreter.internalName
|
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.*
|
import org.jetbrains.kotlin.ir.interpreter.state.*
|
||||||
|
|
||||||
/** This file is generated by org.jetbrains.kotlin.backend.common.interpreter.builtins.GenerateBuiltInsMap.generateMap(). DO NOT MODIFY MANUALLY */
|
/** This file is generated by org.jetbrains.kotlin.backend.common.interpreter.builtins.GenerateBuiltInsMap.generateMap(). DO NOT MODIFY MANUALLY */
|
||||||
@@ -139,7 +139,7 @@ val unaryFunctions = mapOf<CompileTimeFunction, Function1<Any?, Any?>>(
|
|||||||
unaryOperation<Array<Any?>>("size", "Array") { a -> a.size },
|
unaryOperation<Array<Any?>>("size", "Array") { a -> a.size },
|
||||||
unaryOperation<Array<Any?>>("iterator", "Array") { a -> a.iterator() },
|
unaryOperation<Array<Any?>>("iterator", "Array") { a -> a.iterator() },
|
||||||
unaryOperation<Any>("hashCode", "Any") { a -> a.hashCode() },
|
unaryOperation<Any>("hashCode", "Any") { a -> a.hashCode() },
|
||||||
unaryOperation<Any>("toString", "Any") { a -> a.defaultToString() },
|
unaryOperation<Any>("toString", "Any") { a -> a.toString() },
|
||||||
unaryOperation<Any?>("CHECK_NOT_NULL", "T0?") { a -> a!! },
|
unaryOperation<Any?>("CHECK_NOT_NULL", "T0?") { a -> a!! },
|
||||||
unaryOperation<ExceptionState>("message", "Throwable") { a -> a.getMessage() },
|
unaryOperation<ExceptionState>("message", "Throwable") { a -> a.getMessage() },
|
||||||
unaryOperation<ExceptionState>("cause", "Throwable") { a -> a.getCause() }
|
unaryOperation<ExceptionState>("cause", "Throwable") { a -> a.getCause() }
|
||||||
@@ -450,7 +450,7 @@ val binaryFunctions = mapOf<CompileTimeFunction, Function2<Any?, Any?, Any?>>(
|
|||||||
binaryOperation<Long, Long>("greaterOrEqual", "Long", "Long") { a, b -> a >= b },
|
binaryOperation<Long, Long>("greaterOrEqual", "Long", "Long") { a, b -> a >= b },
|
||||||
binaryOperation<Double, Double>("greaterOrEqual", "Double", "Double") { a, b -> a >= b },
|
binaryOperation<Double, Double>("greaterOrEqual", "Double", "Double") { a, b -> a >= b },
|
||||||
binaryOperation<Any?, Any?>("EQEQ", "Any?", "Any?") { a, b -> a == b },
|
binaryOperation<Any?, Any?>("EQEQ", "Any?", "Any?") { a, b -> a == b },
|
||||||
binaryOperation<Any?, Any?>("EQEQEQ", "Any?", "Any?") { a, b -> a === b },
|
binaryOperation<Any?, Any?>("EQEQEQ", "Any?", "Any?") { a, b -> if (a is IrInterpreter.Proxy && b is IrInterpreter.Proxy) a.state === b.state else a === b },
|
||||||
binaryOperation<Float?, Float?>("ieee754equals", "Float?", "Float?") { a, b -> a == b },
|
binaryOperation<Float?, Float?>("ieee754equals", "Float?", "Float?") { a, b -> a == b },
|
||||||
binaryOperation<Double?, Double?>("ieee754equals", "Double?", "Double?") { a, b -> a == b },
|
binaryOperation<Double?, Double?>("ieee754equals", "Double?", "Double?") { a, b -> a == b },
|
||||||
binaryOperation<Boolean, Boolean>("ANDAND", "Boolean", "Boolean") { a, b -> a && b },
|
binaryOperation<Boolean, Boolean>("ANDAND", "Boolean", "Boolean") { a, b -> a && b },
|
||||||
@@ -470,11 +470,3 @@ val ternaryFunctions = mapOf<CompileTimeFunction, Function3<Any?, Any?, Any?, An
|
|||||||
ternaryOperation<Array<Any?>, Int, Any?>("set", "Array", "Int", "T") { a, b, c -> a.set(b, c) }
|
ternaryOperation<Array<Any?>, Int, Any?>("set", "Array", "Int", "T") { a, b, c -> a.set(b, c) }
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun Any.defaultToString(): String {
|
|
||||||
return when (this) {
|
|
||||||
is Lambda -> this.toString()
|
|
||||||
is State -> "${this.irClass.internalName()}@" + System.identityHashCode(this).toString(16).padStart(8, '0')
|
|
||||||
else -> this.toString().replaceAfter("@", System.identityHashCode(this).toString(16).padStart(8, '0'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -44,7 +44,7 @@ internal object ArrayOf : IntrinsicBase() {
|
|||||||
|
|
||||||
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
|
||||||
val elementsVariable = irFunction.valueParameters.single().symbol
|
val elementsVariable = irFunction.valueParameters.single().symbol
|
||||||
val array = irFunction.getArgsForMethodInvocation(listOf(stack.getVariable(elementsVariable))).toTypedArray()
|
val array = (stack.getVariable(elementsVariable).state as Primitive<*>).value as Array<out Any?>
|
||||||
val typeArguments = irFunction.typeParameters.map { stack.getVariable(it.symbol) }
|
val typeArguments = irFunction.typeParameters.map { stack.getVariable(it.symbol) }
|
||||||
stack.pushReturnValue(array.toState(irFunction.returnType).apply { addTypeArguments(typeArguments) })
|
stack.pushReturnValue(array.toState(irFunction.returnType).apply { addTypeArguments(typeArguments) })
|
||||||
return Next
|
return Next
|
||||||
|
|||||||
@@ -5,15 +5,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.interpreter.state
|
package org.jetbrains.kotlin.ir.interpreter.state
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.interpreter.isInterface
|
import org.jetbrains.kotlin.ir.interpreter.isInterface
|
||||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
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.types.classOrNull
|
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||||
import org.jetbrains.kotlin.ir.types.isNullableAny
|
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
|
|
||||||
internal class Common private constructor(
|
internal class Common private constructor(
|
||||||
override val irClass: IrClass, override val fields: MutableList<Variable>
|
override val irClass: IrClass, override val fields: MutableList<Variable>
|
||||||
@@ -43,23 +39,6 @@ internal class Common private constructor(
|
|||||||
return owner
|
return owner
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getToStringFunction(): IrFunction {
|
|
||||||
return irClass.declarations.filterIsInstance<IrFunction>()
|
|
||||||
.filter { it.name.asString() == "toString" }
|
|
||||||
.first { it.valueParameters.isEmpty() }
|
|
||||||
.let { getOverridden(it as IrSimpleFunction, this) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getEqualsFunction(): IrFunction {
|
|
||||||
val equalsFun = irClass.declarations
|
|
||||||
.filterIsInstance<IrSimpleFunction>()
|
|
||||||
.single {
|
|
||||||
it.name == Name.identifier("equals") && it.dispatchReceiverParameter != null
|
|
||||||
&& it.valueParameters.size == 1 && it.valueParameters[0].type.isNullableAny()
|
|
||||||
}
|
|
||||||
return getOverridden(equalsFun, this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "Common(obj='${irClass.fqNameForIrSerialization}', super=$superClass, values=$fields)"
|
return "Common(obj='${irClass.fqNameForIrSerialization}', super=$superClass, values=$fields)"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,11 @@ import org.jetbrains.kotlin.ir.declarations.IrProperty
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.isNullableAny
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||||
import org.jetbrains.kotlin.ir.util.isInterface
|
import org.jetbrains.kotlin.ir.util.isInterface
|
||||||
import org.jetbrains.kotlin.ir.util.overrides
|
import org.jetbrains.kotlin.ir.util.overrides
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
internal abstract class Complex(override val irClass: IrClass, override val fields: MutableList<Variable>) : State {
|
internal abstract class Complex(override val irClass: IrClass, override val fields: MutableList<Variable>) : State {
|
||||||
var superClass: Complex? = null
|
var superClass: Complex? = null
|
||||||
@@ -90,4 +92,28 @@ internal abstract class Complex(override val irClass: IrClass, override val fiel
|
|||||||
else -> irFunction
|
else -> irFunction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getEqualsFunction(): IrSimpleFunction {
|
||||||
|
val equalsFun = irClass.declarations
|
||||||
|
.filterIsInstance<IrSimpleFunction>()
|
||||||
|
.single {
|
||||||
|
it.name == Name.identifier("equals") && it.dispatchReceiverParameter != null
|
||||||
|
&& it.valueParameters.size == 1 && it.valueParameters[0].type.isNullableAny()
|
||||||
|
}
|
||||||
|
return getOverridden(equalsFun, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getHashCodeFunction(): IrSimpleFunction {
|
||||||
|
return irClass.declarations.filterIsInstance<IrSimpleFunction>()
|
||||||
|
.filter { it.name.asString() == "hashCode" }
|
||||||
|
.first { it.valueParameters.isEmpty() }
|
||||||
|
.let { getOverridden(it, this) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getToStringFunction(): IrSimpleFunction {
|
||||||
|
return irClass.declarations.filterIsInstance<IrSimpleFunction>()
|
||||||
|
.filter { it.name.asString() == "toString" }
|
||||||
|
.first { it.valueParameters.isEmpty() }
|
||||||
|
.let { getOverridden(it, this) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.ir.util.defaultType
|
|||||||
import org.jetbrains.kotlin.ir.util.isFakeOverride
|
import org.jetbrains.kotlin.ir.util.isFakeOverride
|
||||||
import org.jetbrains.kotlin.ir.util.overrides
|
import org.jetbrains.kotlin.ir.util.overrides
|
||||||
|
|
||||||
internal class Primitive<T>(var value: T, val type: IrType) : State {
|
internal class Primitive<T>(val value: T, val type: IrType) : State {
|
||||||
override val fields: MutableList<Variable> = mutableListOf()
|
override val fields: MutableList<Variable> = mutableListOf()
|
||||||
override val typeArguments: MutableList<Variable> = mutableListOf()
|
override val typeArguments: MutableList<Variable> = mutableListOf()
|
||||||
override val irClass: IrClass = type.classOrNull!!.owner
|
override val irClass: IrClass = type.classOrNull!!.owner
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ fun generateMap(): String {
|
|||||||
p.println(File("license/COPYRIGHT.txt").readText())
|
p.println(File("license/COPYRIGHT.txt").readText())
|
||||||
p.println("package org.jetbrains.kotlin.ir.interpreter.builtins")
|
p.println("package org.jetbrains.kotlin.ir.interpreter.builtins")
|
||||||
p.println()
|
p.println()
|
||||||
p.println("import org.jetbrains.kotlin.ir.interpreter.internalName")
|
p.println("import org.jetbrains.kotlin.ir.interpreter.IrInterpreter")
|
||||||
p.println("import org.jetbrains.kotlin.ir.interpreter.state.*")
|
p.println("import org.jetbrains.kotlin.ir.interpreter.state.*")
|
||||||
p.println()
|
p.println()
|
||||||
p.println("/** This file is generated by org.jetbrains.kotlin.backend.common.interpreter.builtins.GenerateBuiltInsMap.generateMap(). DO NOT MODIFY MANUALLY */")
|
p.println("/** This file is generated by org.jetbrains.kotlin.backend.common.interpreter.builtins.GenerateBuiltInsMap.generateMap(). DO NOT MODIFY MANUALLY */")
|
||||||
@@ -68,19 +68,6 @@ fun generateMap(): String {
|
|||||||
p.println(")")
|
p.println(")")
|
||||||
p.println()
|
p.println()
|
||||||
|
|
||||||
p.println(
|
|
||||||
"""
|
|
||||||
private fun Any.defaultToString(): String {
|
|
||||||
return when (this) {
|
|
||||||
is Lambda -> this.toString()
|
|
||||||
is State -> "${'$'}{this.irClass.internalName()}@" + System.identityHashCode(this).toString(16).padStart(8, '0')
|
|
||||||
else -> this.toString().replaceAfter("@", System.identityHashCode(this).toString(16).padStart(8, '0'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
""".trimIndent()
|
|
||||||
)
|
|
||||||
p.println()
|
|
||||||
|
|
||||||
return sb.toString()
|
return sb.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,10 +137,7 @@ private fun generateUnaryBody(unaryOperationsMap: Map<CallableDescriptor, Pair<S
|
|||||||
return unaryOperationsMap.entries.joinToString(separator = ",\n", postfix = ",\n") { (function, parameters) ->
|
return unaryOperationsMap.entries.joinToString(separator = ",\n", postfix = ",\n") { (function, parameters) ->
|
||||||
val methodName = "${function.name}"
|
val methodName = "${function.name}"
|
||||||
val parentheses = if (function is FunctionDescriptor) "()" else ""
|
val parentheses = if (function is FunctionDescriptor) "()" else ""
|
||||||
val body =
|
" unaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a -> a.$methodName$parentheses }"
|
||||||
if (methodName == "toString" && parameters.first == "<Any>") "a.defaultToString()"
|
|
||||||
else "a.$methodName$parentheses"
|
|
||||||
" unaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a -> $body }"
|
|
||||||
} +
|
} +
|
||||||
" unaryOperation<Any?>(\"${irNullCheck.name}\", \"${irNullCheck.valueParameters.first().type.originalKotlinType}\") { a -> a!! },\n" +
|
" unaryOperation<Any?>(\"${irNullCheck.name}\", \"${irNullCheck.valueParameters.first().type.originalKotlinType}\") { a -> a!! },\n" +
|
||||||
" unaryOperation<ExceptionState>(\"message\", \"Throwable\") { a -> a.getMessage() },\n" +
|
" unaryOperation<ExceptionState>(\"message\", \"Throwable\") { a -> a.getMessage() },\n" +
|
||||||
@@ -169,7 +153,11 @@ private fun generateBinaryBody(
|
|||||||
} + binaryIrOperationsMap.entries.joinToString(separator = ",\n") { (function, parameters) ->
|
} + binaryIrOperationsMap.entries.joinToString(separator = ",\n") { (function, parameters) ->
|
||||||
val methodName = "${function.name}"
|
val methodName = "${function.name}"
|
||||||
val methodSymbol = getIrMethodSymbolByName(methodName)
|
val methodSymbol = getIrMethodSymbolByName(methodName)
|
||||||
" binaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a, b -> a $methodSymbol b }"
|
val body = when (methodName) {
|
||||||
|
IrBuiltIns.OperatorNames.EQEQEQ -> "if (a is IrInterpreter.Proxy && b is IrInterpreter.Proxy) a.state === b.state else a === b"
|
||||||
|
else -> "a $methodSymbol b"
|
||||||
|
}
|
||||||
|
" binaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a, b -> $body }"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user