Move out intrinsic evaluation from interpreter class
This commit is contained in:
+7
-104
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.interpreter.builtins.*
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.exceptions.InterpreterException
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.exceptions.InterpreterMethodNotFoundException
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.exceptions.InterpreterTimeOutException
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.intrinsics.IntrinsicEvaluator
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.stack.*
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.state.*
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
@@ -32,8 +33,6 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
||||
private val irBuiltIns = irModule.irBuiltins
|
||||
private val irExceptions = irModule.files.flatMap { it.declarations }.filterIsInstance<IrClass>()
|
||||
.filter { it.isSubclassOf(irBuiltIns.throwableClass.owner) }
|
||||
private val classCastException = irExceptions.first { it.name.asString() == ClassCastException::class.java.simpleName }
|
||||
private val illegalArgumentException = irExceptions.first { it.name.asString() == IllegalArgumentException::class.java.simpleName }
|
||||
|
||||
private val stack = StackImpl()
|
||||
private var commandCount = 0
|
||||
@@ -154,71 +153,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
||||
}
|
||||
|
||||
private suspend fun handleIntrinsicMethods(irFunction: IrFunction): ExecutionResult {
|
||||
when (irFunction.name.asString()) {
|
||||
"emptyArray" -> {
|
||||
val result = emptyArray<Any?>()
|
||||
stack.pushReturnValue(result.toState(result.getType(irFunction.returnType)))
|
||||
}
|
||||
"arrayOf" -> {
|
||||
val result = irFunction.getArgsForMethodInvocation(stack.getAll()).toTypedArray()
|
||||
stack.pushReturnValue(result.toState(result.getType(irFunction.returnType)))
|
||||
}
|
||||
"arrayOfNulls" -> {
|
||||
val size = stack.getVariableState(irFunction.valueParameters.first().descriptor).asInt()
|
||||
val result = arrayOfNulls<Any?>(size)
|
||||
stack.pushReturnValue(result.toState(result.getType(irFunction.returnType)))
|
||||
}
|
||||
"values", "enumValues" -> {
|
||||
val enumClass =
|
||||
(irFunction.parent as? IrClass) ?: stack.getVariableState(irFunction.typeParameters.first().descriptor).irClass
|
||||
val enumEntries = enumClass.declarations
|
||||
.filterIsInstance<IrEnumEntry>()
|
||||
.map { entry ->
|
||||
entry.interpret().check { return it }
|
||||
stack.popReturnValue() as Common
|
||||
}
|
||||
stack.pushReturnValue(enumEntries.toTypedArray().toState(irBuiltIns.arrayClass.defaultType))
|
||||
}
|
||||
"valueOf", "enumValueOf" -> {
|
||||
val enumClass =
|
||||
(irFunction.parent as? IrClass) ?: stack.getVariableState(irFunction.typeParameters.first().descriptor).irClass
|
||||
val enumEntryName = stack.getVariableState(irFunction.valueParameters.first().descriptor).asString()
|
||||
val enumEntry = enumClass.declarations
|
||||
.filterIsInstance<IrEnumEntry>()
|
||||
.singleOrNull { it.name.asString() == enumEntryName }
|
||||
if (enumEntry == null) {
|
||||
val message = "No enum constant ${enumClass.fqNameForIrSerialization}.$enumEntryName"
|
||||
stack.pushReturnValue(ExceptionState(IllegalArgumentException(message), illegalArgumentException, stack.getStackTrace()))
|
||||
return Exception
|
||||
} else {
|
||||
enumEntry.interpret().check { return it }
|
||||
}
|
||||
}
|
||||
"replace" -> {
|
||||
val states = stack.getAll().map { it.state }
|
||||
val regex = states.filterIsInstance<Wrapper>().single().value as Regex
|
||||
val input = states.filterIsInstance<Primitive<*>>().single().asString()
|
||||
val transform = states.filterIsInstance<Lambda>().single().irFunction
|
||||
val matchResultParameter = transform.valueParameters.single()
|
||||
val result = regex.replace(input) {
|
||||
val itAsState = Variable(matchResultParameter.descriptor, Wrapper(it, matchResultParameter.type.classOrNull!!.owner))
|
||||
runBlocking { stack.newFrame(initPool = listOf(itAsState)) { transform.interpret() } }//.check { return it }
|
||||
stack.popReturnValue().asString()
|
||||
//TODO("replace not implemented")
|
||||
}
|
||||
stack.pushReturnValue(result.toState(irBuiltIns.stringType))
|
||||
}
|
||||
"hashCode" -> {
|
||||
if (irFunction.parentAsClass.isEnumClass) {
|
||||
calculateBuiltIns(irFunction.getLastOverridden() as IrSimpleFunction)
|
||||
} else {
|
||||
throw InterpreterException("Hash code function intrinsic is supported only for enum class")
|
||||
}
|
||||
}
|
||||
else -> throw InterpreterException("Unsupported intrinsic ${irFunction.name}")
|
||||
}
|
||||
|
||||
return Next
|
||||
return IntrinsicEvaluator().evaluate(irFunction, stack) { this.interpret() }
|
||||
}
|
||||
|
||||
private suspend fun calculateAbstract(irFunction: IrFunction): ExecutionResult {
|
||||
@@ -419,42 +354,12 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
||||
|
||||
val parent = owner.parent as IrClass
|
||||
if (parent.hasAnnotation(evaluateIntrinsicAnnotation)) {
|
||||
return when (owner.parentAsClass.getEvaluateIntrinsicValue()) {
|
||||
"kotlin.Long" -> {
|
||||
val low = valueArguments[0].state.asInt()
|
||||
val high = valueArguments[1].state.asInt()
|
||||
stack.pushReturnValue((high.toLong().shl(32) + low).toState(irBuiltIns.longType))
|
||||
Next
|
||||
}
|
||||
"kotlin.Char" -> {
|
||||
val value = valueArguments[0].state.asInt()
|
||||
stack.pushReturnValue(value.toChar().toState(irBuiltIns.charType))
|
||||
Next
|
||||
}
|
||||
else -> stack.newFrame(initPool = valueArguments) { Wrapper.getConstructorMethod(owner).invokeMethod(owner) }
|
||||
}
|
||||
return stack.newFrame(initPool = valueArguments) { Wrapper.getConstructorMethod(owner).invokeMethod(owner) }
|
||||
}
|
||||
|
||||
if (parent.defaultType.isArray() || parent.defaultType.isPrimitiveArray()) {
|
||||
// array constructor doesn't have body so must be treated separately
|
||||
val arrayConstructor = irBuiltIns.primitiveArrays.first().constructors.single { it.owner.valueParameters.size == 2 }
|
||||
val sizeDescriptor = arrayConstructor.owner.valueParameters.single { it.name.asString() == "size" }.descriptor
|
||||
val size = valueArguments[0].state.asInt()
|
||||
|
||||
val arrayValue = MutableList<Any>(size) { 0 }
|
||||
if (owner.valueParameters.size == 2) {
|
||||
val initDescriptor = arrayConstructor.owner.valueParameters.single { it.name.asString() == "init" }.descriptor
|
||||
val initLambda = valueArguments[1].state as Lambda
|
||||
val indexDescriptor = initLambda.irFunction.valueParameters.single().descriptor
|
||||
for (i in 0 until size) {
|
||||
stack.newFrame(initPool = listOf(Variable(indexDescriptor, i.toState(irBuiltIns.intType)))) {
|
||||
initLambda.irFunction.body!!.interpret()
|
||||
}.check(ReturnLabel.RETURN) { return it } // TODO throw exception if label != RETURN
|
||||
arrayValue[i] = stack.popReturnValue().let { (it as? Wrapper)?.value ?: (it as? Primitive<*>)?.value ?: it }
|
||||
}
|
||||
}
|
||||
stack.pushReturnValue(arrayValue.toPrimitiveStateArray(parent.defaultType))
|
||||
return Next
|
||||
return stack.newFrame(initPool = valueArguments) { handleIntrinsicMethods(owner) }
|
||||
}
|
||||
|
||||
val state = Common(parent)
|
||||
@@ -665,11 +570,9 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> stack.popReturnValue()
|
||||
IrTypeOperator.CAST, IrTypeOperator.IMPLICIT_CAST -> {
|
||||
if (!stack.peekReturnValue().irClass.defaultType.isSubtypeOf(expression.type, irBuiltIns)) {
|
||||
val convertibleClassName = stack.popReturnValue().irClass.fqNameForIrSerialization
|
||||
val castClassName = expression.type.classOrNull?.owner?.fqNameForIrSerialization
|
||||
val message = "$convertibleClassName cannot be cast to $castClassName"
|
||||
stack.pushReturnValue(ExceptionState(ClassCastException(message), classCastException, stack.getStackTrace()))
|
||||
return Exception
|
||||
val convertibleClassName = stack.popReturnValue().irClass.fqNameWhenAvailable
|
||||
val castClassName = expression.type.classOrNull?.owner?.fqNameWhenAvailable
|
||||
throw ClassCastException("$convertibleClassName cannot be cast to $castClassName")
|
||||
}
|
||||
}
|
||||
IrTypeOperator.SAFE_CAST -> {
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.backend.common.interpreter.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.ExecutionResult
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.stack.Stack
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
|
||||
interface Intrinsic {
|
||||
fun equalTo(irFunction: IrFunction): Boolean
|
||||
suspend fun evaluate(irFunction: IrFunction, stack: Stack, interpret: suspend IrElement.() -> ExecutionResult): ExecutionResult
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.backend.common.interpreter.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.ExecutionResult
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.exceptions.InterpreterMethodNotFoundException
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.stack.Stack
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
|
||||
class IntrinsicEvaluator {
|
||||
suspend fun evaluate(irFunction: IrFunction, stack: Stack, interpret: suspend IrElement.() -> ExecutionResult): ExecutionResult {
|
||||
return when {
|
||||
EmptyArray.equalTo(irFunction) -> EmptyArray.evaluate(irFunction, stack, interpret)
|
||||
ArrayOf.equalTo(irFunction) -> ArrayOf.evaluate(irFunction, stack, interpret)
|
||||
ArrayOfNulls.equalTo(irFunction) -> ArrayOfNulls.evaluate(irFunction, stack, interpret)
|
||||
EnumValues.equalTo(irFunction) -> EnumValues.evaluate(irFunction, stack, interpret)
|
||||
EnumValueOf.equalTo(irFunction) -> EnumValueOf.evaluate(irFunction, stack, interpret)
|
||||
RegexReplace.equalTo(irFunction) -> RegexReplace.evaluate(irFunction, stack, interpret)
|
||||
EnumHashCode.equalTo(irFunction) -> EnumHashCode.evaluate(irFunction, stack, interpret)
|
||||
JsPrimitives.equalTo(irFunction) -> JsPrimitives.evaluate(irFunction, stack, interpret)
|
||||
ArrayConstructor.equalTo(irFunction) -> ArrayConstructor.evaluate(irFunction, stack, interpret)
|
||||
else -> throw InterpreterMethodNotFoundException("Method ${irFunction.name} hasn't implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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.backend.common.interpreter.intrinsics
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.*
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.stack.Stack
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.state.*
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
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.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
|
||||
sealed class IntrinsicBase : Intrinsic
|
||||
|
||||
object EmptyArray : IntrinsicBase() {
|
||||
override fun equalTo(irFunction: IrFunction): Boolean {
|
||||
val fqName = irFunction.fqNameWhenAvailable.toString()
|
||||
return fqName == "kotlin.emptyArray"
|
||||
}
|
||||
|
||||
override suspend fun evaluate(
|
||||
irFunction: IrFunction, stack: Stack, interpret: suspend IrElement.() -> ExecutionResult
|
||||
): ExecutionResult {
|
||||
stack.pushReturnValue(emptyArray<Any?>().toState(irFunction.returnType))
|
||||
return Next
|
||||
}
|
||||
}
|
||||
|
||||
object ArrayOf : IntrinsicBase() {
|
||||
override fun equalTo(irFunction: IrFunction): Boolean {
|
||||
val fqName = irFunction.fqNameWhenAvailable.toString()
|
||||
return fqName == "kotlin.arrayOf"
|
||||
}
|
||||
|
||||
override suspend fun evaluate(
|
||||
irFunction: IrFunction, stack: Stack, interpret: suspend IrElement.() -> ExecutionResult
|
||||
): ExecutionResult {
|
||||
val array = irFunction.getArgsForMethodInvocation(stack.getAll()).toTypedArray()
|
||||
stack.pushReturnValue(array.toState(irFunction.returnType))
|
||||
return Next
|
||||
}
|
||||
}
|
||||
|
||||
object ArrayOfNulls : IntrinsicBase() {
|
||||
override fun equalTo(irFunction: IrFunction): Boolean {
|
||||
val fqName = irFunction.fqNameWhenAvailable.toString()
|
||||
return fqName == "kotlin.arrayOfNulls"
|
||||
}
|
||||
|
||||
override suspend fun evaluate(
|
||||
irFunction: IrFunction, stack: Stack, interpret: suspend IrElement.() -> ExecutionResult
|
||||
): ExecutionResult {
|
||||
val size = stack.getVariableState(irFunction.valueParameters.first().descriptor).asInt()
|
||||
val array = arrayOfNulls<Any?>(size)
|
||||
stack.pushReturnValue(array.toState(irFunction.returnType))
|
||||
return Next
|
||||
}
|
||||
}
|
||||
|
||||
object EnumValues : IntrinsicBase() {
|
||||
override fun equalTo(irFunction: IrFunction): Boolean {
|
||||
val fqName = irFunction.fqNameWhenAvailable.toString()
|
||||
return (fqName == "kotlin.enumValues" || fqName.endsWith(".values")) && irFunction.valueParameters.isEmpty()
|
||||
}
|
||||
|
||||
override suspend fun evaluate(
|
||||
irFunction: IrFunction, stack: Stack, interpret: suspend IrElement.() -> ExecutionResult
|
||||
): ExecutionResult {
|
||||
val enumClass = when (irFunction.fqNameWhenAvailable.toString()) {
|
||||
"kotlin.enumValues" -> stack.getVariableState(irFunction.typeParameters.first().descriptor).irClass
|
||||
else -> irFunction.parent as IrClass
|
||||
}
|
||||
|
||||
val enumEntries = enumClass.declarations.filterIsInstance<IrEnumEntry>()
|
||||
.map { entry -> entry.interpret().check { return it }.let { stack.popReturnValue() as Common } }
|
||||
stack.pushReturnValue(enumEntries.toTypedArray().toState(irFunction.returnType))
|
||||
return Next
|
||||
}
|
||||
}
|
||||
|
||||
object EnumValueOf : IntrinsicBase() {
|
||||
override fun equalTo(irFunction: IrFunction): Boolean {
|
||||
val fqName = irFunction.fqNameWhenAvailable.toString()
|
||||
return (fqName == "kotlin.enumValueOf" || fqName.endsWith(".valueOf")) && irFunction.valueParameters.size == 1
|
||||
}
|
||||
|
||||
override suspend fun evaluate(
|
||||
irFunction: IrFunction, stack: Stack, interpret: suspend IrElement.() -> ExecutionResult
|
||||
): ExecutionResult {
|
||||
val enumClass = when (irFunction.fqNameWhenAvailable.toString()) {
|
||||
"kotlin.enumValueOf" -> stack.getVariableState(irFunction.typeParameters.first().descriptor).irClass
|
||||
else -> irFunction.parent as IrClass
|
||||
}
|
||||
val enumEntryName = stack.getVariableState(irFunction.valueParameters.first().descriptor).asString()
|
||||
val enumEntry = enumClass.declarations.filterIsInstance<IrEnumEntry>().singleOrNull { it.name.asString() == enumEntryName }
|
||||
enumEntry?.interpret()?.check { return it }
|
||||
?: throw IllegalArgumentException("No enum constant ${enumClass.fqNameWhenAvailable}.$enumEntryName")
|
||||
|
||||
return Next
|
||||
}
|
||||
}
|
||||
|
||||
object RegexReplace : IntrinsicBase() {
|
||||
override fun equalTo(irFunction: IrFunction): Boolean {
|
||||
val fqName = irFunction.fqNameWhenAvailable.toString()
|
||||
return fqName == "kotlin.text.Regex.replace" && irFunction.valueParameters.size == 2
|
||||
}
|
||||
|
||||
override suspend fun evaluate(
|
||||
irFunction: IrFunction, stack: Stack, interpret: suspend IrElement.() -> ExecutionResult
|
||||
): ExecutionResult {
|
||||
val states = stack.getAll().map { it.state }
|
||||
val regex = states.filterIsInstance<Wrapper>().single().value as Regex
|
||||
val input = states.filterIsInstance<Primitive<*>>().single().asString()
|
||||
val transform = states.filterIsInstance<Lambda>().single().irFunction
|
||||
val matchResultParameter = transform.valueParameters.single()
|
||||
val result = regex.replace(input) {
|
||||
val itAsState = Variable(matchResultParameter.descriptor, Wrapper(it, matchResultParameter.type.classOrNull!!.owner))
|
||||
runBlocking { stack.newFrame(initPool = listOf(itAsState)) { transform.interpret() } }//.check { return it }
|
||||
stack.popReturnValue().asString()
|
||||
}
|
||||
stack.pushReturnValue(result.toState(irFunction.returnType))
|
||||
return Next
|
||||
}
|
||||
}
|
||||
|
||||
object EnumHashCode : IntrinsicBase() {
|
||||
override fun equalTo(irFunction: IrFunction): Boolean {
|
||||
val fqName = irFunction.fqNameWhenAvailable.toString()
|
||||
return fqName.endsWith(".hashCode") && irFunction.parentAsClass.isEnumClass
|
||||
}
|
||||
|
||||
override suspend fun evaluate(
|
||||
irFunction: IrFunction, stack: Stack, interpret: suspend IrElement.() -> ExecutionResult
|
||||
): ExecutionResult {
|
||||
val hashCode = stack.getAll().single().state.hashCode()
|
||||
stack.pushReturnValue(hashCode.toState(irFunction.returnType))
|
||||
return Next
|
||||
}
|
||||
}
|
||||
|
||||
object JsPrimitives : IntrinsicBase() {
|
||||
override fun equalTo(irFunction: IrFunction): Boolean {
|
||||
val fqName = irFunction.fqNameWhenAvailable.toString()
|
||||
return fqName == "kotlin.Long.<init>" || fqName == "kotlin.Char.<init>"
|
||||
}
|
||||
|
||||
override suspend fun evaluate(
|
||||
irFunction: IrFunction, stack: Stack, interpret: suspend IrElement.() -> ExecutionResult
|
||||
): ExecutionResult {
|
||||
when (irFunction.fqNameWhenAvailable.toString()) {
|
||||
"kotlin.Long.<init>" -> {
|
||||
val low = stack.getVariableState(irFunction.valueParameters[0].descriptor).asInt()
|
||||
val high = stack.getVariableState(irFunction.valueParameters[1].descriptor).asInt()
|
||||
stack.pushReturnValue((high.toLong().shl(32) + low).toState(irFunction.returnType))
|
||||
}
|
||||
"kotlin.Char.<init>" -> {
|
||||
val value = stack.getVariableState(irFunction.valueParameters[0].descriptor).asInt()
|
||||
stack.pushReturnValue(value.toChar().toState(irFunction.returnType))
|
||||
}
|
||||
}
|
||||
return Next
|
||||
}
|
||||
}
|
||||
|
||||
object ArrayConstructor : IntrinsicBase() {
|
||||
override fun equalTo(irFunction: IrFunction): Boolean {
|
||||
val fqName = irFunction.fqNameWhenAvailable.toString()
|
||||
return fqName.matches("kotlin\\.(Byte|Char|Short|Int|Long|Float|Double|Boolean|)Array\\.<init>".toRegex())
|
||||
}
|
||||
|
||||
override suspend fun evaluate(
|
||||
irFunction: IrFunction, stack: Stack, interpret: suspend IrElement.() -> ExecutionResult
|
||||
): ExecutionResult {
|
||||
val sizeDescriptor = irFunction.valueParameters[0].descriptor
|
||||
val size = stack.getVariableState(sizeDescriptor).asInt()
|
||||
val arrayValue = MutableList<Any>(size) { 0 }
|
||||
|
||||
if (irFunction.valueParameters.size == 2) {
|
||||
val initDescriptor = irFunction.valueParameters[1].descriptor
|
||||
val initLambda = stack.getVariableState(initDescriptor) as Lambda
|
||||
val index = initLambda.irFunction.valueParameters.single()
|
||||
for (i in 0 until size) {
|
||||
val indexVar = listOf(Variable(index.descriptor, i.toState(index.type)))
|
||||
// TODO throw exception if label != RETURN
|
||||
stack.newFrame(initPool = indexVar) { initLambda.irFunction.body!!.interpret() }.check(ReturnLabel.RETURN) { return it }
|
||||
arrayValue[i] = stack.popReturnValue().let { (it as? Wrapper)?.value ?: (it as? Primitive<*>)?.value ?: it }
|
||||
}
|
||||
}
|
||||
|
||||
stack.pushReturnValue(arrayValue.toPrimitiveStateArray(irFunction.parentAsClass.defaultType))
|
||||
return Next
|
||||
}
|
||||
}
|
||||
+5
-2
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||
import org.jetbrains.kotlin.ir.util.isTypeParameter
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import java.lang.invoke.MethodHandle
|
||||
import java.lang.invoke.MethodHandles
|
||||
@@ -63,9 +64,11 @@ class Wrapper private constructor(
|
||||
return Wrapper(objectValue, irClass)
|
||||
}
|
||||
|
||||
fun getConstructorMethod(irConstructor: IrFunction): MethodHandle {
|
||||
val methodType = irConstructor.getMethodType()
|
||||
fun getConstructorMethod(irConstructor: IrFunction): MethodHandle? {
|
||||
val intrinsicValue = irConstructor.parentAsClass.getEvaluateIntrinsicValue()
|
||||
if (intrinsicValue == "kotlin.Char" || intrinsicValue == "kotlin.Long") return null
|
||||
|
||||
val methodType = irConstructor.getMethodType()
|
||||
return MethodHandles.lookup().findConstructor(irConstructor.returnType.getClass(true), methodType)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user