提交 8a927d70 编写于 作者: A Alex Tkachman

array codegen bugs

上级 a06aa17a
package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.objectweb.asm.Type;
/**
* @author abreslav
......@@ -54,4 +53,8 @@ public class CodegenUtil {
}
return (ClassDescriptor) outerDescriptor;
}
public static Type arrayElementType(Type type) {
return Type.getType(type.getDescriptor().substring(1));
}
}
......@@ -378,8 +378,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
gen(expression.getLoopRange(), loopRangeType); // array
v.load(myIndexVar, Type.INT_TYPE);
v.aload(loopRangeType.getElementType());
StackValue.onStack(loopRangeType.getElementType()).put(asmParamType, v);
v.aload(CodegenUtil.arrayElementType(loopRangeType));
StackValue.onStack(CodegenUtil.arrayElementType(loopRangeType)).put(asmParamType, v);
v.store(lookupLocal(parameterDescriptor), asmParamType);
}
......@@ -1683,12 +1683,23 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
private void generateNewArray(JetCallExpression expression, Type type) {
JetType arrayType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
List<? extends ValueArgument> args = expression.getValueArguments();
if (args.size() != 1) {
throw new CompilationException("array constructor requires one value argument");
}
gen(args.get(0).getArgumentExpression(), Type.INT_TYPE);
v.newarray(type.getElementType());
JetType elementType = typeMapper.getGenericsElementType(arrayType);
if(elementType != null) {
generateTypeInfo(elementType);
v.invokestatic("jet/typeinfo/TypeInfo", "newArray", "(ILjet/typeinfo/TypeInfo;)[Ljava/lang/Object;");
v.checkcast(type);
}
else {
v.newarray(CodegenUtil.arrayElementType(type));
}
}
@Override
......@@ -1698,7 +1709,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
gen(array, arrayType);
generateArrayIndex(expression);
if (arrayType.getSort() == Type.ARRAY) {
final Type elementType = arrayType.getElementType();
final Type elementType = CodegenUtil.arrayElementType(arrayType);
return StackValue.arrayElement(elementType);
}
else {
......
......@@ -670,4 +670,20 @@ public class JetTypeMapper {
public String isKnownTypeInfo(JetType jetType) {
return knowTypes.get(jetType);
}
public boolean isGenericsArray(JetType type) {
DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
if(declarationDescriptor instanceof TypeParameterDescriptor)
return true;
if(standardLibrary.getArray().equals(declarationDescriptor))
return isGenericsArray(type.getArguments().get(0).getType());
return false;
}
public JetType getGenericsElementType(JetType arrayType) {
JetType type = arrayType.getArguments().get(0).getType();
return isGenericsArray(type) ? type : null;
}
}
......@@ -152,7 +152,7 @@ public class NamespaceCodegen {
v.aconst(jvmType);
v.iconst(jetType.isNullable() ? 1 : 0);
List<TypeProjection> arguments = jetType.getArguments();
if (arguments.size() > 0) {
if (arguments.size() > 0 && !(jvmType.getSort() == Type.ARRAY && jvmType.getElementType().getSort() != Type.OBJECT)) {
v.iconst(arguments.size());
v.newarray(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
......
......@@ -186,7 +186,7 @@ public abstract class StackValue {
else
v.iconst(0);
}
else if (type.getSort() == Type.OBJECT && this.type.equals(JetTypeMapper.TYPE_OBJECT)) {
else if (type.getSort() == Type.OBJECT && this.type.equals(JetTypeMapper.TYPE_OBJECT) || type.getSort() == Type.ARRAY) {
v.checkcast(type);
}
else if (type.getSort() == Type.OBJECT) {
......@@ -431,6 +431,7 @@ public abstract class StackValue {
@Override
public void put(Type type, InstructionAdapter v) {
v.aload(type); // assumes array and index are on the stack
coerce(type, v);
}
@Override
......
namespace test
class List<T>() {
val a : Array<T> = Array<T>(1)
}
fun box() : String {
val a = List<String>()
a.a[0] = "1"
println(a.a[0])
val b = List<Int?>()
b.a[0] = 10
println(b.a[0])
val c = List<Array<Int>>()
c.a[0] = Array<Int>(4)
println(c.a[0].size)
return "OK"
}
fun println(s : Any?) {
System.out?.println(s);
}
package org.jetbrains.jet.codegen;
import java.lang.reflect.Method;
public class ArrayGenTest extends CodegenTestCase {
public void testKt238 () throws Exception {
blackBoxFile("regressions/kt238.jet");
}
public void testKt326 () throws Exception {
blackBoxFile("regressions/kt326.jet");
}
public void testCreateMultiInt () throws Exception {
loadText("fun foo() = Array<Array<Int>> (5)");
Method foo = generateFunction();
Object invoke = foo.invoke(null);
System.out.println(invoke.getClass());
assertTrue(invoke instanceof int[][]);
}
public void testCreateMultiString () throws Exception {
loadText("fun foo() = Array<Array<String>> (5)");
Method foo = generateFunction();
Object invoke = foo.invoke(null);
System.out.println(invoke.getClass());
assertTrue(invoke instanceof String[][]);
}
public void testCreateMultiGenerics () throws Exception {
/*
loadText("class L<T>() { val a = Array<T>(5) } fun foo() = L<Int>.a");
System.out.println(generateToText());
Method foo = generateFunction();
Object invoke = foo.invoke(null);
System.out.println(invoke.getClass());
assertTrue(invoke instanceof Integer[]);
*/
}
public void testIntGenerics () throws Exception {
loadText("class L<T>(var a : T) {} fun foo() = L<Int>(5).a");
System.out.println(generateToText());
Method foo = generateFunction();
Object invoke = foo.invoke(null);
System.out.println(invoke.getClass());
assertTrue(invoke instanceof Integer);
}
}
package org.jetbrains.jet.codegen;
public class ArrayGenTestCase extends CodegenTestCase {
public void testKt238 () throws Exception {
blackBoxFile("regressions/kt238.jet");
}
}
......@@ -3,6 +3,7 @@ package jet.typeinfo;
import jet.JetObject;
import jet.Tuple0;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.TypeVariable;
import java.util.*;
......@@ -37,6 +38,10 @@ public abstract class TypeInfo<T> implements JetObject {
public static final TypeInfo<Double> NULLABLE_DOUBLE_TYPE_INFO = getTypeInfo(Double.class, true);
public static final TypeInfo<String> NULLABLE_STRING_TYPE_INFO = getTypeInfo(String.class, true);
public static final TypeInfo<Tuple0> NULLABLE_TUPLE0_TYPE_INFO = getTypeInfo(Tuple0.class, true);
public static Object [] newArray(int length, TypeInfo typeInfo) {
return (Object[]) Array.newInstance(((TypeInfoImpl) typeInfo).signature.klazz, length);
}
public static <T> TypeInfoProjection invariantProjection(final TypeInfo<T> typeInfo) {
return (TypeInfoProjection) typeInfo;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册