Mercurial > hg > graal-compiler
diff graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MethodGuardsTest.java @ 19289:62c43fcf5be2
Truffle-DSL: implement @Cached and fixes for the new guard expression syntax.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Tue, 03 Feb 2015 15:07:07 +0100 |
parents | 08aa0372dad4 |
children | 953c813b8e7a |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MethodGuardsTest.java Mon Dec 29 18:32:03 2014 +0100 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MethodGuardsTest.java Tue Feb 03 15:07:07 2015 +0100 @@ -27,295 +27,473 @@ import org.junit.*; +import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.Guard1Factory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.Guard2Factory; -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.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.Interface; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; +import com.oracle.truffle.api.dsl.test.LimitTestFactory.ConstantLimitTestFactory; +import com.oracle.truffle.api.dsl.test.LimitTestFactory.LocalLimitTestFactory; +import com.oracle.truffle.api.dsl.test.LimitTestFactory.MethodLimitTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardCompareWithFieldTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardComplexTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardEqualTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardFieldTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardGreaterEqualTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardGreaterTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardLessEqualTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardLessTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardMethodTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardMultipleAndMethodTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardMultipleOrMethodTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardNotTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardOrTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardStaticFieldTestFactory; +import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardUnboundMethodTestFactory; import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; @SuppressWarnings("unused") public class MethodGuardsTest { - private static final Object NULL = new Object(); + @Test + public void testGuardEqual() { + CallTarget root = createCallTarget(GuardEqualTestFactory.getInstance()); + assertEquals("do1", root.call(1)); + assertEquals("do2", root.call(2)); + assertEquals("do1", root.call(1)); + } + + @NodeChild + static class GuardEqualTest extends ValueNode { + @Specialization(guards = "value == 1") + static String do1(int value) { + return "do1"; + } + + @Specialization + static String do2(int value) { + return "do2"; + } + } @Test - public void testInvocations() { - TestRootNode<Guard1> root = createRoot(Guard1Factory.getInstance()); - - assertEquals(Integer.MAX_VALUE, executeWith(root, Integer.MAX_VALUE - 1)); - assertEquals(1, Guard1.specializedInvocations); - assertEquals(0, Guard1.genericInvocations); - - assertEquals(42, executeWith(root, Integer.MAX_VALUE)); - assertEquals(1, Guard1.specializedInvocations); - assertEquals(1, Guard1.genericInvocations); + public void testGuardLessEqual() { + CallTarget root = createCallTarget(GuardLessEqualTestFactory.getInstance()); + assertEquals("do1", root.call(1)); + assertEquals("do1", root.call(0)); + assertEquals("do2", root.call(2)); + assertEquals("do1", root.call(0)); } @NodeChild - static class Guard1 extends ValueNode { - - static int specializedInvocations = 0; - static int genericInvocations = 0; - - boolean g(int value0) { - return value0 != Integer.MAX_VALUE; + static class GuardLessEqualTest extends ValueNode { + @Specialization(guards = "value <= 1") + static String do1(int value) { + return "do1"; } - @Specialization(guards = "g(value0)") - int f1(int value0) { - specializedInvocations++; - return value0 + 1; + @Specialization + static String do2(int value) { + return "do2"; + } + } + + @Test + public void testGuardLess() { + CallTarget root = createCallTarget(GuardLessTestFactory.getInstance()); + assertEquals("do1", root.call(0)); + assertEquals("do2", root.call(1)); + assertEquals("do2", root.call(2)); + assertEquals("do1", root.call(-1)); + } + + @NodeChild + static class GuardLessTest extends ValueNode { + @Specialization(guards = "value < 1") + static String do1(int value) { + return "do1"; } - @Fallback - int f2(Object value0) { - genericInvocations++; - return 42; + @Specialization + static String do2(int value) { + return "do2"; + } + } + + @Test + public void testGuardGreaterEqual() { + CallTarget root = createCallTarget(GuardGreaterEqualTestFactory.getInstance()); + assertEquals("do1", root.call(1)); + assertEquals("do2", root.call(0)); + assertEquals("do1", root.call(2)); + assertEquals("do2", root.call(0)); + } + + @NodeChild + static class GuardGreaterEqualTest extends ValueNode { + @Specialization(guards = "value >= 1") + static String do1(int value) { + return "do1"; + } + + @Specialization + static String do2(int value) { + return "do2"; } } @Test - public void testGuardSideEffect() { - TestRootNode<Guard2> root = createRoot(Guard2Factory.getInstance()); - - assertEquals(42, executeWith(root, NULL)); - - Guard2.globalFlag = true; - assertEquals(41, executeWith(root, NULL)); - - Guard2.globalFlag = false; - assertEquals(42, executeWith(root, NULL)); + public void testGuardGreater() { + CallTarget root = createCallTarget(GuardGreaterTestFactory.getInstance()); + assertEquals("do1", root.call(2)); + assertEquals("do2", root.call(0)); + assertEquals("do2", root.call(1)); + assertEquals("do2", root.call(0)); } @NodeChild - static class Guard2 extends ValueNode { - - static boolean globalFlag = false; - - static boolean globalFlagGuard() { - return globalFlag; + static class GuardGreaterTest extends ValueNode { + @Specialization(guards = "value > 1") + static String do1(int value) { + return "do1"; } - @Specialization(guards = "globalFlagGuard()") - int f1(Object value0) { - return 41; + @Specialization + static String do2(int value) { + return "do2"; + } + } + + @Test + public void testGuardOr() { + CallTarget root = createCallTarget(GuardOrTestFactory.getInstance()); + assertEquals("do1", root.call(1)); + assertEquals("do1", root.call(0)); + assertEquals("do2", root.call(2)); + assertEquals("do2", root.call(-1)); + } + + @NodeChild + static class GuardOrTest extends ValueNode { + @Specialization(guards = "value == 1 || value == 0") + static String do1(int value) { + return "do1"; } - @Fallback - int f2(Object value0) { - return 42; // the generic answer to all questions + @Specialization + static String do2(int value) { + return "do2"; } } @Test - public void testGuardWithBaseClass() { - TestRootNode<?> root = createRoot(GuardWithBaseClassFactory.getInstance()); - - assertEquals(42, executeWith(root, new BExtendsAbstract())); + public void testGuardNot() { + CallTarget root = createCallTarget(GuardNotTestFactory.getInstance()); + assertEquals("do1", root.call(0)); + assertEquals("do1", root.call(2)); + assertEquals("do2", root.call(1)); + assertEquals("do1", root.call(0)); } - @NodeChild("expression") - public abstract static class GuardWithBaseClass extends ValueNode { - - boolean baseGuard(Abstract base) { - return true; + @NodeChild + static class GuardNotTest extends ValueNode { + @Specialization(guards = "!(value == 1)") + static String do1(int value) { + return "do1"; } - @Specialization(guards = "baseGuard(value0)") - int doSpecialized(BExtendsAbstract value0) { - return 42; - } - } - - @NodeChild("expression") - public abstract static class GuardWithBaseInterface extends ValueNode { - - boolean baseGuard(CharSequence base) { - return true; - } - - @Specialization(guards = "baseGuard(value0)") - int doSpecialized(String value0) { - return 42; + @Specialization + static String do2(int value) { + return "do2"; } } @Test - public void testGuardWithPrimitive() { - TestRootNode<?> root = createRoot(GuardWithBoxedPrimitiveFactory.getInstance()); + public void testGuardField() { + CallTarget root = createCallTarget(GuardFieldTestFactory.getInstance()); + GuardFieldTest node = getNode(root); + node.field = true; + assertEquals("do1", root.call(0)); + assertEquals("do1", root.call(2)); - assertEquals(42, executeWith(root, 42)); + node.field = false; + try { + root.call(2); + fail("expected Assertion failed"); + } catch (AssertionError e) { + } } - @NodeChild("expression") - public abstract static class GuardWithBoxedPrimitive extends ValueNode { + @NodeChild + static class GuardFieldTest extends ValueNode { - boolean baseGuard(Integer primitive) { - return true; + boolean field; + + @Specialization(guards = "field") + static String do1(int value) { + return "do1"; } - @Specialization(guards = "baseGuard(value0)") - int doSpecialized(int value0) { - return value0; + @Specialization + static String do2(int value) { + return "do2"; + } + } + + @Test + public void testGuardCompareWithField() { + CallTarget root = createCallTarget(GuardCompareWithFieldTestFactory.getInstance()); + GuardCompareWithFieldTest node = getNode(root); + node.field = 1; + assertEquals("do1", root.call(1)); + assertEquals("do2", root.call(2)); + + node.field = 2; + assertEquals("do2", root.call(1)); + assertEquals("do1", root.call(2)); + } + + @NodeChild + static class GuardCompareWithFieldTest extends ValueNode { + + int field; + + @Specialization(guards = "value == field") + static String do1(int value) { + return "do1"; + } + + @Specialization + static String do2(int value) { + return "do2"; } } @Test - public void testGuardWithObject() { - TestRootNode<?> root = createRoot(GuardWithObjectFactory.getInstance()); - - assertEquals(42, executeWith(root, 42)); + public void testGuardStaticField() { + CallTarget root = createCallTarget(GuardStaticFieldTestFactory.getInstance()); + GuardStaticFieldTest.field = true; + assertEquals("do1", root.call(1)); + assertEquals("do1", root.call(2)); + GuardStaticFieldTest.field = false; + try { + root.call(2); + fail("expected Assertion failed"); + } catch (AssertionError e) { + } } - @NodeChild("expression") - public abstract static class GuardWithObject extends ValueNode { + @NodeChild + static class GuardStaticFieldTest extends ValueNode { - boolean baseGuard(Object primitive) { - return true; + static boolean field; + + @Specialization(guards = "field") + static String do1(int value) { + return "do1"; } - @Specialization(guards = "baseGuard(value0)") - int doSpecialized(int value0) { - return value0; + @Specialization + static String do2(int value) { + return "do2"; } } @Test - public void testGuardResolve1() { - TestRootNode<?> root = createRoot(TestGuardResolve1Factory.getInstance()); - - assertEquals(42, executeWith(root, 42)); + public void testGuardMethod() { + CallTarget root = createCallTarget(GuardMethodTestFactory.getInstance()); + assertEquals("do1", root.call(1)); + assertEquals("do2", root.call(2)); + assertEquals("do1", root.call(1)); + assertEquals("do2", root.call(0)); } - @NodeChild("expression") - public abstract static class TestGuardResolve1 extends ValueNode { + @NodeChild + static class GuardMethodTest extends ValueNode { - boolean guard(Object primitive) { - return false; + @Specialization(guards = "method(value)") + static String do1(int value) { + return "do1"; } - boolean guard(int primitive) { - return true; + @Specialization + static String do2(int value) { + return "do2"; } - @Specialization(guards = "guard(value0)") - int doSpecialized(int value0) { - return value0; + boolean method(int value) { + return value == 1; } } @Test - public void testGuardResolve2() { - TestRootNode<?> root = createRoot(TestGuardResolve2Factory.getInstance()); - assertEquals(42, executeWith(root, new BExtendsAbstract())); + public void testGuardUnboundMethodField() { + CallTarget root = createCallTarget(GuardUnboundMethodTestFactory.getInstance()); + GuardUnboundMethodTest node = getNode(root); + node.hiddenValue = true; + assertEquals("do1", root.call(1)); + assertEquals("do1", root.call(2)); + node.hiddenValue = false; + try { + root.call(2); + fail("expected Assertion failed"); + } catch (AssertionError e) { + } } - @NodeChild("expression") - public abstract static class TestGuardResolve2 extends ValueNode { + @NodeChild + static class GuardUnboundMethodTest extends ValueNode { - boolean guard(Object primitive) { - return false; + private boolean hiddenValue; + + @Specialization(guards = "method()") + static String do1(int value) { + return "do1"; } - boolean guard(Abstract primitive) { - return true; + boolean method() { + return hiddenValue; + } + } + + @Test + public void testStaticGuardMethod() { + CallTarget root = createCallTarget(GuardMethodTestFactory.getInstance()); + assertEquals("do1", root.call(1)); + assertEquals("do2", root.call(2)); + assertEquals("do1", root.call(1)); + assertEquals("do2", root.call(0)); + } + + @NodeChild + static class StaticGuardMethodTest extends ValueNode { + + @Specialization(guards = "method(value)") + static String do1(int value) { + return "do1"; } - @Specialization(guards = "guard(value0)") - int doSpecialized(BExtendsAbstract value0) { - return 42; + @Specialization + static String do2(int value) { + return "do2"; + } + + static boolean method(int value) { + return value == 1; } } @Test - public void testGuardResolve3() { - TestRootNode<?> root = createRoot(TestGuardResolve3Factory.getInstance()); - - assertEquals(42, executeWith(root, new BExtendsAbstract())); + public void testMultipleGuardAndMethod() { + CallTarget root = createCallTarget(GuardMultipleAndMethodTestFactory.getInstance()); + assertEquals("do1", root.call(1)); + assertEquals("do1", root.call(2)); + assertEquals("do2", root.call(3)); + assertEquals("do2", root.call(0)); } - @NodeChild("expression") - public abstract static class TestGuardResolve3 extends ValueNode { - - boolean guard(Object primitive) { - return false; - } + @NodeChild + static class GuardMultipleAndMethodTest extends ValueNode { - boolean guard(Abstract primitive) { - return false; - } - - boolean guard(BExtendsAbstract primitive) { - return true; + @Specialization(guards = {"method1(value)", "method2(value)"}) + static String do1(int value) { + return "do1"; } - @Specialization(guards = "guard(value0)") - int doSpecialized(BExtendsAbstract value0) { - return 42; - } - } - - @NodeChild("expression") - public abstract static class TestGuardResolve4 extends ValueNode { - - boolean guard(Abstract primitive) { - return false; + @Specialization + static String do2(int value) { + return "do2"; } - @Specialization(guards = "guard(value0)") - int doSpecialized(BExtendsAbstract value0) { - return 42; - } - } - - @NodeChildren({@NodeChild("a"), @NodeChild("b")}) - abstract static class TestGuardResolve5 extends ValueNode { - - @Specialization(guards = "guard(left, right)") - int add(Interface left, Interface right) { - return 42; + boolean method1(int value) { + return value >= 1; } - boolean guard(Interface left, Object right) { - return true; + boolean method2(int value) { + return value <= 2; } } @Test - public void testAbstractGuard1() { - TestRootNode<?> root = createRoot(TestAbstractGuard1Factory.getInstance()); - - assertEquals(BExtendsAbstract.INSTANCE, executeWith(root, BExtendsAbstract.INSTANCE)); - assertEquals(CExtendsAbstract.INSTANCE, executeWith(root, CExtendsAbstract.INSTANCE)); + public void testMultipleGuardOrMethod() { + CallTarget root = createCallTarget(GuardMultipleOrMethodTestFactory.getInstance()); + assertEquals("do1", root.call(1)); + assertEquals("do1", root.call(2)); + assertEquals("do2", root.call(3)); + assertEquals("do2", root.call(0)); } - @NodeChild("expression") - public abstract static class TestAbstractGuard1 extends ValueNode { + @NodeChild + static class GuardMultipleOrMethodTest extends ValueNode { - boolean guard(Abstract value0) { - return true; + @Specialization(guards = {"method1(value) || method2(value)"}) + static String do1(int value) { + return "do1"; } - @Specialization(guards = "guard(value0)") - BExtendsAbstract do1(BExtendsAbstract value0) { - return value0; + @Specialization + static String do2(int value) { + return "do2"; } - @Specialization(guards = "guard(value0)") - CExtendsAbstract do2(CExtendsAbstract value0) { - return value0; + boolean method1(int value) { + return value == 1; + } + + boolean method2(int value) { + return value == 2; } } + @Test + public void testComplexGuard() { + CallTarget root = createCallTarget(GuardComplexTestFactory.getInstance()); + assertEquals("do1", root.call(1)); + assertEquals("do1", root.call(2)); + assertEquals("do2", root.call(3)); + assertEquals("do1", root.call(0)); + } + + @NodeChild + static class GuardComplexTest extends ValueNode { + + int field1 = 1; + static int field2 = 2; + + @Specialization(guards = {"method2(method1(field1 == 1), value <= 2)", "field2 == 2"}) + static String do1(int value) { + return "do1"; + } + + @Specialization + static String do2(int value) { + return "do2"; + } + + static boolean method1(boolean value) { + return value; + } + + boolean method2(boolean value1, boolean value2) { + return value1 && value2; + } + } + + @NodeChild + static class ErrorGuardNotTest extends ValueNode { + @ExpectError("Error parsing expression '!value == 1': The operator ! is undefined for the argument type int.") + @Specialization(guards = "!value == 1") + static String do1(int value) { + return "do1"; + } + } + + @NodeChild + static class ErrorIncompatibleReturnTypeTest extends ValueNode { + + @ExpectError("Incompatible return type int. Guards must return boolean.") + @Specialization(guards = "1") + static String do1(int value) { + return "do1"; + } + + } + }