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:
Ivan Kylchik
2020-05-08 21:16:18 +03:00
parent 38822c3bf8
commit 80d83f8703
2 changed files with 17 additions and 15 deletions
@@ -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()
}
}
@@ -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])