JVM_IR: Implement name mangling exceptions for Result class.

This commit is contained in:
Steven Schäfer
2019-06-24 16:00:53 +02:00
committed by max-kammerer
parent d458e4a7b2
commit 078ccbf077
17 changed files with 75 additions and 19 deletions
@@ -11,7 +11,9 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
/**
* Replace inline classes by their underlying types.
@@ -52,6 +54,13 @@ object InlineClassAbi {
* to avoid clashes between overloaded methods.
*/
fun mangledNameFor(irFunction: IrFunction): Name {
val suffix = when {
irFunction.fullValueParameterList.any { it.type.requiresMangling } ->
hashSuffix(irFunction)
(irFunction.parent as? IrClass)?.isInline == true -> "impl"
else -> return irFunction.name
}
val base = when {
irFunction is IrConstructor ->
"constructor"
@@ -65,13 +74,6 @@ object InlineClassAbi {
irFunction.name.asString()
}
val suffix = when {
irFunction.fullValueParameterList.any { it.type.erasedUpperBound.isInline } ->
hashSuffix(irFunction)
(irFunction.parent as? IrClass)?.isInline == true -> "impl"
else -> return irFunction.name
}
return Name.identifier("$base-$suffix")
}
@@ -89,6 +91,12 @@ object InlineClassAbi {
}
}
internal val IrType.requiresMangling: Boolean
get() {
val irClass = erasedUpperBound
return irClass.isInline && irClass.fqNameWhenAvailable != DescriptorUtils.RESULT_FQ_NAME
}
internal val IrFunction.fullValueParameterList: List<IrValueParameter>
get() = listOfNotNull(extensionReceiverParameter) + valueParameters
@@ -46,18 +46,17 @@ class MemoizedInlineClassReplacements {
val getReplacementFunction: (IrFunction) -> IrReplacementFunction? =
storageManager.createMemoizedFunctionWithNullableValues {
when {
!it.hasInlineClassParameters || it.isSyntheticInlineClassMember || it.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA -> null
!it.hasMangledParameters || it.isSyntheticInlineClassMember || it.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA -> null
it.hasMethodReplacement -> createMethodReplacement(it)
it.hasStaticReplacement -> createStaticReplacement(it)
else -> null
}
}
private val IrFunction.hasInlineClassParameters: Boolean
get() = explicitParameters.any { it.type.erasedUpperBound.isInline && !it.type.isDontMangleType() }
|| (this is IrConstructor && constructedClass.isInline)
private fun IrType.isDontMangleType() = getClass()?.fqNameWhenAvailable == DescriptorUtils.RESULT_FQ_NAME
private val IrFunction.hasMangledParameters: Boolean
get() = dispatchReceiverParameter?.type?.getClass()?.isInline == true ||
fullValueParameterList.any { it.type.requiresMangling } ||
(this is IrConstructor && constructedClass.isInline)
private val IrFunction.hasStaticReplacement: Boolean
get() = origin != IrDeclarationOrigin.FAKE_OVERRIDE &&
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// COMMON_COROUTINES_TEST
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.ContinuationAdapter
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// COMMON_COROUTINES_TEST
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// COMMON_COROUTINES_TEST
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// COMMON_COROUTINES_TEST
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// COMMON_COROUTINES_TEST
@@ -0,0 +1,6 @@
// WITH_RUNTIME
fun box(): String {
val ok = Result.success("OK")
return ok.getOrNull()!!
}
@@ -0,0 +1,14 @@
// !LANGUAGE: +InlineClasses
// WITH_RUNTIME
// FILE: test.kt
inline class A(val s: String) {
fun fromResult(x: Result<String>) =
x.getOrNull() ?: s
}
fun box(): String {
return A("Fail").fromResult(Result.success("OK"))
}
// @TestKt.class:
// 1 INVOKESTATIC A.fromResult
@@ -12615,6 +12615,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
}
@TestMetadata("resultInlining.kt")
public void testResultInlining() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/resultInlining.kt");
}
@TestMetadata("secondaryConstructorWithVararg.kt")
public void testSecondaryConstructorWithVararg() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
@@ -2525,6 +2525,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/resultApiDoesntUseBox.kt");
}
@TestMetadata("resultMangling.kt")
public void testResultMangling() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/resultMangling.kt");
}
@TestMetadata("skipCallToUnderlyingValueOfInlineClass.kt")
public void testSkipCallToUnderlyingValueOfInlineClass() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/skipCallToUnderlyingValueOfInlineClass.kt");
@@ -12620,6 +12620,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
}
@TestMetadata("resultInlining.kt")
public void testResultInlining() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/resultInlining.kt");
}
@TestMetadata("secondaryConstructorWithVararg.kt")
public void testSecondaryConstructorWithVararg() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
@@ -11505,6 +11505,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
}
@TestMetadata("resultInlining.kt")
public void testResultInlining() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/resultInlining.kt");
}
@TestMetadata("secondaryConstructorWithVararg.kt")
public void testSecondaryConstructorWithVararg() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
@@ -2480,6 +2480,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/resultApiDoesntUseBox.kt");
}
@TestMetadata("resultMangling.kt")
public void testResultMangling() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/resultMangling.kt");
}
@TestMetadata("skipCallToUnderlyingValueOfInlineClass.kt")
public void testSkipCallToUnderlyingValueOfInlineClass() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/skipCallToUnderlyingValueOfInlineClass.kt");
@@ -9960,6 +9960,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
}
@TestMetadata("resultInlining.kt")
public void testResultInlining() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/resultInlining.kt");
}
@TestMetadata("secondaryConstructorWithVararg.kt")
public void testSecondaryConstructorWithVararg() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
@@ -11115,6 +11115,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
}
@TestMetadata("resultInlining.kt")
public void testResultInlining() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/resultInlining.kt");
}
@TestMetadata("secondaryConstructorWithVararg.kt")
public void testSecondaryConstructorWithVararg() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");