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;
}
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(
@@ -942,7 +942,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> 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<StackValue, StackValue> 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
@@ -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(")");
@@ -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) {
@@ -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()
@@ -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