From 1135c8ce7a43dcbb05c678e0f032d6b646104066 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Sat, 3 Dec 2011 20:51:56 +0200 Subject: [PATCH] KT-737 compareTo() intrinsic --- .../jetbrains/jet/codegen/JetTypeMapper.java | 3 +- .../jet/codegen/intrinsics/CompareTo.java | 45 +++++++++++++++++++ .../codegen/intrinsics/IntrinsicMethods.java | 3 ++ .../jet/codegen/PrimitiveTypesTest.java | 6 +++ stdlib/src/jet/runtime/Intrinsics.java | 12 +++++ 5 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/CompareTo.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index c51d21d7801..5649fe11f01 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -320,7 +320,8 @@ public class JetTypeMapper { ClassDescriptor containingClass = (ClassDescriptor) functionParent; boolean isInterface = CodegenUtil.isInterface(containingClass); OwnerKind kind1 = isInterface && superCall ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION; - owner = mapType(containingClass.getDefaultType(), kind1).getInternalName(); + Type type = mapType(containingClass.getDefaultType(), kind1); + owner = type.getInternalName(); invokeOpcode = isInterface ? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE) : (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/CompareTo.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/CompareTo.java new file mode 100644 index 00000000000..991d84c1231 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/CompareTo.java @@ -0,0 +1,45 @@ +package org.jetbrains.jet.codegen.intrinsics; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.Nullable; +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; +import org.objectweb.asm.commons.InstructionAdapter; + +import java.util.List; + +/** + * @author alex.tkachman + */ +public class CompareTo implements IntrinsicMethod { + @Override + public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, @Nullable PsiElement element, @Nullable List arguments, StackValue receiver) { + assert arguments != null; + receiver.put(receiver.type, v); + codegen.gen(arguments.get(0), receiver.type); + if(receiver.type == Type.BYTE_TYPE || receiver.type == Type.SHORT_TYPE || receiver.type == Type.CHAR_TYPE) + v.sub(Type.INT_TYPE); + else if(receiver.type == Type.INT_TYPE) { + v.invokestatic("jet/runtime/Intrinsics", "compare", "(II)I"); + } + else if(receiver.type == Type.BOOLEAN_TYPE) { + v.invokestatic("jet/runtime/Intrinsics", "compare", "(ZZ)I"); + } + else if(receiver.type == Type.LONG_TYPE) { + v.invokestatic("jet/runtime/Intrinsics", "compare", "(JJ)I"); + } + else if(receiver.type == Type.FLOAT_TYPE) { + v.invokestatic("java/lang/Float", "compare", "(FF)I"); + } + else if(receiver.type == Type.DOUBLE_TYPE) { + v.invokestatic("java/lang/Double", "compare", "(DD)I"); + } + else { + throw new UnsupportedOperationException(); + } + return StackValue.onStack(Type.INT_TYPE); + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index 33e107c2143..6ccff8d02b3 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -97,6 +97,9 @@ public class IntrinsicMethods { declareIntrinsicFunction("FloatIterator", "next", 0, ITERATOR_NEXT); declareIntrinsicFunction("DoubleIterator", "next", 0, ITERATOR_NEXT); + for (String type : PRIMITIVE_NUMBER_TYPES) { + declareIntrinsicFunction(type, "compareTo", 1, new CompareTo()); + } // declareIntrinsicFunction("Any", "equals", 1, new Equals()); // declareIntrinsicStringMethods(); diff --git a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java index bb38c2d8e1b..6dfec5e3e79 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java @@ -315,6 +315,12 @@ public class PrimitiveTypesTest extends CodegenTestCase { assertTrue(generateToText().contains("IFNULL")); } + public void testKt737() throws Exception { + loadText("fun box() = if(3.compareTo(2) != 1) \"fail\" else if(5.byt.compareTo(10.lng) >= 0) \"fail\" else \"OK\""); + System.out.println(generateToText()); + assertEquals("OK", blackBox()); + } + public void testKt665() throws Exception { loadText("fun f(x: Long, zzz: Long = 1): Long\n" + "{\n" + diff --git a/stdlib/src/jet/runtime/Intrinsics.java b/stdlib/src/jet/runtime/Intrinsics.java index d162e3634d6..19488b98ba2 100644 --- a/stdlib/src/jet/runtime/Intrinsics.java +++ b/stdlib/src/jet/runtime/Intrinsics.java @@ -17,6 +17,18 @@ public class Intrinsics { throw new JetNullPointerException(); } + public static int compare(long thisVal, long anotherVal) { + return (thisVal list = new ArrayList();