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
public StackValue visitSafeQualifiedExpression(JetSafeQualifiedExpression expression, StackValue receiver) {
genToJVMStack(expression.getReceiverExpression());
Label ifnull = new Label();
Label end = new Label();
v.dup();
v.ifnull(ifnull);
JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getReceiverExpression());
StackValue propValue = genQualified(StackValue.onStack(typeMapper.mapType(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);
JetExpression expr = expression.getReceiverExpression();
JetType receiverJetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getReceiverExpression());
Type receiverType = typeMapper.mapType(receiverJetType);
gen(expr, receiverType);
if(receiverType.getSort() != Type.OBJECT && receiverType.getSort() != Type.ARRAY) {
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.mark(ifnull);
v.pop();
if(!propValue.type.equals(Type.VOID_TYPE)) {
v.aconst(null);
return StackValue.onStack(type);
}
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
@@ -15,6 +15,7 @@ import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import org.objectweb.asm.commons.Method;
import java.util.*;
@@ -415,6 +416,34 @@ public class JetTypeMapper {
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) {
switch (asmType.getSort()) {
case Type.VOID:
@@ -2,6 +2,7 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
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.Type;
@@ -21,6 +22,10 @@ public class BinaryOp implements IntrinsicMethod {
@Override
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) {
// intrinsic is called as an ordinary function
if (receiver != null) {
@@ -33,6 +38,10 @@ public class BinaryOp implements IntrinsicMethod {
codegen.gen(arguments.get(1), expectedType);
}
v.visitInsn(expectedType.getOpcode(opcode));
if(nullable) {
StackValue.onStack(expectedType).put(expectedType = JetTypeMapper.boxType(expectedType), v);
}
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 {
blackBoxFile("regressions/kt299.jet");
}
public void testKt416() throws Exception {
blackBoxFile("regressions/kt416.jet");
System.out.println(generateToText());
}
}