Properly process constants

This commit is contained in:
Mikhael Bogdanov
2020-09-29 12:51:56 +02:00
parent 8a1f7c5859
commit 942e1962d9
6 changed files with 42 additions and 32 deletions
@@ -493,33 +493,28 @@ public class DescriptorAsmUtil {
return index; return index;
} }
public static void genInvokeAppendMethod(@NotNull StringConcatGenerator generator, @NotNull Type type, @Nullable KotlinType kotlinType) {
genInvokeAppendMethod(generator, type, kotlinType, null);
}
public static void genInvokeAppendMethod( public static void genInvokeAppendMethod(
@NotNull StringConcatGenerator generator, @NotNull StringConcatGenerator generator,
@NotNull Type type, @NotNull Type type,
@Nullable KotlinType kotlinType, @Nullable KotlinType kotlinType,
@Nullable KotlinTypeMapper typeMapper @Nullable KotlinTypeMapper typeMapper,
@NotNull StackValue stackValue
) { ) {
Type appendParameterType;
CallableMethod specializedToString = getSpecializedToStringCallableMethodOrNull(kotlinType, typeMapper); CallableMethod specializedToString = getSpecializedToStringCallableMethodOrNull(kotlinType, typeMapper);
if (specializedToString != null) { if (specializedToString != null) {
stackValue.put(type, kotlinType, generator.getMv());
specializedToString.genInvokeInstruction(generator.getMv()); specializedToString.genInvokeInstruction(generator.getMv());
appendParameterType = AsmTypes.JAVA_STRING_TYPE; generator.invokeAppend(AsmTypes.JAVA_STRING_TYPE);
} }
else if (kotlinType != null && InlineClassesUtilsKt.isInlineClassType(kotlinType)) { else if (kotlinType != null && InlineClassesUtilsKt.isInlineClassType(kotlinType)) {
appendParameterType = OBJECT_TYPE;
SimpleType nullableAnyType = kotlinType.getConstructor().getBuiltIns().getNullableAnyType(); 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 { else {
appendParameterType = type; generator.putValueOrProcessConstant(stackValue, type, kotlinType);
} }
generator.invokeAppend(appendParameterType);
} }
public static StackValue genToString( public static StackValue genToString(
@@ -942,7 +942,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
else { else {
String value = ((StringTemplateEntry.Constant) entry).value; String value = ((StringTemplateEntry.Constant) entry).value;
if (value.length() == 1) { if (value.length() == 1) {
generator.addCharConstant(value.charAt(0)); generator.putValueOrProcessConstant(StackValue.constant(value.charAt(0), Type.CHAR_TYPE, null));
} }
else { else {
generator.addStringConstant(value); generator.addStringConstant(value);
@@ -4329,13 +4329,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
Type exprType = expressionType(expr); Type exprType = expressionType(expr);
KotlinType exprKotlinType = kotlinType(expr); KotlinType exprKotlinType = kotlinType(expr);
StackValue value;
if (compileTimeConstant != null) { if (compileTimeConstant != null) {
StackValue.constant(compileTimeConstant.getValue(), exprType, exprKotlinType).put(exprType, exprKotlinType, v); value = StackValue.constant(compileTimeConstant.getValue(), exprType, exprKotlinType);
} else { } else {
gen(expr, exprType, exprKotlinType); value = gen(expr);
} }
genInvokeAppendMethod(generator, exprType, exprKotlinType, typeMapper); genInvokeAppendMethod(generator, exprType, exprKotlinType, typeMapper, value);
} }
@Nullable @Nullable
@@ -132,7 +132,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
kotlinType = DescriptorUtilsKt.getBuiltIns(function).getStringType(); kotlinType = DescriptorUtilsKt.getBuiltIns(function).getStringType();
} }
} }
genInvokeAppendMethod(generator, asmType, kotlinType, typeMapper); genInvokeAppendMethod(generator, asmType, kotlinType, typeMapper, StackValue.onStack(asmType));
} }
generator.addStringConstant(")"); generator.addStringConstant(")");
@@ -6,10 +6,13 @@
package org.jetbrains.kotlin.codegen package org.jetbrains.kotlin.codegen
import com.google.common.collect.Sets 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.codegen.state.GenerationState
import org.jetbrains.kotlin.config.JvmRuntimeStringConcat import org.jetbrains.kotlin.config.JvmRuntimeStringConcat
import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE 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.Handle
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
@@ -32,22 +35,30 @@ class StringConcatGenerator(val mode: JvmRuntimeStringConcat, val mv: Instructio
} }
} }
fun addCharConstant(value: Char) { @JvmOverloads
if (!mode.isDynamic) { fun putValueOrProcessConstant(stackValue: StackValue, type: Type = stackValue.type, kotlinType: KotlinType? = stackValue.kotlinType) {
mv.iconst(value.toInt()) if (mode == JvmRuntimeStringConcat.ENABLE) {
invokeAppend(Type.CHAR_TYPE) when (stackValue) {
} else { is StackValue.Constant -> {
template.append(value) 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) { fun addStringConstant(value: String) {
if (!mode.isDynamic) { putValueOrProcessConstant(StackValue.constant(value, JAVA_STRING_TYPE, null))
mv.aconst(value)
invokeAppend(JAVA_STRING_TYPE)
} else {
template.append(value)
}
} }
fun invokeAppend(type: Type) { fun invokeAppend(type: Type) {
@@ -49,7 +49,7 @@ class Concat : IntrinsicMethod() {
// Explicit plus call LHS?.plus(RHS) or LHS.plus(RHS) // Explicit plus call LHS?.plus(RHS) or LHS.plus(RHS)
receiver.put(AsmTypes.JAVA_STRING_TYPE, v) receiver.put(AsmTypes.JAVA_STRING_TYPE, v)
generator.genStringBuilderConstructorIfNeded(true) generator.genStringBuilderConstructorIfNeded(true)
genInvokeAppendMethod(generator, returnType, null) genInvokeAppendMethod(generator, returnType, null, null, StackValue.onStack(JAVA_STRING_TYPE))
codegen.invokeAppend(generator, arguments[0]) codegen.invokeAppend(generator, arguments[0])
} }
generator.genToString() generator.genToString()
@@ -7,7 +7,7 @@ inline fun test(s: (String) -> Unit) {
} }
fun box(a: String, b: String?) { 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) a.plus(b)
b?.plus(a) b?.plus(a)
@@ -17,6 +17,9 @@ fun box(a: String, b: String?) {
test("123"::plus) test("123"::plus)
} }
// unsigned constant 1u processed as argument (last \u0001)
// 1 "\\u00011234\\u00015.06.07\\u0001truefalse\\u0001"
// 6 INVOKEDYNAMIC makeConcatWithConstants // 6 INVOKEDYNAMIC makeConcatWithConstants
// 0 append // 0 append
// 0 stringPlus // 0 stringPlus