Properly process special symbols during indy-with-constants concatenation

#KT-47320 Fixed
This commit is contained in:
Mikhael Bogdanov
2021-06-25 07:13:48 +02:00
parent e947556aaa
commit 0fd1f549a9
9 changed files with 69 additions and 2 deletions
@@ -22,6 +22,7 @@ import java.lang.StringBuilder
class StringConcatGenerator(val mode: JvmStringConcat, val mv: InstructionAdapter) {
private val template = StringBuilder("")
private val specialSymbolsInTemplate = arrayListOf<String>()
private val paramTypes = arrayListOf<Type>()
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")
@@ -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 {
@@ -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"
@@ -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"
}
@@ -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 {
@@ -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 {
@@ -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())
}
@@ -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");
@@ -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");