Fix inlining of functions with matching JVM signatures in same package
When two functions with matching JVM signatures in the same package were inlined sequentially, inliner could take a wrong method body from the cache due to MethodId clash. This manifested with inline classes, but also was possible with some legal Kotlin overloads with matching erasure. Use internal name of the corresponding implementation owner class instead of FQN of the containing declaration. Such MethodIds can't match accidentally, because corresponding JVM method signatures would clash.
This commit is contained in:
@@ -18,10 +18,9 @@ package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import com.intellij.util.containers.SLRUMap
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
|
||||
data class MethodId(val containingFqName: FqName, val method: Method)
|
||||
data class MethodId(val ownerInternalName: String, val method: Method)
|
||||
|
||||
class InlineCache {
|
||||
val classBytes: SLRUMap<ClassId, ByteArray> = SLRUMap(30, 20)
|
||||
|
||||
@@ -13,7 +13,10 @@ import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.getMethodAsmFlags
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
|
||||
import org.jetbrains.kotlin.codegen.context.ClosureContext
|
||||
import org.jetbrains.kotlin.codegen.coroutines.*
|
||||
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForCoroutineContext
|
||||
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForIntercepted
|
||||
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForSuspendCoroutineUninterceptedOrReturn
|
||||
import org.jetbrains.kotlin.codegen.coroutines.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.bytecode
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.classId
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
@@ -500,7 +503,8 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
else
|
||||
mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor, jvmSignature.asmMethod)
|
||||
|
||||
val methodId = MethodId(DescriptorUtils.getFqNameSafe(functionDescriptor.containingDeclaration), asmMethod)
|
||||
val owner = state.typeMapper.mapImplementationOwner(functionDescriptor)
|
||||
val methodId = MethodId(owner.internalName, asmMethod)
|
||||
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
|
||||
if (!isBuiltInArrayIntrinsic(functionDescriptor) && directMember !is DeserializedCallableMemberDescriptor) {
|
||||
return sourceCompilerForInline.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod)
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.codegen.*;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
||||
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
||||
import org.jetbrains.kotlin.codegen.inline.FictitiousArrayConstructor;
|
||||
import org.jetbrains.kotlin.codegen.signature.AsmTypeFactory;
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
||||
@@ -252,6 +253,10 @@ public class KotlinTypeMapper {
|
||||
return descriptor.getContainingDeclaration().getName().asString();
|
||||
}
|
||||
|
||||
if (directMember instanceof FictitiousArrayConstructor) {
|
||||
return "kotlin.Array";
|
||||
}
|
||||
|
||||
throw new RuntimeException("Could not find package member for " + descriptor +
|
||||
" in package fragment " + descriptor.getContainingDeclaration());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user