JVM_IR: generate more correct names for regenerated objects
and fake lambda types, too. (But those only matter for debugging.) Also, share object name generators between methods with the same name to avoid rewriting objects from one with objects from the other.
This commit is contained in:
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.MemoizedInlineClassReplacements
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||
import org.jetbrains.kotlin.codegen.inline.NameGenerator
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
@@ -35,6 +36,7 @@ import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
|
||||
@@ -71,6 +73,13 @@ class JvmBackendContext(
|
||||
localClassInfo[container.attributeOwnerId] = value
|
||||
}
|
||||
|
||||
// TODO cache these at ClassCodegen level. Currently, sharing this map between classes in a module is required
|
||||
// because IrSourceCompilerForInline constructs a new (Fake)ClassCodegen for every call to
|
||||
// an inline function in the same module. Thus, if two inline functions happen to have the same name
|
||||
// and call a third inline function that has an anonymous object, the one which is called last
|
||||
// will overwrite the other's regenerated copy. (Or don't recompile the inline function for every call.)
|
||||
internal val regeneratedObjectNameGenerators = mutableMapOf<Pair<IrClass, Name>, NameGenerator>()
|
||||
|
||||
internal val localDelegatedProperties = mutableMapOf<IrClass, List<IrLocalDelegatedPropertySymbol>>()
|
||||
|
||||
internal val multifileFacadesToAdd = mutableMapOf<JvmClassName, MutableList<IrClass>>()
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.jvm.lower.constantValue
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper
|
||||
import org.jetbrains.kotlin.codegen.inline.NameGenerator
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages
|
||||
import org.jetbrains.kotlin.codegen.inline.SourceMapper
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
|
||||
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SYNTHETIC_ANNOTATION_FQ_NAME
|
||||
@@ -82,6 +84,13 @@ open class ClassCodegen protected constructor(
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun getRegeneratedObjectNameGenerator(function: IrFunction): NameGenerator {
|
||||
val name = if (function.name.isSpecial) Name.identifier("special") else function.name
|
||||
return context.regeneratedObjectNameGenerators.getOrPut(irClass to name) {
|
||||
NameGenerator("${type.internalName}\$$name\$\$inlined")
|
||||
}
|
||||
}
|
||||
|
||||
fun generate(): ReifiedTypeParametersUsages {
|
||||
if (withinInline) {
|
||||
getOrCreateSourceMapper() //initialize default mapping that would be later written in class file
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ class ExpressionCodegen(
|
||||
override val visitor: InstructionAdapter
|
||||
get() = mv
|
||||
|
||||
override val inlineNameGenerator: NameGenerator = NameGenerator("${classCodegen.type.internalName}\$todo") // TODO
|
||||
override val inlineNameGenerator: NameGenerator = classCodegen.getRegeneratedObjectNameGenerator(irFunction)
|
||||
|
||||
override val typeSystem: TypeSystemCommonBackendContext
|
||||
get() = typeMapper.typeSystem
|
||||
|
||||
+8
-5
@@ -151,11 +151,14 @@ class IrExpressionLambdaImpl(
|
||||
return false //always false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var counter: Int = 123//TODO: pass proper type
|
||||
}
|
||||
|
||||
override val lambdaClassType: Type = Type.getObjectType("test${counter++}")
|
||||
// This name doesn't actually matter: it is used internally to tell this lambda's captured
|
||||
// arguments apart from any other scope's. So long as it's unique, any value is fine.
|
||||
// This particular string slightly aids in debugging internal compiler errors as it at least
|
||||
// points towards the function containing the lambda.
|
||||
override val lambdaClassType: Type = Type.getObjectType(
|
||||
context.getLocalClassInfo(reference)?.internalName
|
||||
?: throw AssertionError("callable reference ${reference.dump()} has no name in context")
|
||||
)
|
||||
|
||||
override val capturedVars: List<CapturedParamDesc> =
|
||||
arrayListOf<CapturedParamDesc>().apply {
|
||||
|
||||
+8
-6
@@ -24,10 +24,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
@@ -51,6 +48,7 @@ internal val inlineCallableReferenceToLambdaPhase = makeIrFilePhase(
|
||||
//
|
||||
internal class InlineCallableReferenceToLambdaPhase(val context: JvmBackendContext) : FileLoweringPass {
|
||||
private val inlinableCR = mutableSetOf<IrCallableReference>()
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildrenVoid(object : IrElementTransformerVoidWithContext() {
|
||||
|
||||
@@ -118,7 +116,9 @@ internal class InlineCallableReferenceToLambdaPhase(val context: JvmBackendConte
|
||||
expression.startOffset, expression.endOffset, field.type,
|
||||
newLambda.symbol, newLambda.symbol.descriptor, 0,
|
||||
IrStatementOrigin.LAMBDA
|
||||
)
|
||||
).apply {
|
||||
copyAttributes(expression)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +209,9 @@ internal class InlineCallableReferenceToLambdaPhase(val context: JvmBackendConte
|
||||
expression.startOffset, expression.endOffset, referencedFunction.returnType,
|
||||
newLambda.symbol, newLambda.symbol.descriptor, referencedFunction.typeParameters.size,
|
||||
IrStatementOrigin.LAMBDA
|
||||
)
|
||||
).apply {
|
||||
copyAttributes(expression)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-2
@@ -1,5 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
inline fun <R> call(crossinline f: () -> R) : R {
|
||||
return { f() }()
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
//NO_CHECK_LAMBDA_INLINING
|
||||
import test.*
|
||||
|
||||
inline fun sameName(s: Long): String = call { "FAIL" }
|
||||
inline fun sameName(s: Int): String = call { "OK" }
|
||||
|
||||
fun box(): String {
|
||||
val result = sameName(1)
|
||||
sameName(1L)
|
||||
return result
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
+5
@@ -1888,6 +1888,11 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
runTest("compiler/testData/codegen/boxInline/lambdaTransformation/regeneratedLambdaName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("regeneratedLambdaName2.kt")
|
||||
public void testRegeneratedLambdaName2() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/lambdaTransformation/regeneratedLambdaName2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("sameCaptured.kt")
|
||||
public void testSameCaptured() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/lambdaTransformation/sameCaptured.kt");
|
||||
|
||||
Generated
+5
@@ -1888,6 +1888,11 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
runTest("compiler/testData/codegen/boxInline/lambdaTransformation/regeneratedLambdaName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("regeneratedLambdaName2.kt")
|
||||
public void testRegeneratedLambdaName2() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/lambdaTransformation/regeneratedLambdaName2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("sameCaptured.kt")
|
||||
public void testSameCaptured() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/lambdaTransformation/sameCaptured.kt");
|
||||
|
||||
+5
@@ -1888,6 +1888,11 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli
|
||||
runTest("compiler/testData/codegen/boxInline/lambdaTransformation/regeneratedLambdaName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("regeneratedLambdaName2.kt")
|
||||
public void testRegeneratedLambdaName2() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/lambdaTransformation/regeneratedLambdaName2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("sameCaptured.kt")
|
||||
public void testSameCaptured() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/lambdaTransformation/sameCaptured.kt");
|
||||
|
||||
Generated
+5
@@ -1888,6 +1888,11 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC
|
||||
runTest("compiler/testData/codegen/boxInline/lambdaTransformation/regeneratedLambdaName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("regeneratedLambdaName2.kt")
|
||||
public void testRegeneratedLambdaName2() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/lambdaTransformation/regeneratedLambdaName2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("sameCaptured.kt")
|
||||
public void testSameCaptured() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/lambdaTransformation/sameCaptured.kt");
|
||||
|
||||
Reference in New Issue
Block a user