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.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.lang.invoke.MethodHandle
|
||||
|
||||
private const val MAX_STACK_SIZE = 10_000
|
||||
@@ -326,14 +327,14 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
||||
if (isLocal) valueArguments.addAll(dispatchReceiver.extractNonLocalDeclarations())
|
||||
|
||||
return stack.newFrame(asSubFrame = irFunction.isInline || irFunction.isLocal, initPool = valueArguments) {
|
||||
val isWrapper = dispatchReceiver is Wrapper && rawExtensionReceiver == null
|
||||
val isInterfaceDefaultMethod = irFunction.body != null && (irFunction.parent as? IrClass)?.isInterface == true
|
||||
// inline only methods are not presented in lookup table, so must be interpreted instead of execution
|
||||
val isInlineOnly = irFunction.hasAnnotation(FqName("kotlin.internal.InlineOnly"))
|
||||
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.isAbstract() -> calculateAbstract(irFunction) //abstract check must be before fake overridden check
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
+12
-11
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.ir.util.isTypeParameter
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithDifferentJvmName
|
||||
import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.firstOverridden
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
@@ -117,7 +116,7 @@ class Wrapper private constructor(
|
||||
|
||||
private fun IrFunction.getMethodType(): MethodType {
|
||||
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
|
||||
val returnClass = this.returnType.getClass(this.isReturnTypePrimitiveAsObject())
|
||||
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> {
|
||||
val fqName = this.getFqName()
|
||||
val fqName = this.getFqName() ?: return Any::class.java // null if this.isTypeParameter()
|
||||
val owner = this.classOrNull?.owner
|
||||
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
|
||||
owner.hasAnnotation(evaluateIntrinsicAnnotation) -> Class.forName(owner!!.getEvaluateIntrinsicValue())
|
||||
//TODO primitive array
|
||||
this.isTypeParameter() -> Any::class.java // TODO use typeArguments
|
||||
else -> JavaToKotlinClassMap.mapKotlinToJava(FqNameUnsafe(fqName!!))?.let { Class.forName(it.getAsString()) }
|
||||
} ?: Class.forName(fqName)
|
||||
owner.hasAnnotation(evaluateIntrinsicAnnotation) -> Class.forName(owner!!.getEvaluateIntrinsicValue())
|
||||
else -> {
|
||||
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
|
||||
val fqName = this.asSingleFqName().toString()
|
||||
val names = fqName.split(".")
|
||||
val names = this.split(".")
|
||||
val result = StringBuilder()
|
||||
for (i in 0 until (names.size - 1)) {
|
||||
result.append(names[i])
|
||||
|
||||
Reference in New Issue
Block a user