# HG changeset patch # User Christian Humer # Date 1407765185 -7200 # Node ID 5148aab962af0d001c1d68a61ed8b7d42fef7e34 # Parent bd28da642eea8a35c65f9ce89b888cdb7c337a28 Truffle-DSL: updated tests for the new generation layout. diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/AssumptionsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/AssumptionsTest.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/AssumptionsTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -48,15 +48,16 @@ @NodeAssumptions("assumption") abstract static class SingleAssumptionNode extends ValueNode { - @Specialization(order = 0, assumptions = "assumption") - int doInt() { + @Specialization(assumptions = "assumption") + int do2() { return 42; } - @Specialization - Object doObject() { + @Generic + Object doFallBack() { return "42"; } + } @Test @@ -67,9 +68,9 @@ Assert.assertEquals(42, TestHelper.executeWith(root)); assumption2.invalidate(); - Assert.assertEquals("42", TestHelper.executeWith(root)); + Assert.assertEquals("41", TestHelper.executeWith(root)); assumption1.invalidate(); - Assert.assertEquals("43", TestHelper.executeWith(root)); + Assert.assertEquals("42", TestHelper.executeWith(root)); } @NodeAssumptions({"assumption1", "assumption2"}) @@ -82,12 +83,12 @@ @Specialization(assumptions = "assumption1") Object doObject() { - return "42"; + return "41"; } @Generic - Object doGeneric() { - return "43"; + Object doFallBack() { + return "42"; } } @@ -107,10 +108,11 @@ @NodeAssumptions({"additionalAssumption"}) abstract static class DerivedAssumptionNode extends SingleAssumptionNode { - @Specialization(order = 1, assumptions = "additionalAssumption") + @Specialization(assumptions = "additionalAssumption") int doIntDerived() { return 43; } + } @Test @@ -129,7 +131,7 @@ @NodeAssumptions({"additionalAssumption", "assumption"}) abstract static class DerivedAssumptionRedeclaredNode extends SingleAssumptionNode { - @Specialization(order = 1, assumptions = "additionalAssumption") + @Specialization(assumptions = "additionalAssumption") int doIntDerived() { return 43; } diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/CodeFormatTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/CodeFormatTest.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/CodeFormatTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -28,6 +28,9 @@ import com.oracle.truffle.api.dsl.test.CodeFormatTestFactory.LineWrappingTestFactory; import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; +/** + * Tests the generated code compiles without warnings for unusual large guard names. + */ public class CodeFormatTest { @Test diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ContainsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ContainsTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -0,0 +1,603 @@ +/* + * 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 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.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 node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { + if (value instanceof String) { + // assert that the final specialization is always Object + Assert.assertEquals(Object.class, ((DSLNode) node.getNode()).getMetadata0().getSpecializedTypes()[0]); + } + } + }); + } + + @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") + 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 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; + } + + @Implies("isGreaterZero") + static boolean isOne(int a) { + return a == 1; + } + + @Specialization(guards = {"isOne"}) + int f1(int a) { + return a + 1; + } + + @Specialization(contains = "f1", guards = {"isGreaterZero"}) + 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 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 isGreaterEqualZero(int a) { + return a >= 0; + } + + @Implies("isGreaterEqualZero") + static boolean isOne(int a) { + return a == 1; + } + + @Specialization(guards = {"isOne"}) + int f0(int a) { + return 1; + } + + @Specialization(contains = "f0", guards = {"isGreaterEqualZero"}) + 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).", "The contained specialization 'f0' is not fully compatible.%"}) + @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; + } + + @ExpectError("The contained specialization 'f0' is not fully compatible.%") + @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; + } + + @ExpectError("The contained specialization 'f0' is not fully compatible.%") + @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().", "The contained specialization 'f0' is not fully compatible.%"}) + @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; + } + + @ExpectError({"The contained specialization 'f0' is not fully compatible.%"}) + @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; + } + + @ExpectError({"The contained specialization 'f0' is not fully compatible.%"}) + @Specialization(guards = "g2", contains = "f0") + Object f1() { + return null; + } + } + + abstract static class ContainsGuard5 extends ValueNode { + + @Implies("g2") + 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 { + + @Implies("!g2") + 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; + } + } + + @NodeAssumptions("a1") + abstract static class ContainsAssumption1 extends ValueNode { + + @Specialization(assumptions = "a1") + Object f0() { + return null; + } + + @Specialization(contains = "f0") + Object f1() { + return null; + } + } + + @NodeAssumptions("a1") + abstract static class ContainsAssumption2 extends ValueNode { + + @Specialization + Object f0() { + return null; + } + + @ExpectError({"Specialization is not reachable. It is shadowed by f0().", "The contained specialization 'f0' is not fully compatible.%"}) + @Specialization(contains = "f0", assumptions = "a1") + Object f1() { + return null; + } + } + + @NodeAssumptions({"a1", "a2"}) + abstract static class ContainsAssumption3 extends ValueNode { + + @Specialization(assumptions = "a1") + Object f0() { + return null; + } + + @ExpectError({"The contained specialization 'f0' is not fully compatible.%"}) + @Specialization(contains = "f0", assumptions = "a2") + Object f1() { + return null; + } + } + + @NodeAssumptions({"a1", "a2"}) + abstract static class ContainsAssumption4 extends ValueNode { + + @Specialization(assumptions = {"a1", "a2"}) + Object f0() { + return null; + } + + @Specialization(contains = "f0", assumptions = "a1") + Object f1() { + return null; + } + } + + @NodeAssumptions({"a1", "a2"}) + abstract static class ContainsAssumption5 extends ValueNode { + + @Specialization(assumptions = {"a2", "a1"}) + Object f0() { + return null; + } + + @Specialization(contains = "f0", assumptions = "a1") + 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; + } + } + +} diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/FallbackTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/FallbackTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -0,0 +1,186 @@ +/* + * 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 org.junit.*; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.test.FallbackTestFactory.Fallback1Factory; +import com.oracle.truffle.api.dsl.test.FallbackTestFactory.Fallback2Factory; +import com.oracle.truffle.api.dsl.test.FallbackTestFactory.Fallback3Factory; +import com.oracle.truffle.api.dsl.test.FallbackTestFactory.Fallback4Factory; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.*; +import com.oracle.truffle.api.nodes.*; + +public class FallbackTest { + + private static final Object UNKNOWN_OBJECT = new Object() { + }; + + @Test + public void testFallback1() { + assertRuns(Fallback1Factory.getInstance(), // + array(42, UNKNOWN_OBJECT), // + array("(int)", "(fallback)")); + } + + /** + * test with fallback handler defined + */ + @SuppressWarnings("unused") + @NodeChild("a") + abstract static class Fallback1 extends ValueNode { + + @Specialization + String f1(int a) { + return "(int)"; + } + + @Generic + String f2(Object a) { + return "(fallback)"; + } + } + + @Test + public void testFallback2() { + assertRuns(Fallback2Factory.getInstance(), // + array(42, UNKNOWN_OBJECT), // + array("(int)", UnsupportedSpecializationException.class)); + } + + /** + * test without fallback handler defined + */ + @SuppressWarnings("unused") + @NodeChild("a") + abstract static class Fallback2 extends ValueNode { + + @Specialization + String f1(int a) { + return "(int)"; + } + + } + + @Test + public void testFallback3() { + assertRuns(Fallback3Factory.getInstance(), // + array(42, 43, UNKNOWN_OBJECT, "somestring"), // + array("(int)", "(int)", "(object)", "(object)")); + } + + /** + * test without fallback handler and unreachable + */ + @SuppressWarnings("unused") + @NodeChild("a") + abstract static class Fallback3 extends ValueNode { + + @Specialization + String f1(int a) { + return "(int)"; + } + + @Specialization(guards = "notInt") + String f2(Object a) { + return "(object)"; + } + + boolean notInt(Object value) { + return !(value instanceof Integer); + } + + } + + /** + * Tests the contents of the {@link UnsupportedSpecializationException} contents in polymorphic + * nodes. + */ + @Test + public void testFallback4() { + TestRootNode node = createRoot(Fallback4Factory.getInstance()); + + Assert.assertEquals("(int)", executeWith(node, 1)); + Assert.assertEquals("(boolean)", executeWith(node, true)); + try { + executeWith(node, UNKNOWN_OBJECT); + Assert.fail(); + } catch (UnsupportedSpecializationException e) { + Assert.assertEquals(node.getNode(), e.getNode()); + Assert.assertArrayEquals(NodeUtil.findNodeChildren(node.getNode()).subList(0, 1).toArray(new Node[0]), e.getSuppliedNodes()); + Assert.assertArrayEquals(new Object[]{UNKNOWN_OBJECT}, e.getSuppliedValues()); + } + } + + /** + * test without fallback handler and unreachable + */ + @SuppressWarnings("unused") + @NodeChild("a") + abstract static class Fallback4 extends ValueNode { + + @Specialization + String f1(int a) { + return "(int)"; + } + + @Specialization + String f2(boolean a) { + return "(boolean)"; + } + } + + /** + * Tests the contents of the {@link UnsupportedSpecializationException} contents in monomorphic + * nodes. + */ + @Test + public void testFallback5() { + TestRootNode node = createRoot(Fallback4Factory.getInstance()); + + Assert.assertEquals("(int)", executeWith(node, 1)); + try { + executeWith(node, UNKNOWN_OBJECT); + Assert.fail(); + } catch (UnsupportedSpecializationException e) { + Assert.assertEquals(node.getNode(), e.getNode()); + Assert.assertArrayEquals(NodeUtil.findNodeChildren(node.getNode()).subList(0, 1).toArray(new Node[0]), e.getSuppliedNodes()); + Assert.assertArrayEquals(new Object[]{UNKNOWN_OBJECT}, e.getSuppliedValues()); + } + } + + // test without fallback handler and unreachable + @SuppressWarnings("unused") + @NodeChild("a") + abstract static class Fallback5 extends ValueNode { + + @Specialization + String f1(int a) { + return "(int)"; + } + } + +} diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java Mon Aug 11 15:53:05 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,315 +0,0 @@ -/* - * 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.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.GuardsTestFactory.GlobalFlagGuardFactory; -import com.oracle.truffle.api.dsl.test.GuardsTestFactory.GuardWithBaseClassFactory; -import com.oracle.truffle.api.dsl.test.GuardsTestFactory.GuardWithBaseInterfaceFactory; -import com.oracle.truffle.api.dsl.test.GuardsTestFactory.GuardWithBoxedPrimitiveFactory; -import com.oracle.truffle.api.dsl.test.GuardsTestFactory.GuardWithObjectFactory; -import com.oracle.truffle.api.dsl.test.GuardsTestFactory.InvocationGuardFactory; -import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestAbstractGuard1Factory; -import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestGuardResolve1Factory; -import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestGuardResolve2Factory; -import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestGuardResolve3Factory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.Abstract; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.BExtendsAbstract; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.CExtendsAbstract; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -@SuppressWarnings("unused") -public class GuardsTest { - - private static final Object NULL = new Object(); - - @Test - public void testGuardInvocations() { - TestRootNode root = createRoot(InvocationGuardFactory.getInstance()); - - assertEquals(Integer.MAX_VALUE, executeWith(root, Integer.MAX_VALUE - 1, 1)); - assertEquals(1, InvocationGuard.specializedInvocations); - assertEquals(0, InvocationGuard.genericInvocations); - - assertEquals(42, executeWith(root, Integer.MAX_VALUE, 1)); - assertEquals(1, InvocationGuard.specializedInvocations); - assertEquals(1, InvocationGuard.genericInvocations); - } - - @NodeChildren({@NodeChild("value0"), @NodeChild("value1")}) - public abstract static class InvocationGuard extends ValueNode { - - static int specializedInvocations = 0; - static int genericInvocations = 0; - - boolean guard(int value0, int value1) { - return value0 != Integer.MAX_VALUE; - } - - @Specialization(guards = "guard") - int doSpecialized(int value0, int value1) { - specializedInvocations++; - return value0 + value1; - } - - @Generic - int doGeneric(Object value0, Object value1) { - genericInvocations++; - return 42; // the generic answer to all questions - } - } - - @Test - public void testGuardGlobal() { - TestRootNode root = createRoot(GlobalFlagGuardFactory.getInstance()); - - assertEquals(42, executeWith(root, NULL)); - - GlobalFlagGuard.globalFlag = true; - assertEquals(41, executeWith(root, NULL)); - - GlobalFlagGuard.globalFlag = false; - assertEquals(42, executeWith(root, NULL)); - } - - @NodeChild("expression") - public abstract static class GlobalFlagGuard extends ValueNode { - - static boolean globalFlag = false; - - static boolean globalFlagGuard() { - return globalFlag; - } - - @Specialization(guards = "globalFlagGuard") - int doSpecialized(Object value0) { - return 41; - } - - @Generic - int doGeneric(Object value0) { - return 42; // the generic answer to all questions - } - } - - @Test - public void testGuardWithBaseClass() { - TestRootNode root = createRoot(GuardWithBaseClassFactory.getInstance()); - - assertEquals(42, executeWith(root, new BExtendsAbstract())); - } - - @NodeChild("expression") - public abstract static class GuardWithBaseClass extends ValueNode { - - boolean baseGuard(Abstract base) { - return true; - } - - @Specialization(guards = "baseGuard") - int doSpecialized(BExtendsAbstract value0) { - return 42; - } - } - - @Test - public void testGuardWithBaseInterface() { - TestRootNode root = createRoot(GuardWithBaseInterfaceFactory.getInstance()); - - assertEquals(42, executeWith(root, "anything")); - } - - @NodeChild("expression") - public abstract static class GuardWithBaseInterface extends ValueNode { - - boolean baseGuard(CharSequence base) { - return true; - } - - @Specialization(guards = "baseGuard") - int doSpecialized(String value0) { - return 42; - } - } - - @Test - public void testGuardWithPrimitive() { - TestRootNode root = createRoot(GuardWithBoxedPrimitiveFactory.getInstance()); - - assertEquals(42, executeWith(root, 42)); - } - - @NodeChild("expression") - public abstract static class GuardWithBoxedPrimitive extends ValueNode { - - boolean baseGuard(Integer primitive) { - return true; - } - - @Specialization(guards = "baseGuard") - int doSpecialized(int value0) { - return value0; - } - } - - @Test - public void testGuardWithObject() { - TestRootNode root = createRoot(GuardWithObjectFactory.getInstance()); - - assertEquals(42, executeWith(root, 42)); - } - - @NodeChild("expression") - public abstract static class GuardWithObject extends ValueNode { - - boolean baseGuard(Object primitive) { - return true; - } - - @Specialization(guards = "baseGuard") - int doSpecialized(int value0) { - return value0; - } - } - - @Test - public void testGuardResolve1() { - TestRootNode root = createRoot(TestGuardResolve1Factory.getInstance()); - - assertEquals(42, executeWith(root, 42)); - } - - @NodeChild("expression") - public abstract static class TestGuardResolve1 extends ValueNode { - - boolean guard(Object primitive) { - return false; - } - - boolean guard(int primitive) { - return true; - } - - @Specialization(guards = "guard") - int doSpecialized(int value0) { - return value0; - } - } - - @Test - public void testGuardResolve2() { - TestRootNode root = createRoot(TestGuardResolve2Factory.getInstance()); - assertEquals(42, executeWith(root, new BExtendsAbstract())); - } - - @NodeChild("expression") - public abstract static class TestGuardResolve2 extends ValueNode { - - boolean guard(Object primitive) { - return false; - } - - boolean guard(Abstract primitive) { - return true; - } - - @Specialization(guards = "guard") - int doSpecialized(BExtendsAbstract value0) { - return 42; - } - } - - @Test - public void testGuardResolve3() { - TestRootNode root = createRoot(TestGuardResolve3Factory.getInstance()); - - assertEquals(42, executeWith(root, new BExtendsAbstract())); - } - - @NodeChild("expression") - public abstract static class TestGuardResolve3 extends ValueNode { - - boolean guard(Object primitive) { - return false; - } - - boolean guard(Abstract primitive) { - return false; - } - - boolean guard(BExtendsAbstract primitive) { - return true; - } - - @Specialization(guards = "guard") - int doSpecialized(BExtendsAbstract value0) { - return 42; - } - } - - @NodeChild("expression") - public abstract static class TestGuardResolve4 extends ValueNode { - - boolean guard(Abstract primitive) { - return false; - } - - @Specialization(guards = "guard") - int doSpecialized(BExtendsAbstract value0) { - return 42; - } - } - - @Test - public void testAbstractGuard1() { - TestRootNode root = createRoot(TestAbstractGuard1Factory.getInstance()); - - assertEquals(BExtendsAbstract.INSTANCE, executeWith(root, BExtendsAbstract.INSTANCE)); - assertEquals(CExtendsAbstract.INSTANCE, executeWith(root, CExtendsAbstract.INSTANCE)); - } - - @NodeChild("expression") - public abstract static class TestAbstractGuard1 extends ValueNode { - - boolean guard(Abstract value0) { - return true; - } - - @Specialization(order = 1, guards = "guard") - BExtendsAbstract doSpecialized1(BExtendsAbstract value0) { - return value0; - } - - @Specialization(order = 2, guards = "guard") - CExtendsAbstract doSpecialized2(CExtendsAbstract value0) { - return value0; - } - } - -} diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImplicitCastTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImplicitCastTest.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImplicitCastTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -34,7 +34,7 @@ public class ImplicitCastTest { - @TypeSystem({int.class, boolean.class, String.class}) + @TypeSystem({int.class, String.class, boolean.class}) static class ImplicitCast0Types { @ImplicitCast @@ -55,12 +55,12 @@ public abstract Object executeEvaluated(VirtualFrame frame, Object value2); - @Specialization(order = 1) + @Specialization public String op1(String value) { return value; } - @Specialization(order = 2) + @Specialization public boolean op1(boolean value) { return value; } @@ -81,22 +81,21 @@ @TypeSystemReference(ImplicitCast0Types.class) @NodeChild(value = "operand", type = ImplicitCast1Node.class) - // TODO temporary workaround abstract static class ImplicitCast1Node extends ValueNode { public abstract Object executeEvaluated(VirtualFrame frame, Object operand); - @Specialization(order = 0) + @Specialization public String op0(String value) { return value; } - @Specialization(order = 1, rewriteOn = RuntimeException.class) + @Specialization(rewriteOn = RuntimeException.class) public boolean op1(@SuppressWarnings("unused") boolean value) throws RuntimeException { throw new RuntimeException(); } - @Specialization(order = 2) + @Specialization(contains = "op1") public boolean op2(boolean value) { return value; } @@ -120,18 +119,18 @@ // TODO temporary workaround abstract static class ImplicitCast2Node extends ValueNode { - @Specialization(order = 0) + @Specialization public String op0(String v0, String v1) { return v0 + v1; } @SuppressWarnings("unused") - @Specialization(order = 1, rewriteOn = RuntimeException.class) + @Specialization(rewriteOn = RuntimeException.class) public boolean op1(boolean v0, boolean v1) throws RuntimeException { throw new RuntimeException(); } - @Specialization(order = 2) + @Specialization(contains = "op1") public boolean op2(boolean v0, boolean v1) { return v0 && v1; } @@ -156,4 +155,15 @@ Assert.assertEquals(true, root.getNode().executeEvaluated(null, true, true)); } + @TypeSystem({String.class, boolean.class}) + static class ImplicitCastError1 { + + @ImplicitCast + @ExpectError("Target type and source type of an @ImplicitCast must not be the same type.") + String castInvalid(@SuppressWarnings("unused") String value) { + throw new AssertionError(); + } + + } + } diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/InsertBeforeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/InsertBeforeTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -0,0 +1,144 @@ +/* + * 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 com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; + +public class InsertBeforeTest { + + @NodeChild("a") + static class InsertBefore1Base extends ValueNode { + + boolean g1(int a) { + return a == 1; + } + + boolean g2(int a) { + return a == 2; + } + + @Specialization(guards = "g1") + int f1(int a) { + return a; + } + + @Specialization(guards = "g2") + int f3(int a) { + return a; + } + + } + + @NodeChild("a") + static class InsertBefore1T1 extends InsertBefore1Base { + + @Specialization + int f0(int a) { + return a; + } + + } + + @NodeChild("a") + static class InsertBefore1T2 extends InsertBefore1Base { + + boolean g0(int a) { + return a == 0; + } + + @Specialization(guards = "g0", insertBefore = "f1") + int f0(int a) { + return a; + } + + } + + @NodeChild("a") + static class InsertBefore1T3 extends InsertBefore1Base { + + boolean g0(int a) { + return a == 0; + } + + @Specialization(guards = "g0", insertBefore = "f3") + int f0(int a) { + return a; + } + + } + + @NodeChild("a") + @ExpectError({"Element int f3(int) at annotation @Specialization is erroneous: Specialization is not reachable. It is shadowed by f0(int).", + "Element int f1(int) at annotation @Specialization is erroneous: Specialization is not reachable. It is shadowed by f0(int)."}) + static class InsertBefore1T4 extends InsertBefore1Base { + + boolean g0(int a) { + return a == 0; + } + + @Specialization(insertBefore = "f1") + int f0(int a) { + return a; + } + + } + + @NodeChild("a") + @ExpectError({"Element int f3(int) at annotation @Specialization is erroneous: Specialization is not reachable. It is shadowed by f0(int)."}) + static class InsertBefore1T5 extends InsertBefore1Base { + + boolean g0(int a) { + return a == 0; + } + + @Specialization(insertBefore = "f3") + int f0(int a) { + return a; + } + + } + + @NodeChild("a") + static class InsertBefore1Error1 extends InsertBefore1Base { + + @ExpectError("Specializations can only be inserted before specializations in superclasses.") + @Specialization(insertBefore = "f0") + int f0(int a) { + return a; + } + + } + + @NodeChild("a") + static class InsertBefore1Error2 extends InsertBefore1Base { + + @ExpectError("The referenced specialization 'asdf' could not be found.") + @Specialization(insertBefore = "asdf") + int f0(int a) { + return a; + } + + } + +} diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MethodGuardsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MethodGuardsTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -0,0 +1,308 @@ +/* + * 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.junit.Assert.*; + +import org.junit.*; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GlobalFlagGuardFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardWithBaseClassFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardWithBoxedPrimitiveFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardWithObjectFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.InvocationGuardFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.TestAbstractGuard1Factory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.TestGuardResolve1Factory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.TestGuardResolve2Factory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.TestGuardResolve3Factory; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.Abstract; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.BExtendsAbstract; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.CExtendsAbstract; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; + +@SuppressWarnings("unused") +public class MethodGuardsTest { + + private static final Object NULL = new Object(); + + @Test + public void testGuardInvocations() { + TestRootNode root = createRoot(InvocationGuardFactory.getInstance()); + + assertEquals(Integer.MAX_VALUE, executeWith(root, Integer.MAX_VALUE - 1, 1)); + assertEquals(1, InvocationGuard.specializedInvocations); + assertEquals(0, InvocationGuard.genericInvocations); + + assertEquals(42, executeWith(root, Integer.MAX_VALUE, 1)); + assertEquals(1, InvocationGuard.specializedInvocations); + assertEquals(1, InvocationGuard.genericInvocations); + } + + @NodeChildren({@NodeChild("value0"), @NodeChild("value1")}) + public abstract static class InvocationGuard extends ValueNode { + + static int specializedInvocations = 0; + static int genericInvocations = 0; + + boolean guard(int value0, int value1) { + return value0 != Integer.MAX_VALUE; + } + + @Specialization(guards = "guard") + int doSpecialized(int value0, int value1) { + specializedInvocations++; + return value0 + value1; + } + + @Generic + int doGeneric(Object value0, Object value1) { + genericInvocations++; + return 42; // the generic answer to all questions + } + } + + @Test + public void testGuardGlobal() { + TestRootNode root = createRoot(GlobalFlagGuardFactory.getInstance()); + + assertEquals(42, executeWith(root, NULL)); + + GlobalFlagGuard.globalFlag = true; + assertEquals(41, executeWith(root, NULL)); + + GlobalFlagGuard.globalFlag = false; + assertEquals(42, executeWith(root, NULL)); + } + + @NodeChild("expression") + public abstract static class GlobalFlagGuard extends ValueNode { + + static boolean globalFlag = false; + + static boolean globalFlagGuard() { + return globalFlag; + } + + @Specialization(guards = "globalFlagGuard") + int doSpecialized(Object value0) { + return 41; + } + + @Generic + int doGeneric(Object value0) { + return 42; // the generic answer to all questions + } + } + + @Test + public void testGuardWithBaseClass() { + TestRootNode root = createRoot(GuardWithBaseClassFactory.getInstance()); + + assertEquals(42, executeWith(root, new BExtendsAbstract())); + } + + @NodeChild("expression") + public abstract static class GuardWithBaseClass extends ValueNode { + + boolean baseGuard(Abstract base) { + return true; + } + + @Specialization(guards = "baseGuard") + int doSpecialized(BExtendsAbstract value0) { + return 42; + } + } + + @NodeChild("expression") + public abstract static class GuardWithBaseInterface extends ValueNode { + + boolean baseGuard(CharSequence base) { + return true; + } + + @Specialization(guards = "baseGuard") + @ExpectError("No compatible guard with method name 'baseGuard' found. Please note that all signature types of the method guard must be declared in the type system.") + int doSpecialized(String value0) { + return 42; + } + } + + @Test + public void testGuardWithPrimitive() { + TestRootNode root = createRoot(GuardWithBoxedPrimitiveFactory.getInstance()); + + assertEquals(42, executeWith(root, 42)); + } + + @NodeChild("expression") + public abstract static class GuardWithBoxedPrimitive extends ValueNode { + + boolean baseGuard(Integer primitive) { + return true; + } + + @Specialization(guards = "baseGuard") + int doSpecialized(int value0) { + return value0; + } + } + + @Test + public void testGuardWithObject() { + TestRootNode root = createRoot(GuardWithObjectFactory.getInstance()); + + assertEquals(42, executeWith(root, 42)); + } + + @NodeChild("expression") + public abstract static class GuardWithObject extends ValueNode { + + boolean baseGuard(Object primitive) { + return true; + } + + @Specialization(guards = "baseGuard") + int doSpecialized(int value0) { + return value0; + } + } + + @Test + public void testGuardResolve1() { + TestRootNode root = createRoot(TestGuardResolve1Factory.getInstance()); + + assertEquals(42, executeWith(root, 42)); + } + + @NodeChild("expression") + public abstract static class TestGuardResolve1 extends ValueNode { + + boolean guard(Object primitive) { + return false; + } + + boolean guard(int primitive) { + return true; + } + + @Specialization(guards = "guard") + int doSpecialized(int value0) { + return value0; + } + } + + @Test + public void testGuardResolve2() { + TestRootNode root = createRoot(TestGuardResolve2Factory.getInstance()); + assertEquals(42, executeWith(root, new BExtendsAbstract())); + } + + @NodeChild("expression") + public abstract static class TestGuardResolve2 extends ValueNode { + + boolean guard(Object primitive) { + return false; + } + + boolean guard(Abstract primitive) { + return true; + } + + @Specialization(guards = "guard") + int doSpecialized(BExtendsAbstract value0) { + return 42; + } + } + + @Test + public void testGuardResolve3() { + TestRootNode root = createRoot(TestGuardResolve3Factory.getInstance()); + + assertEquals(42, executeWith(root, new BExtendsAbstract())); + } + + @NodeChild("expression") + public abstract static class TestGuardResolve3 extends ValueNode { + + boolean guard(Object primitive) { + return false; + } + + boolean guard(Abstract primitive) { + return false; + } + + boolean guard(BExtendsAbstract primitive) { + return true; + } + + @Specialization(guards = "guard") + int doSpecialized(BExtendsAbstract value0) { + return 42; + } + } + + @NodeChild("expression") + public abstract static class TestGuardResolve4 extends ValueNode { + + boolean guard(Abstract primitive) { + return false; + } + + @Specialization(guards = "guard") + int doSpecialized(BExtendsAbstract value0) { + return 42; + } + } + + @Test + public void testAbstractGuard1() { + TestRootNode root = createRoot(TestAbstractGuard1Factory.getInstance()); + + assertEquals(BExtendsAbstract.INSTANCE, executeWith(root, BExtendsAbstract.INSTANCE)); + assertEquals(CExtendsAbstract.INSTANCE, executeWith(root, CExtendsAbstract.INSTANCE)); + } + + @NodeChild("expression") + public abstract static class TestAbstractGuard1 extends ValueNode { + + boolean guard(Abstract value0) { + return true; + } + + @Specialization(guards = "guard") + BExtendsAbstract do1(BExtendsAbstract value0) { + return value0; + } + + @Specialization(guards = "guard") + CExtendsAbstract do2(CExtendsAbstract value0) { + return value0; + } + } + +} diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NegatedGuardsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NegatedGuardsTest.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NegatedGuardsTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -45,12 +45,12 @@ return true; } - @Specialization(order = 1, guards = "!guard") + @Specialization(guards = "!guard") int do1() { throw new AssertionError(); } - @Specialization(order = 2) + @Specialization() int do2() { return 42; // the generic answer to all questions } diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeFieldTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeFieldTest.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeFieldTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -117,12 +117,12 @@ public abstract String getField(); - @Specialization(order = 1, rewriteOn = RuntimeException.class) + @Specialization(rewriteOn = RuntimeException.class) String alwaysRewrite() { throw new RuntimeException(); } - @Specialization(order = 2) + @Specialization(contains = "alwaysRewrite") String returnField() { return getField(); } diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -25,11 +25,15 @@ import static com.oracle.truffle.api.dsl.test.TestHelper.*; import static org.junit.Assert.*; +import java.util.*; + import org.junit.*; import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.BinaryNodeTest.BinaryNode; -import com.oracle.truffle.api.dsl.test.PolymorphicTestFactory.Node1Factory; +import com.oracle.truffle.api.dsl.test.PolymorphicTestFactory.Polymorphic1Factory; +import com.oracle.truffle.api.dsl.test.PolymorphicTestFactory.Polymorphic2Factory; +import com.oracle.truffle.api.dsl.test.PolymorphicTestFactory.Polymorphic3Factory; +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.*; @@ -47,103 +51,155 @@ } } + public static void assertNoDuplicates(Node node, Node... ignored) { + assertNoDuplicatesRec(new HashSet<>(Arrays.asList(ignored)), new HashSet>(), node); + } + + private static void assertNoDuplicatesRec(Set ignored, Set> seenClasses, Node current) { + if (!ignored.contains(current)) { + if (seenClasses.contains(current.getClass())) { + Assert.fail(String.format("Multiple occurences of the same class %s. %nTree: %s", current.getClass().getSimpleName(), NodeUtil.printCompactTreeToString(current.getRootNode()))); + } else { + seenClasses.add(current.getClass()); + } + } + + for (Node child : current.getChildren()) { + if (child != null) { + assertNoDuplicatesRec(ignored, seenClasses, child); + } + } + } + @Test - public void testJustSpecialize() { - TestRootNode node = TestHelper.createRoot(Node1Factory.getInstance()); - assertEquals("(int,int)", executeWith(node, 42, 42)); - assertEquals("(boolean,boolean)", executeWith(node, false, false)); - assertEquals("(int,boolean)", executeWith(node, 42, false)); - assertEquals("(boolean,int)", executeWith(node, false, 42)); - assertEquals(NodeCost.MONOMORPHIC, node.getNode().getCost()); - assertParent(node.getNode(), node.getNode().getLeft()); - assertParent(node.getNode(), node.getNode().getRight()); + public void testPolymorphic1() { + assertRuns(Polymorphic1Factory.getInstance(), // + array(42, 43, true, false, "a", "b"), // + array(42, 43, true, false, "a", "b"),// + new ExecutionListener() { + public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { + Polymorphic1 polymorphic = ((Polymorphic1) node.getNode()); + assertParent(node.getNode(), polymorphic.getA()); + assertNoDuplicates(polymorphic, polymorphic.getA()); + if (index == 0) { + assertEquals(NodeCost.MONOMORPHIC, node.getNode().getCost()); + } + } + }); + } + + @NodeChild("a") + abstract static class Polymorphic1 extends ValueNode { + + public abstract ValueNode getA(); + + @Specialization + int add(int a) { + return a; + } + + @Specialization + boolean add(boolean a) { + return a; + } + + @Specialization + String add(String a) { + return a; + } + + @Generic + String add(Object left) { + throw new AssertionError(left.toString()); + } + } @Test public void testPolymorphic2() { - TestRootNode node = TestHelper.createRoot(Node1Factory.getInstance()); - assertEquals("(int,boolean)", executeWith(node, 42, false)); - assertEquals("(int,int)", executeWith(node, 42, 42)); - assertEquals(NodeCost.POLYMORPHIC, node.getNode().getCost()); - assertParent(node.getNode(), node.getNode().getLeft()); - assertParent(node.getNode(), node.getNode().getRight()); + assertRuns(Polymorphic2Factory.getInstance(), // + array(0, 1, 1, "1", "2", 2, 3), // + array(0, 1, 1, "1", "2", 2, 3),// + new ExecutionListener() { + public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { + Polymorphic2 polymorphic = ((Polymorphic2) node.getNode()); + assertParent(node.getNode(), polymorphic.getA()); + assertNoDuplicates(polymorphic, polymorphic.getA()); + if (index == 0) { + assertEquals(NodeCost.MONOMORPHIC, node.getNode().getCost()); + } + } + }); + } + + @NodeChild("a") + abstract static class Polymorphic2 extends ValueNode { + + public abstract ValueNode getA(); + + @Specialization + String s2(String a) { + return a; + } + + @Specialization(rewriteOn = RuntimeException.class) + int s0(int a) { + if (a == 1) { + throw new RuntimeException(); + } + return a; + } + + @Specialization + int s1(int a) { + return a; + } + } @Test public void testPolymorphic3() { - TestRootNode node = TestHelper.createRoot(Node1Factory.getInstance()); - assertEquals("(int,boolean)", executeWith(node, 42, false)); - assertEquals("(boolean,boolean)", executeWith(node, true, false)); - assertEquals("(int,int)", executeWith(node, 42, 42)); - assertEquals(NodeCost.POLYMORPHIC, node.getNode().getCost()); - assertParent(node.getNode(), node.getNode().getLeft()); - assertParent(node.getNode(), node.getNode().getRight()); - } - - @Test - public void testGenericLimitReached() { - TestRootNode node = TestHelper.createRoot(Node1Factory.getInstance()); - assertEquals("(boolean,int)", executeWith(node, false, 42)); - assertEquals("(int,boolean)", executeWith(node, 42, false)); - assertEquals("(boolean,boolean)", executeWith(node, true, false)); - assertEquals("(int,int)", executeWith(node, 42, 42)); - assertEquals(NodeCost.MEGAMORPHIC, node.getNode().getCost()); - assertParent(node.getNode(), node.getNode().getLeft()); - assertParent(node.getNode(), node.getNode().getRight()); - } - - @Test - public void testGenericInitial() { - TestRootNode node = TestHelper.createRoot(Node1Factory.getInstance()); - assertEquals("(generic,generic)", executeWith(node, "1", "1")); - assertEquals(NodeCost.MEGAMORPHIC, node.getNode().getCost()); - assertParent(node.getNode(), node.getNode().getLeft()); - assertParent(node.getNode(), node.getNode().getRight()); + assertRuns(Polymorphic3Factory.getInstance(), // + array("0", "1", 1, 1, 2, 2, 3, 3), // + array("0", "1", 1, 1, 2, 2, 3, 3),// + new ExecutionListener() { + public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { + Polymorphic3 polymorphic = ((Polymorphic3) node.getNode()); + assertParent(node.getNode(), polymorphic.getA()); + assertNoDuplicates(polymorphic, polymorphic.getA()); + } + }); } - @Test - public void testGenericPolymorphic1() { - TestRootNode node = TestHelper.createRoot(Node1Factory.getInstance()); - assertEquals("(boolean,int)", executeWith(node, false, 42)); - assertEquals("(boolean,boolean)", executeWith(node, false, false)); - assertEquals("(generic,generic)", executeWith(node, "", "")); - assertEquals(NodeCost.MEGAMORPHIC, node.getNode().getCost()); - /* Assertions for bug GRAAL-425 */ - assertParent(node.getNode(), node.getNode().getLeft()); - assertParent(node.getNode(), node.getNode().getRight()); - } + @NodeChild("a") + abstract static class Polymorphic3 extends ValueNode { - @SuppressWarnings("unused") - @PolymorphicLimit(3) - abstract static class Node1 extends BinaryNode { - - public abstract ValueNode getLeft(); + public abstract ValueNode getA(); - public abstract ValueNode getRight(); - - @Specialization(order = 1) - String add(int left, int right) { - return "(int,int)"; + @Specialization + String s2(String a) { + return a; } - @Specialization(order = 2) - String add(boolean left, boolean right) { - return "(boolean,boolean)"; + @Specialization(rewriteOn = RuntimeException.class) + int s0(int a) { + if (a == 1) { + throw new RuntimeException(); + } + return a; } - @Specialization(order = 3) - String add(int left, boolean right) { - return "(int,boolean)"; + @Specialization(rewriteOn = RuntimeException.class) + int s1(int a) { + if (a == 1) { + throw new RuntimeException(); + } + return a; } - @Specialization(order = 4) - String add(boolean left, int right) { - return "(boolean,int)"; - } - - @Generic - String add(Object left, Object right) { - return "(generic,generic)"; + @Specialization + int s2(int a) { + return a; } } diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java Mon Aug 11 15:53:05 2014 +0200 @@ -29,7 +29,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.dsl.test.BinaryNodeTest.BinaryNode; -import com.oracle.truffle.api.dsl.test.PolymorphicTest2Factory.Node1Factory; +import com.oracle.truffle.api.dsl.test.PolymorphicTest2Factory.Polymorphic1Factory; import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; import com.oracle.truffle.api.nodes.*; @@ -38,7 +38,7 @@ @Test public void testMultipleTypes() { /* Tests the unexpected polymorphic case. */ - TestRootNode node = TestHelper.createRoot(Node1Factory.getInstance()); + TestRootNode node = TestHelper.createRoot(Polymorphic1Factory.getInstance()); assertEquals(21, executeWith(node, false, false)); assertEquals(42, executeWith(node, 21, 21)); assertEquals("(boolean,int)", executeWith(node, false, 42)); @@ -46,8 +46,7 @@ } @SuppressWarnings("unused") - @PolymorphicLimit(3) - abstract static class Node1 extends BinaryNode { + abstract static class Polymorphic1 extends BinaryNode { @Specialization(order = 1) int add(int left, int right) { diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ReachabilityTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ReachabilityTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -0,0 +1,353 @@ +package com.oracle.truffle.api.dsl.test; + +import java.math.*; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.*; + +public class ReachabilityTest { + + static class Reachability1 extends ValueNode { + @Specialization + int do2() { + return 2; + } + + @ExpectError("Specialization is not reachable. It is shadowed by do2().") + @Specialization + int do1() { + return 2; + } + } + + @NodeChildren({@NodeChild("a")}) + static class ReachabilityType1 extends ValueNode { + @Specialization + int do2(int a) { + return a; + } + + @ExpectError("Specialization is not reachable. It is shadowed by do2(int).") + @Specialization + int do1(int a) { + return a; + } + } + + @NodeChildren({@NodeChild("a")}) + static class ReachabilityType2 extends ValueNode { + @Specialization + BExtendsAbstract do2(BExtendsAbstract a) { + return a; + } + + @ExpectError("Specialization is not reachable. It is shadowed by do2(BExtendsAbstract).") + @Specialization + BExtendsAbstract do1(BExtendsAbstract a) { + return a; + } + } + + @NodeChildren({@NodeChild("a")}) + static class ReachabilityType3 extends ValueNode { + @Specialization + Abstract do2(Abstract a) { + return a; + } + + @ExpectError("Specialization is not reachable. It is shadowed by do2(Abstract).") + @Specialization + BExtendsAbstract do1(BExtendsAbstract a) { + return a; + } + } + + @NodeChildren({@NodeChild("a")}) + static class ReachabilityType4 extends ValueNode { + + @Specialization + BExtendsAbstract do2(BExtendsAbstract a) { + return a; + } + + @Specialization + Abstract do1(Abstract a) { + return a; + } + + } + + @NodeChildren({@NodeChild("a")}) + static class ReachabilityType5 extends ValueNode { + + @Specialization + double do2(double a) { + return a; + } + + @ExpectError("Specialization is not reachable. It is shadowed by do2(double).") + @Specialization + int do1(int a) { + return a; + } + + } + + @NodeChildren({@NodeChild("a")}) + static class ReachabilityType6 extends ValueNode { + + @Specialization + BigInteger do2(BigInteger a) { + return a; + } + + @ExpectError("Specialization is not reachable. It is shadowed by do2(BigInteger).") + @Specialization + int do1(int a) { + return a; + } + + } + + @NodeChildren({@NodeChild("a")}) + static class ReachabilityType7 extends ValueNode { + + @Specialization + int do2(int a) { + return a; + } + + @Specialization + BigInteger do1(BigInteger a) { + return a; + } + + } + + @NodeChildren({@NodeChild("a")}) + static class ReachabilityType8 extends ValueNode { + + @Specialization + int do2(int a) { + return a; + } + + @Specialization + Object do1(Object a) { + return a; + } + + } + + @NodeChildren({@NodeChild("a")}) + static class ReachabilityType9 extends ValueNode { + + @Specialization + Object do2(Object a) { + return a; + } + + @ExpectError("Specialization is not reachable. It is shadowed by do2(Object).") + @Specialization + int do1(int a) { + return a; + } + } + + static class ReachabilityGuard1 extends ValueNode { + + boolean foo() { + return false; + } + + @Specialization(guards = "foo") + int do2() { + return 1; + } + + @Specialization + int do1() { + return 2; + } + + } + + static class ReachabilityGuard2 extends ValueNode { + + boolean foo() { + return false; + } + + @Specialization + int do2() { + return 2; + } + + @ExpectError("Specialization is not reachable. It is shadowed by do2().") + @Specialization(guards = "foo") + int do1() { + return 1; + } + + } + + static class ReachabilityGuard3 extends ValueNode { + + boolean foo() { + return false; + } + + @Specialization(guards = "foo") + int do2() { + return 1; + } + + @Specialization + int do1() { + return 2; + } + + } + + static class ReachabilityGuard4 extends ValueNode { + + boolean foo() { + return false; + } + + @Specialization(guards = "foo") + int do2() { + return 1; + } + + @ExpectError("Specialization is not reachable. It is shadowed by do2().") + @Specialization(guards = "foo") + int do1() { + return 2; + } + + } + + @NodeAssumptions({"a1"}) + static class ReachabilityAssumption1 extends ValueNode { + + @Specialization(assumptions = "a1") + int do2() { + return 1; + } + + @Specialization + int do1() { + return 2; + } + + } + + @NodeAssumptions({"a1"}) + static class ReachabilityAssumption2 extends ValueNode { + + @Specialization(assumptions = "a1") + int do2() { + return 1; + } + + @ExpectError("Specialization is not reachable. It is shadowed by do2().") + @Specialization(assumptions = "a1") + int do1() { + return 2; + } + + } + + @NodeAssumptions({"a1", "a2"}) + static class ReachabilityAssumption3 extends ValueNode { + + @Specialization(assumptions = {"a1", "a2"}) + int do2() { + return 1; + } + + @Specialization(assumptions = "a1") + int do1() { + return 2; + } + + } + + @NodeAssumptions({"a1", "a2"}) + static class ReachabilityAssumption4 extends ValueNode { + + @Specialization(assumptions = "a1") + int do2() { + return 1; + } + + @Specialization(assumptions = "a2") + int do1() { + return 2; + } + + } + + @NodeAssumptions({"a1", "a2"}) + static class ReachabilityAssumption5 extends ValueNode { + + @Specialization + int do2() { + return 1; + } + + @ExpectError("Specialization is not reachable. It is shadowed by do2().") + @Specialization(assumptions = "a2") + int do1() { + return 2; + } + + } + + @NodeAssumptions({"a1", "a2"}) + static class ReachabilityAssumption6 extends ValueNode { + + @Specialization(assumptions = {"a1"}) + int do2() { + return 1; + } + + @ExpectError("Specialization is not reachable. It is shadowed by do2().") + @Specialization(assumptions = {"a1", "a2"}) + int do1() { + return 2; + } + + } + + static class ReachabilityThrowable1 extends ValueNode { + + @Specialization(rewriteOn = RuntimeException.class) + int do2() throws RuntimeException { + return 1; + } + + @Specialization + int do1() { + return 2; + } + + } + + static class ReachabilityThrowable2 extends ValueNode { + + @Specialization + int do2() { + return 1; + } + + @ExpectError("Specialization is not reachable. It is shadowed by do2().") + @Specialization(rewriteOn = RuntimeException.class) + int do1() throws RuntimeException { + return 2; + } + + } + +} diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SlowPathTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SlowPathTest.java Mon Aug 11 15:53:05 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - * 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 org.junit.*; - -import com.oracle.truffle.api.CompilerDirectives.SlowPath; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.SlowPathTestFactory.SlowPathOnGeneric0Factory; -import com.oracle.truffle.api.dsl.test.SlowPathTestFactory.SlowPathOnGeneric1Factory; -import com.oracle.truffle.api.dsl.test.SlowPathTestFactory.SlowPathOnGeneric2Factory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** Tests the generated placement of {@link SlowPath} in generated methods. */ -public class SlowPathTest { - - @Test - public void testSlowPathOnGeneric0() throws NoSuchMethodException, SecurityException { - Node node = SlowPathOnGeneric0Factory.create(null); - Assert.assertNull(node.getClass().getSuperclass().getDeclaredMethod("executeGeneric0", VirtualFrame.class, Object.class).getAnnotation(SlowPath.class)); - } - - @NodeChild - abstract static class SlowPathOnGeneric0 extends ValueNode { - - @Specialization - @SuppressWarnings("unused") - Object doObject0(VirtualFrame frame, int value0) { - throw new AssertionError(); - } - - } - - @Test - public void testSlowPathOnGeneric1() throws NoSuchMethodException, SecurityException { - Node node = SlowPathOnGeneric1Factory.create(null); - Assert.assertNotNull(node.getClass().getSuperclass().getDeclaredMethod("executeGeneric0", Object.class).getAnnotation(SlowPath.class)); - } - - @NodeChild - abstract static class SlowPathOnGeneric1 extends ValueNode { - - @Specialization - @SuppressWarnings("unused") - Object doObject0(int value0) { - throw new AssertionError(); - } - - } - - @Test - public void testSlowPathOnGeneric2() throws NoSuchMethodException, SecurityException { - Node node = SlowPathOnGeneric2Factory.create(null); - Assert.assertNull(node.getClass().getSuperclass().getDeclaredMethod("executeGeneric0", VirtualFrame.class, Object.class).getAnnotation(SlowPath.class)); - } - - @NodeChild - abstract static class SlowPathOnGeneric2 extends ValueNode { - - @Specialization(order = 0) - @SuppressWarnings("unused") - Object doObject0(int value0) { - throw new AssertionError(); - } - - @Specialization(order = 1) - @SuppressWarnings("unused") - Object doObject1(VirtualFrame frame, String value0) { - throw new AssertionError(); - } - - } - -} diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SpecializationFallthroughTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SpecializationFallthroughTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -0,0 +1,350 @@ +package com.oracle.truffle.api.dsl.test; + +import static com.oracle.truffle.api.dsl.test.TestHelper.*; + +import org.junit.*; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.test.SpecializationFallthroughTestFactory.FallthroughTest0Factory; +import com.oracle.truffle.api.dsl.test.SpecializationFallthroughTestFactory.FallthroughTest1Factory; +import com.oracle.truffle.api.dsl.test.SpecializationFallthroughTestFactory.FallthroughTest2Factory; +import com.oracle.truffle.api.dsl.test.SpecializationFallthroughTestFactory.FallthroughTest3Factory; +import com.oracle.truffle.api.dsl.test.SpecializationFallthroughTestFactory.FallthroughTest4Factory; +import com.oracle.truffle.api.dsl.test.SpecializationFallthroughTestFactory.FallthroughTest5Factory; +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; + +public class SpecializationFallthroughTest { + + @Test + public void testFallthrough0() { + assertRuns(FallthroughTest0Factory.getInstance(), // + array(0, 0, 1, 2), // + array(0, 0, 1, 2),// + new ExecutionListener() { + public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { + if (!last) { + return; + } + if (FallthroughTest0.fallthroughCount > 1) { + Assert.fail("The fallthrough case must never be triggered twice. Therfore count must be <= 1, but is not."); + } + } + }); + } + + @NodeChildren({@NodeChild("a")}) + static class FallthroughTest0 extends ValueNode { + + static int fallthroughCount = 0; + + public FallthroughTest0() { + fallthroughCount = 0; + } + + @Specialization(rewriteOn = ArithmeticException.class) + int do1(int a) throws ArithmeticException { + if (a == 0) { + fallthroughCount++; + throw new ArithmeticException(); + } + return a; + } + + @Generic + Object doFallback(Object a) { + return a; + } + } + + /* + * Tests that the fall through is never triggered twice for monomorphic cases. + */ + @Test + public void testFallthrough1() { + assertRuns(FallthroughTest1Factory.getInstance(), // + array(0, 0, 0, 1, 2), // + array(0, 0, 0, 1, 2),// + new ExecutionListener() { + public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { + if (!last) { + return; + } + if (FallthroughTest1.fallthroughCount > 1) { + Assert.fail("The fallthrough case must never be triggered twice. Therfore count must be <= 1, but is not."); + } + } + }); + } + + /* TODO assert falltrough do1 before do2 */ + @NodeChildren({@NodeChild("a")}) + static class FallthroughTest1 extends ValueNode { + + static int fallthroughCount; + + public FallthroughTest1() { + fallthroughCount = 0; + } + + @Specialization(rewriteOn = ArithmeticException.class) + int do1(int a) throws ArithmeticException { + if (a == 0) { + fallthroughCount++; + throw new ArithmeticException(); + } + return a; + } + + @Specialization + int do2(int a) { + return a; + } + + } + + /* + * Tests that the fall through is never triggered twice with two falltrhoughs in one operation. + */ + @Test + public void testFallthrough2() { + assertRuns(FallthroughTest2Factory.getInstance(), // + array(0, 0, 1, 1, 2, 2), // + array(0, 0, 1, 1, 2, 2),// + new ExecutionListener() { + public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { + if (!last) { + return; + } + if (FallthroughTest2.fallthrough1 > 1) { + Assert.fail(); + } + if (FallthroughTest2.fallthrough2 > 1) { + Assert.fail(); + } + FallthroughTest2.fallthrough1 = 0; + FallthroughTest2.fallthrough2 = 0; + } + }); + } + + @NodeChildren({@NodeChild("a")}) + static class FallthroughTest2 extends ValueNode { + + static int fallthrough1; + static int fallthrough2; + + @Specialization(order = 1, rewriteOn = ArithmeticException.class) + int do1(int a) throws ArithmeticException { + if (a == 0) { + fallthrough1++; + throw new ArithmeticException(); + } + return a; + } + + @Specialization(order = 2, rewriteOn = ArithmeticException.class) + int do2(int a) throws ArithmeticException { + if (a == 1) { + fallthrough2++; + throw new ArithmeticException(); + } + return a; + } + + @Specialization + int do3(int a) { + return a; + } + } + + /* + * Tests that the fall through is never triggered twice. In this case mixed fallthrough with + * normal specializations. + */ + @Test + public void testFallthrough3() { + assertRuns(FallthroughTest3Factory.getInstance(), // + array(0, 0, 1, 1, 2, 2), // + array(0, 0, 1, 1, 2, 2),// + new ExecutionListener() { + public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { + if (!last) { + return; + } + if (FallthroughTest3.fallthrough1 > 1) { + Assert.fail(String.valueOf(FallthroughTest3.fallthrough1)); + } + FallthroughTest3.fallthrough1 = 0; + } + }); + } + + @NodeChildren({@NodeChild("a")}) + static class FallthroughTest3 extends ValueNode { + + static int fallthrough1; + + boolean guard0(int a) { + return a == 1; + } + + @Specialization(guards = "guard0") + int do2(int a) { + return a; + } + + @Specialization(rewriteOn = ArithmeticException.class) + int do1(int a) throws ArithmeticException { + if (a == 0) { + fallthrough1++; + throw new ArithmeticException(); + } + return a; + } + + @Specialization + int do3(int a) { + return a; + } + + } + + @Test + public void testFallthrough4() { + assertRuns(FallthroughTest4Factory.getInstance(), // + array(0, 0, 1, 1, 2, 2), // + array(0, 0, 1, 1, 2, 2),// + new ExecutionListener() { + public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { + if (!last) { + return; + } + if (FallthroughTest4.fallthrough1 > 1) { + Assert.fail(String.valueOf(FallthroughTest4.fallthrough1)); + } + if (FallthroughTest4.fallthrough2 > 1) { + Assert.fail(String.valueOf(FallthroughTest4.fallthrough1)); + } + FallthroughTest4.fallthrough1 = 0; + FallthroughTest4.fallthrough2 = 0; + } + }); + } + + @NodeChildren({@NodeChild("a")}) + static class FallthroughTest4 extends ValueNode { + + static int fallthrough1; + static int fallthrough2; + + @Specialization(order = 1, rewriteOn = ArithmeticException.class) + int do1(int a) throws ArithmeticException { + if (a == 0) { + fallthrough1++; + throw new ArithmeticException(); + } + return a; + } + + @Specialization(order = 2, rewriteOn = ArithmeticException.class) + int do2(int a) throws ArithmeticException { + if (a == 1) { + fallthrough2++; + throw new ArithmeticException(); + } + return a; + } + + @Specialization + int do3(int a) { + return a; + } + + } + + @Test + public void testFallthrough5() { + assertRuns(FallthroughTest5Factory.getInstance(), // + array(0, 0, 1, 1, 2, 2), // + array(0, 0, 1, 1, 2, 2),// + new ExecutionListener() { + public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { + if (!last) { + return; + } + if (FallthroughTest5.fallthrough1 > 1) { + Assert.fail(String.valueOf(FallthroughTest5.fallthrough1)); + } + FallthroughTest5.fallthrough1 = 0; + } + }); + } + + @NodeChildren({@NodeChild("a")}) + static class FallthroughTest5 extends ValueNode { + + static int fallthrough1; + + @Specialization(guards = "isDo1", rewriteOn = ArithmeticException.class) + int do1(int a) throws ArithmeticException { + if (a == 0) { + fallthrough1++; + throw new ArithmeticException(); + } + return a; + } + + protected static boolean isDo1(int a) { + return a == 0 || a == 1; + } + + @Specialization(guards = "isDo1") + int do2(int a) { + return a; + } + + @Specialization + int do3(int a) { + return a; + } + + } + + @NodeChildren({@NodeChild("a")}) + static class FallthroughTest6 extends ValueNode { + + static int fallthrough1; + static int fallthrough2; + static int fallthrough3; + static int fallthrough4; + + @Specialization(order = 1, rewriteOn = ArithmeticException.class) + int do4(int a) throws ArithmeticException { + return a; + } + + @Specialization(order = 2, rewriteOn = ArithmeticException.class) + int do2(int a) throws ArithmeticException { + return a; + } + + @Specialization(order = 3, rewriteOn = ArithmeticException.class) + int do3(int a) throws ArithmeticException { + return a; + } + + @Specialization(order = 4, rewriteOn = ArithmeticException.class) + int do1(int a) throws ArithmeticException { + return a; + } + + @Specialization + double do5(double a) { + return a; + } + + } + +} diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SpecializationGroupingTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SpecializationGroupingTest.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SpecializationGroupingTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -48,7 +48,7 @@ MockAssumption a2 = new MockAssumption(false); MockAssumption a3 = new MockAssumption(true); - TestRootNode root = TestHelper.createGenericRoot(TestGroupingFactory.getInstance(), a1, a2, a3); + TestRootNode root = TestHelper.createRoot(TestGroupingFactory.getInstance(), a1, a2, a3); SimpleTypes.intCast = 0; SimpleTypes.intCheck = 0; @@ -59,29 +59,29 @@ TestGrouping.true3 = 0; Assert.assertEquals(42, TestHelper.executeWith(root, 21, 21)); - Assert.assertEquals(1, TestGrouping.true1); - Assert.assertEquals(1, TestGrouping.false1); - Assert.assertEquals(1, TestGrouping.true2); - Assert.assertEquals(1, TestGrouping.false2); - Assert.assertEquals(1, TestGrouping.true3); - Assert.assertEquals(2, SimpleTypes.intCheck); - Assert.assertEquals(2, SimpleTypes.intCast); - Assert.assertEquals(1, a1.checked); - Assert.assertEquals(1, a2.checked); - Assert.assertEquals(1, a3.checked); + Assert.assertEquals(4, TestGrouping.true1); + Assert.assertEquals(0, TestGrouping.false1); + Assert.assertEquals(4, TestGrouping.true2); + Assert.assertEquals(5, TestGrouping.false2); + Assert.assertEquals(5, TestGrouping.true3); + Assert.assertEquals(8, SimpleTypes.intCheck); + Assert.assertEquals(8, SimpleTypes.intCast); + Assert.assertEquals(4, a1.checked); + Assert.assertEquals(0, a2.checked); + Assert.assertEquals(4, a3.checked); Assert.assertEquals(42, TestHelper.executeWith(root, 21, 21)); - Assert.assertEquals(2, TestGrouping.true1); - Assert.assertEquals(2, TestGrouping.false1); - Assert.assertEquals(2, TestGrouping.true2); - Assert.assertEquals(2, TestGrouping.false2); - Assert.assertEquals(2, TestGrouping.true3); + Assert.assertEquals(5, TestGrouping.true1); + Assert.assertEquals(0, TestGrouping.false1); + Assert.assertEquals(5, TestGrouping.true2); + Assert.assertEquals(6, TestGrouping.false2); + Assert.assertEquals(6, TestGrouping.true3); - Assert.assertEquals(2, a1.checked); - Assert.assertEquals(2, a2.checked); - Assert.assertEquals(2, a3.checked); - Assert.assertEquals(4, SimpleTypes.intCheck); - Assert.assertEquals(4, SimpleTypes.intCast); + Assert.assertEquals(5, a1.checked); + Assert.assertEquals(0, a2.checked); + Assert.assertEquals(5, a3.checked); + Assert.assertEquals(8, SimpleTypes.intCheck); + Assert.assertEquals(8, SimpleTypes.intCast); } @@ -121,39 +121,39 @@ return true; } - @Specialization(order = 1) + @Specialization public int fail(int value1, String value2) { throw new AssertionError(); } - @Specialization(order = 2, guards = {"true1", "false1"}) - public int fail1(int value1, int value2) { - throw new AssertionError(); - } - - @Specialization(order = 3, guards = {"true1", "true2"}, assumptions = {"a1", "a2"}) - public int fail2(int value1, int value2) { - throw new AssertionError(); - } - - @Specialization(order = 4, guards = {"true1", "true2"}, assumptions = {"a1", "a3"}, rewriteOn = RuntimeException.class) + @Specialization(guards = {"true1", "true2", "!false2", "true3"}, assumptions = {"a1", "a3"}, rewriteOn = RuntimeException.class) public int throwRewrite(int value1, int value2) { throw new RuntimeException(); } - @Specialization(order = 5, guards = {"true1", "true2", "false2"}, assumptions = {"a1", "a3"}) + @Specialization(guards = {"true1", "true2", "!false2", "true3"}, contains = "throwRewrite", assumptions = {"a1", "a3"}) + public int success(int value1, int value2) { + return value1 + value2; + } + + @Specialization(guards = {"true1", "true2", "!false2", "!true3"}, assumptions = {"a1", "a3"}) + public int fail5(int value1, int value2) { + throw new AssertionError(); + } + + @Specialization(guards = {"true1", "true2", "false2"}, assumptions = {"a1", "a3"}) public int fail4(int value1, int value2) { throw new AssertionError(); } - @Specialization(order = 6, guards = {"true1", "true2", "!false2", "!true3"}, assumptions = {"a1", "a3"}) - public int fail5(int value1, int value2) { + @Specialization(guards = {"true1", "true2"}, assumptions = {"a1", "a3"}) + public int fail2break(int value1, int value2) { throw new AssertionError(); } - @Specialization(order = 7, guards = {"true1", "true2", "!false2", "true3"}, assumptions = {"a1", "a3"}) - public int success(int value1, int value2) { - return value1 + value2; + @Specialization(guards = {"true1", "false1"}) + public int fail1(int value1, int value2) { + throw new AssertionError(); } } @@ -168,18 +168,18 @@ @NodeChild(value = "genericChild", type = GenericInt.class) public abstract static class TestElseConnectionBug1 extends ValueNode { - @Specialization(order = 1, rewriteOn = {SlowPathException.class}, guards = "isInitialized") - public int doInteger(int value) throws SlowPathException { + @Specialization(rewriteOn = {SlowPathException.class}, guards = "isInitialized") + public int do1(int value) throws SlowPathException { throw new SlowPathException(); } - @Specialization(order = 3, guards = "isInitialized") - public int doObject(int value) { + @Specialization(contains = "do1", guards = "isInitialized") + public int do2(int value) { return value == 42 ? value : 0; } - @Specialization(order = 4, guards = "!isInitialized") - public Object doUninitialized(int value) { + @Specialization(guards = "!isInitialized") + public Object do3(int value) { throw new AssertionError(); } @@ -204,25 +204,25 @@ @Test public void testElseConnectionBug2() { - TestHelper.assertRuns(TestElseConnectionBug2Factory.getInstance(), 42, 42); + TestHelper.assertRuns(TestElseConnectionBug2Factory.getInstance(), new Object[]{42}, new Object[]{42}); } @SuppressWarnings("unused") @NodeChild public abstract static class TestElseConnectionBug2 extends ValueNode { - @Specialization(order = 2, guards = "guard0") - public int doGuard0(int value) { + @Specialization(guards = "guard0") + public int do1(int value) { throw new AssertionError(); } - @Specialization(order = 3, guards = "guard1") - public int doGuard1(int value) { + @Specialization(guards = "guard1") + public int do2(int value) { throw new AssertionError(); } - @Specialization(order = 4, guards = "!guard0") - public int doUninitialized(int value) { + @Specialization(guards = "!guard0") + public int do3(int value) { return value; } diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestHelper.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestHelper.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestHelper.java Mon Aug 11 15:53:05 2014 +0200 @@ -98,7 +98,7 @@ return createCallTarget(node).call(values); } - static Object array(Object... val) { + static Object[] array(Object... val) { return val; } @@ -138,29 +138,71 @@ return output; } + static void assertRuns(NodeFactory factory, Object[] testValues, Object[] result) { + assertRuns(factory, testValues, result, null); + } + /* Methods tests all test values in combinational order. */ - static void assertRuns(NodeFactory factory, Object result, Object... testValues) { + static void assertRuns(NodeFactory factory, Object[] testValues, Object[] result, ExecutionListener listener) { // test each run by its own. for (int i = 0; i < testValues.length; i++) { - assertValue(createRoot(factory), result, testValues); + assertValue(createRoot(factory), 0, testValues[i], result[i], listener, true); } // test all combinations of the test values - List> permuts = permutations(Arrays.asList(testValues)); + List testValuesList = Arrays.asList(testValues); + List> permuts = permutations(testValuesList); for (List list : permuts) { TestRootNode root = createRoot(factory); + int index = 0; for (Object object : list) { - assertValue(root, result, object); + assertValue(root, index, object, result[testValuesList.indexOf(object)], listener, index == list.size() - 1); + index++; } } } - static void assertValue(TestRootNode root, Object result, Object testValues) { - if (testValues instanceof Object[]) { - assertEquals(result, executeWith(root, (Object[]) testValues)); + static void assertValue(TestRootNode root, int index, Object value, Object result, ExecutionListener listener, boolean last) { + Object actualResult = null; + if (result instanceof Class && Throwable.class.isAssignableFrom((Class) result)) { + try { + if (value instanceof Object[]) { + actualResult = executeWith(root, (Object[]) value); + } else { + actualResult = executeWith(root, value); + } + fail(String.format("Exception %s expected but not occured.", result.getClass())); + } catch (Throwable e) { + actualResult = e; + if (!e.getClass().isAssignableFrom(((Class) result))) { + e.printStackTrace(); + fail(String.format("Incompatible exception class thrown. Expected %s but was %s.", result.toString(), e.getClass())); + } + } + } else if (value instanceof Object[]) { + actualResult = executeWith(root, (Object[]) value); + assertEquals(result, actualResult); } else { - assertEquals(result, executeWith(root, testValues)); + actualResult = executeWith(root, value); + assertEquals(result, actualResult); + } + if (listener != null) { + listener.afterExecution(root, index, value, result, actualResult, last); } } + public static final class LogListener implements ExecutionListener { + + public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { + System.out.printf("Run %3d Node:%-20s Parameters: %10s Expected: %10s Result %10s%n", index, node.getNode().getClass().getSimpleName(), value, expectedResult, actualResult); + } + + } + + interface ExecutionListener { + + void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last); + + } + } diff -r bd28da642eea -r 5148aab962af graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java Mon Aug 11 15:53:05 2014 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.truffle.api.dsl.test; +import java.math.*; + import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; @@ -29,7 +31,7 @@ public class TypeSystemTest { - @TypeSystem({int.class, boolean.class, String.class, CallTarget.class, BExtendsAbstract.class, CExtendsAbstract.class, Abstract.class, Object[].class}) + @TypeSystem({int.class, double.class, boolean.class, BigInteger.class, String.class, CallTarget.class, BExtendsAbstract.class, CExtendsAbstract.class, Abstract.class, Object[].class}) static class SimpleTypes { static int intCheck; @@ -47,10 +49,20 @@ return (int) value; } + @ImplicitCast + public double castDouble(int value) { + return value; + } + + @ImplicitCast + public BigInteger castBigInteger(int value) { + return BigInteger.valueOf(value); + } + } @TypeSystemReference(SimpleTypes.class) - public abstract static class ValueNode extends Node { + public static class ValueNode extends Node { public ValueNode() { super(null); @@ -72,6 +84,10 @@ return SimpleTypesGen.SIMPLETYPES.expectObjectArray(execute(frame)); } + public BigInteger executeBigInteger(VirtualFrame frame) throws UnexpectedResultException { + return SimpleTypesGen.SIMPLETYPES.expectBigInteger(execute(frame)); + } + public BExtendsAbstract executeBExtendsAbstract(VirtualFrame frame) throws UnexpectedResultException { return SimpleTypesGen.SIMPLETYPES.expectBExtendsAbstract(execute(frame)); } @@ -80,7 +96,17 @@ return SimpleTypesGen.SIMPLETYPES.expectCExtendsAbstract(execute(frame)); } - public abstract Object execute(VirtualFrame frame); + public Abstract executeAbstract(VirtualFrame frame) throws UnexpectedResultException { + return SimpleTypesGen.SIMPLETYPES.expectAbstract(execute(frame)); + } + + public double executeDouble(VirtualFrame frame) throws UnexpectedResultException { + return SimpleTypesGen.SIMPLETYPES.expectDouble(execute(frame)); + } + + public Object execute(@SuppressWarnings("unused") VirtualFrame frame) { + throw new UnsupportedOperationException(); + } @Override public ValueNode copy() {