diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/DescriptorAsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/DescriptorAsmUtil.java index 5c1534a1b7e..350cbe3026a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/DescriptorAsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/DescriptorAsmUtil.java @@ -493,33 +493,28 @@ public class DescriptorAsmUtil { return index; } - public static void genInvokeAppendMethod(@NotNull StringConcatGenerator generator, @NotNull Type type, @Nullable KotlinType kotlinType) { - genInvokeAppendMethod(generator, type, kotlinType, null); - } - public static void genInvokeAppendMethod( @NotNull StringConcatGenerator generator, @NotNull Type type, @Nullable KotlinType kotlinType, - @Nullable KotlinTypeMapper typeMapper + @Nullable KotlinTypeMapper typeMapper, + @NotNull StackValue stackValue ) { - Type appendParameterType; - CallableMethod specializedToString = getSpecializedToStringCallableMethodOrNull(kotlinType, typeMapper); if (specializedToString != null) { + stackValue.put(type, kotlinType, generator.getMv()); specializedToString.genInvokeInstruction(generator.getMv()); - appendParameterType = AsmTypes.JAVA_STRING_TYPE; + generator.invokeAppend(AsmTypes.JAVA_STRING_TYPE); } else if (kotlinType != null && InlineClassesUtilsKt.isInlineClassType(kotlinType)) { - appendParameterType = OBJECT_TYPE; SimpleType nullableAnyType = kotlinType.getConstructor().getBuiltIns().getNullableAnyType(); - StackValue.coerce(type, kotlinType, appendParameterType, nullableAnyType, generator.getMv()); + stackValue.put(type, kotlinType, generator.getMv()); + StackValue.coerce(type, kotlinType, OBJECT_TYPE, nullableAnyType, generator.getMv()); + generator.invokeAppend(OBJECT_TYPE); } else { - appendParameterType = type; + generator.putValueOrProcessConstant(stackValue, type, kotlinType); } - - generator.invokeAppend(appendParameterType); } public static StackValue genToString( diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 0877e64f963..287ea8e5b9e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -942,7 +942,7 @@ public class ExpressionCodegen extends KtVisitor impleme else { String value = ((StringTemplateEntry.Constant) entry).value; if (value.length() == 1) { - generator.addCharConstant(value.charAt(0)); + generator.putValueOrProcessConstant(StackValue.constant(value.charAt(0), Type.CHAR_TYPE, null)); } else { generator.addStringConstant(value); @@ -4329,13 +4329,14 @@ public class ExpressionCodegen extends KtVisitor impleme Type exprType = expressionType(expr); KotlinType exprKotlinType = kotlinType(expr); + StackValue value; if (compileTimeConstant != null) { - StackValue.constant(compileTimeConstant.getValue(), exprType, exprKotlinType).put(exprType, exprKotlinType, v); + value = StackValue.constant(compileTimeConstant.getValue(), exprType, exprKotlinType); } else { - gen(expr, exprType, exprKotlinType); + value = gen(expr); } - genInvokeAppendMethod(generator, exprType, exprKotlinType, typeMapper); + genInvokeAppendMethod(generator, exprType, exprKotlinType, typeMapper, value); } @Nullable diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionsFromAnyGeneratorImpl.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionsFromAnyGeneratorImpl.java index 61c4c9b191e..b53fa912717 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionsFromAnyGeneratorImpl.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionsFromAnyGeneratorImpl.java @@ -132,7 +132,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator { kotlinType = DescriptorUtilsKt.getBuiltIns(function).getStringType(); } } - genInvokeAppendMethod(generator, asmType, kotlinType, typeMapper); + genInvokeAppendMethod(generator, asmType, kotlinType, typeMapper, StackValue.onStack(asmType)); } generator.addStringConstant(")"); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StringConcatGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/StringConcatGenerator.kt index fc5f7a4bb74..6bfa5815c1f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StringConcatGenerator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StringConcatGenerator.kt @@ -6,10 +6,13 @@ package org.jetbrains.kotlin.codegen import com.google.common.collect.Sets +import org.jetbrains.kotlin.codegen.BranchedValue.Companion.FALSE +import org.jetbrains.kotlin.codegen.BranchedValue.Companion.TRUE import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.config.JvmRuntimeStringConcat import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE +import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Handle import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type @@ -32,22 +35,30 @@ class StringConcatGenerator(val mode: JvmRuntimeStringConcat, val mv: Instructio } } - fun addCharConstant(value: Char) { - if (!mode.isDynamic) { - mv.iconst(value.toInt()) - invokeAppend(Type.CHAR_TYPE) - } else { - template.append(value) + @JvmOverloads + fun putValueOrProcessConstant(stackValue: StackValue, type: Type = stackValue.type, kotlinType: KotlinType? = stackValue.kotlinType) { + if (mode == JvmRuntimeStringConcat.ENABLE) { + when (stackValue) { + is StackValue.Constant -> { + template.append(stackValue.value) + return + } + TRUE -> { + template.append(true) + return + } + FALSE -> { + template.append(false) + return + } + } } + stackValue.put(type, kotlinType, mv) + invokeAppend(type) } fun addStringConstant(value: String) { - if (!mode.isDynamic) { - mv.aconst(value) - invokeAppend(JAVA_STRING_TYPE) - } else { - template.append(value) - } + putValueOrProcessConstant(StackValue.constant(value, JAVA_STRING_TYPE, null)) } fun invokeAppend(type: Type) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt index 4debbeb4382..ff4285f5c75 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt @@ -49,7 +49,7 @@ class Concat : IntrinsicMethod() { // Explicit plus call LHS?.plus(RHS) or LHS.plus(RHS) receiver.put(AsmTypes.JAVA_STRING_TYPE, v) generator.genStringBuilderConstructorIfNeded(true) - genInvokeAppendMethod(generator, returnType, null) + genInvokeAppendMethod(generator, returnType, null, null, StackValue.onStack(JAVA_STRING_TYPE)) codegen.invokeAppend(generator, arguments[0]) } generator.genToString() diff --git a/compiler/testData/codegen/bytecodeText/stringOperations/concatDynamic.kt b/compiler/testData/codegen/bytecodeText/stringOperations/concatDynamic.kt index 2cc2e211755..7f62670a90a 100644 --- a/compiler/testData/codegen/bytecodeText/stringOperations/concatDynamic.kt +++ b/compiler/testData/codegen/bytecodeText/stringOperations/concatDynamic.kt @@ -7,7 +7,7 @@ inline fun test(s: (String) -> Unit) { } fun box(a: String, b: String?) { - val s = a + "1" + "2" + 3 + 4L + b + 5.0 + 6F + '7' + A() + val s = a + "1" + "2" + 3 + 4L + b + 5.0 + 6F + '7' + A() + true + false + 1u a.plus(b) b?.plus(a) @@ -17,6 +17,9 @@ fun box(a: String, b: String?) { test("123"::plus) } +// unsigned constant 1u processed as argument (last \u0001) + +// 1 "\\u00011234\\u00015.06.07\\u0001truefalse\\u0001" // 6 INVOKEDYNAMIC makeConcatWithConstants // 0 append // 0 stringPlus \ No newline at end of file