Introduce StringAppendGenerator
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
@@ -42,7 +43,7 @@ interface Callable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap) {
|
fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap, state: GenerationState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,12 +69,6 @@ import static org.jetbrains.kotlin.types.TypeUtils.isNullableType;
|
|||||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
public class DescriptorAsmUtil {
|
public class DescriptorAsmUtil {
|
||||||
private static final Set<Type> STRING_BUILDER_OBJECT_APPEND_ARG_TYPES = Sets.newHashSet(
|
|
||||||
getType(String.class),
|
|
||||||
getType(StringBuffer.class),
|
|
||||||
getType(CharSequence.class)
|
|
||||||
);
|
|
||||||
|
|
||||||
private DescriptorAsmUtil() {
|
private DescriptorAsmUtil() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,12 +495,12 @@ public class DescriptorAsmUtil {
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void genInvokeAppendMethod(@NotNull InstructionAdapter v, @NotNull Type type, @Nullable KotlinType kotlinType) {
|
public static void genInvokeAppendMethod(@NotNull StringAppendGenerator generator, @NotNull Type type, @Nullable KotlinType kotlinType) {
|
||||||
genInvokeAppendMethod(v, type, kotlinType, null);
|
genInvokeAppendMethod(generator, type, kotlinType, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void genInvokeAppendMethod(
|
public static void genInvokeAppendMethod(
|
||||||
@NotNull InstructionAdapter v,
|
@NotNull StringAppendGenerator generator,
|
||||||
@NotNull Type type,
|
@NotNull Type type,
|
||||||
@Nullable KotlinType kotlinType,
|
@Nullable KotlinType kotlinType,
|
||||||
@Nullable KotlinTypeMapper typeMapper
|
@Nullable KotlinTypeMapper typeMapper
|
||||||
@@ -515,33 +509,19 @@ public class DescriptorAsmUtil {
|
|||||||
|
|
||||||
CallableMethod specializedToString = getSpecializedToStringCallableMethodOrNull(kotlinType, typeMapper);
|
CallableMethod specializedToString = getSpecializedToStringCallableMethodOrNull(kotlinType, typeMapper);
|
||||||
if (specializedToString != null) {
|
if (specializedToString != null) {
|
||||||
specializedToString.genInvokeInstruction(v);
|
specializedToString.genInvokeInstruction(generator.getMv());
|
||||||
appendParameterType = AsmTypes.JAVA_STRING_TYPE;
|
appendParameterType = AsmTypes.JAVA_STRING_TYPE;
|
||||||
}
|
}
|
||||||
else if (kotlinType != null && InlineClassesUtilsKt.isInlineClassType(kotlinType)) {
|
else if (kotlinType != null && InlineClassesUtilsKt.isInlineClassType(kotlinType)) {
|
||||||
appendParameterType = OBJECT_TYPE;
|
appendParameterType = OBJECT_TYPE;
|
||||||
SimpleType nullableAnyType = kotlinType.getConstructor().getBuiltIns().getNullableAnyType();
|
SimpleType nullableAnyType = kotlinType.getConstructor().getBuiltIns().getNullableAnyType();
|
||||||
StackValue.coerce(type, kotlinType, appendParameterType, nullableAnyType, v);
|
StackValue.coerce(type, kotlinType, appendParameterType, nullableAnyType, generator.getMv());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
appendParameterType = stringBuilderAppendType(type);
|
appendParameterType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
v.invokevirtual("java/lang/StringBuilder", "append", "(" + appendParameterType.getDescriptor() + ")Ljava/lang/StringBuilder;", false);
|
generator.invokeAppend(appendParameterType);
|
||||||
}
|
|
||||||
|
|
||||||
private static Type stringBuilderAppendType(Type type) {
|
|
||||||
switch (type.getSort()) {
|
|
||||||
case Type.OBJECT:
|
|
||||||
return STRING_BUILDER_OBJECT_APPEND_ARG_TYPES.contains(type) ? type : OBJECT_TYPE;
|
|
||||||
case Type.ARRAY:
|
|
||||||
return OBJECT_TYPE;
|
|
||||||
case Type.BYTE:
|
|
||||||
case Type.SHORT:
|
|
||||||
return Type.INT_TYPE;
|
|
||||||
default:
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StackValue genToString(
|
public static StackValue genToString(
|
||||||
|
|||||||
@@ -925,28 +925,27 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return StackValue.operation(type, v -> {
|
return StackValue.operation(type, v -> {
|
||||||
genStringBuilderConstructor(v);
|
StringAppendGenerator generator = StringAppendGenerator.Companion.create(state, v);
|
||||||
invokeAppendForEntries(v, entries);
|
generator.genStringBuilderConstructorIfNeded();
|
||||||
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
|
invokeAppendForEntries(generator, entries);
|
||||||
|
generator.genToString();
|
||||||
return Unit.INSTANCE;
|
return Unit.INSTANCE;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void invokeAppendForEntries(InstructionAdapter v, List<StringTemplateEntry> entries) {
|
private void invokeAppendForEntries(StringAppendGenerator generator, List<StringTemplateEntry> entries) {
|
||||||
for (StringTemplateEntry entry : entries) {
|
for (StringTemplateEntry entry : entries) {
|
||||||
if (entry instanceof StringTemplateEntry.Expression) {
|
if (entry instanceof StringTemplateEntry.Expression) {
|
||||||
invokeAppend(v, ((StringTemplateEntry.Expression) entry).expression);
|
invokeAppend(generator, ((StringTemplateEntry.Expression) entry).expression);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String value = ((StringTemplateEntry.Constant) entry).value;
|
String value = ((StringTemplateEntry.Constant) entry).value;
|
||||||
if (value.length() == 1) {
|
if (value.length() == 1) {
|
||||||
v.iconst(value.charAt(0));
|
generator.addCharConstant(value.charAt(0));
|
||||||
genInvokeAppendMethod(v, Type.CHAR_TYPE, null);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v.aconst(value);
|
generator.addStringConstant(value);
|
||||||
genInvokeAppendMethod(v, JAVA_STRING_TYPE, null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2840,7 +2839,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
myFrameMap.leaveTemp(firstReceiverType);
|
myFrameMap.leaveTemp(firstReceiverType);
|
||||||
}
|
}
|
||||||
|
|
||||||
callableMethod.afterReceiverGeneration(v, myFrameMap);
|
callableMethod.afterReceiverGeneration(v, myFrameMap, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4301,7 +4300,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invokeAppend(InstructionAdapter v, KtExpression expr) {
|
public void invokeAppend(StringAppendGenerator generator, KtExpression expr) {
|
||||||
expr = KtPsiUtil.safeDeparenthesize(expr);
|
expr = KtPsiUtil.safeDeparenthesize(expr);
|
||||||
|
|
||||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expr);
|
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expr);
|
||||||
@@ -4315,15 +4314,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
Type leftType = expressionType(left);
|
Type leftType = expressionType(left);
|
||||||
|
|
||||||
if (leftType.equals(JAVA_STRING_TYPE)) {
|
if (leftType.equals(JAVA_STRING_TYPE)) {
|
||||||
invokeAppend(v, left);
|
invokeAppend(generator, left);
|
||||||
invokeAppend(v, right);
|
invokeAppend(generator, right);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (expr instanceof KtStringTemplateExpression) {
|
else if (expr instanceof KtStringTemplateExpression) {
|
||||||
List<StringTemplateEntry> entries = preprocessStringTemplate((KtStringTemplateExpression) expr);
|
List<StringTemplateEntry> entries = preprocessStringTemplate((KtStringTemplateExpression) expr);
|
||||||
invokeAppendForEntries(v, entries);
|
invokeAppendForEntries(generator, entries);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4336,7 +4335,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
gen(expr, exprType, exprKotlinType);
|
gen(expr, exprType, exprKotlinType);
|
||||||
}
|
}
|
||||||
|
|
||||||
genInvokeAppendMethod(v, exprType, exprKotlinType, typeMapper);
|
genInvokeAppendMethod(generator, exprType, exprKotlinType, typeMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
+8
-8
@@ -101,18 +101,19 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
|||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
genStringBuilderConstructor(iv);
|
|
||||||
|
|
||||||
|
StringAppendGenerator generator = StringAppendGenerator.Companion.create(generationState, iv);
|
||||||
|
generator.genStringBuilderConstructorIfNeded();
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
|
|
||||||
for (PropertyDescriptor propertyDescriptor : properties) {
|
for (PropertyDescriptor propertyDescriptor : properties) {
|
||||||
if (first) {
|
if (first) {
|
||||||
iv.aconst(classDescriptor.getName() + "(" + propertyDescriptor.getName().asString() + "=");
|
generator.addStringConstant(classDescriptor.getName() + "(" + propertyDescriptor.getName().asString() + "=");
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
iv.aconst(", " + propertyDescriptor.getName().asString() + "=");
|
generator.addStringConstant(", " + propertyDescriptor.getName().asString() + "=");
|
||||||
}
|
}
|
||||||
genInvokeAppendMethod(iv, JAVA_STRING_TYPE, null);
|
|
||||||
|
|
||||||
JvmKotlinType type = genOrLoadOnStack(iv, context, propertyDescriptor, 0);
|
JvmKotlinType type = genOrLoadOnStack(iv, context, propertyDescriptor, 0);
|
||||||
Type asmType = type.getType();
|
Type asmType = type.getType();
|
||||||
@@ -131,13 +132,12 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
|||||||
kotlinType = DescriptorUtilsKt.getBuiltIns(function).getStringType();
|
kotlinType = DescriptorUtilsKt.getBuiltIns(function).getStringType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
genInvokeAppendMethod(iv, asmType, kotlinType, typeMapper);
|
genInvokeAppendMethod(generator, asmType, kotlinType, typeMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
iv.aconst(")");
|
generator.addStringConstant(")");
|
||||||
genInvokeAppendMethod(iv, JAVA_STRING_TYPE, null);
|
|
||||||
|
|
||||||
iv.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
|
generator.genToString();
|
||||||
iv.areturn(JAVA_STRING_TYPE);
|
iv.areturn(JAVA_STRING_TYPE);
|
||||||
|
|
||||||
FunctionCodegen.endVisit(mv, toStringMethodName, getDeclaration());
|
FunctionCodegen.endVisit(mv, toStringMethodName, getDeclaration());
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets
|
||||||
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE
|
||||||
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
|
|
||||||
|
class StringAppendGenerator(val useInvokeDynamic: Boolean, val mv: InstructionAdapter) {
|
||||||
|
|
||||||
|
@JvmOverloads
|
||||||
|
fun genStringBuilderConstructorIfNeded(swap: Boolean = false) {
|
||||||
|
if (useInvokeDynamic) return
|
||||||
|
mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder")
|
||||||
|
mv.dup()
|
||||||
|
mv.invokespecial("java/lang/StringBuilder", "<init>", "()V", false)
|
||||||
|
if (swap) {
|
||||||
|
mv.swap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addArgOnStack(type: Type) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addCharConstant(value: Int) {
|
||||||
|
mv.iconst(value)
|
||||||
|
invokeAppend(Type.CHAR_TYPE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addStringConstant(value: String) {
|
||||||
|
mv.aconst(value)
|
||||||
|
invokeAppend(JAVA_STRING_TYPE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun invokeAppend(type: Type) {
|
||||||
|
if (!useInvokeDynamic) {
|
||||||
|
mv.invokevirtual(
|
||||||
|
"java/lang/StringBuilder",
|
||||||
|
"append",
|
||||||
|
"(" + stringBuilderAppendType(type) + ")Ljava/lang/StringBuilder;",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun genToString() {
|
||||||
|
if (!useInvokeDynamic) {
|
||||||
|
mv.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val STRING_BUILDER_OBJECT_APPEND_ARG_TYPES: Set<Type> = Sets.newHashSet(
|
||||||
|
AsmTypes.getType(String::class.java),
|
||||||
|
AsmTypes.getType(StringBuffer::class.java),
|
||||||
|
AsmTypes.getType(CharSequence::class.java)
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun stringBuilderAppendType(type: Type): Type {
|
||||||
|
return when (type.sort) {
|
||||||
|
Type.OBJECT -> if (STRING_BUILDER_OBJECT_APPEND_ARG_TYPES.contains(type)) type else AsmTypes.OBJECT_TYPE
|
||||||
|
Type.ARRAY -> AsmTypes.OBJECT_TYPE
|
||||||
|
Type.BYTE, Type.SHORT -> Type.INT_TYPE
|
||||||
|
else -> type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun create(state: GenerationState, mv: InstructionAdapter) = StringAppendGenerator(false, mv)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.codegen.intrinsics
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil.genStringBuilderConstructor
|
|
||||||
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.genInvokeAppendMethod
|
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.genInvokeAppendMethod
|
||||||
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||||
@@ -39,26 +39,27 @@ class Concat : IntrinsicMethod() {
|
|||||||
arguments: List<KtExpression>,
|
arguments: List<KtExpression>,
|
||||||
receiver: StackValue
|
receiver: StackValue
|
||||||
): Type {
|
): Type {
|
||||||
|
val generator = StringAppendGenerator.create(codegen.state, v)
|
||||||
if (element is KtBinaryExpression && element.operationReference.getReferencedNameElementType() == KtTokens.PLUS) {
|
if (element is KtBinaryExpression && element.operationReference.getReferencedNameElementType() == KtTokens.PLUS) {
|
||||||
// LHS + RHS
|
// LHS + RHS
|
||||||
genStringBuilderConstructor(v)
|
generator.genStringBuilderConstructorIfNeded()
|
||||||
codegen.invokeAppend(v, element.left)
|
codegen.invokeAppend(generator, element.left)
|
||||||
codegen.invokeAppend(v, element.right)
|
codegen.invokeAppend(generator, element.right)
|
||||||
} else {
|
} else {
|
||||||
// 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)
|
||||||
genStringBuilderConstructor(v)
|
generator.genStringBuilderConstructorIfNeded(true)
|
||||||
v.swap()
|
genInvokeAppendMethod(generator, returnType, null)
|
||||||
genInvokeAppendMethod(v, returnType, null)
|
codegen.invokeAppend(generator, arguments[0])
|
||||||
codegen.invokeAppend(v, arguments[0])
|
|
||||||
}
|
}
|
||||||
|
generator.genToString()
|
||||||
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
|
|
||||||
return JAVA_STRING_TYPE
|
return JAVA_STRING_TYPE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable =
|
override fun toCallable(method: CallableMethod): Callable =
|
||||||
object : IntrinsicCallable(method) {
|
object : IntrinsicCallable(method) {
|
||||||
|
lateinit var generator: StringAppendGenerator
|
||||||
override fun invokeMethodWithArguments(
|
override fun invokeMethodWithArguments(
|
||||||
resolvedCall: ResolvedCall<*>,
|
resolvedCall: ResolvedCall<*>,
|
||||||
receiver: StackValue,
|
receiver: StackValue,
|
||||||
@@ -81,9 +82,14 @@ class Concat : IntrinsicMethod() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap) {
|
override fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap, state: GenerationState) {
|
||||||
v.generateNewInstanceDupAndPlaceBeforeStackTop(frameMap, AsmTypes.JAVA_STRING_TYPE, "java/lang/StringBuilder")
|
generator = StringAppendGenerator.create(state, v)
|
||||||
v.invokespecial("java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false)
|
if (!generator.useInvokeDynamic) {
|
||||||
|
v.generateNewInstanceDupAndPlaceBeforeStackTop(frameMap, JAVA_STRING_TYPE, "java/lang/StringBuilder")
|
||||||
|
v.invokespecial("java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false)
|
||||||
|
} else {
|
||||||
|
generator.invokeAppend(JAVA_STRING_TYPE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
@@ -91,8 +97,8 @@ class Concat : IntrinsicMethod() {
|
|||||||
// in case of callable reference passed to a generic function, e.g.:
|
// in case of callable reference passed to a generic function, e.g.:
|
||||||
// charArrayOf('O', 'K').fold("", String::plus)
|
// charArrayOf('O', 'K').fold("", String::plus)
|
||||||
// TODO Make String::plus generic, and invoke proper StringBuilder#append.
|
// TODO Make String::plus generic, and invoke proper StringBuilder#append.
|
||||||
genInvokeAppendMethod(v, AsmTypes.OBJECT_TYPE, null)
|
generator.invokeAppend(AsmTypes.OBJECT_TYPE)
|
||||||
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
|
generator.genToString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.codegen.Callable
|
|||||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||||
import org.jetbrains.kotlin.codegen.FrameMap
|
import org.jetbrains.kotlin.codegen.FrameMap
|
||||||
import org.jetbrains.kotlin.codegen.generateNewInstanceDupAndPlaceBeforeStackTop
|
import org.jetbrains.kotlin.codegen.generateNewInstanceDupAndPlaceBeforeStackTop
|
||||||
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.Type.*
|
import org.jetbrains.org.objectweb.asm.Type.*
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
@@ -48,7 +49,7 @@ class RangeTo : IntrinsicMethod() {
|
|||||||
nullOr(method.dispatchReceiverType, argType),
|
nullOr(method.dispatchReceiverType, argType),
|
||||||
nullOr(method.extensionReceiverType, argType)
|
nullOr(method.extensionReceiverType, argType)
|
||||||
) {
|
) {
|
||||||
override fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap) {
|
override fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap, state: GenerationState) {
|
||||||
v.generateNewInstanceDupAndPlaceBeforeStackTop(frameMap, argType, returnType.internalName)
|
v.generateNewInstanceDupAndPlaceBeforeStackTop(frameMap, argType, returnType.internalName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user