From 0fd1f549a970b188100b8b6521c2455290d14c57 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Fri, 25 Jun 2021 07:13:48 +0200 Subject: [PATCH] Properly process special symbols during indy-with-constants concatenation #KT-47320 Fixed --- .../kotlin/codegen/StringConcatGenerator.kt | 15 +++++++++++++-- .../codegen/FirBytecodeTextTestGenerated.java | 6 ++++++ .../concatDynamicSpecialSymbols.kt | 17 +++++++++++++++++ .../java9/box/concatDynamicSpecialSymbols.kt | 10 ++++++++++ .../codegen/BytecodeTextTestGenerated.java | 6 ++++++ .../codegen/IrBytecodeTextTestGenerated.java | 6 ++++++ .../AbstractCustomJDKBlackBoxCodegenTest.kt | 1 + .../Jdk9BlackBoxCodegenTestGenerated.java | 5 +++++ .../Jdk9IrBlackBoxCodegenTestGenerated.java | 5 +++++ 9 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicSpecialSymbols.kt create mode 100644 compiler/testData/codegen/java9/box/concatDynamicSpecialSymbols.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StringConcatGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/StringConcatGenerator.kt index 22b6ff25a4d..856fd9cc259 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StringConcatGenerator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StringConcatGenerator.kt @@ -22,6 +22,7 @@ import java.lang.StringBuilder class StringConcatGenerator(val mode: JvmStringConcat, val mv: InstructionAdapter) { private val template = StringBuilder("") + private val specialSymbolsInTemplate = arrayListOf() private val paramTypes = arrayListOf() private var justFlushed = false @@ -42,7 +43,16 @@ class StringConcatGenerator(val mode: JvmStringConcat, val mv: InstructionAdapte if (mode == JvmStringConcat.INDY_WITH_CONSTANTS) { when (stackValue) { is StackValue.Constant -> { - template.append(stackValue.value) + val value = stackValue.value + if (value is String && (value.contains("\u0001") || value.contains("\u0002"))) { + template.append("\u0002") //reference to special symbols added on next line + specialSymbolsInTemplate.add(value) + } else if (value is Char && (value == 1.toChar() || value == 2.toChar())) { + template.append("\u0002") //reference to special symbols added on next line + specialSymbolsInTemplate.add(value.toString()) + } else { + template.append(value) + } return } TRUE -> { @@ -104,7 +114,7 @@ class StringConcatGenerator(val mode: JvmStringConcat, val mv: InstructionAdapte "makeConcatWithConstants", Type.getMethodDescriptor(JAVA_STRING_TYPE, *paramTypes.toTypedArray()), bootstrap, - arrayOf(template.toString()) + arrayOf(template.toString()) + specialSymbolsInTemplate ) } else { val bootstrap = Handle( @@ -123,6 +133,7 @@ class StringConcatGenerator(val mode: JvmStringConcat, val mv: InstructionAdapte ) } template.clear() + specialSymbolsInTemplate.clear() paramTypes.clear() paramTypes.add(JAVA_STRING_TYPE) template.append("\u0001") diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java index 986cc39c2f4..66eba35ed4e 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java @@ -5134,6 +5134,12 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicIndyDataClass.kt"); } + @Test + @TestMetadata("concatDynamicSpecialSymbols.kt") + public void testConcatDynamicSpecialSymbols() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicSpecialSymbols.kt"); + } + @Test @TestMetadata("concatDynamicUnit.kt") public void testConcatDynamicUnit() throws Exception { diff --git a/compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicSpecialSymbols.kt b/compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicSpecialSymbols.kt new file mode 100644 index 00000000000..bede79dee4a --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicSpecialSymbols.kt @@ -0,0 +1,17 @@ +// JVM_TARGET: 9 + +fun box(a: String, b: String?) { + val s = a + "\u0001" + 2.toChar() + 3.toChar() + 4L + b + 5.0 + 6F + '7' + b + "\u0002" + 1.toChar() +} + +// 1 INVOKEDYNAMIC makeConcatWithConstants + +// JVM_TEMPLATES +// 1 "\\u0001\\u0002\\u0002\\u00034\\u00015.06.07\\u0001\\u0002\\u0002" +// 2 "\\u0001" +// 2 "\\u0002" + +// JVM_IR_TEMPLATES +// 1 "\\u0001\\u0002\\u00015.06.07\\u0001\\u0002" +// 1 "\\u0001\\u0002\\u00034" +// 1 "\\u0002\\u0001" \ No newline at end of file diff --git a/compiler/testData/codegen/java9/box/concatDynamicSpecialSymbols.kt b/compiler/testData/codegen/java9/box/concatDynamicSpecialSymbols.kt new file mode 100644 index 00000000000..e4b68fd14e0 --- /dev/null +++ b/compiler/testData/codegen/java9/box/concatDynamicSpecialSymbols.kt @@ -0,0 +1,10 @@ +// JVM_TARGET: 9 + +fun test(a: String, b: String?): String { + return a + "\u0001" + 2.toChar() + 3.toChar() + 4L + b + 5.0 + 6F + '7' + b + "\u0002" + 1.toChar() +} + +fun box(): String { + val test = test("O", "K") + return if (test != "O\u0001\u0002\u00034K5.06.07K\u0002\u0001") "fail ${test}" else "OK" +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java index 36a0822605d..34cd7dd6572 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java @@ -5002,6 +5002,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicIndyDataClass.kt"); } + @Test + @TestMetadata("concatDynamicSpecialSymbols.kt") + public void testConcatDynamicSpecialSymbols() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicSpecialSymbols.kt"); + } + @Test @TestMetadata("concatDynamicUnit.kt") public void testConcatDynamicUnit() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java index 61755a1a2ad..a4c9237018e 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java @@ -5134,6 +5134,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicIndyDataClass.kt"); } + @Test + @TestMetadata("concatDynamicSpecialSymbols.kt") + public void testConcatDynamicSpecialSymbols() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicSpecialSymbols.kt"); + } + @Test @TestMetadata("concatDynamicUnit.kt") public void testConcatDynamicUnit() throws Exception { diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractCustomJDKBlackBoxCodegenTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractCustomJDKBlackBoxCodegenTest.kt index 7bf00e5d4dd..19b8888db66 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractCustomJDKBlackBoxCodegenTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractCustomJDKBlackBoxCodegenTest.kt @@ -92,5 +92,6 @@ internal fun runJvmInstance( val process = ProcessBuilder(*command).inheritIO().start() process.waitFor(1, TimeUnit.MINUTES) + process.outputStream.flush() AbstractBlackBoxCodegenTest.assertEquals(0, process.exitValue()) } diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/Jdk9BlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/Jdk9BlackBoxCodegenTestGenerated.java index c1beba372dc..d77b3f8c3a1 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/Jdk9BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/Jdk9BlackBoxCodegenTestGenerated.java @@ -59,6 +59,11 @@ public class Jdk9BlackBoxCodegenTestGenerated extends AbstractJdk9BlackBoxCodege runTest("compiler/testData/codegen/java9/box/concatDynamicInlineClasses.kt"); } + @TestMetadata("concatDynamicSpecialSymbols.kt") + public void testConcatDynamicSpecialSymbols() throws Exception { + runTest("compiler/testData/codegen/java9/box/concatDynamicSpecialSymbols.kt"); + } + @TestMetadata("concatDynamicWithInline.kt") public void testConcatDynamicWithInline() throws Exception { runTest("compiler/testData/codegen/java9/box/concatDynamicWithInline.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/Jdk9IrBlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/Jdk9IrBlackBoxCodegenTestGenerated.java index 62481f13f6f..b67c72fa2b7 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/Jdk9IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/Jdk9IrBlackBoxCodegenTestGenerated.java @@ -60,6 +60,11 @@ public class Jdk9IrBlackBoxCodegenTestGenerated extends AbstractJdk9IrBlackBoxCo runTest("compiler/testData/codegen/java9/box/concatDynamicInlineClasses.kt"); } + @TestMetadata("concatDynamicSpecialSymbols.kt") + public void testConcatDynamicSpecialSymbols() throws Exception { + runTest("compiler/testData/codegen/java9/box/concatDynamicSpecialSymbols.kt"); + } + @TestMetadata("concatDynamicWithInline.kt") public void testConcatDynamicWithInline() throws Exception { runTest("compiler/testData/codegen/java9/box/concatDynamicWithInline.kt");