From 80d83f8703bbe16097cf80336812c79de6db8191 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Fri, 8 May 2020 21:16:18 +0300 Subject: [PATCH] Change check for Wrapper method For now method is wrapper if its receiver is Wrapper and method itself isn't inline only --- .../common/interpreter/IrInterpreter.kt | 9 ++++---- .../common/interpreter/state/Wrapper.kt | 23 ++++++++++--------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt index d6e99197725..27090690238 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt @@ -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() } } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/state/Wrapper.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/state/Wrapper.kt index 7f2ab4e2fa2..71fc223461f 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/state/Wrapper.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/state/Wrapper.kt @@ -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 { - 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::class.javaObjectType else Array::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])