From d07314a8b500fd9eea8a7e74c3b013ace9b6159f Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Tue, 1 Nov 2011 10:56:24 +0100 Subject: [PATCH] KT-416 --- .../jet/codegen/ExpressionCodegen.java | 55 ++++++++++++------- .../jetbrains/jet/codegen/JetTypeMapper.java | 29 ++++++++++ .../jet/codegen/intrinsics/BinaryOp.java | 9 +++ .../testData/codegen/regressions/kt416.jet | 4 ++ .../jet/codegen/ControlStructuresTest.java | 5 ++ 5 files changed, 82 insertions(+), 20 deletions(-) create mode 100644 compiler/testData/codegen/regressions/kt416.jet diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index a76f5e3d782..c0fd4c8b2e2 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1238,29 +1238,44 @@ public class ExpressionCodegen extends JetVisitor { @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 diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 947cf407491..e0a184f7676 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -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: diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java index a34e333845c..e813857f0de 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java @@ -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 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); } } diff --git a/compiler/testData/codegen/regressions/kt416.jet b/compiler/testData/codegen/regressions/kt416.jet new file mode 100644 index 00000000000..a2108a6b9fb --- /dev/null +++ b/compiler/testData/codegen/regressions/kt416.jet @@ -0,0 +1,4 @@ +fun box() : String { + var a = 10 + return if(a?.plus(10) == 20) "OK" else "fail" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java b/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java index f6da4b65c87..d3748a7b737 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java @@ -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()); + } }