diff truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ContainsTest.java @ 21951:9c8c0937da41

Moving all sources into truffle subdirectory
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Wed, 17 Jun 2015 10:58:08 +0200
parents graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ContainsTest.java@f4792a544170
children dc83cc1f94f2
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ContainsTest.java	Wed Jun 17 10:58:08 2015 +0200
@@ -0,0 +1,555 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl.test;
+
+import static com.oracle.truffle.api.dsl.test.TestHelper.*;
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.dsl.internal.*;
+import com.oracle.truffle.api.dsl.test.ContainsTestFactory.Contains1Factory;
+import com.oracle.truffle.api.dsl.test.ContainsTestFactory.Contains2Factory;
+import com.oracle.truffle.api.dsl.test.ContainsTestFactory.Contains3Factory;
+import com.oracle.truffle.api.dsl.test.ContainsTestFactory.Contains4Factory;
+import com.oracle.truffle.api.dsl.test.ContainsTestFactory.PolymorphicToMonomorphic0Factory;
+import com.oracle.truffle.api.dsl.test.TestHelper.ExecutionListener;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
+import com.oracle.truffle.api.nodes.*;
+
+@SuppressWarnings("unused")
+public class ContainsTest {
+
+    /*
+     * Tests a simple monomorphic inclusion.
+     */
+    @Test
+    public void testContains1() {
+        assertRuns(Contains1Factory.getInstance(), //
+                        array(1, "a", 2, "b"), //
+                        array(2, "aa", 3, "ba"), //
+                        new ExecutionListener() {
+                            public void afterExecution(TestRootNode<? extends ValueNode> node, int index, Object value, Object expectedResult, Object actualResult, boolean last) {
+                                if (value instanceof String) {
+                                    if (node.getNode() instanceof DSLNode) {
+                                        // assert that the final specialization is always Object
+                                        Assert.assertEquals(Object.class, ((DSLNode) node.getNode()).getMetadata0().getSpecializedTypes()[0]);
+                                    } else {
+                                        Assert.assertTrue(((SpecializedNode) node.getNode()).getSpecializationNode().toString().startsWith("F2Node_"));
+                                    }
+                                }
+                            }
+                        });
+    }
+
+    @NodeChild("a")
+    abstract static class Contains1 extends ValueNode {
+
+        @Specialization
+        int f1(int a) {
+            return a + 1;
+        }
+
+        @Specialization(contains = "f1")
+        Object f2(Object a) {
+            if (a instanceof Integer) {
+                return ((Integer) a) + 1;
+            }
+            return a + "a";
+        }
+    }
+
+    /*
+     * Tests an inclusion in within a polymorphic chain.
+     */
+    @Test
+    public void testContains2() {
+        assertRuns(Contains2Factory.getInstance(), //
+                        array(true, 1, 0, false), //
+                        array(false, -1, 1, true) //
+        );
+    }
+
+    @NodeChild("a")
+    abstract static class Contains2 extends ValueNode {
+
+        static boolean isZero(int a) {
+            return a == 0;
+        }
+
+        @Specialization(guards = "isZero(a)")
+        int f1(int a) {
+            return a + 1;
+        }
+
+        @Specialization(contains = "f1")
+        int f2(int a) {
+            if (a == 0) {
+                return a + 1;
+            }
+            return -a;
+        }
+
+        @Specialization
+        boolean f3(boolean a) {
+            return !a;
+        }
+    }
+
+    /*
+     * Tests transitive monomorphic inclusion.
+     */
+    @Test
+    public void testContains3() {
+        assertRuns(Contains3Factory.getInstance(), //
+                        array(2, 1, 2, -3, -4), //
+                        array(-2, 2, -2, -3, -4), //
+                        new ExecutionListener() {
+                            public void afterExecution(TestRootNode<? extends ValueNode> node, int index, Object value, Object expectedResult, Object actualResult, boolean last) {
+                                // assert that we are always monomorphic
+                                Assert.assertEquals(NodeCost.MONOMORPHIC, node.getNode().getCost());
+                            }
+                        });
+    }
+
+    @NodeChild("a")
+    abstract static class Contains3 extends ValueNode {
+
+        static boolean isGreaterZero(int a) {
+            return a > 0;
+        }
+
+        static boolean isOne(int a) {
+            return a == 1;
+        }
+
+        @Specialization(guards = {"isOne(a)"})
+        int f1(int a) {
+            return a + 1;
+        }
+
+        @Specialization(contains = "f1", guards = {"isGreaterZero(a)"})
+        int f2(int a) {
+            if (a == 1) {
+                return 2;
+            }
+            return -a;
+        }
+
+        @Specialization(contains = "f2")
+        int f3(int a) {
+            if (a > 0) {
+                return a == 1 ? 2 : -a;
+            } else {
+                return a;
+            }
+        }
+
+    }
+
+    /*
+     * Tests that if it can be derived that two specializations actually a as powerful as the latter
+     * we can combine them. Therefore operation should always become monomorphic in the end.
+     */
+    @Test
+    public void testContains4() {
+        assertRuns(Contains4Factory.getInstance(), //
+                        array(-1, 0, 1, 2), //
+                        array(1, 0, 1, 2), //
+                        new ExecutionListener() {
+                            public void afterExecution(TestRootNode<? extends ValueNode> node, int index, Object value, Object expectedResult, Object actualResult, boolean last) {
+                                Assert.assertEquals(NodeCost.MONOMORPHIC, node.getNode().getCost());
+                            }
+                        });
+    }
+
+    @NodeChild("a")
+    abstract static class Contains4 extends ValueNode {
+
+        static boolean isOne(int a) {
+            return a == 1;
+        }
+
+        @Specialization(guards = "isOne(a)")
+        int f0(int a) {
+            return 1;
+        }
+
+        @Specialization(contains = "f0", guards = "a >= 0")
+        int f1(int a) {
+            return a;
+        }
+
+        @Specialization(contains = {"f1"})
+        int f2(int a) {
+            return Math.abs(a);
+        }
+
+    }
+
+    @NodeChild("a")
+    abstract static class ContainsError1 extends ValueNode {
+        @ExpectError("The contained specialization 'f1' must be declared before the containing specialization.")
+        @Specialization(contains = "f1")
+        int f0(int a) {
+            return a;
+        }
+
+        @Specialization
+        Object f1(String a) {
+            return a;
+        }
+    }
+
+    @NodeChild("a")
+    abstract static class ContainsError2 extends ValueNode {
+
+        @ExpectError("The referenced specialization 'does not exist' could not be found.")
+        @Specialization(contains = "does not exist")
+        int f0(int a) {
+            return a;
+        }
+    }
+
+    @NodeChild("a")
+    abstract static class ContainsError3 extends ValueNode {
+
+        @Specialization
+        int f0(int a) {
+            return a;
+        }
+
+        @ExpectError("Duplicate contains declaration 'f0'.")
+        @Specialization(contains = {"f0", "f0"})
+        Object f1(double a) {
+            return a;
+        }
+    }
+
+    @NodeChild("a")
+    abstract static class ContainsError4 extends ValueNode {
+
+        @ExpectError("Circular contained specialization 'f1(double)' found.")
+        @Specialization(contains = {"f1"})
+        Object f1(double a) {
+            return a;
+        }
+    }
+
+    @NodeChild("a")
+    abstract static class ContainsError5 extends ValueNode {
+
+        @ExpectError({"Circular contained specialization 'f0(int)' found.", "Circular contained specialization 'f1(double)' found.",
+                        "The contained specialization 'f1' must be declared before the containing specialization."})
+        @Specialization(contains = "f1")
+        int f0(int a) {
+            return a;
+        }
+
+        @ExpectError("Circular contained specialization 'f1(double)' found.")
+        @Specialization(contains = {"f0"})
+        Object f1(double a) {
+            return a;
+        }
+    }
+
+    @NodeChild("a")
+    abstract static class ContainsType1 extends ValueNode {
+        @Specialization
+        int f0(int a) {
+            return a;
+        }
+
+        @ExpectError("Specialization is not reachable. It is shadowed by f0(int).")
+        @Specialization(contains = "f0")
+        Object f1(int a) {
+            return a;
+        }
+    }
+
+    @NodeChild("a")
+    abstract static class ContainsType2 extends ValueNode {
+        @Specialization
+        int f0(int a) {
+            return a;
+        }
+
+        @Specialization(contains = "f0")
+        Object f1(Object a) {
+            return a;
+        }
+    }
+
+    @NodeChild("a")
+    abstract static class ContainsType3 extends ValueNode {
+        @Specialization
+        int f0(int a) {
+            return a;
+        }
+
+        @Specialization(contains = "f0")
+        Object f1(double a) { // implicit type
+            return a;
+        }
+    }
+
+    @NodeChild("a")
+    abstract static class ContainsType4 extends ValueNode {
+        @Specialization
+        double f0(double a) {
+            return a;
+        }
+
+        @ExpectError({"Specialization is not reachable. It is shadowed by f0(double)."})
+        @Specialization(contains = "f0")
+        int f1(int a) { // implicit type
+            return a;
+        }
+    }
+
+    @NodeChildren({@NodeChild("a"), @NodeChild("b")})
+    abstract static class ContainsType5 extends ValueNode {
+        @Specialization
+        Object f0(Object a, int b) {
+            return a;
+        }
+
+        @Specialization(contains = "f0")
+        Object f1(int a, Object b) {
+            return a;
+        }
+    }
+
+    @NodeChildren({@NodeChild("a"), @NodeChild("b")})
+    abstract static class ContainsType6 extends ValueNode {
+        @Specialization
+        Object f0(double a, int b) {
+            return a;
+        }
+
+        @Specialization(contains = "f0")
+        Object f1(int a, double b) { // implicit type
+            return a;
+        }
+    }
+
+    abstract static class ContainsGuard1 extends ValueNode {
+
+        boolean g1() {
+            return true;
+        }
+
+        @Specialization(guards = "g1()")
+        Object f0() {
+            return null;
+        }
+
+        @Specialization(contains = "f0")
+        Object f1() {
+            return null;
+        }
+    }
+
+    abstract static class ContainsGuard2 extends ValueNode {
+
+        boolean g1() {
+            return true;
+        }
+
+        @Specialization
+        Object f0() {
+            return null;
+        }
+
+        @ExpectError({"Specialization is not reachable. It is shadowed by f0()."})
+        @Specialization(guards = "g1()", contains = "f0")
+        Object f1() {
+            return null;
+        }
+    }
+
+    abstract static class ContainsGuard3 extends ValueNode {
+
+        boolean g1() {
+            return true;
+        }
+
+        @Specialization(guards = "g1()")
+        Object f0() {
+            return null;
+        }
+
+        @Specialization(guards = "!g1()", contains = "f0")
+        Object f1() {
+            return null;
+        }
+    }
+
+    abstract static class ContainsGuard4 extends ValueNode {
+
+        boolean g1() {
+            return true;
+        }
+
+        boolean g2() {
+            return true;
+        }
+
+        @Specialization(guards = "g1()")
+        Object f0() {
+            return null;
+        }
+
+        @Specialization(guards = "g2()", contains = "f0")
+        Object f1() {
+            return null;
+        }
+    }
+
+    abstract static class ContainsGuard5 extends ValueNode {
+
+        boolean g1() {
+            return true;
+        }
+
+        boolean g2() {
+            return true;
+        }
+
+        @Specialization(guards = "g1()")
+        Object f0() {
+            return null;
+        }
+
+        @Specialization(guards = "g2()", contains = "f0")
+        Object f1() {
+            return null;
+        }
+    }
+
+    abstract static class ContainsGuard6 extends ValueNode {
+
+        boolean g1() {
+            return true;
+        }
+
+        boolean g2() {
+            return true;
+        }
+
+        @Specialization(guards = "g1()")
+        Object f0() {
+            return null;
+        }
+
+        @Specialization(guards = "!g2()", contains = "f0")
+        Object f1() {
+            return null;
+        }
+    }
+
+    abstract static class ContainsGuard7 extends ValueNode {
+
+        boolean g1() {
+            return true;
+        }
+
+        boolean g2() {
+            return true;
+        }
+
+        @Specialization(guards = {"g1()", "g2()"})
+        Object f0() {
+            return null;
+        }
+
+        @Specialization(guards = "g2()", contains = "f0")
+        Object f1() {
+            return null;
+        }
+    }
+
+    abstract static class ContainsThrowable1 extends ValueNode {
+
+        @Specialization(rewriteOn = RuntimeException.class)
+        Object f0() throws RuntimeException {
+            throw new RuntimeException();
+        }
+
+        @Specialization(contains = "f0")
+        Object f1() {
+            return null;
+        }
+    }
+
+    abstract static class ContainsThrowable2 extends ValueNode {
+
+        @Specialization(rewriteOn = RuntimeException.class)
+        Object f0() throws RuntimeException {
+            throw new RuntimeException();
+        }
+
+        @Specialization(contains = "f0", rewriteOn = RuntimeException.class)
+        Object f1() throws RuntimeException {
+            throw new RuntimeException();
+        }
+
+        @Specialization(contains = "f1")
+        Object f2() {
+            return null;
+        }
+    }
+
+    @Test
+    public void testPolymorphicToMonomorphic0() {
+        TestRootNode<PolymorphicToMonomorphic0> root = createRoot(PolymorphicToMonomorphic0Factory.getInstance());
+        assertThat((int) executeWith(root, 1), is(1));
+        assertThat((int) executeWith(root, 2), is(2));
+        assertThat((int) executeWith(root, 3), is(3));
+        assertThat(root.getNode().getCost(), is(NodeCost.MONOMORPHIC));
+    }
+
+    @NodeChild("a")
+    static class PolymorphicToMonomorphic0 extends ValueNode {
+
+        @Specialization(guards = "a == 1")
+        int do1(int a) {
+            return a;
+        }
+
+        @Specialization(guards = "a == 2")
+        int do2(int a) {
+            return a;
+        }
+
+        @Specialization(contains = {"do1", "do2"})
+        int do3(int a) {
+            return a;
+        }
+
+    }
+
+}