Support large strings in indy-with-constants concatenation

#KT-47917 Fixed
This commit is contained in:
Mikhael Bogdanov
2021-09-01 12:57:15 +02:00
committed by Space
parent d2d3708827
commit 19474ee30f
19 changed files with 314 additions and 24 deletions
@@ -869,12 +869,9 @@ class ExpressionCodegen(
private fun generateStringConstant(value: String) {
val length = value.length
// Strings in constant pool contain at most 2^16-1 = 65535 bytes.
// Non-BMP characters in UTF8 require at most 4 bytes.
val maxPartLength = 65535 / 4
if (length <= maxPartLength) {
mv.aconst(value)
val splitted = splitStringConstant(value)
if (splitted.size == 1) {
mv.aconst(splitted.first())
} else {
// Split strings into parts, each of which satisfies JVM class file constant pool constraints.
// Note that even if we split surrogate pairs between parts, they will be joined on concatenation.
@@ -882,12 +879,9 @@ class ExpressionCodegen(
mv.dup()
mv.iconst(length)
mv.invokespecial("java/lang/StringBuilder", "<init>", "(I)V", false)
var i = 0
while (i < length) {
val j = minOf(i + maxPartLength, length)
mv.aconst(value.substring(i, j))
for (part in splitted) {
mv.aconst(part)
mv.invokevirtual("java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false)
i += maxPartLength
}
mv.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
}