/* * 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 org.junit.Assert.assertEquals; import org.junit.Test; import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.dsl.ImplicitCast; import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.dsl.NodeChildren; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.TypeSystem; import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.DoubleChildNodeFactory; import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.ShortCircuitWithImplicitCastNodeFactory; import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.SingleChildNodeFactory; import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.VarArgsNodeFactory; import com.oracle.truffle.api.dsl.test.TypeSystemTest.ArgumentNode; import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; public class ShortCircuitTest { @Test public void testSingleChild1() { ArgumentNode arg0 = new ArgumentNode(0); CallTarget callTarget = TestHelper.createCallTarget(SingleChildNodeFactory.create(arg0)); SingleChildNode.needsChild = true; assertEquals(42, callTarget.call(new Object[]{42})); assertEquals(1, arg0.getInvocationCount()); } @Test public void testSingleChild2() { ArgumentNode arg0 = new ArgumentNode(0); CallTarget callTarget = TestHelper.createCallTarget(SingleChildNodeFactory.create(arg0)); SingleChildNode.needsChild = false; assertEquals(0, callTarget.call(new Object[]{42})); assertEquals(0, arg0.getInvocationCount()); } @NodeChild("child0") abstract static class SingleChildNode extends ValueNode { static boolean needsChild; @SuppressWarnings("deprecation") @com.oracle.truffle.api.dsl.ShortCircuit("child0") boolean needsChild0() { return needsChild; } @Specialization int doIt(boolean hasChild0, int child0) { assert hasChild0 == needsChild0(); return child0; } } @Test public void testDoubleChild1() { ArgumentNode arg0 = new ArgumentNode(0); ArgumentNode arg1 = new ArgumentNode(1); CallTarget callTarget = TestHelper.createCallTarget(DoubleChildNodeFactory.create(arg0, arg1)); assertEquals(42, callTarget.call(new Object[]{41, 42})); assertEquals(1, arg1.getInvocationCount()); } @Test public void testDoubleChild2() { ArgumentNode arg0 = new ArgumentNode(0); ArgumentNode arg1 = new ArgumentNode(1); CallTarget callTarget = TestHelper.createCallTarget(DoubleChildNodeFactory.create(arg0, arg1)); assertEquals(0, callTarget.call(new Object[]{42, 42})); assertEquals(0, arg1.getInvocationCount()); } @NodeChildren({@NodeChild("child0"), @NodeChild("child1")}) @SuppressWarnings("unused") abstract static class DoubleChildNode extends ValueNode { @SuppressWarnings("deprecation") @com.oracle.truffle.api.dsl.ShortCircuit("child1") boolean needsChild1(Object leftValue) { return leftValue.equals(41); } @Specialization int doIt(int child0, boolean hasChild1, int child1) { return child1; } } @NodeChildren({@NodeChild("child0"), @NodeChild("child1")}) @SuppressWarnings("unused") abstract static class GuardChildNode extends ValueNode { @SuppressWarnings("deprecation") @com.oracle.truffle.api.dsl.ShortCircuit("child1") boolean needsChild1(Object a) { return a.equals(new Integer(42)); } static boolean guard(int a, boolean hasB, int b) { return false; } @Specialization(guards = "guard(a, hasB, b)") int doIt(int a, boolean hasB, int b) { return a + b; } } @Test public void testVarArgs1() { ArgumentNode arg0 = new ArgumentNode(0); ArgumentNode arg1 = new ArgumentNode(1); CallTarget callTarget = TestHelper.createCallTarget(VarArgsNodeFactory.create(new ValueNode[]{arg0, arg1})); assertEquals(42, callTarget.call(new Object[]{41, 42})); assertEquals(1, arg1.getInvocationCount()); } @Test public void testVarArgs2() { ArgumentNode arg0 = new ArgumentNode(0); ArgumentNode arg1 = new ArgumentNode(1); CallTarget callTarget = TestHelper.createCallTarget(VarArgsNodeFactory.create(new ValueNode[]{arg0, arg1})); assertEquals(0, callTarget.call(new Object[]{42, 42})); assertEquals(0, arg1.getInvocationCount()); } @NodeChild(value = "children", type = ValueNode[].class) abstract static class VarArgsNode extends ValueNode { @SuppressWarnings("deprecation") @com.oracle.truffle.api.dsl.ShortCircuit("children[1]") boolean needsChild1(Object leftValue) { return leftValue.equals(41); } @Specialization @SuppressWarnings("unused") int doIt(int child0, boolean hasChild1, int child1) { return child1; } } @Test public void testShortCircuitWithImplicitCastNode() { ArgumentNode arg0 = new ArgumentNode(0); ArgumentNode arg1 = new ArgumentNode(1); CallTarget callTarget = TestHelper.createCallTarget(ShortCircuitWithImplicitCastNodeFactory.create(new ValueNode[]{arg0, arg1})); assertEquals(42, callTarget.call(new Object[]{42, 41})); } @TypeSystem(int.class) abstract static class ShortCircuitWithImplicitCastTypes { @ImplicitCast public static int doAnImplicitCast(String foo) { return Integer.parseInt(foo); } } @NodeChild(value = "children", type = ValueNode[].class) @TypeSystemReference(ShortCircuitWithImplicitCastTypes.class) abstract static class ShortCircuitWithImplicitCastNode extends ValueNode { @SuppressWarnings("deprecation") @com.oracle.truffle.api.dsl.ShortCircuit("children[1]") public boolean needsRightNode(Object left) { return (int) left == 41; } @Specialization public int doInteger(int left, boolean needsRight, int right) { return needsRight ? right : left; } } }