fix KT-6192: VerifyError when using spreads with primitive arrays
#KT-6192 Fixed
This commit is contained in:
@@ -45,6 +45,7 @@ import org.jetbrains.jet.lang.types.Approximation;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypesPackage;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
@@ -159,6 +160,12 @@ public class AsmUtil {
|
||||
return Type.getType(internalName.substring(1));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PrimitiveType asmPrimitiveTypeToLangPrimitiveType(Type type) {
|
||||
JvmPrimitiveType jvmPrimitiveType = primitiveTypeByAsmSort.get(type.getSort());
|
||||
return jvmPrimitiveType != null ? jvmPrimitiveType.getPrimitiveType() : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Method method(@NotNull String name, @NotNull Type returnType, @NotNull Type... parameterTypes) {
|
||||
return new Method(name, Type.getMethodDescriptor(returnType, parameterTypes));
|
||||
|
||||
@@ -2524,10 +2524,25 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
gen(arguments.get(0).getArgumentExpression(), type);
|
||||
}
|
||||
else {
|
||||
String owner = "kotlin/jvm/internal/SpreadBuilder";
|
||||
String owner;
|
||||
String addDescriptor;
|
||||
String toArrayDescriptor;
|
||||
boolean arrayOfReferences = KotlinBuiltIns.isArray(outType);
|
||||
if (arrayOfReferences) {
|
||||
owner = "kotlin/jvm/internal/SpreadBuilder";
|
||||
addDescriptor = "(Ljava/lang/Object;)V";
|
||||
toArrayDescriptor = "([Ljava/lang/Object;)[Ljava/lang/Object;";
|
||||
}
|
||||
else {
|
||||
String spreadBuilderClassName = AsmUtil.asmPrimitiveTypeToLangPrimitiveType(elementType).getTypeName().getIdentifier() + "SpreadBuilder";
|
||||
owner = "kotlin/jvm/internal/" + spreadBuilderClassName;
|
||||
addDescriptor = "(" + elementType.getDescriptor() + ")V";
|
||||
toArrayDescriptor = "()" + type.getDescriptor();
|
||||
}
|
||||
v.anew(Type.getObjectType(owner));
|
||||
v.dup();
|
||||
v.invokespecial(owner, "<init>", "()V", false);
|
||||
v.iconst(size);
|
||||
v.invokespecial(owner, "<init>", "(I)V", false);
|
||||
for (int i = 0; i != size; ++i) {
|
||||
v.dup();
|
||||
ValueArgument argument = arguments.get(i);
|
||||
@@ -2537,15 +2552,19 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
else {
|
||||
gen(argument.getArgumentExpression(), elementType);
|
||||
v.invokevirtual(owner, "add", "(Ljava/lang/Object;)Z", false);
|
||||
v.pop();
|
||||
v.invokevirtual(owner, "add", addDescriptor, false);
|
||||
}
|
||||
}
|
||||
v.dup();
|
||||
v.invokevirtual(owner, "size", "()I", false);
|
||||
newArrayInstruction(outType);
|
||||
v.invokevirtual(owner, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", false);
|
||||
v.checkcast(type);
|
||||
if (arrayOfReferences) {
|
||||
v.dup();
|
||||
v.invokevirtual(owner, "size", "()I", false);
|
||||
newArrayInstruction(outType);
|
||||
v.invokevirtual(owner, "toArray", toArrayDescriptor, false);
|
||||
v.checkcast(type);
|
||||
}
|
||||
else {
|
||||
v.invokevirtual(owner, "toArray", toArrayDescriptor, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
@@ -1229,24 +1230,12 @@ public abstract class StackValue {
|
||||
case Type.OBJECT:
|
||||
case Type.ARRAY:
|
||||
return OBJECT_REF_TYPE;
|
||||
case Type.BYTE:
|
||||
return Type.getObjectType("kotlin/jvm/internal/Ref$ByteRef");
|
||||
case Type.SHORT:
|
||||
return Type.getObjectType("kotlin/jvm/internal/Ref$ShortRef");
|
||||
case Type.CHAR:
|
||||
return Type.getObjectType("kotlin/jvm/internal/Ref$CharRef");
|
||||
case Type.INT:
|
||||
return Type.getObjectType("kotlin/jvm/internal/Ref$IntRef");
|
||||
case Type.LONG:
|
||||
return Type.getObjectType("kotlin/jvm/internal/Ref$LongRef");
|
||||
case Type.BOOLEAN:
|
||||
return Type.getObjectType("kotlin/jvm/internal/Ref$BooleanRef");
|
||||
case Type.FLOAT:
|
||||
return Type.getObjectType("kotlin/jvm/internal/Ref$FloatRef");
|
||||
case Type.DOUBLE:
|
||||
return Type.getObjectType("kotlin/jvm/internal/Ref$DoubleRef");
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
PrimitiveType primitiveType = AsmUtil.asmPrimitiveTypeToLangPrimitiveType(type);
|
||||
if (primitiveType == null) throw new UnsupportedOperationException();
|
||||
|
||||
String typeName = primitiveType.getTypeName().getIdentifier();
|
||||
return Type.getObjectType("kotlin/jvm/internal/Ref$" + typeName + "Ref");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user