array code gen rewrite and work in progress on outer type info
This commit is contained in:
@@ -45,9 +45,4 @@ public class ClassCodegen {
|
||||
}
|
||||
|
||||
|
||||
public static void newTypeInfo(InstructionAdapter v, boolean isNullable, Type asmType) {
|
||||
v.aconst(asmType);
|
||||
v.iconst(isNullable?1:0);
|
||||
v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
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.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||
import org.objectweb.asm.Type;
|
||||
@@ -43,7 +46,7 @@ public class CodegenUtil {
|
||||
return getOuterClassDescriptor(classDescriptor) != null && !isClassObject(classDescriptor);
|
||||
}
|
||||
|
||||
public static ClassDescriptor getOuterClassDescriptor(ClassDescriptor descriptor) {
|
||||
public static ClassDescriptor getOuterClassDescriptor(DeclarationDescriptor descriptor) {
|
||||
DeclarationDescriptor outerDescriptor = descriptor.getContainingDeclaration();
|
||||
while(outerDescriptor != null) {
|
||||
if(outerDescriptor instanceof ClassDescriptor)
|
||||
@@ -54,6 +57,48 @@ public class CodegenUtil {
|
||||
return (ClassDescriptor) outerDescriptor;
|
||||
}
|
||||
|
||||
public static boolean hasOuterTypeInfo(ClassDescriptor descriptor) {
|
||||
ClassDescriptor outerClassDescriptor = getOuterClassDescriptor(descriptor);
|
||||
if(outerClassDescriptor == null)
|
||||
return false;
|
||||
|
||||
if(outerClassDescriptor.getTypeConstructor().getParameters().size() > 0)
|
||||
return true;
|
||||
|
||||
return hasOuterTypeInfo(outerClassDescriptor);
|
||||
}
|
||||
|
||||
public static boolean hasTypeInfoField(JetType type) {
|
||||
if(type.getConstructor().getParameters().size() > 0)
|
||||
return true;
|
||||
|
||||
for (JetType jetType : type.getConstructor().getSupertypes()) {
|
||||
if(hasTypeInfoField(jetType))
|
||||
return true;
|
||||
}
|
||||
|
||||
ClassDescriptor outerClassDescriptor = getOuterClassDescriptor(type.getConstructor().getDeclarationDescriptor());
|
||||
if(outerClassDescriptor == null)
|
||||
return false;
|
||||
|
||||
return hasTypeInfoField(outerClassDescriptor.getDefaultType());
|
||||
}
|
||||
|
||||
public static boolean hasDerivedTypeInfoField(JetType type, boolean exceptOwn) {
|
||||
if(!exceptOwn) {
|
||||
if(!isInterface(type))
|
||||
if(hasTypeInfoField(type))
|
||||
return true;
|
||||
}
|
||||
|
||||
for (JetType jetType : type.getConstructor().getSupertypes()) {
|
||||
if(hasDerivedTypeInfoField(jetType, false))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Type arrayElementType(Type type) {
|
||||
return Type.getType(type.getDescriptor().substring(1));
|
||||
}
|
||||
|
||||
@@ -17,11 +17,9 @@ public class ConstructorFrameMap extends FrameMap {
|
||||
private int myFirstTypeParameter = -1;
|
||||
private int myTypeParameterCount = 0;
|
||||
|
||||
public ConstructorFrameMap(CallableMethod callableMethod, @Nullable ConstructorDescriptor descriptor, OwnerKind kind) {
|
||||
public ConstructorFrameMap(CallableMethod callableMethod, @Nullable ConstructorDescriptor descriptor, ClassDescriptor classDescriptor, OwnerKind kind) {
|
||||
enterTemp(); // this
|
||||
ClassDescriptor classDescriptor = null;
|
||||
if (descriptor != null) {
|
||||
classDescriptor = descriptor.getContainingDeclaration();
|
||||
if (CodegenUtil.hasThis0(classDescriptor)) {
|
||||
myOuterThisIndex = enterTemp(); // outer class instance
|
||||
}
|
||||
@@ -37,7 +35,6 @@ public class ConstructorFrameMap extends FrameMap {
|
||||
enter(parameter, explicitArgTypes.get(i).getSize());
|
||||
}
|
||||
|
||||
|
||||
if (classDescriptor != null) {
|
||||
myTypeParameterCount = classDescriptor.getTypeConstructor().getParameters().size();
|
||||
if (kind == OwnerKind.IMPLEMENTATION) {
|
||||
|
||||
@@ -200,7 +200,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
final JetExpression loopRange = expression.getLoopRange();
|
||||
final JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, loopRange);
|
||||
Type loopRangeType = typeMapper.mapType(expressionType);
|
||||
if (loopRangeType.getSort() == Type.ARRAY) {
|
||||
if (state.getStandardLibrary().getArray().equals(expressionType.getConstructor().getDeclarationDescriptor())) {
|
||||
new ForInArrayLoopGenerator(expression, loopRangeType).invoke();
|
||||
return StackValue.none();
|
||||
}
|
||||
@@ -364,6 +364,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
protected void generatePrologue() {
|
||||
myLengthVar = myMap.enterTemp();
|
||||
gen(expression.getLoopRange(), loopRangeType);
|
||||
derefArray(bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getLoopRange()));
|
||||
v.arraylength();
|
||||
v.store(myLengthVar, Type.INT_TYPE);
|
||||
myIndexVar = myMap.enterTemp();
|
||||
@@ -377,9 +378,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
v.ificmpge(end);
|
||||
|
||||
gen(expression.getLoopRange(), loopRangeType); // array
|
||||
derefArray(bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getLoopRange()));
|
||||
v.load(myIndexVar, Type.INT_TYPE);
|
||||
v.aload(CodegenUtil.arrayElementType(loopRangeType));
|
||||
StackValue.onStack(CodegenUtil.arrayElementType(loopRangeType)).put(asmParamType, v);
|
||||
v.aload(asmParamType);
|
||||
StackValue.onStack(asmParamType).put(asmParamType, v);
|
||||
v.store(lookupLocal(parameterDescriptor), asmParamType);
|
||||
}
|
||||
|
||||
@@ -1622,9 +1624,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
else if (constructorDescriptor instanceof ConstructorDescriptor) {
|
||||
//noinspection ConstantConditions
|
||||
type = typeMapper.mapType(bindingContext.get(BindingContext.EXPRESSION_TYPE, expression), OwnerKind.IMPLEMENTATION);
|
||||
if (type.getSort() == Type.ARRAY) {
|
||||
generateNewArray(expression, type);
|
||||
JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
|
||||
type = typeMapper.mapType(expressionType, OwnerKind.IMPLEMENTATION);
|
||||
if (state.getStandardLibrary().getArray().equals(expressionType.getConstructor().getDeclarationDescriptor())) {
|
||||
generateNewArray(expression, expressionType);
|
||||
}
|
||||
else {
|
||||
ClassDescriptor classDecl = (ClassDescriptor) constructorDescriptor.getContainingDeclaration();
|
||||
@@ -1682,9 +1685,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return type;
|
||||
}
|
||||
|
||||
private void generateNewArray(JetCallExpression expression, Type type) {
|
||||
JetType arrayType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
|
||||
|
||||
private void generateNewArray(JetCallExpression expression, JetType arrayType) {
|
||||
List<? extends ValueArgument> args = expression.getValueArguments();
|
||||
if (args.size() != 1) {
|
||||
throw new CompilationException("array constructor requires one value argument");
|
||||
@@ -1694,23 +1695,53 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
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);
|
||||
v.invokestatic("jet/arrays/JetArray", "newArray", "(ILjet/typeinfo/TypeInfo;)Ljet/arrays/JetArray;");
|
||||
}
|
||||
else {
|
||||
v.newarray(CodegenUtil.arrayElementType(type));
|
||||
elementType = arrayType.getArguments().get(0).getType();
|
||||
JetStandardLibrary standardLibrary = state.getStandardLibrary();
|
||||
if (elementType.equals(standardLibrary.getIntType())) {
|
||||
v.invokestatic("jet/arrays/JetArray", "newIntArray", "(I)Ljet/arrays/JetIntArray;");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getLongType())) {
|
||||
v.invokestatic("jet/arrays/JetArray", "newLongArray", "(I)Ljet/arrays/JetLongArray;");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getShortType())) {
|
||||
v.invokestatic("jet/arrays/JetArray", "newShortArray", "(I)Ljet/arrays/JetShortArray;");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getByteType())) {
|
||||
v.invokestatic("jet/arrays/JetArray", "newByteArray", "(I)Ljet/arrays/JetByteArray;");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getCharType())) {
|
||||
v.invokestatic("jet/arrays/JetArray", "newCharArray", "(I)Ljet/arrays/JetCharArray;");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getFloatType())) {
|
||||
v.invokestatic("jet/arrays/JetArray", "newFloatArray", "(I)Ljet/arrays/JetFloatArray;");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getDoubleType())) {
|
||||
v.invokestatic("jet/arrays/JetArray", "newDoubleArray", "(I)Ljet/arrays/JetDoubleArray;");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getBooleanType())) {
|
||||
v.invokestatic("jet/arrays/JetArray", "newBoolArray", "(I)Ljet/arrays/JetBoolArray;");
|
||||
}
|
||||
else {
|
||||
generateTypeInfo(elementType);
|
||||
v.invokestatic("jet/arrays/JetArray", "newGenericArray", "(ILjet/typeinfo/TypeInfo;)Ljet/arrays/JetGenericArray;");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitArrayAccessExpression(JetArrayAccessExpression expression, StackValue receiver) {
|
||||
final JetExpression array = expression.getArrayExpression();
|
||||
final Type arrayType = expressionType(array);
|
||||
JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, array);
|
||||
final Type arrayType = type == null ? Type.VOID_TYPE : typeMapper.mapType(type);
|
||||
gen(array, arrayType);
|
||||
derefArray(type);
|
||||
generateArrayIndex(expression);
|
||||
if (arrayType.getSort() == Type.ARRAY) {
|
||||
final Type elementType = CodegenUtil.arrayElementType(arrayType);
|
||||
return StackValue.arrayElement(elementType);
|
||||
if (state.getStandardLibrary().getArray().equals(type.getConstructor().getDeclarationDescriptor())) {
|
||||
JetType elementType = type.getArguments().get(0).getType();
|
||||
return StackValue.arrayElement(typeMapper.mapType(elementType), typeMapper.isGenericsArray(type));
|
||||
}
|
||||
else {
|
||||
final PsiElement declaration = BindingContextUtils.resolveToDeclarationPsiElement(bindingContext, expression);
|
||||
@@ -1733,6 +1764,46 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
}
|
||||
|
||||
public void derefArray(JetType type) {
|
||||
if (state.getStandardLibrary().getArray().equals(type.getConstructor().getDeclarationDescriptor())) {
|
||||
JetType elementType = type.getArguments().get(0).getType();
|
||||
JetStandardLibrary standardLibrary = state.getStandardLibrary();
|
||||
if (elementType.equals(standardLibrary.getIntType())) {
|
||||
v.getfield("jet/arrays/JetIntArray", "array", "[I");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getLongType())) {
|
||||
v.getfield("jet/arrays/JetLongArray", "array", "[J");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getShortType())) {
|
||||
v.getfield("jet/arrays/JetShortArray", "array", "[S");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getByteType())) {
|
||||
v.getfield("jet/arrays/JetByteArray", "array", "[B");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getCharType())) {
|
||||
v.getfield("jet/arrays/JetCharArray", "array", "[C");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getFloatType())) {
|
||||
v.getfield("jet/arrays/JetFloatArray", "array", "[F");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getDoubleType())) {
|
||||
v.getfield("jet/arrays/JetDoubleArray", "array", "[D");
|
||||
}
|
||||
else if (elementType.equals(standardLibrary.getBooleanType())) {
|
||||
v.getfield("jet/arrays/JetBooleanArray", "array", "[Z");
|
||||
}
|
||||
else {
|
||||
if(typeMapper.isGenericsArray(type)) {
|
||||
v.visitTypeInsn(Opcodes.CHECKCAST, "jet/arrays/JetArray");
|
||||
}
|
||||
else {
|
||||
v.getfield("jet/arrays/JetGenericArray", "array", "[Ljava/lang/Object;");
|
||||
v.visitTypeInsn(Opcodes.CHECKCAST, "[" + typeMapper.mapType(elementType).getDescriptor());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateArrayIndex(JetArrayAccessExpression expression) {
|
||||
final List<JetExpression> indices = expression.getIndexExpressions();
|
||||
for (JetExpression index : indices) {
|
||||
@@ -1989,9 +2060,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return;
|
||||
}
|
||||
|
||||
if(jetType.getArguments().size() == 0 && !(declarationDescriptor instanceof JavaClassDescriptor)) {
|
||||
if(!CodegenUtil.hasTypeInfoField(jetType)) {
|
||||
// TODO: we need some better checks here
|
||||
v.getstatic(typeMapper.mapType(jetType, OwnerKind.IMPLEMENTATION).getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
v.getstatic(typeMapper.mapType(jetType, OwnerKind.IMPLEMENTATION).getInternalName(), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2044,23 +2115,33 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return;
|
||||
}
|
||||
DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration();
|
||||
if (containingDeclaration == contextType() && contextType() instanceof ClassDescriptor) {
|
||||
if (contextType() instanceof ClassDescriptor) {
|
||||
ClassDescriptor descriptor = (ClassDescriptor) contextType();
|
||||
JetType defaultType = descriptor.getDefaultType();
|
||||
JetType defaultType = ((ClassDescriptor)containingDeclaration).getDefaultType();
|
||||
Type ownerType = typeMapper.mapType(defaultType);
|
||||
ownerType = JetTypeMapper.boxType(ownerType);
|
||||
if(!CodegenUtil.isInterface(descriptor)) {
|
||||
if (descriptor.getTypeConstructor().getParameters().size() > 0) {
|
||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
v.getfield(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
if (containingDeclaration == contextType()) {
|
||||
if(!CodegenUtil.isInterface(descriptor)) {
|
||||
if (CodegenUtil.hasTypeInfoField(defaultType)) {
|
||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
v.getfield(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
else {
|
||||
v.getstatic(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
}
|
||||
else {
|
||||
v.getstatic(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
v.invokeinterface("jet/JetObject", "getTypeInfo", "()Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
}
|
||||
else {
|
||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
v.invokeinterface("jet/JetObject", "getTypeInfo", "()Ljet/typeinfo/TypeInfo;");
|
||||
while(descriptor != containingDeclaration) {
|
||||
descriptor = CodegenUtil.getOuterClassDescriptor(descriptor);
|
||||
v.invokevirtual("jet/typeinfo/TypeInfo", "getOuterTypeInfo", "()Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
}
|
||||
v.aconst(ownerType);
|
||||
v.iconst(typeParameterDescriptor.getIndex());
|
||||
|
||||
@@ -8,7 +8,6 @@ import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.OverridingUtil;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
@@ -99,6 +98,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
);
|
||||
v.visitSource(myClass.getContainingFile().getName(), null);
|
||||
|
||||
if(descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||
v.visitOuterClass(state.getTypeMapper().jvmType((ClassDescriptor) descriptor.getContainingDeclaration(), OwnerKind.IMPLEMENTATION).getInternalName(), null, null);
|
||||
}
|
||||
|
||||
if(myClass instanceof JetClass) {
|
||||
AnnotationVisitor annotationVisitor = v.visitAnnotation("Ljet/typeinfo/JetSignature;", true);
|
||||
annotationVisitor.visit("value", SignatureUtil.classToSignature((JetClass)myClass, state.getBindingContext(), state.getTypeMapper()));
|
||||
@@ -205,7 +208,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
Method method;
|
||||
CallableMethod callableMethod;
|
||||
if (constructorDescriptor == null) {
|
||||
method = new Method("<init>", Type.VOID_TYPE, new Type[0]);
|
||||
List<Type> parameterTypes = new ArrayList<Type>();
|
||||
if (CodegenUtil.hasThis0(descriptor)) {
|
||||
parameterTypes.add(state.getTypeMapper().jvmType(CodegenUtil.getOuterClassDescriptor(descriptor), OwnerKind.IMPLEMENTATION));
|
||||
}
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeConstructor().getParameters();
|
||||
for (int n = typeParameters.size(); n > 0; n--) {
|
||||
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO);
|
||||
}
|
||||
|
||||
method = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
callableMethod = new CallableMethod("", method, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList());
|
||||
}
|
||||
else {
|
||||
@@ -220,13 +233,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
? constructorDescriptor.getValueParameters()
|
||||
: Collections.<ValueParameterDescriptor>emptyList();
|
||||
|
||||
ConstructorFrameMap frameMap = new ConstructorFrameMap(callableMethod, constructorDescriptor, kind);
|
||||
ConstructorFrameMap frameMap = new ConstructorFrameMap(callableMethod, constructorDescriptor, descriptor, kind);
|
||||
|
||||
final InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state);
|
||||
|
||||
for(int slot = 0; slot != frameMap.getTypeParameterCount(); ++slot) {
|
||||
codegen.addTypeParameter(constructorDescriptor.getTypeParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO));
|
||||
if(constructorDescriptor != null)
|
||||
codegen.addTypeParameter(constructorDescriptor.getTypeParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO));
|
||||
else
|
||||
codegen.addTypeParameter(descriptor.getTypeConstructor().getParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO));
|
||||
}
|
||||
|
||||
String classname = state.getTypeMapper().jvmName(descriptor, kind);
|
||||
@@ -241,7 +257,24 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
if (superCall == null || superCall instanceof JetDelegatorToSuperClass) {
|
||||
iv.load(0, Type.getType("L" + superClass + ";"));
|
||||
iv.invokespecial(superClass, "<init>", "()V");
|
||||
if(superCall == null) {
|
||||
iv.invokespecial(superClass, "<init>", "()V");
|
||||
}
|
||||
else {
|
||||
JetType superType = state.getBindingContext().get(BindingContext.TYPE, superCall.getTypeReference());
|
||||
List<Type> parameterTypes = new ArrayList<Type>();
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
if (CodegenUtil.hasThis0(superClassDescriptor)) {
|
||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
||||
parameterTypes.add(state.getTypeMapper().jvmType(CodegenUtil.getOuterClassDescriptor(descriptor), OwnerKind.IMPLEMENTATION));
|
||||
}
|
||||
for(TypeProjection typeParameterDescriptor : superType.getArguments()) {
|
||||
codegen.generateTypeInfo(typeParameterDescriptor.getType());
|
||||
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO);
|
||||
}
|
||||
Method superCallMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
iv.invokespecial(state.getTypeMapper().jvmName(superClassDescriptor, OwnerKind.IMPLEMENTATION), "<init>", superCallMethod.getDescriptor());
|
||||
}
|
||||
}
|
||||
else {
|
||||
iv.load(0, classType);
|
||||
@@ -285,7 +318,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.putfield(classname, fieldName, interfaceDesc);
|
||||
}
|
||||
|
||||
if (frameMap.getFirstTypeParameter() > 0 && kind == OwnerKind.IMPLEMENTATION) {
|
||||
if (CodegenUtil.hasTypeInfoField(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) {
|
||||
generateTypeInfoInitializer(frameMap.getFirstTypeParameter(), frameMap.getTypeParameterCount(), iv);
|
||||
}
|
||||
|
||||
@@ -473,7 +506,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
final MethodVisitor mv = v.visitMethod(flags, "<init>", method.getSignature().getDescriptor(), null, null);
|
||||
mv.visitCode();
|
||||
|
||||
ConstructorFrameMap frameMap = new ConstructorFrameMap(method, constructorDescriptor, kind);
|
||||
ConstructorFrameMap frameMap = new ConstructorFrameMap(method, constructorDescriptor, descriptor, kind);
|
||||
|
||||
final InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state);
|
||||
@@ -507,17 +540,38 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
iv.aconst(state.getTypeMapper().jvmType(descriptor, OwnerKind.IMPLEMENTATION));
|
||||
iv.iconst(0);
|
||||
iv.iconst(typeParamCount);
|
||||
iv.newarray(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
|
||||
|
||||
for (int i = 0; i < typeParamCount; i++) {
|
||||
iv.dup();
|
||||
iv.iconst(i);
|
||||
iv.load(firstTypeParameter + i, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.checkcast(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
|
||||
iv.astore(JetTypeMapper.TYPE_OBJECT);
|
||||
if(CodegenUtil.hasOuterTypeInfo(descriptor)) {
|
||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.invokeinterface("jet/JetObject", "getTypeInfo", "()Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z[Ljet/typeinfo/TypeInfoProjection;)Ljet/typeinfo/TypeInfo;");
|
||||
|
||||
if(typeParamCount != 0) {
|
||||
iv.iconst(typeParamCount);
|
||||
iv.newarray(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
|
||||
|
||||
for (int i = 0; i < typeParamCount; i++) {
|
||||
iv.dup();
|
||||
iv.iconst(i);
|
||||
iv.load(firstTypeParameter + i, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.checkcast(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
|
||||
iv.astore(JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
|
||||
if(CodegenUtil.hasOuterTypeInfo(descriptor)) {
|
||||
iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;ZLjet/typeinfo/TypeInfo;[Ljet/typeinfo/TypeInfoProjection;)Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
else
|
||||
iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z[Ljet/typeinfo/TypeInfoProjection;)Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
else {
|
||||
if(CodegenUtil.hasOuterTypeInfo(descriptor)) {
|
||||
iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;ZLjet/typeinfo/TypeInfo;)Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
else
|
||||
iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
|
||||
iv.invokevirtual(state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V");
|
||||
}
|
||||
|
||||
@@ -617,8 +671,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
return;
|
||||
|
||||
JetType defaultType = descriptor.getDefaultType();
|
||||
if(isParametrizedClass(defaultType)) {
|
||||
if(!hasDerivedTypeInfoField(defaultType, true)) {
|
||||
if(CodegenUtil.hasTypeInfoField(defaultType)) {
|
||||
if(!CodegenUtil.hasDerivedTypeInfoField(defaultType, true)) {
|
||||
v.visitField(Opcodes.ACC_PRIVATE, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null);
|
||||
|
||||
MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null);
|
||||
@@ -642,51 +696,45 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
}
|
||||
else {
|
||||
if(descriptor.getTypeConstructor().getParameters().isEmpty()) {
|
||||
v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null);
|
||||
staticInitializerChunks.add(new CodeChunk() {
|
||||
@Override
|
||||
public void generate(InstructionAdapter v) {
|
||||
JetTypeMapper typeMapper = state.getTypeMapper();
|
||||
ClassCodegen.newTypeInfo(v, false, typeMapper.jvmType(descriptor, OwnerKind.IMPLEMENTATION));
|
||||
v.putstatic(typeMapper.jvmName(descriptor, kind), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
});
|
||||
|
||||
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null);
|
||||
mv.visitCode();
|
||||
InstructionAdapter v = new InstructionAdapter(mv);
|
||||
String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
||||
v.getstatic(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
v.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null);
|
||||
staticInitializerChunks.add(new CodeChunk() {
|
||||
@Override
|
||||
public void generate(InstructionAdapter v) {
|
||||
JetTypeMapper typeMapper = state.getTypeMapper();
|
||||
ClassCodegen.newTypeInfo(v, false, typeMapper.jvmType(descriptor, OwnerKind.IMPLEMENTATION));
|
||||
v.putstatic(typeMapper.jvmName(descriptor, kind), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
});
|
||||
|
||||
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null);
|
||||
mv.visitCode();
|
||||
InstructionAdapter v = new InstructionAdapter(mv);
|
||||
String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
||||
v.getstatic(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
v.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
genGetStaticGetTypeInfoMethod();
|
||||
staticTypeInfoField();
|
||||
}
|
||||
}
|
||||
|
||||
private void genGetStaticGetTypeInfoMethod() {
|
||||
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null);
|
||||
mv.visitCode();
|
||||
InstructionAdapter v = new InstructionAdapter(mv);
|
||||
String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
||||
v.getstatic(owner, "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
v.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
private void staticTypeInfoField() {
|
||||
v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC, "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;", null, null);
|
||||
staticInitializerChunks.add(new CodeChunk() {
|
||||
@Override
|
||||
public void generate(InstructionAdapter v) {
|
||||
JetTypeMapper typeMapper = state.getTypeMapper();
|
||||
v.aconst(typeMapper.jvmType(descriptor, OwnerKind.IMPLEMENTATION));
|
||||
v.iconst(0);
|
||||
ClassDescriptor outerClassDescriptor = CodegenUtil.getOuterClassDescriptor(descriptor);
|
||||
if(outerClassDescriptor == null) {
|
||||
v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
else {
|
||||
v.getstatic(state.getTypeMapper().jvmName(outerClassDescriptor, OwnerKind.IMPLEMENTATION), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;ZLjet/typeinfo/TypeInfo;)Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
v.putstatic(typeMapper.jvmName(descriptor, kind), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void generateClassObject(JetClassObject declaration) {
|
||||
state.forClass().generate(context, declaration.getObjectDeclaration());
|
||||
}
|
||||
@@ -737,30 +785,4 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static boolean isParametrizedClass(JetType type) {
|
||||
if(type.getConstructor().getParameters().size() > 0)
|
||||
return true;
|
||||
|
||||
for (JetType jetType : type.getConstructor().getSupertypes()) {
|
||||
if(isParametrizedClass(jetType))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasDerivedTypeInfoField(JetType type, boolean exceptOwn) {
|
||||
if(!exceptOwn) {
|
||||
if(!CodegenUtil.isInterface(type))
|
||||
if(isParametrizedClass(type))
|
||||
return true;
|
||||
}
|
||||
|
||||
for (JetType jetType : type.getConstructor().getSupertypes()) {
|
||||
if(hasDerivedTypeInfoField(jetType, false))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,12 +40,23 @@ public class JetTypeMapper {
|
||||
public static final Type JL_NUMBER_TYPE = Type.getObjectType("java/lang/Number");
|
||||
public static final Type JL_STRING_BUILDER = Type.getObjectType("java/lang/StringBuilder");
|
||||
|
||||
public static final Type ARRAY_INT_TYPE = Type.getObjectType("jet/arrays/JetIntArray");
|
||||
public static final Type ARRAY_LONG_TYPE = Type.getObjectType("jet/arrays/JetLongArray");
|
||||
public static final Type ARRAY_SHORT_TYPE = Type.getObjectType("jet/arrays/JetShortArray");
|
||||
public static final Type ARRAY_BYTE_TYPE = Type.getObjectType("jet/arrays/JetByteArray");
|
||||
public static final Type ARRAY_CHAR_TYPE = Type.getObjectType("jet/arrays/JetCharArray");
|
||||
public static final Type ARRAY_FLOAT_TYPE = Type.getObjectType("jet/arrays/JetFloatArray");
|
||||
public static final Type ARRAY_DOUBLE_TYPE = Type.getObjectType("jet/arrays/JetDoubleArray");
|
||||
public static final Type ARRAY_BOOL_TYPE = Type.getObjectType("jet/arrays/JetBoolArray");
|
||||
public static final Type ARRAY_GENERIC_TYPE = Type.getObjectType("jet/arrays/JetGenericArray");
|
||||
|
||||
private final JetStandardLibrary standardLibrary;
|
||||
private final BindingContext bindingContext;
|
||||
private final Map<JetExpression, String> classNamesForAnonymousClasses = new HashMap<JetExpression, String>();
|
||||
private final Map<String, Integer> anonymousSubclassesCount = new HashMap<String, Integer>();
|
||||
|
||||
private final HashMap<JetType,String> knowTypes = new HashMap<JetType, String>();
|
||||
private final HashMap<JetType,String> knowArrayTypes = new HashMap<JetType, String>();
|
||||
|
||||
public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) {
|
||||
this.standardLibrary = standardLibrary;
|
||||
@@ -377,9 +388,36 @@ public class JetTypeMapper {
|
||||
if (jetType.getArguments().size() != 1) {
|
||||
throw new UnsupportedOperationException("arrays must have one type argument");
|
||||
}
|
||||
TypeProjection memberType = jetType.getArguments().get(0);
|
||||
Type elementType = mapType(memberType.getType());
|
||||
return Type.getType("[" + elementType.getDescriptor());
|
||||
JetType memberType = jetType.getArguments().get(0).getType();
|
||||
|
||||
if (memberType.equals(standardLibrary.getIntType())) {
|
||||
return ARRAY_INT_TYPE;
|
||||
}
|
||||
if (memberType.equals(standardLibrary.getLongType())) {
|
||||
return ARRAY_LONG_TYPE;
|
||||
}
|
||||
if (memberType.equals(standardLibrary.getShortType())) {
|
||||
return ARRAY_SHORT_TYPE;
|
||||
}
|
||||
if (memberType.equals(standardLibrary.getByteType())) {
|
||||
return ARRAY_BYTE_TYPE;
|
||||
}
|
||||
if (memberType.equals(standardLibrary.getCharType())) {
|
||||
return ARRAY_CHAR_TYPE;
|
||||
}
|
||||
if (memberType.equals(standardLibrary.getFloatType())) {
|
||||
return ARRAY_FLOAT_TYPE;
|
||||
}
|
||||
if (memberType.equals(standardLibrary.getDoubleType())) {
|
||||
return ARRAY_DOUBLE_TYPE;
|
||||
}
|
||||
if (memberType.equals(standardLibrary.getBooleanType())) {
|
||||
return ARRAY_BOOL_TYPE;
|
||||
}
|
||||
if(!isGenericsArray(jetType))
|
||||
return ARRAY_GENERIC_TYPE;
|
||||
else
|
||||
return TYPE_OBJECT;
|
||||
}
|
||||
if (JetStandardClasses.getAny().equals(descriptor)) {
|
||||
return Type.getType(Object.class);
|
||||
@@ -665,9 +703,21 @@ public class JetTypeMapper {
|
||||
knowTypes.put(standardLibrary.getNullableStringType(),"NULLABLE_STRING_TYPE_INFO");
|
||||
knowTypes.put(standardLibrary.getTuple0Type(),"TUPLE0_TYPE_INFO");
|
||||
knowTypes.put(standardLibrary.getNullableTuple0Type(),"NULLABLE_TUPLE0_TYPE_INFO");
|
||||
|
||||
knowArrayTypes.put(standardLibrary.getIntType(), "INT_ARRAY_TYPE_INFO");
|
||||
knowArrayTypes.put(standardLibrary.getLongType(), "LONG_ARRAY_TYPE_INFO");
|
||||
knowArrayTypes.put(standardLibrary.getShortType(),"SHORT_ARRAY_TYPE_INFO");
|
||||
knowArrayTypes.put(standardLibrary.getByteType(),"BYTE_ARRAY_TYPE_INFO");
|
||||
knowArrayTypes.put(standardLibrary.getCharType(),"CHAR_ARRAY_TYPE_INFO");
|
||||
knowArrayTypes.put(standardLibrary.getFloatType(),"FLOAT_ARRAY_TYPE_INFO");
|
||||
knowArrayTypes.put(standardLibrary.getDoubleType(),"DOUBLE_ARRAY_TYPE_INFO");
|
||||
knowArrayTypes.put(standardLibrary.getBooleanType(),"BOOLEAN_ARRAY_TYPE_INFO");
|
||||
}
|
||||
|
||||
public String isKnownTypeInfo(JetType jetType) {
|
||||
if(standardLibrary.getArray().equals(jetType.getConstructor().getDeclarationDescriptor()))
|
||||
return knowArrayTypes.get(jetType.getArguments().get(0).getType());
|
||||
|
||||
return knowTypes.get(jetType);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import jet.typeinfo.TypeInfoVariance;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
import org.jetbrains.jet.lang.psi.JetDelegationSpecifier;
|
||||
import org.jetbrains.jet.lang.psi.JetTypeParameter;
|
||||
import org.jetbrains.jet.lang.psi.JetTypeReference;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -44,7 +40,11 @@ public class SignatureUtil {
|
||||
sb.append(type.getDescriptor());
|
||||
}
|
||||
else {
|
||||
sb.append("T").append(descriptor.getName()).append(";");
|
||||
sb.append("T");
|
||||
sb.append(descriptor.getContainingDeclaration().getName());
|
||||
sb.append(";");
|
||||
sb.append(descriptor.getName());
|
||||
sb.append(";");
|
||||
}
|
||||
if(!jetType.getArguments().isEmpty()) {
|
||||
sb.append("<");
|
||||
|
||||
@@ -13,7 +13,7 @@ import org.objectweb.asm.commons.Method;
|
||||
* @author yole
|
||||
*/
|
||||
public abstract class StackValue {
|
||||
protected final Type type;
|
||||
public final Type type;
|
||||
|
||||
public StackValue(Type type) {
|
||||
this.type = type;
|
||||
@@ -75,8 +75,8 @@ public abstract class StackValue {
|
||||
return new Invert(stackValue);
|
||||
}
|
||||
|
||||
public static StackValue arrayElement(Type type) {
|
||||
return new ArrayElement(type);
|
||||
public static StackValue arrayElement(Type type, boolean genericsArray) {
|
||||
return new ArrayElement(type, genericsArray);
|
||||
}
|
||||
|
||||
public static StackValue collectionElement(Type type, CallableMethod getter, CallableMethod setter) {
|
||||
@@ -424,19 +424,32 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
private static class ArrayElement extends StackValue {
|
||||
public ArrayElement(Type type) {
|
||||
private boolean genericsArray;
|
||||
|
||||
public ArrayElement(Type type, boolean genericsArray) {
|
||||
super(type);
|
||||
this.genericsArray = genericsArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
v.aload(type); // assumes array and index are on the stack
|
||||
if(genericsArray) {
|
||||
v.invokevirtual("jet/arrays/JetArray", "get", "(I)Ljava/lang/Object;");
|
||||
}
|
||||
else {
|
||||
v.aload(this.type); // assumes array and index are on the stack
|
||||
}
|
||||
coerce(type, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(InstructionAdapter v) {
|
||||
v.astore(type); // assumes array and index are on the stack
|
||||
if(genericsArray) {
|
||||
v.invokevirtual("jet/arrays/JetArray", "set", "(ILjava/lang/Object;)V");
|
||||
}
|
||||
else {
|
||||
v.astore(type); // assumes array and index are on the stack
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
@@ -17,7 +18,33 @@ public class ArraySize implements IntrinsicMethod {
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
v.arraylength();
|
||||
if(receiver.type.equals(JetTypeMapper.TYPE_OBJECT)) {
|
||||
v.visitTypeInsn(Opcodes.CHECKCAST, "jet/arrays/JetArray");
|
||||
v.invokevirtual("jet/arrays/JetArray", "getSize", "()I");
|
||||
}
|
||||
else {
|
||||
if(receiver.type.equals(JetTypeMapper.ARRAY_BYTE_TYPE))
|
||||
v.getfield(receiver.type.getInternalName(), "array", "[B");
|
||||
else if(receiver.type.equals(JetTypeMapper.ARRAY_SHORT_TYPE))
|
||||
v.getfield(receiver.type.getInternalName(), "array", "[S");
|
||||
else if(receiver.type.equals(JetTypeMapper.ARRAY_INT_TYPE))
|
||||
v.getfield(receiver.type.getInternalName(), "array", "[I");
|
||||
else if(receiver.type.equals(JetTypeMapper.ARRAY_LONG_TYPE))
|
||||
v.getfield(receiver.type.getInternalName(), "array", "[J");
|
||||
else if(receiver.type.equals(JetTypeMapper.ARRAY_FLOAT_TYPE))
|
||||
v.getfield(receiver.type.getInternalName(), "array", "[F");
|
||||
else if(receiver.type.equals(JetTypeMapper.ARRAY_DOUBLE_TYPE))
|
||||
v.getfield(receiver.type.getInternalName(), "array", "[D");
|
||||
else if(receiver.type.equals(JetTypeMapper.ARRAY_CHAR_TYPE))
|
||||
v.getfield(receiver.type.getInternalName(), "array", "[C");
|
||||
else if(receiver.type.equals(JetTypeMapper.ARRAY_BOOL_TYPE))
|
||||
v.getfield(receiver.type.getInternalName(), "array", "[Z");
|
||||
else
|
||||
v.getfield("jet/arrays/JetGenericArray", "array", "[Ljava/lang/Object;");
|
||||
|
||||
v.arraylength();
|
||||
}
|
||||
|
||||
return StackValue.onStack(Type.INT_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,22 +63,23 @@ public class JetStandardLibrary {
|
||||
private final ClassDescriptor typeInfoClass;
|
||||
|
||||
private final JetType byteType;
|
||||
private final JetType nullableByteType;
|
||||
private final JetType charType;
|
||||
private final JetType nullableCharType;
|
||||
private final JetType shortType;
|
||||
private final JetType nullableShortType;
|
||||
private final JetType intType;
|
||||
private final JetType nullableIntType;
|
||||
private final JetType longType;
|
||||
private final JetType nullableLongType;
|
||||
private final JetType floatType;
|
||||
private final JetType nullableFloatType;
|
||||
private final JetType doubleType;
|
||||
private final JetType nullableDoubleType;
|
||||
private final JetType booleanType;
|
||||
private final JetType nullableBooleanType;
|
||||
private final JetType stringType;
|
||||
|
||||
private final JetType nullableByteType;
|
||||
private final JetType nullableCharType;
|
||||
private final JetType nullableShortType;
|
||||
private final JetType nullableIntType;
|
||||
private final JetType nullableLongType;
|
||||
private final JetType nullableFloatType;
|
||||
private final JetType nullableDoubleType;
|
||||
private final JetType nullableBooleanType;
|
||||
private final JetType nullableTuple0Type;
|
||||
|
||||
public JetType getTuple0Type() {
|
||||
|
||||
Reference in New Issue
Block a user