From e74ea049afce6f64d2fb513fb86c918411cc06d9 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 15 Apr 2011 15:14:55 +0200 Subject: [PATCH] elvis for primitive types; unboxing support --- .../jet/codegen/ExpressionCodegen.java | 8 ++++- .../org/jetbrains/jet/codegen/StackValue.java | 30 +++++++++++++++++++ .../jet/codegen/NamespaceGenTest.java | 7 +++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index cc17addc722..6c058df6985 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -62,6 +62,10 @@ public class ExpressionCodegen extends JetVisitor { } } + private void genToStack(JetExpression expr) { + gen(expr, expressionType(expr)); + } + @Override public void visitExpression(JetExpression expression) { throw new UnsupportedOperationException("Codegen for " + expression + " is not yet implemented"); @@ -621,11 +625,13 @@ public class ExpressionCodegen extends JetVisitor { private void generateElvis(JetBinaryExpression expression) { final Type exprType = expressionType(expression); - gen(expression.getLeft(), exprType); + final Type leftType = expressionType(expression.getLeft()); + gen(expression.getLeft(), leftType); v.dup(); Label end = new Label(); Label ifNull = new Label(); v.ifnull(ifNull); + StackValue.onStack(leftType).put(exprType, v); v.goTo(end); v.mark(ifNull); v.pop(); diff --git a/idea/src/org/jetbrains/jet/codegen/StackValue.java b/idea/src/org/jetbrains/jet/codegen/StackValue.java index 9ddd16fe1f2..518b26fcbae 100644 --- a/idea/src/org/jetbrains/jet/codegen/StackValue.java +++ b/idea/src/org/jetbrains/jet/codegen/StackValue.java @@ -69,10 +69,40 @@ public abstract class StackValue { } } + private static void unbox(final Type type, InstructionAdapter v) { + if (type == Type.INT_TYPE) { + v.invokevirtual("java/lang/Number", "intValue", "()I"); + } + else if (type == Type.BOOLEAN_TYPE) { + v.invokevirtual("java/lang/Boolean", "booleanValue", "()Z"); + } + else if (type == Type.CHAR_TYPE) { + v.invokevirtual("java/lang/Character", "charValue", "()C"); + } + else if (type == Type.SHORT_TYPE) { + v.invokevirtual("java/lang/Number", "shortValue", "()S"); + } + else if (type == Type.LONG_TYPE) { + v.invokevirtual("java/lang/Number", "longValue", "()J"); + } + else if (type == Type.BYTE_TYPE) { + v.invokevirtual("java/lang/Number", "byteValue", "()B"); + } + else if (type == Type.FLOAT_TYPE) { + v.invokevirtual("java/lang/Number", "floatValue", "()F"); + } + else if (type == Type.DOUBLE_TYPE) { + v.invokevirtual("java/lang/Number", "doubleValue", "()D"); + } + } + protected void coerce(Type type, InstructionAdapter v) { if (type.getSort() == Type.OBJECT) { box(this.type, v); } + else if (this.type.getSort() == Type.OBJECT && type.getSort() <= Type.DOUBLE) { + unbox(type, v); + } else if (type != this.type) { v.cast(this.type, type); } diff --git a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java index 76ad65eb589..5d473846373 100644 --- a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java @@ -275,6 +275,13 @@ public class NamespaceGenTest extends CodegenTestCase { assertEquals("null", main.invoke(null, new Object[] { null })); } + public void testElvisInt() throws Exception { + loadText("fun foo(a: Int?): Int = a ?: 239"); + final Method main = generateFunction(); + assertEquals(610, main.invoke(null, 610)); + assertEquals(239, main.invoke(null, new Object[]{null})); + } + public void _testVarargs() throws Exception { loadText("fun foo() = java.util.Arrays.asList(\"IntelliJ\", \"IDEA\")"); final Method main = generateFunction();