This commit is contained in:
Alex Tkachman
2011-11-01 10:56:24 +01:00
parent 43faa77478
commit d07314a8b5
5 changed files with 82 additions and 20 deletions
@@ -1238,29 +1238,44 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override @Override
public StackValue visitSafeQualifiedExpression(JetSafeQualifiedExpression expression, StackValue receiver) { public StackValue visitSafeQualifiedExpression(JetSafeQualifiedExpression expression, StackValue receiver) {
genToJVMStack(expression.getReceiverExpression()); JetExpression expr = expression.getReceiverExpression();
Label ifnull = new Label(); JetType receiverJetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getReceiverExpression());
Label end = new Label(); Type receiverType = typeMapper.mapType(receiverJetType);
v.dup(); gen(expr, receiverType);
v.ifnull(ifnull); if(receiverType.getSort() != Type.OBJECT && receiverType.getSort() != Type.ARRAY) {
JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getReceiverExpression()); StackValue propValue = genQualified(StackValue.onStack(receiverType), expression.getSelectorExpression());
StackValue propValue = genQualified(StackValue.onStack(typeMapper.mapType(receiverType)), expression.getSelectorExpression()); Type type = propValue.type;
Type type = propValue.type; propValue.put(type, v);
propValue.put(type, v); if(JetTypeMapper.isPrimitive(type) && !type.equals(Type.VOID_TYPE)) {
if(JetTypeMapper.isPrimitive(type) && !type.equals(Type.VOID_TYPE)) { StackValue.valueOf(v, type);
StackValue.valueOf(v, type); type = JetTypeMapper.boxType(type);
type = JetTypeMapper.boxType(type); }
}
v.goTo(end);
v.mark(ifnull); return StackValue.onStack(type);
v.pop();
if(!propValue.type.equals(Type.VOID_TYPE)) {
v.aconst(null);
} }
v.mark(end); else {
Label ifnull = new Label();
Label end = new Label();
v.dup();
v.ifnull(ifnull);
StackValue propValue = genQualified(StackValue.onStack(receiverType), expression.getSelectorExpression());
Type type = propValue.type;
propValue.put(type, v);
if(JetTypeMapper.isPrimitive(type) && !type.equals(Type.VOID_TYPE)) {
StackValue.valueOf(v, type);
type = JetTypeMapper.boxType(type);
}
v.goTo(end);
return StackValue.onStack(type); v.mark(ifnull);
v.pop();
if(!propValue.type.equals(Type.VOID_TYPE)) {
v.aconst(null);
}
v.mark(end);
return StackValue.onStack(type);
}
} }
@Override @Override
@@ -15,6 +15,7 @@ import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.resolve.DescriptorRenderer; import org.jetbrains.jet.resolve.DescriptorRenderer;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import org.objectweb.asm.commons.Method; import org.objectweb.asm.commons.Method;
import java.util.*; import java.util.*;
@@ -415,6 +416,34 @@ public class JetTypeMapper {
throw new UnsupportedOperationException("Unknown type " + jetType); throw new UnsupportedOperationException("Unknown type " + jetType);
} }
public static Type unboxType(final Type type) {
if (type == JL_INTEGER_TYPE) {
return Type.INT_TYPE;
}
else if (type == JL_BOOLEAN_TYPE) {
return Type.BOOLEAN_TYPE;
}
else if (type == JL_CHAR_TYPE) {
return Type.CHAR_TYPE;
}
else if (type == JL_SHORT_TYPE) {
return Type.SHORT_TYPE;
}
else if (type == JL_LONG_TYPE) {
return Type.LONG_TYPE;
}
else if (type == JL_BYTE_TYPE) {
return Type.BYTE_TYPE;
}
else if (type == JL_FLOAT_TYPE) {
return Type.FLOAT_TYPE;
}
else if (type == JL_DOUBLE_TYPE) {
return Type.DOUBLE_TYPE;
}
throw new UnsupportedOperationException("Unboxing: " + type);
}
public static Type boxType(Type asmType) { public static Type boxType(Type asmType) {
switch (asmType.getSort()) { switch (asmType.getSort()) {
case Type.VOID: case Type.VOID:
@@ -2,6 +2,7 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
@@ -21,6 +22,10 @@ public class BinaryOp implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) { public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
boolean nullable = expectedType.getSort() == Type.OBJECT;
if(nullable) {
expectedType = JetTypeMapper.unboxType(expectedType);
}
if (arguments.size() == 1) { if (arguments.size() == 1) {
// intrinsic is called as an ordinary function // intrinsic is called as an ordinary function
if (receiver != null) { if (receiver != null) {
@@ -33,6 +38,10 @@ public class BinaryOp implements IntrinsicMethod {
codegen.gen(arguments.get(1), expectedType); codegen.gen(arguments.get(1), expectedType);
} }
v.visitInsn(expectedType.getOpcode(opcode)); v.visitInsn(expectedType.getOpcode(opcode));
if(nullable) {
StackValue.onStack(expectedType).put(expectedType = JetTypeMapper.boxType(expectedType), v);
}
return StackValue.onStack(expectedType); return StackValue.onStack(expectedType);
} }
} }
@@ -0,0 +1,4 @@
fun box() : String {
var a = 10
return if(a?.plus(10) == 20) "OK" else "fail"
}
@@ -207,4 +207,9 @@ public class ControlStructuresTest extends CodegenTestCase {
public void testKt299() throws Exception { public void testKt299() throws Exception {
blackBoxFile("regressions/kt299.jet"); blackBoxFile("regressions/kt299.jet");
} }
public void testKt416() throws Exception {
blackBoxFile("regressions/kt416.jet");
System.out.println(generateToText());
}
} }