Change check for Wrapper method
For now method is wrapper if its receiver is Wrapper and method itself isn't inline only
This commit is contained in:
+5
-4
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import java.lang.invoke.MethodHandle
|
import java.lang.invoke.MethodHandle
|
||||||
|
|
||||||
private const val MAX_STACK_SIZE = 10_000
|
private const val MAX_STACK_SIZE = 10_000
|
||||||
@@ -326,14 +327,14 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
if (isLocal) valueArguments.addAll(dispatchReceiver.extractNonLocalDeclarations())
|
if (isLocal) valueArguments.addAll(dispatchReceiver.extractNonLocalDeclarations())
|
||||||
|
|
||||||
return stack.newFrame(asSubFrame = irFunction.isInline || irFunction.isLocal, initPool = valueArguments) {
|
return stack.newFrame(asSubFrame = irFunction.isInline || irFunction.isLocal, initPool = valueArguments) {
|
||||||
val isWrapper = dispatchReceiver is Wrapper && rawExtensionReceiver == null
|
// inline only methods are not presented in lookup table, so must be interpreted instead of execution
|
||||||
val isInterfaceDefaultMethod = irFunction.body != null && (irFunction.parent as? IrClass)?.isInterface == true
|
val isInlineOnly = irFunction.hasAnnotation(FqName("kotlin.internal.InlineOnly"))
|
||||||
return@newFrame when {
|
return@newFrame when {
|
||||||
isWrapper && !isInterfaceDefaultMethod -> (dispatchReceiver as Wrapper).getMethod(irFunction).invokeMethod(irFunction)
|
dispatchReceiver is Wrapper && !isInlineOnly -> dispatchReceiver.getMethod(irFunction).invokeMethod(irFunction)
|
||||||
irFunction.hasAnnotation(evaluateIntrinsicAnnotation) -> Wrapper.getStaticMethod(irFunction).invokeMethod(irFunction)
|
irFunction.hasAnnotation(evaluateIntrinsicAnnotation) -> Wrapper.getStaticMethod(irFunction).invokeMethod(irFunction)
|
||||||
irFunction.isAbstract() -> calculateAbstract(irFunction) //abstract check must be before fake overridden check
|
irFunction.isAbstract() -> calculateAbstract(irFunction) //abstract check must be before fake overridden check
|
||||||
irFunction.isFakeOverridden() -> calculateOverridden(irFunction as IrSimpleFunction)
|
irFunction.isFakeOverridden() -> calculateOverridden(irFunction as IrSimpleFunction)
|
||||||
irFunction.body == null || dispatchReceiver is Primitive<*> -> calculateBuiltIns(irFunction)
|
irFunction.body == null || dispatchReceiver is Primitive<*> -> calculateBuiltIns(irFunction) // is Primitive because of js char and long
|
||||||
else -> irFunction.interpret()
|
else -> irFunction.interpret()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-11
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.ir.util.isTypeParameter
|
|||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithDifferentJvmName
|
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithDifferentJvmName
|
||||||
import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties
|
import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.firstOverridden
|
import org.jetbrains.kotlin.resolve.descriptorUtil.firstOverridden
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
@@ -117,7 +116,7 @@ class Wrapper private constructor(
|
|||||||
|
|
||||||
private fun IrFunction.getMethodType(): MethodType {
|
private fun IrFunction.getMethodType(): MethodType {
|
||||||
val argsClasses = this.valueParameters.map { it.type.getClass(this.isValueParameterPrimitiveAsObject(it.index)) }
|
val argsClasses = this.valueParameters.map { it.type.getClass(this.isValueParameterPrimitiveAsObject(it.index)) }
|
||||||
return if (this is IrFunctionImpl) {
|
return if (this is IrSimpleFunction) {
|
||||||
// for regular methods and functions
|
// for regular methods and functions
|
||||||
val returnClass = this.returnType.getClass(this.isReturnTypePrimitiveAsObject())
|
val returnClass = this.returnType.getClass(this.isReturnTypePrimitiveAsObject())
|
||||||
val extensionClass = this.extensionReceiverParameter?.type?.getClass(this.isExtensionReceiverPrimitive())
|
val extensionClass = this.extensionReceiverParameter?.type?.getClass(this.isExtensionReceiverPrimitive())
|
||||||
@@ -130,22 +129,24 @@ class Wrapper private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun IrType.getClass(asObject: Boolean): Class<out Any> {
|
private fun IrType.getClass(asObject: Boolean): Class<out Any> {
|
||||||
val fqName = this.getFqName()
|
val fqName = this.getFqName() ?: return Any::class.java // null if this.isTypeParameter()
|
||||||
val owner = this.classOrNull?.owner
|
val owner = this.classOrNull?.owner
|
||||||
return when {
|
return when {
|
||||||
this.isPrimitiveType() -> getPrimitiveClass(fqName!!, asObject)
|
this.isPrimitiveType() -> getPrimitiveClass(fqName, asObject)!!
|
||||||
this.isArray() -> if (asObject) Array<Any?>::class.javaObjectType else Array<Any?>::class.java
|
this.isArray() -> if (asObject) Array<Any?>::class.javaObjectType else Array<Any?>::class.java
|
||||||
owner.hasAnnotation(evaluateIntrinsicAnnotation) -> Class.forName(owner!!.getEvaluateIntrinsicValue())
|
|
||||||
//TODO primitive array
|
//TODO primitive array
|
||||||
this.isTypeParameter() -> Any::class.java // TODO use typeArguments
|
owner.hasAnnotation(evaluateIntrinsicAnnotation) -> Class.forName(owner!!.getEvaluateIntrinsicValue())
|
||||||
else -> JavaToKotlinClassMap.mapKotlinToJava(FqNameUnsafe(fqName!!))?.let { Class.forName(it.getAsString()) }
|
else -> {
|
||||||
} ?: Class.forName(fqName)
|
val javaClassId = JavaToKotlinClassMap.mapKotlinToJava(FqNameUnsafe(fqName))
|
||||||
|
val className = javaClassId?.asSingleFqName()?.asString() ?: fqName
|
||||||
|
Class.forName(className.replaceDotWithDollarForInnerClasses())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ClassId.getAsString(): String {
|
private fun String.replaceDotWithDollarForInnerClasses(): String? {
|
||||||
// TODO come up with something better
|
// TODO come up with something better
|
||||||
val fqName = this.asSingleFqName().toString()
|
val names = this.split(".")
|
||||||
val names = fqName.split(".")
|
|
||||||
val result = StringBuilder()
|
val result = StringBuilder()
|
||||||
for (i in 0 until (names.size - 1)) {
|
for (i in 0 until (names.size - 1)) {
|
||||||
result.append(names[i])
|
result.append(names[i])
|
||||||
|
|||||||
Reference in New Issue
Block a user